OSDN Git Service

8d61bb61cbe5220ecb903461763a9cd13b550c26
[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
63 ;; UNSPEC usage:
64
65 (define_c_enum "unspec" [
66   ;; Relocation specifiers
67   UNSPEC_GOT
68   UNSPEC_GOTOFF
69   UNSPEC_GOTPCREL
70   UNSPEC_GOTTPOFF
71   UNSPEC_TPOFF
72   UNSPEC_NTPOFF
73   UNSPEC_DTPOFF
74   UNSPEC_GOTNTPOFF
75   UNSPEC_INDNTPOFF
76   UNSPEC_PLTOFF
77   UNSPEC_MACHOPIC_OFFSET
78
79   ;; Prologue support
80   UNSPEC_STACK_ALLOC
81   UNSPEC_SET_GOT
82   UNSPEC_REG_SAVE
83   UNSPEC_DEF_CFA
84   UNSPEC_SET_RIP
85   UNSPEC_SET_GOT_OFFSET
86   UNSPEC_MEMORY_BLOCKAGE
87
88   ;; TLS support
89   UNSPEC_TP
90   UNSPEC_TLS_GD
91   UNSPEC_TLS_LD_BASE
92   UNSPEC_TLSDESC
93
94   ;; Other random patterns
95   UNSPEC_SCAS
96   UNSPEC_FNSTSW
97   UNSPEC_SAHF
98   UNSPEC_PARITY
99   UNSPEC_FSTCW
100   UNSPEC_ADD_CARRY
101   UNSPEC_FLDCW
102   UNSPEC_REP
103   UNSPEC_LD_MPIC        ; load_macho_picbase
104   UNSPEC_TRUNC_NOOP
105
106   ;; For SSE/MMX support:
107   UNSPEC_FIX_NOTRUNC
108   UNSPEC_MASKMOV
109   UNSPEC_MOVMSK
110   UNSPEC_MOVNT
111   UNSPEC_MOVU
112   UNSPEC_RCP
113   UNSPEC_RSQRT
114   UNSPEC_SFENCE
115   UNSPEC_PFRCP
116   UNSPEC_PFRCPIT1
117   UNSPEC_PFRCPIT2
118   UNSPEC_PFRSQRT
119   UNSPEC_PFRSQIT1
120   UNSPEC_MFENCE
121   UNSPEC_LFENCE
122   UNSPEC_PSADBW
123   UNSPEC_LDDQU
124   UNSPEC_MS_TO_SYSV_CALL
125
126   ;; Generic math support
127   UNSPEC_COPYSIGN
128   UNSPEC_IEEE_MIN       ; not commutative
129   UNSPEC_IEEE_MAX       ; not commutative
130
131   ;; x87 Floating point
132   UNSPEC_SIN
133   UNSPEC_COS
134   UNSPEC_FPATAN
135   UNSPEC_FYL2X
136   UNSPEC_FYL2XP1
137   UNSPEC_FRNDINT
138   UNSPEC_FIST
139   UNSPEC_F2XM1
140   UNSPEC_TAN
141   UNSPEC_FXAM
142
143   ;; x87 Rounding
144   UNSPEC_FRNDINT_FLOOR
145   UNSPEC_FRNDINT_CEIL
146   UNSPEC_FRNDINT_TRUNC
147   UNSPEC_FRNDINT_MASK_PM
148   UNSPEC_FIST_FLOOR
149   UNSPEC_FIST_CEIL
150
151   ;; x87 Double output FP
152   UNSPEC_SINCOS_COS
153   UNSPEC_SINCOS_SIN
154   UNSPEC_XTRACT_FRACT
155   UNSPEC_XTRACT_EXP
156   UNSPEC_FSCALE_FRACT
157   UNSPEC_FSCALE_EXP
158   UNSPEC_FPREM_F
159   UNSPEC_FPREM_U
160   UNSPEC_FPREM1_F
161   UNSPEC_FPREM1_U
162
163   UNSPEC_C2_FLAG
164   UNSPEC_FXAM_MEM
165
166   ;; SSP patterns
167   UNSPEC_SP_SET
168   UNSPEC_SP_TEST
169   UNSPEC_SP_TLS_SET
170   UNSPEC_SP_TLS_TEST
171
172   ;; SSSE3
173   UNSPEC_PSHUFB
174   UNSPEC_PSIGN
175   UNSPEC_PALIGNR
176
177   ;; For SSE4A support
178   UNSPEC_EXTRQI
179   UNSPEC_EXTRQ
180   UNSPEC_INSERTQI
181   UNSPEC_INSERTQ
182
183   ;; For SSE4.1 support
184   UNSPEC_BLENDV
185   UNSPEC_INSERTPS
186   UNSPEC_DP
187   UNSPEC_MOVNTDQA
188   UNSPEC_MPSADBW
189   UNSPEC_PHMINPOSUW
190   UNSPEC_PTEST
191   UNSPEC_ROUND
192
193   ;; For SSE4.2 support
194   UNSPEC_CRC32
195   UNSPEC_PCMPESTR
196   UNSPEC_PCMPISTR
197
198   ;; For FMA4 support
199   UNSPEC_FMA4_INTRINSIC
200   UNSPEC_FMA4_FMADDSUB
201   UNSPEC_FMA4_FMSUBADD
202   UNSPEC_XOP_UNSIGNED_CMP
203   UNSPEC_XOP_TRUEFALSE
204   UNSPEC_XOP_PERMUTE
205   UNSPEC_FRCZ
206
207   ;; For AES support
208   UNSPEC_AESENC
209   UNSPEC_AESENCLAST
210   UNSPEC_AESDEC
211   UNSPEC_AESDECLAST
212   UNSPEC_AESIMC
213   UNSPEC_AESKEYGENASSIST
214
215   ;; For PCLMUL support
216   UNSPEC_PCLMUL
217
218   ;; For AVX support
219   UNSPEC_PCMP
220   UNSPEC_VPERMIL
221   UNSPEC_VPERMIL2
222   UNSPEC_VPERMIL2F128
223   UNSPEC_MASKLOAD
224   UNSPEC_MASKSTORE
225   UNSPEC_CAST
226   UNSPEC_VTESTP
227   UNSPEC_VCVTPH2PS
228   UNSPEC_VCVTPS2PH
229 ])
230
231 (define_c_enum "unspecv" [
232   UNSPECV_BLOCKAGE
233   UNSPECV_STACK_PROBE
234   UNSPECV_PROBE_STACK_RANGE
235   UNSPECV_EMMS
236   UNSPECV_LDMXCSR
237   UNSPECV_STMXCSR
238   UNSPECV_FEMMS
239   UNSPECV_CLFLUSH
240   UNSPECV_ALIGN
241   UNSPECV_MONITOR
242   UNSPECV_MWAIT
243   UNSPECV_CMPXCHG
244   UNSPECV_XCHG
245   UNSPECV_LOCK
246   UNSPECV_PROLOGUE_USE
247   UNSPECV_CLD
248   UNSPECV_VZEROALL
249   UNSPECV_VZEROUPPER
250   UNSPECV_RDTSC
251   UNSPECV_RDTSCP
252   UNSPECV_RDPMC
253   UNSPECV_LLWP_INTRINSIC
254   UNSPECV_SLWP_INTRINSIC
255   UNSPECV_LWPVAL_INTRINSIC
256   UNSPECV_LWPINS_INTRINSIC
257   UNSPECV_RDFSBASE
258   UNSPECV_RDGSBASE
259   UNSPECV_WRFSBASE
260   UNSPECV_WRGSBASE
261   UNSPECV_RDRAND
262 ])
263
264 ;; Constants to represent pcomtrue/pcomfalse variants
265 (define_constants
266   [(PCOM_FALSE                  0)
267    (PCOM_TRUE                   1)
268    (COM_FALSE_S                 2)
269    (COM_FALSE_P                 3)
270    (COM_TRUE_S                  4)
271    (COM_TRUE_P                  5)
272   ])
273
274 ;; Constants used in the XOP pperm instruction
275 (define_constants
276   [(PPERM_SRC                   0x00)   /* copy source */
277    (PPERM_INVERT                0x20)   /* invert source */
278    (PPERM_REVERSE               0x40)   /* bit reverse source */
279    (PPERM_REV_INV               0x60)   /* bit reverse & invert src */
280    (PPERM_ZERO                  0x80)   /* all 0's */
281    (PPERM_ONES                  0xa0)   /* all 1's */
282    (PPERM_SIGN                  0xc0)   /* propagate sign bit */
283    (PPERM_INV_SIGN              0xe0)   /* invert & propagate sign */
284    (PPERM_SRC1                  0x00)   /* use first source byte */
285    (PPERM_SRC2                  0x10)   /* use second source byte */
286    ])
287
288 ;; Registers by name.
289 (define_constants
290   [(AX_REG                       0)
291    (DX_REG                       1)
292    (CX_REG                       2)
293    (BX_REG                       3)
294    (SI_REG                       4)
295    (DI_REG                       5)
296    (BP_REG                       6)
297    (SP_REG                       7)
298    (ST0_REG                      8)
299    (ST1_REG                      9)
300    (ST2_REG                     10)
301    (ST3_REG                     11)
302    (ST4_REG                     12)
303    (ST5_REG                     13)
304    (ST6_REG                     14)
305    (ST7_REG                     15)
306    (FLAGS_REG                   17)
307    (FPSR_REG                    18)
308    (FPCR_REG                    19)
309    (XMM0_REG                    21)
310    (XMM1_REG                    22)
311    (XMM2_REG                    23)
312    (XMM3_REG                    24)
313    (XMM4_REG                    25)
314    (XMM5_REG                    26)
315    (XMM6_REG                    27)
316    (XMM7_REG                    28)
317    (MM0_REG                     29)
318    (MM1_REG                     30)
319    (MM2_REG                     31)
320    (MM3_REG                     32)
321    (MM4_REG                     33)
322    (MM5_REG                     34)
323    (MM6_REG                     35)
324    (MM7_REG                     36)
325    (R8_REG                      37)
326    (R9_REG                      38)
327    (R10_REG                     39)
328    (R11_REG                     40)
329    (R12_REG                     41)
330    (R13_REG                     42)
331    (XMM8_REG                    45)
332    (XMM9_REG                    46)
333    (XMM10_REG                   47)
334    (XMM11_REG                   48)
335    (XMM12_REG                   49)
336    (XMM13_REG                   50)
337    (XMM14_REG                   51)
338    (XMM15_REG                   52)
339   ])
340
341 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
342 ;; from i386.c.
343
344 ;; In C guard expressions, put expressions which may be compile-time
345 ;; constants first.  This allows for better optimization.  For
346 ;; example, write "TARGET_64BIT && reload_completed", not
347 ;; "reload_completed && TARGET_64BIT".
348
349 \f
350 ;; Processor type.
351 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,atom,
352                     generic64,amdfam10,bdver1"
353   (const (symbol_ref "ix86_schedule")))
354
355 ;; A basic instruction type.  Refinements due to arguments to be
356 ;; provided in other attributes.
357 (define_attr "type"
358   "other,multi,
359    alu,alu1,negnot,imov,imovx,lea,
360    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
361    icmp,test,ibr,setcc,icmov,
362    push,pop,call,callv,leave,
363    str,bitmanip,
364    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
365    sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
366    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
367    ssemuladd,sse4arg,lwp,
368    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
369   (const_string "other"))
370
371 ;; Main data type used by the insn
372 (define_attr "mode"
373   "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
374   (const_string "unknown"))
375
376 ;; The CPU unit operations uses.
377 (define_attr "unit" "integer,i387,sse,mmx,unknown"
378   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
379            (const_string "i387")
380          (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
381                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
382                           ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
383            (const_string "sse")
384          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
385            (const_string "mmx")
386          (eq_attr "type" "other")
387            (const_string "unknown")]
388          (const_string "integer")))
389
390 ;; The (bounding maximum) length of an instruction immediate.
391 (define_attr "length_immediate" ""
392   (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
393                           bitmanip")
394            (const_int 0)
395          (eq_attr "unit" "i387,sse,mmx")
396            (const_int 0)
397          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
398                           imul,icmp,push,pop")
399            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
400          (eq_attr "type" "imov,test")
401            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
402          (eq_attr "type" "call")
403            (if_then_else (match_operand 0 "constant_call_address_operand" "")
404              (const_int 4)
405              (const_int 0))
406          (eq_attr "type" "callv")
407            (if_then_else (match_operand 1 "constant_call_address_operand" "")
408              (const_int 4)
409              (const_int 0))
410          ;; We don't know the size before shorten_branches.  Expect
411          ;; the instruction to fit for better scheduling.
412          (eq_attr "type" "ibr")
413            (const_int 1)
414          ]
415          (symbol_ref "/* Update immediate_length and other attributes! */
416                       gcc_unreachable (),1")))
417
418 ;; The (bounding maximum) length of an instruction address.
419 (define_attr "length_address" ""
420   (cond [(eq_attr "type" "str,other,multi,fxch")
421            (const_int 0)
422          (and (eq_attr "type" "call")
423               (match_operand 0 "constant_call_address_operand" ""))
424              (const_int 0)
425          (and (eq_attr "type" "callv")
426               (match_operand 1 "constant_call_address_operand" ""))
427              (const_int 0)
428          ]
429          (symbol_ref "ix86_attr_length_address_default (insn)")))
430
431 ;; Set when length prefix is used.
432 (define_attr "prefix_data16" ""
433   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
434            (const_int 0)
435          (eq_attr "mode" "HI")
436            (const_int 1)
437          (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
438            (const_int 1)
439         ]
440         (const_int 0)))
441
442 ;; Set when string REP prefix is used.
443 (define_attr "prefix_rep" ""
444   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
445            (const_int 0)
446          (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
447            (const_int 1)
448         ]
449         (const_int 0)))
450
451 ;; Set when 0f opcode prefix is used.
452 (define_attr "prefix_0f" ""
453   (if_then_else
454     (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
455          (eq_attr "unit" "sse,mmx"))
456     (const_int 1)
457     (const_int 0)))
458
459 ;; Set when REX opcode prefix is used.
460 (define_attr "prefix_rex" ""
461   (cond [(ne (symbol_ref "!TARGET_64BIT") (const_int 0))
462            (const_int 0)
463          (and (eq_attr "mode" "DI")
464               (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
465                    (eq_attr "unit" "!mmx")))
466            (const_int 1)
467          (and (eq_attr "mode" "QI")
468               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
469                   (const_int 0)))
470            (const_int 1)
471          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
472              (const_int 0))
473            (const_int 1)
474          (and (eq_attr "type" "imovx")
475               (match_operand:QI 1 "ext_QIreg_operand" ""))
476            (const_int 1)
477         ]
478         (const_int 0)))
479
480 ;; There are also additional prefixes in 3DNOW, SSSE3.
481 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
482 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
483 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
484 (define_attr "prefix_extra" ""
485   (cond [(eq_attr "type" "ssemuladd,sse4arg")
486            (const_int 2)
487          (eq_attr "type" "sseiadd1,ssecvt1")
488            (const_int 1)
489         ]
490         (const_int 0)))
491
492 ;; Prefix used: original, VEX or maybe VEX.
493 (define_attr "prefix" "orig,vex,maybe_vex"
494   (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
495     (const_string "vex")
496     (const_string "orig")))
497
498 ;; VEX W bit is used.
499 (define_attr "prefix_vex_w" "" (const_int 0))
500
501 ;; The length of VEX prefix
502 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
503 ;; 0f38/0f3a prefixes can't.  In i386.md 0f3[8a] is
504 ;; still prefix_0f 1, with prefix_extra 1.
505 (define_attr "length_vex" ""
506   (if_then_else (and (eq_attr "prefix_0f" "1")
507                      (eq_attr "prefix_extra" "0"))
508     (if_then_else (eq_attr "prefix_vex_w" "1")
509       (symbol_ref "ix86_attr_length_vex_default (insn, 1, 1)")
510       (symbol_ref "ix86_attr_length_vex_default (insn, 1, 0)"))
511     (if_then_else (eq_attr "prefix_vex_w" "1")
512       (symbol_ref "ix86_attr_length_vex_default (insn, 0, 1)")
513       (symbol_ref "ix86_attr_length_vex_default (insn, 0, 0)"))))
514
515 ;; Set when modrm byte is used.
516 (define_attr "modrm" ""
517   (cond [(eq_attr "type" "str,leave")
518            (const_int 0)
519          (eq_attr "unit" "i387")
520            (const_int 0)
521          (and (eq_attr "type" "incdec")
522               (and (eq (symbol_ref "TARGET_64BIT") (const_int 0))
523                    (ior (match_operand:SI 1 "register_operand" "")
524                         (match_operand:HI 1 "register_operand" ""))))
525            (const_int 0)
526          (and (eq_attr "type" "push")
527               (not (match_operand 1 "memory_operand" "")))
528            (const_int 0)
529          (and (eq_attr "type" "pop")
530               (not (match_operand 0 "memory_operand" "")))
531            (const_int 0)
532          (and (eq_attr "type" "imov")
533               (and (not (eq_attr "mode" "DI"))
534                    (ior (and (match_operand 0 "register_operand" "")
535                              (match_operand 1 "immediate_operand" ""))
536                         (ior (and (match_operand 0 "ax_reg_operand" "")
537                                   (match_operand 1 "memory_displacement_only_operand" ""))
538                              (and (match_operand 0 "memory_displacement_only_operand" "")
539                                   (match_operand 1 "ax_reg_operand" ""))))))
540            (const_int 0)
541          (and (eq_attr "type" "call")
542               (match_operand 0 "constant_call_address_operand" ""))
543              (const_int 0)
544          (and (eq_attr "type" "callv")
545               (match_operand 1 "constant_call_address_operand" ""))
546              (const_int 0)
547          (and (eq_attr "type" "alu,alu1,icmp,test")
548               (match_operand 0 "ax_reg_operand" ""))
549              (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
550          ]
551          (const_int 1)))
552
553 ;; The (bounding maximum) length of an instruction in bytes.
554 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
555 ;; Later we may want to split them and compute proper length as for
556 ;; other insns.
557 (define_attr "length" ""
558   (cond [(eq_attr "type" "other,multi,fistp,frndint")
559            (const_int 16)
560          (eq_attr "type" "fcmp")
561            (const_int 4)
562          (eq_attr "unit" "i387")
563            (plus (const_int 2)
564                  (plus (attr "prefix_data16")
565                        (attr "length_address")))
566          (ior (eq_attr "prefix" "vex")
567               (and (eq_attr "prefix" "maybe_vex")
568                     (ne (symbol_ref "TARGET_AVX") (const_int 0))))
569            (plus (attr "length_vex")
570                  (plus (attr "length_immediate")
571                        (plus (attr "modrm")
572                              (attr "length_address"))))]
573          (plus (plus (attr "modrm")
574                      (plus (attr "prefix_0f")
575                            (plus (attr "prefix_rex")
576                                  (plus (attr "prefix_extra")
577                                        (const_int 1)))))
578                (plus (attr "prefix_rep")
579                      (plus (attr "prefix_data16")
580                            (plus (attr "length_immediate")
581                                  (attr "length_address")))))))
582
583 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
584 ;; `store' if there is a simple memory reference therein, or `unknown'
585 ;; if the instruction is complex.
586
587 (define_attr "memory" "none,load,store,both,unknown"
588   (cond [(eq_attr "type" "other,multi,str,lwp")
589            (const_string "unknown")
590          (eq_attr "type" "lea,fcmov,fpspc")
591            (const_string "none")
592          (eq_attr "type" "fistp,leave")
593            (const_string "both")
594          (eq_attr "type" "frndint")
595            (const_string "load")
596          (eq_attr "type" "push")
597            (if_then_else (match_operand 1 "memory_operand" "")
598              (const_string "both")
599              (const_string "store"))
600          (eq_attr "type" "pop")
601            (if_then_else (match_operand 0 "memory_operand" "")
602              (const_string "both")
603              (const_string "load"))
604          (eq_attr "type" "setcc")
605            (if_then_else (match_operand 0 "memory_operand" "")
606              (const_string "store")
607              (const_string "none"))
608          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
609            (if_then_else (ior (match_operand 0 "memory_operand" "")
610                               (match_operand 1 "memory_operand" ""))
611              (const_string "load")
612              (const_string "none"))
613          (eq_attr "type" "ibr")
614            (if_then_else (match_operand 0 "memory_operand" "")
615              (const_string "load")
616              (const_string "none"))
617          (eq_attr "type" "call")
618            (if_then_else (match_operand 0 "constant_call_address_operand" "")
619              (const_string "none")
620              (const_string "load"))
621          (eq_attr "type" "callv")
622            (if_then_else (match_operand 1 "constant_call_address_operand" "")
623              (const_string "none")
624              (const_string "load"))
625          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
626               (match_operand 1 "memory_operand" ""))
627            (const_string "both")
628          (and (match_operand 0 "memory_operand" "")
629               (match_operand 1 "memory_operand" ""))
630            (const_string "both")
631          (match_operand 0 "memory_operand" "")
632            (const_string "store")
633          (match_operand 1 "memory_operand" "")
634            (const_string "load")
635          (and (eq_attr "type"
636                  "!alu1,negnot,ishift1,
637                    imov,imovx,icmp,test,bitmanip,
638                    fmov,fcmp,fsgn,
639                    sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
640                    sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
641               (match_operand 2 "memory_operand" ""))
642            (const_string "load")
643          (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
644               (match_operand 3 "memory_operand" ""))
645            (const_string "load")
646         ]
647         (const_string "none")))
648
649 ;; Indicates if an instruction has both an immediate and a displacement.
650
651 (define_attr "imm_disp" "false,true,unknown"
652   (cond [(eq_attr "type" "other,multi")
653            (const_string "unknown")
654          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
655               (and (match_operand 0 "memory_displacement_operand" "")
656                    (match_operand 1 "immediate_operand" "")))
657            (const_string "true")
658          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
659               (and (match_operand 0 "memory_displacement_operand" "")
660                    (match_operand 2 "immediate_operand" "")))
661            (const_string "true")
662         ]
663         (const_string "false")))
664
665 ;; Indicates if an FP operation has an integer source.
666
667 (define_attr "fp_int_src" "false,true"
668   (const_string "false"))
669
670 ;; Defines rounding mode of an FP operation.
671
672 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
673   (const_string "any"))
674
675 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
676 (define_attr "use_carry" "0,1" (const_string "0"))
677
678 ;; Define attribute to indicate unaligned ssemov insns
679 (define_attr "movu" "0,1" (const_string "0"))
680
681 ;; Describe a user's asm statement.
682 (define_asm_attributes
683   [(set_attr "length" "128")
684    (set_attr "type" "multi")])
685
686 (define_code_iterator plusminus [plus minus])
687
688 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
689
690 ;; Base name for define_insn
691 (define_code_attr plusminus_insn
692   [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
693    (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
694
695 ;; Base name for insn mnemonic.
696 (define_code_attr plusminus_mnemonic
697   [(plus "add") (ss_plus "adds") (us_plus "addus")
698    (minus "sub") (ss_minus "subs") (us_minus "subus")])
699 (define_code_attr plusminus_carry_mnemonic
700   [(plus "adc") (minus "sbb")])
701
702 ;; Mark commutative operators as such in constraints.
703 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
704                         (minus "") (ss_minus "") (us_minus "")])
705
706 ;; Mapping of signed max and min
707 (define_code_iterator smaxmin [smax smin])
708
709 ;; Mapping of unsigned max and min
710 (define_code_iterator umaxmin [umax umin])
711
712 ;; Mapping of signed/unsigned max and min
713 (define_code_iterator maxmin [smax smin umax umin])
714
715 ;; Base name for integer and FP insn mnemonic
716 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
717                               (umax "maxu") (umin "minu")])
718 (define_code_attr maxmin_float [(smax "max") (smin "min")])
719
720 ;; Mapping of logic operators
721 (define_code_iterator any_logic [and ior xor])
722 (define_code_iterator any_or [ior xor])
723
724 ;; Base name for insn mnemonic.
725 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
726
727 ;; Mapping of shift-right operators
728 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
729
730 ;; Base name for define_insn
731 (define_code_attr shiftrt_insn [(lshiftrt "lshr") (ashiftrt "ashr")])
732
733 ;; Base name for insn mnemonic.
734 (define_code_attr shiftrt [(lshiftrt "shr") (ashiftrt "sar")])
735
736 ;; Mapping of rotate operators
737 (define_code_iterator any_rotate [rotate rotatert])
738
739 ;; Base name for define_insn
740 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
741
742 ;; Base name for insn mnemonic.
743 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
744
745 ;; Mapping of abs neg operators
746 (define_code_iterator absneg [abs neg])
747
748 ;; Base name for x87 insn mnemonic.
749 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
750
751 ;; Used in signed and unsigned widening multiplications.
752 (define_code_iterator any_extend [sign_extend zero_extend])
753
754 ;; Various insn prefixes for signed and unsigned operations.
755 (define_code_attr u [(sign_extend "") (zero_extend "u")
756                      (div "") (udiv "u")])
757 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
758
759 ;; Used in signed and unsigned divisions.
760 (define_code_iterator any_div [div udiv])
761
762 ;; Instruction prefix for signed and unsigned operations.
763 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")
764                              (div "i") (udiv "")])
765
766 ;; 64bit single word integer modes.
767 (define_mode_iterator SWI1248x [QI HI SI DI])
768
769 ;; 64bit single word integer modes without QImode and HImode.
770 (define_mode_iterator SWI48x [SI DI])
771
772 ;; Single word integer modes.
773 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
774
775 ;; Single word integer modes without SImode and DImode.
776 (define_mode_iterator SWI12 [QI HI])
777
778 ;; Single word integer modes without DImode.
779 (define_mode_iterator SWI124 [QI HI SI])
780
781 ;; Single word integer modes without QImode and DImode.
782 (define_mode_iterator SWI24 [HI SI])
783
784 ;; Single word integer modes without QImode.
785 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
786
787 ;; Single word integer modes without QImode and HImode.
788 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
789
790 ;; All math-dependant single and double word integer modes.
791 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
792                              (HI "TARGET_HIMODE_MATH")
793                              SI DI (TI "TARGET_64BIT")])
794
795 ;; Math-dependant single word integer modes.
796 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
797                             (HI "TARGET_HIMODE_MATH")
798                             SI (DI "TARGET_64BIT")])
799
800 ;; Math-dependant single word integer modes without DImode.
801 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
802                                (HI "TARGET_HIMODE_MATH")
803                                SI])
804
805 ;; Math-dependant single word integer modes without QImode.
806 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
807                                SI (DI "TARGET_64BIT")])
808
809 ;; Double word integer modes.
810 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
811                            (TI "TARGET_64BIT")])
812
813 ;; Double word integer modes as mode attribute.
814 (define_mode_attr DWI [(SI "DI") (DI "TI")])
815 (define_mode_attr dwi [(SI "di") (DI "ti")])
816
817 ;; Half mode for double word integer modes.
818 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
819                             (DI "TARGET_64BIT")])
820
821 ;; Instruction suffix for integer modes.
822 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
823
824 ;; Register class for integer modes.
825 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
826
827 ;; Immediate operand constraint for integer modes.
828 (define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")])
829
830 ;; General operand constraint for word modes.
831 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "g") (DI "rme")])
832
833 ;; Immediate operand constraint for double integer modes.
834 (define_mode_attr di [(SI "iF") (DI "e")])
835
836 ;; Immediate operand constraint for shifts.
837 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
838
839 ;; General operand predicate for integer modes.
840 (define_mode_attr general_operand
841         [(QI "general_operand")
842          (HI "general_operand")
843          (SI "general_operand")
844          (DI "x86_64_general_operand")
845          (TI "x86_64_general_operand")])
846
847 ;; General sign/zero extend operand predicate for integer modes.
848 (define_mode_attr general_szext_operand
849         [(QI "general_operand")
850          (HI "general_operand")
851          (SI "general_operand")
852          (DI "x86_64_szext_general_operand")])
853
854 ;; Immediate operand predicate for integer modes.
855 (define_mode_attr immediate_operand
856         [(QI "immediate_operand")
857          (HI "immediate_operand")
858          (SI "immediate_operand")
859          (DI "x86_64_immediate_operand")])
860
861 ;; Operand predicate for shifts.
862 (define_mode_attr shift_operand
863         [(QI "nonimmediate_operand")
864          (HI "nonimmediate_operand")
865          (SI "nonimmediate_operand")
866          (DI "shiftdi_operand")
867          (TI "register_operand")])
868
869 ;; Operand predicate for shift argument.
870 (define_mode_attr shift_immediate_operand
871         [(QI "const_1_to_31_operand")
872          (HI "const_1_to_31_operand")
873          (SI "const_1_to_31_operand")
874          (DI "const_1_to_63_operand")])
875
876 ;; Input operand predicate for arithmetic left shifts.
877 (define_mode_attr ashl_input_operand
878         [(QI "nonimmediate_operand")
879          (HI "nonimmediate_operand")
880          (SI "nonimmediate_operand")
881          (DI "ashldi_input_operand")
882          (TI "reg_or_pm1_operand")])
883
884 ;; SSE and x87 SFmode and DFmode floating point modes
885 (define_mode_iterator MODEF [SF DF])
886
887 ;; All x87 floating point modes
888 (define_mode_iterator X87MODEF [SF DF XF])
889
890 ;; All integer modes handled by x87 fisttp operator.
891 (define_mode_iterator X87MODEI [HI SI DI])
892
893 ;; All integer modes handled by integer x87 operators.
894 (define_mode_iterator X87MODEI12 [HI SI])
895
896 ;; All integer modes handled by SSE cvtts?2si* operators.
897 (define_mode_iterator SSEMODEI24 [SI DI])
898
899 ;; SSE asm suffix for floating point modes
900 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
901
902 ;; SSE vector mode corresponding to a scalar mode
903 (define_mode_attr ssevecmode
904   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
905
906 ;; Instruction suffix for REX 64bit operators.
907 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
908
909 ;; This mode iterator allows :P to be used for patterns that operate on
910 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
911 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
912 \f
913 ;; Scheduling descriptions
914
915 (include "pentium.md")
916 (include "ppro.md")
917 (include "k6.md")
918 (include "athlon.md")
919 (include "geode.md")
920 (include "atom.md")
921
922 \f
923 ;; Operand and operator predicates and constraints
924
925 (include "predicates.md")
926 (include "constraints.md")
927
928 \f
929 ;; Compare and branch/compare and store instructions.
930
931 (define_expand "cbranch<mode>4"
932   [(set (reg:CC FLAGS_REG)
933         (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
934                     (match_operand:SDWIM 2 "<general_operand>" "")))
935    (set (pc) (if_then_else
936                (match_operator 0 "ordered_comparison_operator"
937                 [(reg:CC FLAGS_REG) (const_int 0)])
938                (label_ref (match_operand 3 "" ""))
939                (pc)))]
940   ""
941 {
942   if (MEM_P (operands[1]) && MEM_P (operands[2]))
943     operands[1] = force_reg (<MODE>mode, operands[1]);
944   ix86_expand_branch (GET_CODE (operands[0]),
945                       operands[1], operands[2], operands[3]);
946   DONE;
947 })
948
949 (define_expand "cstore<mode>4"
950   [(set (reg:CC FLAGS_REG)
951         (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
952                     (match_operand:SWIM 3 "<general_operand>" "")))
953    (set (match_operand:QI 0 "register_operand" "")
954         (match_operator 1 "ordered_comparison_operator"
955           [(reg:CC FLAGS_REG) (const_int 0)]))]
956   ""
957 {
958   if (MEM_P (operands[2]) && MEM_P (operands[3]))
959     operands[2] = force_reg (<MODE>mode, operands[2]);
960   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
961                      operands[2], operands[3]);
962   DONE;
963 })
964
965 (define_expand "cmp<mode>_1"
966   [(set (reg:CC FLAGS_REG)
967         (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
968                     (match_operand:SWI48 1 "<general_operand>" "")))]
969   ""
970   "")
971
972 (define_insn "*cmp<mode>_ccno_1"
973   [(set (reg FLAGS_REG)
974         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
975                  (match_operand:SWI 1 "const0_operand" "")))]
976   "ix86_match_ccmode (insn, CCNOmode)"
977   "@
978    test{<imodesuffix>}\t%0, %0
979    cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
980   [(set_attr "type" "test,icmp")
981    (set_attr "length_immediate" "0,1")
982    (set_attr "mode" "<MODE>")])
983
984 (define_insn "*cmp<mode>_1"
985   [(set (reg FLAGS_REG)
986         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
987                  (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
988   "ix86_match_ccmode (insn, CCmode)"
989   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
990   [(set_attr "type" "icmp")
991    (set_attr "mode" "<MODE>")])
992
993 (define_insn "*cmp<mode>_minus_1"
994   [(set (reg FLAGS_REG)
995         (compare
996           (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
997                      (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
998           (const_int 0)))]
999   "ix86_match_ccmode (insn, CCGOCmode)"
1000   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1001   [(set_attr "type" "icmp")
1002    (set_attr "mode" "<MODE>")])
1003
1004 (define_insn "*cmpqi_ext_1"
1005   [(set (reg FLAGS_REG)
1006         (compare
1007           (match_operand:QI 0 "general_operand" "Qm")
1008           (subreg:QI
1009             (zero_extract:SI
1010               (match_operand 1 "ext_register_operand" "Q")
1011               (const_int 8)
1012               (const_int 8)) 0)))]
1013   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1014   "cmp{b}\t{%h1, %0|%0, %h1}"
1015   [(set_attr "type" "icmp")
1016    (set_attr "mode" "QI")])
1017
1018 (define_insn "*cmpqi_ext_1_rex64"
1019   [(set (reg FLAGS_REG)
1020         (compare
1021           (match_operand:QI 0 "register_operand" "Q")
1022           (subreg:QI
1023             (zero_extract:SI
1024               (match_operand 1 "ext_register_operand" "Q")
1025               (const_int 8)
1026               (const_int 8)) 0)))]
1027   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1028   "cmp{b}\t{%h1, %0|%0, %h1}"
1029   [(set_attr "type" "icmp")
1030    (set_attr "mode" "QI")])
1031
1032 (define_insn "*cmpqi_ext_2"
1033   [(set (reg FLAGS_REG)
1034         (compare
1035           (subreg:QI
1036             (zero_extract:SI
1037               (match_operand 0 "ext_register_operand" "Q")
1038               (const_int 8)
1039               (const_int 8)) 0)
1040           (match_operand:QI 1 "const0_operand" "")))]
1041   "ix86_match_ccmode (insn, CCNOmode)"
1042   "test{b}\t%h0, %h0"
1043   [(set_attr "type" "test")
1044    (set_attr "length_immediate" "0")
1045    (set_attr "mode" "QI")])
1046
1047 (define_expand "cmpqi_ext_3"
1048   [(set (reg:CC FLAGS_REG)
1049         (compare:CC
1050           (subreg:QI
1051             (zero_extract:SI
1052               (match_operand 0 "ext_register_operand" "")
1053               (const_int 8)
1054               (const_int 8)) 0)
1055           (match_operand:QI 1 "immediate_operand" "")))]
1056   ""
1057   "")
1058
1059 (define_insn "*cmpqi_ext_3_insn"
1060   [(set (reg FLAGS_REG)
1061         (compare
1062           (subreg:QI
1063             (zero_extract:SI
1064               (match_operand 0 "ext_register_operand" "Q")
1065               (const_int 8)
1066               (const_int 8)) 0)
1067           (match_operand:QI 1 "general_operand" "Qmn")))]
1068   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1069   "cmp{b}\t{%1, %h0|%h0, %1}"
1070   [(set_attr "type" "icmp")
1071    (set_attr "modrm" "1")
1072    (set_attr "mode" "QI")])
1073
1074 (define_insn "*cmpqi_ext_3_insn_rex64"
1075   [(set (reg FLAGS_REG)
1076         (compare
1077           (subreg:QI
1078             (zero_extract:SI
1079               (match_operand 0 "ext_register_operand" "Q")
1080               (const_int 8)
1081               (const_int 8)) 0)
1082           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1083   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1084   "cmp{b}\t{%1, %h0|%h0, %1}"
1085   [(set_attr "type" "icmp")
1086    (set_attr "modrm" "1")
1087    (set_attr "mode" "QI")])
1088
1089 (define_insn "*cmpqi_ext_4"
1090   [(set (reg FLAGS_REG)
1091         (compare
1092           (subreg:QI
1093             (zero_extract:SI
1094               (match_operand 0 "ext_register_operand" "Q")
1095               (const_int 8)
1096               (const_int 8)) 0)
1097           (subreg:QI
1098             (zero_extract:SI
1099               (match_operand 1 "ext_register_operand" "Q")
1100               (const_int 8)
1101               (const_int 8)) 0)))]
1102   "ix86_match_ccmode (insn, CCmode)"
1103   "cmp{b}\t{%h1, %h0|%h0, %h1}"
1104   [(set_attr "type" "icmp")
1105    (set_attr "mode" "QI")])
1106
1107 ;; These implement float point compares.
1108 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1109 ;; which would allow mix and match FP modes on the compares.  Which is what
1110 ;; the old patterns did, but with many more of them.
1111
1112 (define_expand "cbranchxf4"
1113   [(set (reg:CC FLAGS_REG)
1114         (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1115                     (match_operand:XF 2 "nonmemory_operand" "")))
1116    (set (pc) (if_then_else
1117               (match_operator 0 "ix86_fp_comparison_operator"
1118                [(reg:CC FLAGS_REG)
1119                 (const_int 0)])
1120               (label_ref (match_operand 3 "" ""))
1121               (pc)))]
1122   "TARGET_80387"
1123 {
1124   ix86_expand_branch (GET_CODE (operands[0]),
1125                       operands[1], operands[2], operands[3]);
1126   DONE;
1127 })
1128
1129 (define_expand "cstorexf4"
1130   [(set (reg:CC FLAGS_REG)
1131         (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1132                     (match_operand:XF 3 "nonmemory_operand" "")))
1133    (set (match_operand:QI 0 "register_operand" "")
1134               (match_operator 1 "ix86_fp_comparison_operator"
1135                [(reg:CC FLAGS_REG)
1136                 (const_int 0)]))]
1137   "TARGET_80387"
1138 {
1139   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1140                      operands[2], operands[3]);
1141   DONE;
1142 })
1143
1144 (define_expand "cbranch<mode>4"
1145   [(set (reg:CC FLAGS_REG)
1146         (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1147                     (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1148    (set (pc) (if_then_else
1149               (match_operator 0 "ix86_fp_comparison_operator"
1150                [(reg:CC FLAGS_REG)
1151                 (const_int 0)])
1152               (label_ref (match_operand 3 "" ""))
1153               (pc)))]
1154   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1155 {
1156   ix86_expand_branch (GET_CODE (operands[0]),
1157                       operands[1], operands[2], operands[3]);
1158   DONE;
1159 })
1160
1161 (define_expand "cstore<mode>4"
1162   [(set (reg:CC FLAGS_REG)
1163         (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1164                     (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1165    (set (match_operand:QI 0 "register_operand" "")
1166               (match_operator 1 "ix86_fp_comparison_operator"
1167                [(reg:CC FLAGS_REG)
1168                 (const_int 0)]))]
1169   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1170 {
1171   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1172                      operands[2], operands[3]);
1173   DONE;
1174 })
1175
1176 (define_expand "cbranchcc4"
1177   [(set (pc) (if_then_else
1178               (match_operator 0 "comparison_operator"
1179                [(match_operand 1 "flags_reg_operand" "")
1180                 (match_operand 2 "const0_operand" "")])
1181               (label_ref (match_operand 3 "" ""))
1182               (pc)))]
1183   ""
1184 {
1185   ix86_expand_branch (GET_CODE (operands[0]),
1186                       operands[1], operands[2], operands[3]);
1187   DONE;
1188 })
1189
1190 (define_expand "cstorecc4"
1191   [(set (match_operand:QI 0 "register_operand" "")
1192               (match_operator 1 "comparison_operator"
1193                [(match_operand 2 "flags_reg_operand" "")
1194                 (match_operand 3 "const0_operand" "")]))]
1195   ""
1196 {
1197   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1198                      operands[2], operands[3]);
1199   DONE;
1200 })
1201
1202
1203 ;; FP compares, step 1:
1204 ;; Set the FP condition codes.
1205 ;;
1206 ;; CCFPmode     compare with exceptions
1207 ;; CCFPUmode    compare with no exceptions
1208
1209 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1210 ;; used to manage the reg stack popping would not be preserved.
1211
1212 (define_insn "*cmpfp_0"
1213   [(set (match_operand:HI 0 "register_operand" "=a")
1214         (unspec:HI
1215           [(compare:CCFP
1216              (match_operand 1 "register_operand" "f")
1217              (match_operand 2 "const0_operand" ""))]
1218         UNSPEC_FNSTSW))]
1219   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1220    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1221   "* return output_fp_compare (insn, operands, 0, 0);"
1222   [(set_attr "type" "multi")
1223    (set_attr "unit" "i387")
1224    (set (attr "mode")
1225      (cond [(match_operand:SF 1 "" "")
1226               (const_string "SF")
1227             (match_operand:DF 1 "" "")
1228               (const_string "DF")
1229            ]
1230            (const_string "XF")))])
1231
1232 (define_insn_and_split "*cmpfp_0_cc"
1233   [(set (reg:CCFP FLAGS_REG)
1234         (compare:CCFP
1235           (match_operand 1 "register_operand" "f")
1236           (match_operand 2 "const0_operand" "")))
1237    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1238   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1239    && TARGET_SAHF && !TARGET_CMOVE
1240    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1241   "#"
1242   "&& reload_completed"
1243   [(set (match_dup 0)
1244         (unspec:HI
1245           [(compare:CCFP (match_dup 1)(match_dup 2))]
1246         UNSPEC_FNSTSW))
1247    (set (reg:CC FLAGS_REG)
1248         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1249   ""
1250   [(set_attr "type" "multi")
1251    (set_attr "unit" "i387")
1252    (set (attr "mode")
1253      (cond [(match_operand:SF 1 "" "")
1254               (const_string "SF")
1255             (match_operand:DF 1 "" "")
1256               (const_string "DF")
1257            ]
1258            (const_string "XF")))])
1259
1260 (define_insn "*cmpfp_xf"
1261   [(set (match_operand:HI 0 "register_operand" "=a")
1262         (unspec:HI
1263           [(compare:CCFP
1264              (match_operand:XF 1 "register_operand" "f")
1265              (match_operand:XF 2 "register_operand" "f"))]
1266           UNSPEC_FNSTSW))]
1267   "TARGET_80387"
1268   "* return output_fp_compare (insn, operands, 0, 0);"
1269   [(set_attr "type" "multi")
1270    (set_attr "unit" "i387")
1271    (set_attr "mode" "XF")])
1272
1273 (define_insn_and_split "*cmpfp_xf_cc"
1274   [(set (reg:CCFP FLAGS_REG)
1275         (compare:CCFP
1276           (match_operand:XF 1 "register_operand" "f")
1277           (match_operand:XF 2 "register_operand" "f")))
1278    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1279   "TARGET_80387
1280    && TARGET_SAHF && !TARGET_CMOVE"
1281   "#"
1282   "&& reload_completed"
1283   [(set (match_dup 0)
1284         (unspec:HI
1285           [(compare:CCFP (match_dup 1)(match_dup 2))]
1286         UNSPEC_FNSTSW))
1287    (set (reg:CC FLAGS_REG)
1288         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1289   ""
1290   [(set_attr "type" "multi")
1291    (set_attr "unit" "i387")
1292    (set_attr "mode" "XF")])
1293
1294 (define_insn "*cmpfp_<mode>"
1295   [(set (match_operand:HI 0 "register_operand" "=a")
1296         (unspec:HI
1297           [(compare:CCFP
1298              (match_operand:MODEF 1 "register_operand" "f")
1299              (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1300           UNSPEC_FNSTSW))]
1301   "TARGET_80387"
1302   "* return output_fp_compare (insn, operands, 0, 0);"
1303   [(set_attr "type" "multi")
1304    (set_attr "unit" "i387")
1305    (set_attr "mode" "<MODE>")])
1306
1307 (define_insn_and_split "*cmpfp_<mode>_cc"
1308   [(set (reg:CCFP FLAGS_REG)
1309         (compare:CCFP
1310           (match_operand:MODEF 1 "register_operand" "f")
1311           (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1312    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1313   "TARGET_80387
1314    && TARGET_SAHF && !TARGET_CMOVE"
1315   "#"
1316   "&& reload_completed"
1317   [(set (match_dup 0)
1318         (unspec:HI
1319           [(compare:CCFP (match_dup 1)(match_dup 2))]
1320         UNSPEC_FNSTSW))
1321    (set (reg:CC FLAGS_REG)
1322         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1323   ""
1324   [(set_attr "type" "multi")
1325    (set_attr "unit" "i387")
1326    (set_attr "mode" "<MODE>")])
1327
1328 (define_insn "*cmpfp_u"
1329   [(set (match_operand:HI 0 "register_operand" "=a")
1330         (unspec:HI
1331           [(compare:CCFPU
1332              (match_operand 1 "register_operand" "f")
1333              (match_operand 2 "register_operand" "f"))]
1334           UNSPEC_FNSTSW))]
1335   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1336    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1337   "* return output_fp_compare (insn, operands, 0, 1);"
1338   [(set_attr "type" "multi")
1339    (set_attr "unit" "i387")
1340    (set (attr "mode")
1341      (cond [(match_operand:SF 1 "" "")
1342               (const_string "SF")
1343             (match_operand:DF 1 "" "")
1344               (const_string "DF")
1345            ]
1346            (const_string "XF")))])
1347
1348 (define_insn_and_split "*cmpfp_u_cc"
1349   [(set (reg:CCFPU FLAGS_REG)
1350         (compare:CCFPU
1351           (match_operand 1 "register_operand" "f")
1352           (match_operand 2 "register_operand" "f")))
1353    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1354   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1355    && TARGET_SAHF && !TARGET_CMOVE
1356    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1357   "#"
1358   "&& reload_completed"
1359   [(set (match_dup 0)
1360         (unspec:HI
1361           [(compare:CCFPU (match_dup 1)(match_dup 2))]
1362         UNSPEC_FNSTSW))
1363    (set (reg:CC FLAGS_REG)
1364         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1365   ""
1366   [(set_attr "type" "multi")
1367    (set_attr "unit" "i387")
1368    (set (attr "mode")
1369      (cond [(match_operand:SF 1 "" "")
1370               (const_string "SF")
1371             (match_operand:DF 1 "" "")
1372               (const_string "DF")
1373            ]
1374            (const_string "XF")))])
1375
1376 (define_insn "*cmpfp_<mode>"
1377   [(set (match_operand:HI 0 "register_operand" "=a")
1378         (unspec:HI
1379           [(compare:CCFP
1380              (match_operand 1 "register_operand" "f")
1381              (match_operator 3 "float_operator"
1382                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1383           UNSPEC_FNSTSW))]
1384   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1385    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1386    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1387   "* return output_fp_compare (insn, operands, 0, 0);"
1388   [(set_attr "type" "multi")
1389    (set_attr "unit" "i387")
1390    (set_attr "fp_int_src" "true")
1391    (set_attr "mode" "<MODE>")])
1392
1393 (define_insn_and_split "*cmpfp_<mode>_cc"
1394   [(set (reg:CCFP FLAGS_REG)
1395         (compare:CCFP
1396           (match_operand 1 "register_operand" "f")
1397           (match_operator 3 "float_operator"
1398             [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1399    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1400   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1401    && TARGET_SAHF && !TARGET_CMOVE
1402    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1403    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1404   "#"
1405   "&& reload_completed"
1406   [(set (match_dup 0)
1407         (unspec:HI
1408           [(compare:CCFP
1409              (match_dup 1)
1410              (match_op_dup 3 [(match_dup 2)]))]
1411         UNSPEC_FNSTSW))
1412    (set (reg:CC FLAGS_REG)
1413         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1414   ""
1415   [(set_attr "type" "multi")
1416    (set_attr "unit" "i387")
1417    (set_attr "fp_int_src" "true")
1418    (set_attr "mode" "<MODE>")])
1419
1420 ;; FP compares, step 2
1421 ;; Move the fpsw to ax.
1422
1423 (define_insn "x86_fnstsw_1"
1424   [(set (match_operand:HI 0 "register_operand" "=a")
1425         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1426   "TARGET_80387"
1427   "fnstsw\t%0"
1428   [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1429    (set_attr "mode" "SI")
1430    (set_attr "unit" "i387")])
1431
1432 ;; FP compares, step 3
1433 ;; Get ax into flags, general case.
1434
1435 (define_insn "x86_sahf_1"
1436   [(set (reg:CC FLAGS_REG)
1437         (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1438                    UNSPEC_SAHF))]
1439   "TARGET_SAHF"
1440 {
1441 #ifndef HAVE_AS_IX86_SAHF
1442   if (TARGET_64BIT)
1443     return ASM_BYTE "0x9e";
1444   else
1445 #endif
1446   return "sahf";
1447 }
1448   [(set_attr "length" "1")
1449    (set_attr "athlon_decode" "vector")
1450    (set_attr "amdfam10_decode" "direct")
1451    (set_attr "mode" "SI")])
1452
1453 ;; Pentium Pro can do steps 1 through 3 in one go.
1454 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1455 (define_insn "*cmpfp_i_mixed"
1456   [(set (reg:CCFP FLAGS_REG)
1457         (compare:CCFP (match_operand 0 "register_operand" "f,x")
1458                       (match_operand 1 "nonimmediate_operand" "f,xm")))]
1459   "TARGET_MIX_SSE_I387
1460    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1461    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1462   "* return output_fp_compare (insn, operands, 1, 0);"
1463   [(set_attr "type" "fcmp,ssecomi")
1464    (set_attr "prefix" "orig,maybe_vex")
1465    (set (attr "mode")
1466      (if_then_else (match_operand:SF 1 "" "")
1467         (const_string "SF")
1468         (const_string "DF")))
1469    (set (attr "prefix_rep")
1470         (if_then_else (eq_attr "type" "ssecomi")
1471                       (const_string "0")
1472                       (const_string "*")))
1473    (set (attr "prefix_data16")
1474         (cond [(eq_attr "type" "fcmp")
1475                  (const_string "*")
1476                (eq_attr "mode" "DF")
1477                  (const_string "1")
1478               ]
1479               (const_string "0")))
1480    (set_attr "athlon_decode" "vector")
1481    (set_attr "amdfam10_decode" "direct")])
1482
1483 (define_insn "*cmpfp_i_sse"
1484   [(set (reg:CCFP FLAGS_REG)
1485         (compare:CCFP (match_operand 0 "register_operand" "x")
1486                       (match_operand 1 "nonimmediate_operand" "xm")))]
1487   "TARGET_SSE_MATH
1488    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1489    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1490   "* return output_fp_compare (insn, operands, 1, 0);"
1491   [(set_attr "type" "ssecomi")
1492    (set_attr "prefix" "maybe_vex")
1493    (set (attr "mode")
1494      (if_then_else (match_operand:SF 1 "" "")
1495         (const_string "SF")
1496         (const_string "DF")))
1497    (set_attr "prefix_rep" "0")
1498    (set (attr "prefix_data16")
1499         (if_then_else (eq_attr "mode" "DF")
1500                       (const_string "1")
1501                       (const_string "0")))
1502    (set_attr "athlon_decode" "vector")
1503    (set_attr "amdfam10_decode" "direct")])
1504
1505 (define_insn "*cmpfp_i_i387"
1506   [(set (reg:CCFP FLAGS_REG)
1507         (compare:CCFP (match_operand 0 "register_operand" "f")
1508                       (match_operand 1 "register_operand" "f")))]
1509   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1510    && TARGET_CMOVE
1511    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1512    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1513   "* return output_fp_compare (insn, operands, 1, 0);"
1514   [(set_attr "type" "fcmp")
1515    (set (attr "mode")
1516      (cond [(match_operand:SF 1 "" "")
1517               (const_string "SF")
1518             (match_operand:DF 1 "" "")
1519               (const_string "DF")
1520            ]
1521            (const_string "XF")))
1522    (set_attr "athlon_decode" "vector")
1523    (set_attr "amdfam10_decode" "direct")])
1524
1525 (define_insn "*cmpfp_iu_mixed"
1526   [(set (reg:CCFPU FLAGS_REG)
1527         (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1528                        (match_operand 1 "nonimmediate_operand" "f,xm")))]
1529   "TARGET_MIX_SSE_I387
1530    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1531    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1532   "* return output_fp_compare (insn, operands, 1, 1);"
1533   [(set_attr "type" "fcmp,ssecomi")
1534    (set_attr "prefix" "orig,maybe_vex")
1535    (set (attr "mode")
1536      (if_then_else (match_operand:SF 1 "" "")
1537         (const_string "SF")
1538         (const_string "DF")))
1539    (set (attr "prefix_rep")
1540         (if_then_else (eq_attr "type" "ssecomi")
1541                       (const_string "0")
1542                       (const_string "*")))
1543    (set (attr "prefix_data16")
1544         (cond [(eq_attr "type" "fcmp")
1545                  (const_string "*")
1546                (eq_attr "mode" "DF")
1547                  (const_string "1")
1548               ]
1549               (const_string "0")))
1550    (set_attr "athlon_decode" "vector")
1551    (set_attr "amdfam10_decode" "direct")])
1552
1553 (define_insn "*cmpfp_iu_sse"
1554   [(set (reg:CCFPU FLAGS_REG)
1555         (compare:CCFPU (match_operand 0 "register_operand" "x")
1556                        (match_operand 1 "nonimmediate_operand" "xm")))]
1557   "TARGET_SSE_MATH
1558    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1559    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1560   "* return output_fp_compare (insn, operands, 1, 1);"
1561   [(set_attr "type" "ssecomi")
1562    (set_attr "prefix" "maybe_vex")
1563    (set (attr "mode")
1564      (if_then_else (match_operand:SF 1 "" "")
1565         (const_string "SF")
1566         (const_string "DF")))
1567    (set_attr "prefix_rep" "0")
1568    (set (attr "prefix_data16")
1569         (if_then_else (eq_attr "mode" "DF")
1570                       (const_string "1")
1571                       (const_string "0")))
1572    (set_attr "athlon_decode" "vector")
1573    (set_attr "amdfam10_decode" "direct")])
1574
1575 (define_insn "*cmpfp_iu_387"
1576   [(set (reg:CCFPU FLAGS_REG)
1577         (compare:CCFPU (match_operand 0 "register_operand" "f")
1578                        (match_operand 1 "register_operand" "f")))]
1579   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1580    && TARGET_CMOVE
1581    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1582    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1583   "* return output_fp_compare (insn, operands, 1, 1);"
1584   [(set_attr "type" "fcmp")
1585    (set (attr "mode")
1586      (cond [(match_operand:SF 1 "" "")
1587               (const_string "SF")
1588             (match_operand:DF 1 "" "")
1589               (const_string "DF")
1590            ]
1591            (const_string "XF")))
1592    (set_attr "athlon_decode" "vector")
1593    (set_attr "amdfam10_decode" "direct")])
1594 \f
1595 ;; Move instructions.
1596
1597 (define_expand "movoi"
1598   [(set (match_operand:OI 0 "nonimmediate_operand" "")
1599         (match_operand:OI 1 "general_operand" ""))]
1600   "TARGET_AVX"
1601   "ix86_expand_move (OImode, operands); DONE;")
1602
1603 (define_expand "movti"
1604   [(set (match_operand:TI 0 "nonimmediate_operand" "")
1605         (match_operand:TI 1 "nonimmediate_operand" ""))]
1606   "TARGET_64BIT || TARGET_SSE"
1607 {
1608   if (TARGET_64BIT)
1609     ix86_expand_move (TImode, operands);
1610   else if (push_operand (operands[0], TImode))
1611     ix86_expand_push (TImode, operands[1]);
1612   else
1613     ix86_expand_vector_move (TImode, operands);
1614   DONE;
1615 })
1616
1617 ;; This expands to what emit_move_complex would generate if we didn't
1618 ;; have a movti pattern.  Having this avoids problems with reload on
1619 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1620 ;; to have around all the time.
1621 (define_expand "movcdi"
1622   [(set (match_operand:CDI 0 "nonimmediate_operand" "")
1623         (match_operand:CDI 1 "general_operand" ""))]
1624   ""
1625 {
1626   if (push_operand (operands[0], CDImode))
1627     emit_move_complex_push (CDImode, operands[0], operands[1]);
1628   else
1629     emit_move_complex_parts (operands[0], operands[1]);
1630   DONE;
1631 })
1632
1633 (define_expand "mov<mode>"
1634   [(set (match_operand:SWI1248x 0 "nonimmediate_operand" "")
1635         (match_operand:SWI1248x 1 "general_operand" ""))]
1636   ""
1637   "ix86_expand_move (<MODE>mode, operands); DONE;")
1638
1639 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1640 ;; general_operand.
1641 ;;
1642 ;; %%% We don't use a post-inc memory reference because x86 is not a
1643 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1644 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1645 ;; targets without our curiosities, and it is just as easy to represent
1646 ;; this differently.
1647
1648 (define_insn "*pushdi2_rex64"
1649   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1650         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1651   "TARGET_64BIT"
1652   "@
1653    push{q}\t%1
1654    #"
1655   [(set_attr "type" "push,multi")
1656    (set_attr "mode" "DI")])
1657
1658 ;; Convert impossible pushes of immediate to existing instructions.
1659 ;; First try to get scratch register and go through it.  In case this
1660 ;; fails, push sign extended lower part first and then overwrite
1661 ;; upper part by 32bit move.
1662 (define_peephole2
1663   [(match_scratch:DI 2 "r")
1664    (set (match_operand:DI 0 "push_operand" "")
1665         (match_operand:DI 1 "immediate_operand" ""))]
1666   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1667    && !x86_64_immediate_operand (operands[1], DImode)"
1668   [(set (match_dup 2) (match_dup 1))
1669    (set (match_dup 0) (match_dup 2))]
1670   "")
1671
1672 ;; We need to define this as both peepholer and splitter for case
1673 ;; peephole2 pass is not run.
1674 ;; "&& 1" is needed to keep it from matching the previous pattern.
1675 (define_peephole2
1676   [(set (match_operand:DI 0 "push_operand" "")
1677         (match_operand:DI 1 "immediate_operand" ""))]
1678   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1679    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1680   [(set (match_dup 0) (match_dup 1))
1681    (set (match_dup 2) (match_dup 3))]
1682 {
1683   split_di (&operands[1], 1, &operands[2], &operands[3]);
1684
1685   operands[1] = gen_lowpart (DImode, operands[2]);
1686   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1687                                                    GEN_INT (4)));
1688 })
1689
1690 (define_split
1691   [(set (match_operand:DI 0 "push_operand" "")
1692         (match_operand:DI 1 "immediate_operand" ""))]
1693   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1694                     ? epilogue_completed : reload_completed)
1695    && !symbolic_operand (operands[1], DImode)
1696    && !x86_64_immediate_operand (operands[1], DImode)"
1697   [(set (match_dup 0) (match_dup 1))
1698    (set (match_dup 2) (match_dup 3))]
1699 {
1700   split_di (&operands[1], 1, &operands[2], &operands[3]);
1701
1702   operands[1] = gen_lowpart (DImode, operands[2]);
1703   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1704                                                    GEN_INT (4)));
1705 })
1706
1707 (define_insn "*pushdi2"
1708   [(set (match_operand:DI 0 "push_operand" "=<")
1709         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1710   "!TARGET_64BIT"
1711   "#")
1712
1713 (define_split
1714   [(set (match_operand:DI 0 "push_operand" "")
1715         (match_operand:DI 1 "general_operand" ""))]
1716   "!TARGET_64BIT && reload_completed
1717    && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1718   [(const_int 0)]
1719   "ix86_split_long_move (operands); DONE;")
1720
1721 (define_insn "*pushsi2"
1722   [(set (match_operand:SI 0 "push_operand" "=<")
1723         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1724   "!TARGET_64BIT"
1725   "push{l}\t%1"
1726   [(set_attr "type" "push")
1727    (set_attr "mode" "SI")])
1728
1729 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1730 ;; "push a byte/word".  But actually we use pushl, which has the effect
1731 ;; of rounding the amount pushed up to a word.
1732
1733 ;; For 64BIT abi we always round up to 8 bytes.
1734 (define_insn "*push<mode>2_rex64"
1735   [(set (match_operand:SWI124 0 "push_operand" "=X")
1736         (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1737   "TARGET_64BIT"
1738   "push{q}\t%q1"
1739   [(set_attr "type" "push")
1740    (set_attr "mode" "DI")])
1741
1742 (define_insn "*push<mode>2"
1743   [(set (match_operand:SWI12 0 "push_operand" "=X")
1744         (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1745   "!TARGET_64BIT"
1746   "push{l}\t%k1"
1747   [(set_attr "type" "push")
1748    (set_attr "mode" "SI")])
1749
1750 (define_insn "*push<mode>2_prologue"
1751   [(set (match_operand:P 0 "push_operand" "=<")
1752         (match_operand:P 1 "general_no_elim_operand" "r<i>*m"))
1753    (clobber (mem:BLK (scratch)))]
1754   ""
1755   "push{<imodesuffix>}\t%1"
1756   [(set_attr "type" "push")
1757    (set_attr "mode" "<MODE>")])
1758
1759 (define_insn "popdi1"
1760   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1761         (mem:DI (reg:DI SP_REG)))
1762    (set (reg:DI SP_REG)
1763         (plus:DI (reg:DI SP_REG) (const_int 8)))]
1764   "TARGET_64BIT"
1765   "pop{q}\t%0"
1766   [(set_attr "type" "pop")
1767    (set_attr "mode" "DI")])
1768
1769 (define_insn "popsi1"
1770   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1771         (mem:SI (reg:SI SP_REG)))
1772    (set (reg:SI SP_REG)
1773         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1774   "!TARGET_64BIT"
1775   "pop{l}\t%0"
1776   [(set_attr "type" "pop")
1777    (set_attr "mode" "SI")])
1778
1779 (define_insn "*popdi1_epilogue"
1780   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1781         (mem:DI (reg:DI SP_REG)))
1782    (set (reg:DI SP_REG)
1783         (plus:DI (reg:DI SP_REG) (const_int 8)))
1784    (clobber (mem:BLK (scratch)))]
1785   "TARGET_64BIT"
1786   "pop{q}\t%0"
1787   [(set_attr "type" "pop")
1788    (set_attr "mode" "DI")])
1789
1790 (define_insn "*popsi1_epilogue"
1791   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1792         (mem:SI (reg:SI SP_REG)))
1793    (set (reg:SI SP_REG)
1794         (plus:SI (reg:SI SP_REG) (const_int 4)))
1795    (clobber (mem:BLK (scratch)))]
1796   "!TARGET_64BIT"
1797   "pop{l}\t%0"
1798   [(set_attr "type" "pop")
1799    (set_attr "mode" "SI")])
1800
1801 (define_insn "*mov<mode>_xor"
1802   [(set (match_operand:SWI48 0 "register_operand" "=r")
1803         (match_operand:SWI48 1 "const0_operand" ""))
1804    (clobber (reg:CC FLAGS_REG))]
1805   "reload_completed"
1806   "xor{l}\t%k0, %k0"
1807   [(set_attr "type" "alu1")
1808    (set_attr "mode" "SI")
1809    (set_attr "length_immediate" "0")])
1810
1811 (define_insn "*mov<mode>_or"
1812   [(set (match_operand:SWI48 0 "register_operand" "=r")
1813         (match_operand:SWI48 1 "const_int_operand" ""))
1814    (clobber (reg:CC FLAGS_REG))]
1815   "reload_completed
1816    && operands[1] == constm1_rtx"
1817   "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1818   [(set_attr "type" "alu1")
1819    (set_attr "mode" "<MODE>")
1820    (set_attr "length_immediate" "1")])
1821
1822 (define_insn "*movoi_internal_avx"
1823   [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
1824         (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
1825   "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1826 {
1827   switch (which_alternative)
1828     {
1829     case 0:
1830       return "vxorps\t%0, %0, %0";
1831     case 1:
1832     case 2:
1833       if (misaligned_operand (operands[0], OImode)
1834           || misaligned_operand (operands[1], OImode))
1835         return "vmovdqu\t{%1, %0|%0, %1}";
1836       else
1837         return "vmovdqa\t{%1, %0|%0, %1}";
1838     default:
1839       gcc_unreachable ();
1840     }
1841 }
1842   [(set_attr "type" "sselog1,ssemov,ssemov")
1843    (set_attr "prefix" "vex")
1844    (set_attr "mode" "OI")])
1845
1846 (define_insn "*movti_internal_rex64"
1847   [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
1848         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
1849   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1850 {
1851   switch (which_alternative)
1852     {
1853     case 0:
1854     case 1:
1855       return "#";
1856     case 2:
1857       if (get_attr_mode (insn) == MODE_V4SF)
1858         return "%vxorps\t%0, %d0";
1859       else
1860         return "%vpxor\t%0, %d0";
1861     case 3:
1862     case 4:
1863       /* TDmode values are passed as TImode on the stack.  Moving them
1864          to stack may result in unaligned memory access.  */
1865       if (misaligned_operand (operands[0], TImode)
1866           || misaligned_operand (operands[1], TImode))
1867         {
1868           if (get_attr_mode (insn) == MODE_V4SF)
1869             return "%vmovups\t{%1, %0|%0, %1}";
1870          else
1871            return "%vmovdqu\t{%1, %0|%0, %1}";
1872         }
1873       else
1874         {
1875           if (get_attr_mode (insn) == MODE_V4SF)
1876             return "%vmovaps\t{%1, %0|%0, %1}";
1877          else
1878            return "%vmovdqa\t{%1, %0|%0, %1}";
1879         }
1880     default:
1881       gcc_unreachable ();
1882     }
1883 }
1884   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1885    (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1886    (set (attr "mode")
1887         (cond [(eq_attr "alternative" "2,3")
1888                  (if_then_else
1889                    (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1890                        (const_int 0))
1891                    (const_string "V4SF")
1892                    (const_string "TI"))
1893                (eq_attr "alternative" "4")
1894                  (if_then_else
1895                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
1896                             (const_int 0))
1897                         (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1898                             (const_int 0)))
1899                    (const_string "V4SF")
1900                    (const_string "TI"))]
1901                (const_string "DI")))])
1902
1903 (define_split
1904   [(set (match_operand:TI 0 "nonimmediate_operand" "")
1905         (match_operand:TI 1 "general_operand" ""))]
1906   "reload_completed
1907    && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1908   [(const_int 0)]
1909   "ix86_split_long_move (operands); DONE;")
1910
1911 (define_insn "*movti_internal_sse"
1912   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
1913         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
1914   "TARGET_SSE && !TARGET_64BIT
1915    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1916 {
1917   switch (which_alternative)
1918     {
1919     case 0:
1920       if (get_attr_mode (insn) == MODE_V4SF)
1921         return "%vxorps\t%0, %d0";
1922       else
1923         return "%vpxor\t%0, %d0";
1924     case 1:
1925     case 2:
1926       /* TDmode values are passed as TImode on the stack.  Moving them
1927          to stack may result in unaligned memory access.  */
1928       if (misaligned_operand (operands[0], TImode)
1929           || misaligned_operand (operands[1], TImode))
1930         {
1931           if (get_attr_mode (insn) == MODE_V4SF)
1932             return "%vmovups\t{%1, %0|%0, %1}";
1933          else
1934            return "%vmovdqu\t{%1, %0|%0, %1}";
1935         }
1936       else
1937         {
1938           if (get_attr_mode (insn) == MODE_V4SF)
1939             return "%vmovaps\t{%1, %0|%0, %1}";
1940          else
1941            return "%vmovdqa\t{%1, %0|%0, %1}";
1942         }
1943     default:
1944       gcc_unreachable ();
1945     }
1946 }
1947   [(set_attr "type" "sselog1,ssemov,ssemov")
1948    (set_attr "prefix" "maybe_vex")
1949    (set (attr "mode")
1950         (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1951                     (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1952                         (const_int 0)))
1953                  (const_string "V4SF")
1954                (and (eq_attr "alternative" "2")
1955                     (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
1956                         (const_int 0)))
1957                  (const_string "V4SF")]
1958               (const_string "TI")))])
1959
1960 (define_insn "*movdi_internal_rex64"
1961   [(set (match_operand:DI 0 "nonimmediate_operand"
1962           "=r,r  ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
1963         (match_operand:DI 1 "general_operand"
1964           "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r   ,m  ,C ,*x,*Yi,*x,r  ,m ,*Ym,*x"))]
1965   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1966 {
1967   switch (get_attr_type (insn))
1968     {
1969     case TYPE_SSECVT:
1970       if (SSE_REG_P (operands[0]))
1971         return "movq2dq\t{%1, %0|%0, %1}";
1972       else
1973         return "movdq2q\t{%1, %0|%0, %1}";
1974
1975     case TYPE_SSEMOV:
1976       if (TARGET_AVX)
1977         {
1978           if (get_attr_mode (insn) == MODE_TI)
1979             return "vmovdqa\t{%1, %0|%0, %1}";
1980           else
1981             return "vmovq\t{%1, %0|%0, %1}";
1982         }
1983
1984       if (get_attr_mode (insn) == MODE_TI)
1985         return "movdqa\t{%1, %0|%0, %1}";
1986       /* FALLTHRU */
1987
1988     case TYPE_MMXMOV:
1989       /* Moves from and into integer register is done using movd
1990          opcode with REX prefix.  */
1991       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1992         return "movd\t{%1, %0|%0, %1}";
1993       return "movq\t{%1, %0|%0, %1}";
1994
1995     case TYPE_SSELOG1:
1996       return "%vpxor\t%0, %d0";
1997
1998     case TYPE_MMX:
1999       return "pxor\t%0, %0";
2000
2001     case TYPE_MULTI:
2002       return "#";
2003
2004     case TYPE_LEA:
2005       return "lea{q}\t{%a1, %0|%0, %a1}";
2006
2007     default:
2008       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2009       if (get_attr_mode (insn) == MODE_SI)
2010         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2011       else if (which_alternative == 2)
2012         return "movabs{q}\t{%1, %0|%0, %1}";
2013       else
2014         return "mov{q}\t{%1, %0|%0, %1}";
2015     }
2016 }
2017   [(set (attr "type")
2018      (cond [(eq_attr "alternative" "5")
2019               (const_string "mmx")
2020             (eq_attr "alternative" "6,7,8,9,10")
2021               (const_string "mmxmov")
2022             (eq_attr "alternative" "11")
2023               (const_string "sselog1")
2024             (eq_attr "alternative" "12,13,14,15,16")
2025               (const_string "ssemov")
2026             (eq_attr "alternative" "17,18")
2027               (const_string "ssecvt")
2028             (eq_attr "alternative" "4")
2029               (const_string "multi")
2030             (match_operand:DI 1 "pic_32bit_operand" "")
2031               (const_string "lea")
2032            ]
2033            (const_string "imov")))
2034    (set (attr "modrm")
2035      (if_then_else
2036        (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2037          (const_string "0")
2038          (const_string "*")))
2039    (set (attr "length_immediate")
2040      (if_then_else
2041        (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2042          (const_string "8")
2043          (const_string "*")))
2044    (set_attr "prefix_rex" "*,*,*,*,*,*,*,1,*,1,*,*,*,*,*,*,*,*,*")
2045    (set_attr "prefix_data16" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,1,*,*,*")
2046    (set (attr "prefix")
2047      (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
2048        (const_string "maybe_vex")
2049        (const_string "orig")))
2050    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2051
2052 ;; Convert impossible stores of immediate to existing instructions.
2053 ;; First try to get scratch register and go through it.  In case this
2054 ;; fails, move by 32bit parts.
2055 (define_peephole2
2056   [(match_scratch:DI 2 "r")
2057    (set (match_operand:DI 0 "memory_operand" "")
2058         (match_operand:DI 1 "immediate_operand" ""))]
2059   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2060    && !x86_64_immediate_operand (operands[1], DImode)"
2061   [(set (match_dup 2) (match_dup 1))
2062    (set (match_dup 0) (match_dup 2))]
2063   "")
2064
2065 ;; We need to define this as both peepholer and splitter for case
2066 ;; peephole2 pass is not run.
2067 ;; "&& 1" is needed to keep it from matching the previous pattern.
2068 (define_peephole2
2069   [(set (match_operand:DI 0 "memory_operand" "")
2070         (match_operand:DI 1 "immediate_operand" ""))]
2071   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2072    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2073   [(set (match_dup 2) (match_dup 3))
2074    (set (match_dup 4) (match_dup 5))]
2075   "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2076
2077 (define_split
2078   [(set (match_operand:DI 0 "memory_operand" "")
2079         (match_operand:DI 1 "immediate_operand" ""))]
2080   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2081                     ? epilogue_completed : reload_completed)
2082    && !symbolic_operand (operands[1], DImode)
2083    && !x86_64_immediate_operand (operands[1], DImode)"
2084   [(set (match_dup 2) (match_dup 3))
2085    (set (match_dup 4) (match_dup 5))]
2086   "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2087
2088 (define_insn "*movdi_internal"
2089   [(set (match_operand:DI 0 "nonimmediate_operand"
2090                         "=r  ,o  ,*y,m*y,*y,*Y2,m  ,*Y2,*Y2,*x,m ,*x,*x")
2091         (match_operand:DI 1 "general_operand"
2092                         "riFo,riF,C ,*y ,m ,C  ,*Y2,*Y2,m  ,C ,*x,*x,m "))]
2093   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2094   "@
2095    #
2096    #
2097    pxor\t%0, %0
2098    movq\t{%1, %0|%0, %1}
2099    movq\t{%1, %0|%0, %1}
2100    %vpxor\t%0, %d0
2101    %vmovq\t{%1, %0|%0, %1}
2102    %vmovdqa\t{%1, %0|%0, %1}
2103    %vmovq\t{%1, %0|%0, %1}
2104    xorps\t%0, %0
2105    movlps\t{%1, %0|%0, %1}
2106    movaps\t{%1, %0|%0, %1}
2107    movlps\t{%1, %0|%0, %1}"
2108   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2109    (set (attr "prefix")
2110      (if_then_else (eq_attr "alternative" "5,6,7,8")
2111        (const_string "vex")
2112        (const_string "orig")))
2113    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2114
2115 (define_split
2116   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2117         (match_operand:DI 1 "general_operand" ""))]
2118   "!TARGET_64BIT && reload_completed
2119    && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2120    && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2121   [(const_int 0)]
2122   "ix86_split_long_move (operands); DONE;")
2123
2124 (define_insn "*movsi_internal"
2125   [(set (match_operand:SI 0 "nonimmediate_operand"
2126                         "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2127         (match_operand:SI 1 "general_operand"
2128                         "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r   ,m "))]
2129   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2130 {
2131   switch (get_attr_type (insn))
2132     {
2133     case TYPE_SSELOG1:
2134       if (get_attr_mode (insn) == MODE_TI)
2135         return "%vpxor\t%0, %d0";
2136       return "%vxorps\t%0, %d0";
2137
2138     case TYPE_SSEMOV:
2139       switch (get_attr_mode (insn))
2140         {
2141         case MODE_TI:
2142           return "%vmovdqa\t{%1, %0|%0, %1}";
2143         case MODE_V4SF:
2144           return "%vmovaps\t{%1, %0|%0, %1}";
2145         case MODE_SI:
2146           return "%vmovd\t{%1, %0|%0, %1}";
2147         case MODE_SF:
2148           return "%vmovss\t{%1, %0|%0, %1}";
2149         default:
2150           gcc_unreachable ();
2151         }
2152
2153     case TYPE_MMX:
2154       return "pxor\t%0, %0";
2155
2156     case TYPE_MMXMOV:
2157       if (get_attr_mode (insn) == MODE_DI)
2158         return "movq\t{%1, %0|%0, %1}";
2159       return "movd\t{%1, %0|%0, %1}";
2160
2161     case TYPE_LEA:
2162       return "lea{l}\t{%a1, %0|%0, %a1}";
2163
2164     default:
2165       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2166       return "mov{l}\t{%1, %0|%0, %1}";
2167     }
2168 }
2169   [(set (attr "type")
2170      (cond [(eq_attr "alternative" "2")
2171               (const_string "mmx")
2172             (eq_attr "alternative" "3,4,5")
2173               (const_string "mmxmov")
2174             (eq_attr "alternative" "6")
2175               (const_string "sselog1")
2176             (eq_attr "alternative" "7,8,9,10,11")
2177               (const_string "ssemov")
2178             (match_operand:DI 1 "pic_32bit_operand" "")
2179               (const_string "lea")
2180            ]
2181            (const_string "imov")))
2182    (set (attr "prefix")
2183      (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2184        (const_string "orig")
2185        (const_string "maybe_vex")))
2186    (set (attr "prefix_data16")
2187      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2188        (const_string "1")
2189        (const_string "*")))
2190    (set (attr "mode")
2191      (cond [(eq_attr "alternative" "2,3")
2192               (const_string "DI")
2193             (eq_attr "alternative" "6,7")
2194               (if_then_else
2195                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2196                 (const_string "V4SF")
2197                 (const_string "TI"))
2198             (and (eq_attr "alternative" "8,9,10,11")
2199                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
2200               (const_string "SF")
2201            ]
2202            (const_string "SI")))])
2203
2204 (define_insn "*movhi_internal"
2205   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2206         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2207   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2208 {
2209   switch (get_attr_type (insn))
2210     {
2211     case TYPE_IMOVX:
2212       /* movzwl is faster than movw on p2 due to partial word stalls,
2213          though not as fast as an aligned movl.  */
2214       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2215     default:
2216       if (get_attr_mode (insn) == MODE_SI)
2217         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2218       else
2219         return "mov{w}\t{%1, %0|%0, %1}";
2220     }
2221 }
2222   [(set (attr "type")
2223      (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
2224                 (const_int 0))
2225               (const_string "imov")
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 "imov")
2232             (and (eq_attr "alternative" "1,2")
2233                  (match_operand:HI 1 "aligned_operand" ""))
2234               (const_string "imov")
2235             (and (ne (symbol_ref "TARGET_MOVX")
2236                      (const_int 0))
2237                  (eq_attr "alternative" "0,2"))
2238               (const_string "imovx")
2239            ]
2240            (const_string "imov")))
2241     (set (attr "mode")
2242       (cond [(eq_attr "type" "imovx")
2243                (const_string "SI")
2244              (and (eq_attr "alternative" "1,2")
2245                   (match_operand:HI 1 "aligned_operand" ""))
2246                (const_string "SI")
2247              (and (eq_attr "alternative" "0")
2248                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2249                            (const_int 0))
2250                        (eq (symbol_ref "TARGET_HIMODE_MATH")
2251                            (const_int 0))))
2252                (const_string "SI")
2253             ]
2254             (const_string "HI")))])
2255
2256 ;; Situation is quite tricky about when to choose full sized (SImode) move
2257 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
2258 ;; partial register dependency machines (such as AMD Athlon), where QImode
2259 ;; moves issue extra dependency and for partial register stalls machines
2260 ;; that don't use QImode patterns (and QImode move cause stall on the next
2261 ;; instruction).
2262 ;;
2263 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2264 ;; register stall machines with, where we use QImode instructions, since
2265 ;; partial register stall can be caused there.  Then we use movzx.
2266 (define_insn "*movqi_internal"
2267   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2268         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
2269   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2270 {
2271   switch (get_attr_type (insn))
2272     {
2273     case TYPE_IMOVX:
2274       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2275       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2276     default:
2277       if (get_attr_mode (insn) == MODE_SI)
2278         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2279       else
2280         return "mov{b}\t{%1, %0|%0, %1}";
2281     }
2282 }
2283   [(set (attr "type")
2284      (cond [(and (eq_attr "alternative" "5")
2285                  (not (match_operand:QI 1 "aligned_operand" "")))
2286               (const_string "imovx")
2287             (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2288                 (const_int 0))
2289               (const_string "imov")
2290             (and (eq_attr "alternative" "3")
2291                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2292                           (const_int 0))
2293                       (eq (symbol_ref "TARGET_QIMODE_MATH")
2294                           (const_int 0))))
2295               (const_string "imov")
2296             (eq_attr "alternative" "3,5")
2297               (const_string "imovx")
2298             (and (ne (symbol_ref "TARGET_MOVX")
2299                      (const_int 0))
2300                  (eq_attr "alternative" "2"))
2301               (const_string "imovx")
2302            ]
2303            (const_string "imov")))
2304    (set (attr "mode")
2305       (cond [(eq_attr "alternative" "3,4,5")
2306                (const_string "SI")
2307              (eq_attr "alternative" "6")
2308                (const_string "QI")
2309              (eq_attr "type" "imovx")
2310                (const_string "SI")
2311              (and (eq_attr "type" "imov")
2312                   (and (eq_attr "alternative" "0,1")
2313                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
2314                                 (const_int 0))
2315                             (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2316                                      (const_int 0))
2317                                  (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2318                                      (const_int 0))))))
2319                (const_string "SI")
2320              ;; Avoid partial register stalls when not using QImode arithmetic
2321              (and (eq_attr "type" "imov")
2322                   (and (eq_attr "alternative" "0,1")
2323                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
2324                                 (const_int 0))
2325                             (eq (symbol_ref "TARGET_QIMODE_MATH")
2326                                 (const_int 0)))))
2327                (const_string "SI")
2328            ]
2329            (const_string "QI")))])
2330
2331 ;; Stores and loads of ax to arbitrary constant address.
2332 ;; We fake an second form of instruction to force reload to load address
2333 ;; into register when rax is not available
2334 (define_insn "*movabs<mode>_1"
2335   [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2336         (match_operand:SWI1248x 1 "nonmemory_operand" "a,er"))]
2337   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2338   "@
2339    movabs{<imodesuffix>}\t{%1, %P0|%P0, %1}
2340    mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2341   [(set_attr "type" "imov")
2342    (set_attr "modrm" "0,*")
2343    (set_attr "length_address" "8,0")
2344    (set_attr "length_immediate" "0,*")
2345    (set_attr "memory" "store")
2346    (set_attr "mode" "<MODE>")])
2347
2348 (define_insn "*movabs<mode>_2"
2349   [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2350         (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2351   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2352   "@
2353    movabs{<imodesuffix>}\t{%P1, %0|%0, %P1}
2354    mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2355   [(set_attr "type" "imov")
2356    (set_attr "modrm" "0,*")
2357    (set_attr "length_address" "8,0")
2358    (set_attr "length_immediate" "0")
2359    (set_attr "memory" "load")
2360    (set_attr "mode" "<MODE>")])
2361
2362 (define_insn "*swap<mode>"
2363   [(set (match_operand:SWI48 0 "register_operand" "+r")
2364         (match_operand:SWI48 1 "register_operand" "+r"))
2365    (set (match_dup 1)
2366         (match_dup 0))]
2367   ""
2368   "xchg{<imodesuffix>}\t%1, %0"
2369   [(set_attr "type" "imov")
2370    (set_attr "mode" "<MODE>")
2371    (set_attr "pent_pair" "np")
2372    (set_attr "athlon_decode" "vector")
2373    (set_attr "amdfam10_decode" "double")])
2374
2375 (define_insn "*swap<mode>_1"
2376   [(set (match_operand:SWI12 0 "register_operand" "+r")
2377         (match_operand:SWI12 1 "register_operand" "+r"))
2378    (set (match_dup 1)
2379         (match_dup 0))]
2380   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2381   "xchg{l}\t%k1, %k0"
2382   [(set_attr "type" "imov")
2383    (set_attr "mode" "SI")
2384    (set_attr "pent_pair" "np")
2385    (set_attr "athlon_decode" "vector")
2386    (set_attr "amdfam10_decode" "double")])
2387
2388 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2389 ;; is disabled for AMDFAM10
2390 (define_insn "*swap<mode>_2"
2391   [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2392         (match_operand:SWI12 1 "register_operand" "+<r>"))
2393    (set (match_dup 1)
2394         (match_dup 0))]
2395   "TARGET_PARTIAL_REG_STALL"
2396   "xchg{<imodesuffix>}\t%1, %0"
2397   [(set_attr "type" "imov")
2398    (set_attr "mode" "<MODE>")
2399    (set_attr "pent_pair" "np")
2400    (set_attr "athlon_decode" "vector")])
2401
2402 (define_expand "movstrict<mode>"
2403   [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand" ""))
2404         (match_operand:SWI12 1 "general_operand" ""))]
2405   ""
2406 {
2407   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2408     FAIL;
2409   /* Don't generate memory->memory moves, go through a register */
2410   if (MEM_P (operands[0]) && MEM_P (operands[1]))
2411     operands[1] = force_reg (<MODE>mode, operands[1]);
2412 })
2413
2414 (define_insn "*movstrict<mode>_1"
2415   [(set (strict_low_part
2416           (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2417         (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2418   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2419    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2420   "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2421   [(set_attr "type" "imov")
2422    (set_attr "mode" "<MODE>")])
2423
2424 (define_insn "*movstrict<mode>_xor"
2425   [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2426         (match_operand:SWI12 1 "const0_operand" ""))
2427    (clobber (reg:CC FLAGS_REG))]
2428   "reload_completed"
2429   "xor{<imodesuffix>}\t%0, %0"
2430   [(set_attr "type" "alu1")
2431    (set_attr "mode" "<MODE>")
2432    (set_attr "length_immediate" "0")])
2433
2434 (define_insn "*mov<mode>_extv_1"
2435   [(set (match_operand:SWI24 0 "register_operand" "=R")
2436         (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2437                             (const_int 8)
2438                             (const_int 8)))]
2439   ""
2440   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2441   [(set_attr "type" "imovx")
2442    (set_attr "mode" "SI")])
2443
2444 (define_insn "*movqi_extv_1_rex64"
2445   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2446         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2447                          (const_int 8)
2448                          (const_int 8)))]
2449   "TARGET_64BIT"
2450 {
2451   switch (get_attr_type (insn))
2452     {
2453     case TYPE_IMOVX:
2454       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2455     default:
2456       return "mov{b}\t{%h1, %0|%0, %h1}";
2457     }
2458 }
2459   [(set (attr "type")
2460      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2461                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2462                              (ne (symbol_ref "TARGET_MOVX")
2463                                  (const_int 0))))
2464         (const_string "imovx")
2465         (const_string "imov")))
2466    (set (attr "mode")
2467      (if_then_else (eq_attr "type" "imovx")
2468         (const_string "SI")
2469         (const_string "QI")))])
2470
2471 (define_insn "*movqi_extv_1"
2472   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2473         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2474                          (const_int 8)
2475                          (const_int 8)))]
2476   "!TARGET_64BIT"
2477 {
2478   switch (get_attr_type (insn))
2479     {
2480     case TYPE_IMOVX:
2481       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2482     default:
2483       return "mov{b}\t{%h1, %0|%0, %h1}";
2484     }
2485 }
2486   [(set (attr "type")
2487      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2488                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2489                              (ne (symbol_ref "TARGET_MOVX")
2490                                  (const_int 0))))
2491         (const_string "imovx")
2492         (const_string "imov")))
2493    (set (attr "mode")
2494      (if_then_else (eq_attr "type" "imovx")
2495         (const_string "SI")
2496         (const_string "QI")))])
2497
2498 (define_insn "*mov<mode>_extzv_1"
2499   [(set (match_operand:SWI48 0 "register_operand" "=R")
2500         (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2501                             (const_int 8)
2502                             (const_int 8)))]
2503   ""
2504   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2505   [(set_attr "type" "imovx")
2506    (set_attr "mode" "SI")])
2507
2508 (define_insn "*movqi_extzv_2_rex64"
2509   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2510         (subreg:QI
2511           (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2512                            (const_int 8)
2513                            (const_int 8)) 0))]
2514   "TARGET_64BIT"
2515 {
2516   switch (get_attr_type (insn))
2517     {
2518     case TYPE_IMOVX:
2519       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2520     default:
2521       return "mov{b}\t{%h1, %0|%0, %h1}";
2522     }
2523 }
2524   [(set (attr "type")
2525      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2526                         (ne (symbol_ref "TARGET_MOVX")
2527                             (const_int 0)))
2528         (const_string "imovx")
2529         (const_string "imov")))
2530    (set (attr "mode")
2531      (if_then_else (eq_attr "type" "imovx")
2532         (const_string "SI")
2533         (const_string "QI")))])
2534
2535 (define_insn "*movqi_extzv_2"
2536   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2537         (subreg:QI
2538           (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2539                            (const_int 8)
2540                            (const_int 8)) 0))]
2541   "!TARGET_64BIT"
2542 {
2543   switch (get_attr_type (insn))
2544     {
2545     case TYPE_IMOVX:
2546       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2547     default:
2548       return "mov{b}\t{%h1, %0|%0, %h1}";
2549     }
2550 }
2551   [(set (attr "type")
2552      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2553                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2554                              (ne (symbol_ref "TARGET_MOVX")
2555                                  (const_int 0))))
2556         (const_string "imovx")
2557         (const_string "imov")))
2558    (set (attr "mode")
2559      (if_then_else (eq_attr "type" "imovx")
2560         (const_string "SI")
2561         (const_string "QI")))])
2562
2563 (define_expand "mov<mode>_insv_1"
2564   [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "")
2565                             (const_int 8)
2566                             (const_int 8))
2567         (match_operand:SWI48 1 "nonmemory_operand" ""))]
2568   ""
2569   "")
2570
2571 (define_insn "*mov<mode>_insv_1_rex64"
2572   [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2573                              (const_int 8)
2574                              (const_int 8))
2575         (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2576   "TARGET_64BIT"
2577   "mov{b}\t{%b1, %h0|%h0, %b1}"
2578   [(set_attr "type" "imov")
2579    (set_attr "mode" "QI")])
2580
2581 (define_insn "*movsi_insv_1"
2582   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2583                          (const_int 8)
2584                          (const_int 8))
2585         (match_operand:SI 1 "general_operand" "Qmn"))]
2586   "!TARGET_64BIT"
2587   "mov{b}\t{%b1, %h0|%h0, %b1}"
2588   [(set_attr "type" "imov")
2589    (set_attr "mode" "QI")])
2590
2591 (define_insn "*movqi_insv_2"
2592   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2593                          (const_int 8)
2594                          (const_int 8))
2595         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2596                      (const_int 8)))]
2597   ""
2598   "mov{b}\t{%h1, %h0|%h0, %h1}"
2599   [(set_attr "type" "imov")
2600    (set_attr "mode" "QI")])
2601 \f
2602 ;; Floating point move instructions.
2603
2604 (define_expand "movtf"
2605   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2606         (match_operand:TF 1 "nonimmediate_operand" ""))]
2607   "TARGET_SSE2"
2608 {
2609   ix86_expand_move (TFmode, operands);
2610   DONE;
2611 })
2612
2613 (define_expand "mov<mode>"
2614   [(set (match_operand:X87MODEF 0 "nonimmediate_operand" "")
2615         (match_operand:X87MODEF 1 "general_operand" ""))]
2616   ""
2617   "ix86_expand_move (<MODE>mode, operands); DONE;")
2618
2619 (define_insn "*pushtf"
2620   [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2621         (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2622   "TARGET_SSE2"
2623 {
2624   /* This insn should be already split before reg-stack.  */
2625   gcc_unreachable ();
2626 }
2627   [(set_attr "type" "multi")
2628    (set_attr "unit" "sse,*,*")
2629    (set_attr "mode" "TF,SI,SI")])
2630
2631 (define_split
2632   [(set (match_operand:TF 0 "push_operand" "")
2633         (match_operand:TF 1 "general_operand" ""))]
2634   "TARGET_SSE2 && reload_completed
2635    && !SSE_REG_P (operands[1])"
2636   [(const_int 0)]
2637   "ix86_split_long_move (operands); DONE;")
2638
2639 (define_split
2640   [(set (match_operand:TF 0 "push_operand" "")
2641         (match_operand:TF 1 "any_fp_register_operand" ""))]
2642   "TARGET_SSE2"
2643   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2644    (set (mem:TF (reg:P SP_REG)) (match_dup 1))]
2645   "")
2646
2647 (define_insn "*pushxf"
2648   [(set (match_operand:XF 0 "push_operand" "=<,<")
2649         (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2650   "optimize_function_for_speed_p (cfun)"
2651 {
2652   /* This insn should be already split before reg-stack.  */
2653   gcc_unreachable ();
2654 }
2655   [(set_attr "type" "multi")
2656    (set_attr "unit" "i387,*")
2657    (set_attr "mode" "XF,SI")])
2658
2659 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2660 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2661 ;; Pushing using integer instructions is longer except for constants
2662 ;; and direct memory references (assuming that any given constant is pushed
2663 ;; only once, but this ought to be handled elsewhere).
2664
2665 (define_insn "*pushxf_nointeger"
2666   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2667         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2668   "optimize_function_for_size_p (cfun)"
2669 {
2670   /* This insn should be already split before reg-stack.  */
2671   gcc_unreachable ();
2672 }
2673   [(set_attr "type" "multi")
2674    (set_attr "unit" "i387,*,*")
2675    (set_attr "mode" "XF,SI,SI")])
2676
2677 (define_split
2678   [(set (match_operand:XF 0 "push_operand" "")
2679         (match_operand:XF 1 "any_fp_register_operand" ""))]
2680   "reload_completed"
2681   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2682    (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2683   "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2684
2685 (define_split
2686   [(set (match_operand:XF 0 "push_operand" "")
2687         (match_operand:XF 1 "general_operand" ""))]
2688   "reload_completed
2689    && !ANY_FP_REG_P (operands[1])"
2690   [(const_int 0)]
2691   "ix86_split_long_move (operands); DONE;")
2692
2693 (define_insn "*pushdf"
2694   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2695         (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2696   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2697 {
2698   /* This insn should be already split before reg-stack.  */
2699   gcc_unreachable ();
2700 }
2701   [(set_attr "type" "multi")
2702    (set_attr "unit" "i387,*,*")
2703    (set_attr "mode" "DF,SI,DF")])
2704
2705 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2706 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2707 ;; On the average, pushdf using integers can be still shorter.  Allow this
2708 ;; pattern for optimize_size too.
2709
2710 (define_insn "*pushdf_nointeger"
2711   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2712         (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2713   "!(TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES)"
2714 {
2715   /* This insn should be already split before reg-stack.  */
2716   gcc_unreachable ();
2717 }
2718   [(set_attr "type" "multi")
2719    (set_attr "unit" "i387,*,*,*")
2720    (set_attr "mode" "DF,SI,SI,DF")])
2721
2722 ;; %%% Kill this when call knows how to work this out.
2723 (define_split
2724   [(set (match_operand:DF 0 "push_operand" "")
2725         (match_operand:DF 1 "any_fp_register_operand" ""))]
2726   "reload_completed"
2727   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2728    (set (mem:DF (reg:P SP_REG)) (match_dup 1))]
2729   "")
2730
2731 (define_split
2732   [(set (match_operand:DF 0 "push_operand" "")
2733         (match_operand:DF 1 "general_operand" ""))]
2734   "reload_completed
2735    && !ANY_FP_REG_P (operands[1])"
2736   [(const_int 0)]
2737   "ix86_split_long_move (operands); DONE;")
2738
2739 (define_insn "*pushsf_rex64"
2740   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2741         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2742   "TARGET_64BIT"
2743 {
2744   /* Anything else should be already split before reg-stack.  */
2745   gcc_assert (which_alternative == 1);
2746   return "push{q}\t%q1";
2747 }
2748   [(set_attr "type" "multi,push,multi")
2749    (set_attr "unit" "i387,*,*")
2750    (set_attr "mode" "SF,DI,SF")])
2751
2752 (define_insn "*pushsf"
2753   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2754         (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2755   "!TARGET_64BIT"
2756 {
2757   /* Anything else should be already split before reg-stack.  */
2758   gcc_assert (which_alternative == 1);
2759   return "push{l}\t%1";
2760 }
2761   [(set_attr "type" "multi,push,multi")
2762    (set_attr "unit" "i387,*,*")
2763    (set_attr "mode" "SF,SI,SF")])
2764
2765 (define_split
2766   [(set (match_operand:SF 0 "push_operand" "")
2767         (match_operand:SF 1 "memory_operand" ""))]
2768   "reload_completed
2769    && MEM_P (operands[1])
2770    && (operands[2] = find_constant_src (insn))"
2771   [(set (match_dup 0)
2772         (match_dup 2))])
2773
2774 ;; %%% Kill this when call knows how to work this out.
2775 (define_split
2776   [(set (match_operand:SF 0 "push_operand" "")
2777         (match_operand:SF 1 "any_fp_register_operand" ""))]
2778   "reload_completed"
2779   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2780    (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2781   "operands[2] = GEN_INT (-GET_MODE_SIZE (<MODE>mode));")
2782
2783 (define_insn "*movtf_internal"
2784   [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
2785         (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
2786   "TARGET_SSE2
2787    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2788 {
2789   switch (which_alternative)
2790     {
2791     case 0:
2792     case 1:
2793       if (get_attr_mode (insn) == MODE_V4SF)
2794         return "%vmovaps\t{%1, %0|%0, %1}";
2795       else
2796         return "%vmovdqa\t{%1, %0|%0, %1}";
2797     case 2:
2798       if (get_attr_mode (insn) == MODE_V4SF)
2799         return "%vxorps\t%0, %d0";
2800       else
2801         return "%vpxor\t%0, %d0";
2802     case 3:
2803     case 4:
2804         return "#";
2805     default:
2806       gcc_unreachable ();
2807     }
2808 }
2809   [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
2810    (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2811    (set (attr "mode")
2812         (cond [(eq_attr "alternative" "0,2")
2813                  (if_then_else
2814                    (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2815                        (const_int 0))
2816                    (const_string "V4SF")
2817                    (const_string "TI"))
2818                (eq_attr "alternative" "1")
2819                  (if_then_else
2820                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2821                             (const_int 0))
2822                         (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2823                             (const_int 0)))
2824                    (const_string "V4SF")
2825                    (const_string "TI"))]
2826                (const_string "DI")))])
2827
2828 (define_split
2829   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2830         (match_operand:TF 1 "general_operand" ""))]
2831   "reload_completed
2832    && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
2833   [(const_int 0)]
2834   "ix86_split_long_move (operands); DONE;")
2835
2836 (define_insn "*movxf_internal"
2837   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
2838         (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
2839   "optimize_function_for_speed_p (cfun)
2840    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2841    && (reload_in_progress || reload_completed
2842        || GET_CODE (operands[1]) != CONST_DOUBLE
2843        || memory_operand (operands[0], XFmode))"
2844 {
2845   switch (which_alternative)
2846     {
2847     case 0:
2848     case 1:
2849       return output_387_reg_move (insn, operands);
2850
2851     case 2:
2852       return standard_80387_constant_opcode (operands[1]);
2853
2854     case 3: case 4:
2855       return "#";
2856
2857     default:
2858       gcc_unreachable ();
2859     }
2860 }
2861   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2862    (set_attr "mode" "XF,XF,XF,SI,SI")])
2863
2864 ;; Do not use integer registers when optimizing for size
2865 (define_insn "*movxf_internal_nointeger"
2866   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2867         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2868   "optimize_function_for_size_p (cfun)
2869    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2870    && (reload_in_progress || reload_completed
2871        || standard_80387_constant_p (operands[1])
2872        || GET_CODE (operands[1]) != CONST_DOUBLE
2873        || memory_operand (operands[0], XFmode))"
2874 {
2875   switch (which_alternative)
2876     {
2877     case 0:
2878     case 1:
2879       return output_387_reg_move (insn, operands);
2880
2881     case 2:
2882       return standard_80387_constant_opcode (operands[1]);
2883
2884     case 3: case 4:
2885       return "#";
2886     default:
2887       gcc_unreachable ();
2888     }
2889 }
2890   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2891    (set_attr "mode" "XF,XF,XF,SI,SI")])
2892
2893 (define_split
2894   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2895         (match_operand:XF 1 "general_operand" ""))]
2896   "reload_completed
2897    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2898    && ! (ANY_FP_REG_P (operands[0]) ||
2899          (GET_CODE (operands[0]) == SUBREG
2900           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2901    && ! (ANY_FP_REG_P (operands[1]) ||
2902          (GET_CODE (operands[1]) == SUBREG
2903           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2904   [(const_int 0)]
2905   "ix86_split_long_move (operands); DONE;")
2906
2907 (define_insn "*movdf_internal_rex64"
2908   [(set (match_operand:DF 0 "nonimmediate_operand"
2909                 "=f,m,f,r  ,m ,Y2*x,Y2*x,Y2*x,m   ,Yi,r ")
2910         (match_operand:DF 1 "general_operand"
2911                 "fm,f,G,rmF,Fr,C   ,Y2*x,m   ,Y2*x,r ,Yi"))]
2912   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2913    && (reload_in_progress || reload_completed
2914        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2915        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
2916            && optimize_function_for_size_p (cfun)
2917            && standard_80387_constant_p (operands[1]))
2918        || GET_CODE (operands[1]) != CONST_DOUBLE
2919        || memory_operand (operands[0], DFmode))"
2920 {
2921   switch (which_alternative)
2922     {
2923     case 0:
2924     case 1:
2925       return output_387_reg_move (insn, operands);
2926
2927     case 2:
2928       return standard_80387_constant_opcode (operands[1]);
2929
2930     case 3:
2931     case 4:
2932       return "#";
2933
2934     case 5:
2935       switch (get_attr_mode (insn))
2936         {
2937         case MODE_V4SF:
2938           return "%vxorps\t%0, %d0";
2939         case MODE_V2DF:
2940           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2941             return "%vxorps\t%0, %d0";
2942           else
2943             return "%vxorpd\t%0, %d0";
2944         case MODE_TI:
2945           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2946             return "%vxorps\t%0, %d0";
2947           else
2948             return "%vpxor\t%0, %d0";
2949         default:
2950           gcc_unreachable ();
2951         }
2952     case 6:
2953     case 7:
2954     case 8:
2955       switch (get_attr_mode (insn))
2956         {
2957         case MODE_V4SF:
2958           return "%vmovaps\t{%1, %0|%0, %1}";
2959         case MODE_V2DF:
2960           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2961             return "%vmovaps\t{%1, %0|%0, %1}";
2962           else
2963             return "%vmovapd\t{%1, %0|%0, %1}";
2964         case MODE_TI:
2965           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2966             return "%vmovaps\t{%1, %0|%0, %1}";
2967           else
2968             return "%vmovdqa\t{%1, %0|%0, %1}";
2969         case MODE_DI:
2970           return "%vmovq\t{%1, %0|%0, %1}";
2971         case MODE_DF:
2972           if (TARGET_AVX)
2973             {
2974               if (REG_P (operands[0]) && REG_P (operands[1]))
2975                 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
2976               else
2977                 return "vmovsd\t{%1, %0|%0, %1}";
2978             }
2979           else
2980             return "movsd\t{%1, %0|%0, %1}";
2981         case MODE_V1DF:
2982           return "%vmovlpd\t{%1, %d0|%d0, %1}";
2983         case MODE_V2SF:
2984           return "%vmovlps\t{%1, %d0|%d0, %1}";
2985         default:
2986           gcc_unreachable ();
2987         }
2988
2989     case 9:
2990     case 10:
2991     return "%vmovd\t{%1, %0|%0, %1}";
2992
2993     default:
2994       gcc_unreachable();
2995     }
2996 }
2997   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
2998    (set (attr "prefix")
2999      (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3000        (const_string "orig")
3001        (const_string "maybe_vex")))
3002    (set (attr "prefix_data16")
3003      (if_then_else (eq_attr "mode" "V1DF")
3004        (const_string "1")
3005        (const_string "*")))
3006    (set (attr "mode")
3007         (cond [(eq_attr "alternative" "0,1,2")
3008                  (const_string "DF")
3009                (eq_attr "alternative" "3,4,9,10")
3010                  (const_string "DI")
3011
3012                /* For SSE1, we have many fewer alternatives.  */
3013                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3014                  (cond [(eq_attr "alternative" "5,6")
3015                           (const_string "V4SF")
3016                        ]
3017                    (const_string "V2SF"))
3018
3019                /* xorps is one byte shorter.  */
3020                (eq_attr "alternative" "5")
3021                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3022                             (const_int 0))
3023                           (const_string "V4SF")
3024                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3025                             (const_int 0))
3026                           (const_string "TI")
3027                        ]
3028                        (const_string "V2DF"))
3029
3030                /* For architectures resolving dependencies on
3031                   whole SSE registers use APD move to break dependency
3032                   chains, otherwise use short move to avoid extra work.
3033
3034                   movaps encodes one byte shorter.  */
3035                (eq_attr "alternative" "6")
3036                  (cond
3037                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3038                         (const_int 0))
3039                       (const_string "V4SF")
3040                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3041                         (const_int 0))
3042                       (const_string "V2DF")
3043                    ]
3044                    (const_string "DF"))
3045                /* For architectures resolving dependencies on register
3046                   parts we may avoid extra work to zero out upper part
3047                   of register.  */
3048                (eq_attr "alternative" "7")
3049                  (if_then_else
3050                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3051                        (const_int 0))
3052                    (const_string "V1DF")
3053                    (const_string "DF"))
3054               ]
3055               (const_string "DF")))])
3056
3057 (define_insn "*movdf_internal"
3058   [(set (match_operand:DF 0 "nonimmediate_operand"
3059                 "=f,m,f,r  ,o ,Y2*x,Y2*x,Y2*x,m   ")
3060         (match_operand:DF 1 "general_operand"
3061                 "fm,f,G,roF,Fr,C   ,Y2*x,m   ,Y2*x"))]
3062   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3063    && optimize_function_for_speed_p (cfun)
3064    && TARGET_INTEGER_DFMODE_MOVES
3065    && (reload_in_progress || reload_completed
3066        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3067        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3068            && optimize_function_for_size_p (cfun)
3069            && standard_80387_constant_p (operands[1]))
3070        || GET_CODE (operands[1]) != CONST_DOUBLE
3071        || memory_operand (operands[0], DFmode))"
3072 {
3073   switch (which_alternative)
3074     {
3075     case 0:
3076     case 1:
3077       return output_387_reg_move (insn, operands);
3078
3079     case 2:
3080       return standard_80387_constant_opcode (operands[1]);
3081
3082     case 3:
3083     case 4:
3084       return "#";
3085
3086     case 5:
3087       switch (get_attr_mode (insn))
3088         {
3089         case MODE_V4SF:
3090           return "xorps\t%0, %0";
3091         case MODE_V2DF:
3092           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3093             return "xorps\t%0, %0";
3094           else
3095             return "xorpd\t%0, %0";
3096         case MODE_TI:
3097           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3098             return "xorps\t%0, %0";
3099           else
3100             return "pxor\t%0, %0";
3101         default:
3102           gcc_unreachable ();
3103         }
3104     case 6:
3105     case 7:
3106     case 8:
3107       switch (get_attr_mode (insn))
3108         {
3109         case MODE_V4SF:
3110           return "movaps\t{%1, %0|%0, %1}";
3111         case MODE_V2DF:
3112           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3113             return "movaps\t{%1, %0|%0, %1}";
3114           else
3115             return "movapd\t{%1, %0|%0, %1}";
3116         case MODE_TI:
3117           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3118             return "movaps\t{%1, %0|%0, %1}";
3119           else
3120             return "movdqa\t{%1, %0|%0, %1}";
3121         case MODE_DI:
3122           return "movq\t{%1, %0|%0, %1}";
3123         case MODE_DF:
3124           return "movsd\t{%1, %0|%0, %1}";
3125         case MODE_V1DF:
3126           return "movlpd\t{%1, %0|%0, %1}";
3127         case MODE_V2SF:
3128           return "movlps\t{%1, %0|%0, %1}";
3129         default:
3130           gcc_unreachable ();
3131         }
3132
3133     default:
3134       gcc_unreachable();
3135     }
3136 }
3137   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3138    (set (attr "prefix_data16")
3139      (if_then_else (eq_attr "mode" "V1DF")
3140        (const_string "1")
3141        (const_string "*")))
3142    (set (attr "mode")
3143         (cond [(eq_attr "alternative" "0,1,2")
3144                  (const_string "DF")
3145                (eq_attr "alternative" "3,4")
3146                  (const_string "SI")
3147
3148                /* For SSE1, we have many fewer alternatives.  */
3149                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3150                  (cond [(eq_attr "alternative" "5,6")
3151                           (const_string "V4SF")
3152                        ]
3153                    (const_string "V2SF"))
3154
3155                /* xorps is one byte shorter.  */
3156                (eq_attr "alternative" "5")
3157                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3158                             (const_int 0))
3159                           (const_string "V4SF")
3160                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3161                             (const_int 0))
3162                           (const_string "TI")
3163                        ]
3164                        (const_string "V2DF"))
3165
3166                /* For architectures resolving dependencies on
3167                   whole SSE registers use APD move to break dependency
3168                   chains, otherwise use short move to avoid extra work.
3169
3170                   movaps encodes one byte shorter.  */
3171                (eq_attr "alternative" "6")
3172                  (cond
3173                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3174                         (const_int 0))
3175                       (const_string "V4SF")
3176                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3177                         (const_int 0))
3178                       (const_string "V2DF")
3179                    ]
3180                    (const_string "DF"))
3181                /* For architectures resolving dependencies on register
3182                   parts we may avoid extra work to zero out upper part
3183                   of register.  */
3184                (eq_attr "alternative" "7")
3185                  (if_then_else
3186                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3187                        (const_int 0))
3188                    (const_string "V1DF")
3189                    (const_string "DF"))
3190               ]
3191               (const_string "DF")))])
3192
3193 ;; Moving is usually shorter when only FP registers are used. This separate
3194 ;; movdf pattern avoids the use of integer registers for FP operations
3195 ;; when optimizing for size.
3196
3197 (define_insn "*movdf_internal_nointeger"
3198   [(set (match_operand:DF 0 "nonimmediate_operand"
3199                         "=f,m,f,*r  ,o  ,Y2*x,Y2*x,Y2*x ,m  ")
3200         (match_operand:DF 1 "general_operand"
3201                         "fm,f,G,*roF,*Fr,C   ,Y2*x,mY2*x,Y2*x"))]
3202   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3203    && ((optimize_function_for_size_p (cfun)
3204        || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
3205    && (reload_in_progress || reload_completed
3206        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3207        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3208            && optimize_function_for_size_p (cfun)
3209            && !memory_operand (operands[0], DFmode)
3210            && standard_80387_constant_p (operands[1]))
3211        || GET_CODE (operands[1]) != CONST_DOUBLE
3212        || ((optimize_function_for_size_p (cfun)
3213             || !TARGET_MEMORY_MISMATCH_STALL
3214             || reload_in_progress || reload_completed)
3215            && memory_operand (operands[0], DFmode)))"
3216 {
3217   switch (which_alternative)
3218     {
3219     case 0:
3220     case 1:
3221       return output_387_reg_move (insn, operands);
3222
3223     case 2:
3224       return standard_80387_constant_opcode (operands[1]);
3225
3226     case 3:
3227     case 4:
3228       return "#";
3229     case 5:
3230       switch (get_attr_mode (insn))
3231         {
3232         case MODE_V4SF:
3233           return "%vxorps\t%0, %d0";
3234         case MODE_V2DF:
3235           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3236             return "%vxorps\t%0, %d0";
3237           else
3238             return "%vxorpd\t%0, %d0";
3239         case MODE_TI:
3240           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3241             return "%vxorps\t%0, %d0";
3242           else
3243             return "%vpxor\t%0, %d0";
3244         default:
3245           gcc_unreachable ();
3246         }
3247     case 6:
3248     case 7:
3249     case 8:
3250       switch (get_attr_mode (insn))
3251         {
3252         case MODE_V4SF:
3253           return "%vmovaps\t{%1, %0|%0, %1}";
3254         case MODE_V2DF:
3255           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3256             return "%vmovaps\t{%1, %0|%0, %1}";
3257           else
3258             return "%vmovapd\t{%1, %0|%0, %1}";
3259         case MODE_TI:
3260           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3261             return "%vmovaps\t{%1, %0|%0, %1}";
3262           else
3263             return "%vmovdqa\t{%1, %0|%0, %1}";
3264         case MODE_DI:
3265           return "%vmovq\t{%1, %0|%0, %1}";
3266         case MODE_DF:
3267           if (TARGET_AVX)
3268             {
3269               if (REG_P (operands[0]) && REG_P (operands[1]))
3270                 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3271               else
3272                 return "vmovsd\t{%1, %0|%0, %1}";
3273             }
3274           else
3275             return "movsd\t{%1, %0|%0, %1}";
3276         case MODE_V1DF:
3277           if (TARGET_AVX)
3278             {
3279               if (REG_P (operands[0]))
3280                 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
3281               else
3282                 return "vmovlpd\t{%1, %0|%0, %1}";
3283             }
3284           else
3285             return "movlpd\t{%1, %0|%0, %1}";
3286         case MODE_V2SF:
3287           if (TARGET_AVX)
3288             {
3289               if (REG_P (operands[0]))
3290                 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
3291               else
3292                 return "vmovlps\t{%1, %0|%0, %1}";
3293             }
3294           else
3295             return "movlps\t{%1, %0|%0, %1}";
3296         default:
3297           gcc_unreachable ();
3298         }
3299
3300     default:
3301       gcc_unreachable ();
3302     }
3303 }
3304   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3305    (set (attr "prefix")
3306      (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3307        (const_string "orig")
3308        (const_string "maybe_vex")))
3309    (set (attr "prefix_data16")
3310      (if_then_else (eq_attr "mode" "V1DF")
3311        (const_string "1")
3312        (const_string "*")))
3313    (set (attr "mode")
3314         (cond [(eq_attr "alternative" "0,1,2")
3315                  (const_string "DF")
3316                (eq_attr "alternative" "3,4")
3317                  (const_string "SI")
3318
3319                /* For SSE1, we have many fewer alternatives.  */
3320                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3321                  (cond [(eq_attr "alternative" "5,6")
3322                           (const_string "V4SF")
3323                        ]
3324                    (const_string "V2SF"))
3325
3326                /* xorps is one byte shorter.  */
3327                (eq_attr "alternative" "5")
3328                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3329                             (const_int 0))
3330                           (const_string "V4SF")
3331                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3332                             (const_int 0))
3333                           (const_string "TI")
3334                        ]
3335                        (const_string "V2DF"))
3336
3337                /* For architectures resolving dependencies on
3338                   whole SSE registers use APD move to break dependency
3339                   chains, otherwise use short move to avoid extra work.
3340
3341                   movaps encodes one byte shorter.  */
3342                (eq_attr "alternative" "6")
3343                  (cond
3344                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3345                         (const_int 0))
3346                       (const_string "V4SF")
3347                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3348                         (const_int 0))
3349                       (const_string "V2DF")
3350                    ]
3351                    (const_string "DF"))
3352                /* For architectures resolving dependencies on register
3353                   parts we may avoid extra work to zero out upper part
3354                   of register.  */
3355                (eq_attr "alternative" "7")
3356                  (if_then_else
3357                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3358                        (const_int 0))
3359                    (const_string "V1DF")
3360                    (const_string "DF"))
3361               ]
3362               (const_string "DF")))])
3363
3364 (define_split
3365   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3366         (match_operand:DF 1 "general_operand" ""))]
3367   "reload_completed
3368    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3369    && ! (ANY_FP_REG_P (operands[0]) ||
3370          (GET_CODE (operands[0]) == SUBREG
3371           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3372    && ! (ANY_FP_REG_P (operands[1]) ||
3373          (GET_CODE (operands[1]) == SUBREG
3374           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3375   [(const_int 0)]
3376   "ix86_split_long_move (operands); DONE;")
3377
3378 (define_insn "*movsf_internal"
3379   [(set (match_operand:SF 0 "nonimmediate_operand"
3380           "=f,m,f,r  ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3381         (match_operand:SF 1 "general_operand"
3382           "fm,f,G,rmF,Fr,C,x,xm,x,m  ,*y,*y ,r  ,Yi,r   ,*Ym"))]
3383   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3384    && (reload_in_progress || reload_completed
3385        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3386        || (!TARGET_SSE_MATH && optimize_function_for_size_p (cfun)
3387            && standard_80387_constant_p (operands[1]))
3388        || GET_CODE (operands[1]) != CONST_DOUBLE
3389        || memory_operand (operands[0], SFmode))"
3390 {
3391   switch (which_alternative)
3392     {
3393     case 0:
3394     case 1:
3395       return output_387_reg_move (insn, operands);
3396
3397     case 2:
3398       return standard_80387_constant_opcode (operands[1]);
3399
3400     case 3:
3401     case 4:
3402       return "mov{l}\t{%1, %0|%0, %1}";
3403     case 5:
3404       if (get_attr_mode (insn) == MODE_TI)
3405         return "%vpxor\t%0, %d0";
3406       else
3407         return "%vxorps\t%0, %d0";
3408     case 6:
3409       if (get_attr_mode (insn) == MODE_V4SF)
3410         return "%vmovaps\t{%1, %0|%0, %1}";
3411       else
3412         return "%vmovss\t{%1, %d0|%d0, %1}";
3413     case 7:
3414       if (TARGET_AVX)
3415         return REG_P (operands[1]) ? "vmovss\t{%1, %0, %0|%0, %0, %1}"
3416                                    : "vmovss\t{%1, %0|%0, %1}";
3417       else
3418         return "movss\t{%1, %0|%0, %1}";
3419     case 8:
3420       return "%vmovss\t{%1, %0|%0, %1}";
3421
3422     case 9: case 10: case 14: case 15:
3423       return "movd\t{%1, %0|%0, %1}";
3424     case 12: case 13:
3425       return "%vmovd\t{%1, %0|%0, %1}";
3426
3427     case 11:
3428       return "movq\t{%1, %0|%0, %1}";
3429
3430     default:
3431       gcc_unreachable ();
3432     }
3433 }
3434   [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
3435    (set (attr "prefix")
3436      (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3437        (const_string "maybe_vex")
3438        (const_string "orig")))
3439    (set (attr "mode")
3440         (cond [(eq_attr "alternative" "3,4,9,10")
3441                  (const_string "SI")
3442                (eq_attr "alternative" "5")
3443                  (if_then_else
3444                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3445                                  (const_int 0))
3446                              (ne (symbol_ref "TARGET_SSE2")
3447                                  (const_int 0)))
3448                         (eq (symbol_ref "optimize_function_for_size_p (cfun)")
3449                             (const_int 0)))
3450                    (const_string "TI")
3451                    (const_string "V4SF"))
3452                /* For architectures resolving dependencies on
3453                   whole SSE registers use APS move to break dependency
3454                   chains, otherwise use short move to avoid extra work.
3455
3456                   Do the same for architectures resolving dependencies on
3457                   the parts.  While in DF mode it is better to always handle
3458                   just register parts, the SF mode is different due to lack
3459                   of instructions to load just part of the register.  It is
3460                   better to maintain the whole registers in single format
3461                   to avoid problems on using packed logical operations.  */
3462                (eq_attr "alternative" "6")
3463                  (if_then_else
3464                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3465                             (const_int 0))
3466                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3467                             (const_int 0)))
3468                    (const_string "V4SF")
3469                    (const_string "SF"))
3470                (eq_attr "alternative" "11")
3471                  (const_string "DI")]
3472                (const_string "SF")))])
3473
3474 (define_split
3475   [(set (match_operand 0 "register_operand" "")
3476         (match_operand 1 "memory_operand" ""))]
3477   "reload_completed
3478    && MEM_P (operands[1])
3479    && (GET_MODE (operands[0]) == TFmode
3480        || GET_MODE (operands[0]) == XFmode
3481        || GET_MODE (operands[0]) == DFmode
3482        || GET_MODE (operands[0]) == SFmode)
3483    && (operands[2] = find_constant_src (insn))"
3484   [(set (match_dup 0) (match_dup 2))]
3485 {
3486   rtx c = operands[2];
3487   rtx r = operands[0];
3488
3489   if (GET_CODE (r) == SUBREG)
3490     r = SUBREG_REG (r);
3491
3492   if (SSE_REG_P (r))
3493     {
3494       if (!standard_sse_constant_p (c))
3495         FAIL;
3496     }
3497   else if (FP_REG_P (r))
3498     {
3499       if (!standard_80387_constant_p (c))
3500         FAIL;
3501     }
3502   else if (MMX_REG_P (r))
3503     FAIL;
3504 })
3505
3506 (define_split
3507   [(set (match_operand 0 "register_operand" "")
3508         (float_extend (match_operand 1 "memory_operand" "")))]
3509   "reload_completed
3510    && MEM_P (operands[1])
3511    && (GET_MODE (operands[0]) == TFmode
3512        || GET_MODE (operands[0]) == XFmode
3513        || GET_MODE (operands[0]) == DFmode
3514        || GET_MODE (operands[0]) == SFmode)
3515    && (operands[2] = find_constant_src (insn))"
3516   [(set (match_dup 0) (match_dup 2))]
3517 {
3518   rtx c = operands[2];
3519   rtx r = operands[0];
3520
3521   if (GET_CODE (r) == SUBREG)
3522     r = SUBREG_REG (r);
3523
3524   if (SSE_REG_P (r))
3525     {
3526       if (!standard_sse_constant_p (c))
3527         FAIL;
3528     }
3529   else if (FP_REG_P (r))
3530     {
3531       if (!standard_80387_constant_p (c))
3532         FAIL;
3533     }
3534   else if (MMX_REG_P (r))
3535     FAIL;
3536 })
3537
3538 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3539 (define_split
3540   [(set (match_operand:X87MODEF 0 "register_operand" "")
3541         (match_operand:X87MODEF 1 "immediate_operand" ""))]
3542   "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3543    && (standard_80387_constant_p (operands[1]) == 8
3544        || standard_80387_constant_p (operands[1]) == 9)"
3545   [(set (match_dup 0)(match_dup 1))
3546    (set (match_dup 0)
3547         (neg:X87MODEF (match_dup 0)))]
3548 {
3549   REAL_VALUE_TYPE r;
3550
3551   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3552   if (real_isnegzero (&r))
3553     operands[1] = CONST0_RTX (<MODE>mode);
3554   else
3555     operands[1] = CONST1_RTX (<MODE>mode);
3556 })
3557
3558 (define_insn "swapxf"
3559   [(set (match_operand:XF 0 "register_operand" "+f")
3560         (match_operand:XF 1 "register_operand" "+f"))
3561    (set (match_dup 1)
3562         (match_dup 0))]
3563   "TARGET_80387"
3564 {
3565   if (STACK_TOP_P (operands[0]))
3566     return "fxch\t%1";
3567   else
3568     return "fxch\t%0";
3569 }
3570   [(set_attr "type" "fxch")
3571    (set_attr "mode" "XF")])
3572
3573 (define_insn "*swap<mode>"
3574   [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3575         (match_operand:MODEF 1 "fp_register_operand" "+f"))
3576    (set (match_dup 1)
3577         (match_dup 0))]
3578   "TARGET_80387 || reload_completed"
3579 {
3580   if (STACK_TOP_P (operands[0]))
3581     return "fxch\t%1";
3582   else
3583     return "fxch\t%0";
3584 }
3585   [(set_attr "type" "fxch")
3586    (set_attr "mode" "<MODE>")])
3587 \f
3588 ;; Zero extension instructions
3589
3590 (define_expand "zero_extendhisi2"
3591   [(set (match_operand:SI 0 "register_operand" "")
3592      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3593   ""
3594 {
3595   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3596     {
3597       operands[1] = force_reg (HImode, operands[1]);
3598       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3599       DONE;
3600     }
3601 })
3602
3603 (define_insn "zero_extendhisi2_and"
3604   [(set (match_operand:SI 0 "register_operand" "=r")
3605      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3606    (clobber (reg:CC FLAGS_REG))]
3607   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3608   "#"
3609   [(set_attr "type" "alu1")
3610    (set_attr "mode" "SI")])
3611
3612 (define_split
3613   [(set (match_operand:SI 0 "register_operand" "")
3614         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3615    (clobber (reg:CC FLAGS_REG))]
3616   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND
3617    && optimize_function_for_speed_p (cfun)"
3618   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3619               (clobber (reg:CC FLAGS_REG))])]
3620   "")
3621
3622 (define_insn "*zero_extendhisi2_movzwl"
3623   [(set (match_operand:SI 0 "register_operand" "=r")
3624      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3625   "!TARGET_ZERO_EXTEND_WITH_AND
3626    || optimize_function_for_size_p (cfun)"
3627   "movz{wl|x}\t{%1, %0|%0, %1}"
3628   [(set_attr "type" "imovx")
3629    (set_attr "mode" "SI")])
3630
3631 (define_expand "zero_extendqihi2"
3632   [(parallel
3633     [(set (match_operand:HI 0 "register_operand" "")
3634        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3635      (clobber (reg:CC FLAGS_REG))])]
3636   ""
3637   "")
3638
3639 (define_insn "*zero_extendqihi2_and"
3640   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3641      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3642    (clobber (reg:CC FLAGS_REG))]
3643   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3644   "#"
3645   [(set_attr "type" "alu1")
3646    (set_attr "mode" "HI")])
3647
3648 (define_insn "*zero_extendqihi2_movzbw_and"
3649   [(set (match_operand:HI 0 "register_operand" "=r,r")
3650      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3651    (clobber (reg:CC FLAGS_REG))]
3652   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3653   "#"
3654   [(set_attr "type" "imovx,alu1")
3655    (set_attr "mode" "HI")])
3656
3657 ; zero extend to SImode here to avoid partial register stalls
3658 (define_insn "*zero_extendqihi2_movzbl"
3659   [(set (match_operand:HI 0 "register_operand" "=r")
3660      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3661   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3662    && reload_completed"
3663   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3664   [(set_attr "type" "imovx")
3665    (set_attr "mode" "SI")])
3666
3667 ;; For the movzbw case strip only the clobber
3668 (define_split
3669   [(set (match_operand:HI 0 "register_operand" "")
3670         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3671    (clobber (reg:CC FLAGS_REG))]
3672   "reload_completed
3673    && (!TARGET_ZERO_EXTEND_WITH_AND
3674        || optimize_function_for_size_p (cfun))
3675    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3676   [(set (match_operand:HI 0 "register_operand" "")
3677         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3678
3679 ;; When source and destination does not overlap, clear destination
3680 ;; first and then do the movb
3681 (define_split
3682   [(set (match_operand:HI 0 "register_operand" "")
3683         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3684    (clobber (reg:CC FLAGS_REG))]
3685   "reload_completed
3686    && ANY_QI_REG_P (operands[0])
3687    && (TARGET_ZERO_EXTEND_WITH_AND
3688        && optimize_function_for_speed_p (cfun))
3689    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3690   [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3691 {
3692   operands[2] = gen_lowpart (QImode, operands[0]);
3693   ix86_expand_clear (operands[0]);
3694 })
3695
3696 ;; Rest is handled by single and.
3697 (define_split
3698   [(set (match_operand:HI 0 "register_operand" "")
3699         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3700    (clobber (reg:CC FLAGS_REG))]
3701   "reload_completed
3702    && true_regnum (operands[0]) == true_regnum (operands[1])"
3703   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3704               (clobber (reg:CC FLAGS_REG))])]
3705   "")
3706
3707 (define_expand "zero_extendqisi2"
3708   [(parallel
3709     [(set (match_operand:SI 0 "register_operand" "")
3710        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3711      (clobber (reg:CC FLAGS_REG))])]
3712   ""
3713   "")
3714
3715 (define_insn "*zero_extendqisi2_and"
3716   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3717      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3718    (clobber (reg:CC FLAGS_REG))]
3719   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3720   "#"
3721   [(set_attr "type" "alu1")
3722    (set_attr "mode" "SI")])
3723
3724 (define_insn "*zero_extendqisi2_movzbl_and"
3725   [(set (match_operand:SI 0 "register_operand" "=r,r")
3726      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3727    (clobber (reg:CC FLAGS_REG))]
3728   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3729   "#"
3730   [(set_attr "type" "imovx,alu1")
3731    (set_attr "mode" "SI")])
3732
3733 (define_insn "*zero_extendqisi2_movzbl"
3734   [(set (match_operand:SI 0 "register_operand" "=r")
3735      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3736   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3737    && reload_completed"
3738   "movz{bl|x}\t{%1, %0|%0, %1}"
3739   [(set_attr "type" "imovx")
3740    (set_attr "mode" "SI")])
3741
3742 ;; For the movzbl case strip only the clobber
3743 (define_split
3744   [(set (match_operand:SI 0 "register_operand" "")
3745         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3746    (clobber (reg:CC FLAGS_REG))]
3747   "reload_completed
3748    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3749    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3750   [(set (match_dup 0)
3751         (zero_extend:SI (match_dup 1)))])
3752
3753 ;; When source and destination does not overlap, clear destination
3754 ;; first and then do the movb
3755 (define_split
3756   [(set (match_operand:SI 0 "register_operand" "")
3757         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3758    (clobber (reg:CC FLAGS_REG))]
3759   "reload_completed
3760    && ANY_QI_REG_P (operands[0])
3761    && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3762    && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3763    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3764   [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3765 {
3766   operands[2] = gen_lowpart (QImode, operands[0]);
3767   ix86_expand_clear (operands[0]);
3768 })
3769
3770 ;; Rest is handled by single and.
3771 (define_split
3772   [(set (match_operand:SI 0 "register_operand" "")
3773         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3774    (clobber (reg:CC FLAGS_REG))]
3775   "reload_completed
3776    && true_regnum (operands[0]) == true_regnum (operands[1])"
3777   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3778               (clobber (reg:CC FLAGS_REG))])]
3779   "")
3780
3781 ;; %%% Kill me once multi-word ops are sane.
3782 (define_expand "zero_extendsidi2"
3783   [(set (match_operand:DI 0 "register_operand" "")
3784      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3785   ""
3786 {
3787   if (!TARGET_64BIT)
3788     {
3789       emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3790       DONE;
3791     }
3792 })
3793
3794 (define_insn "zero_extendsidi2_32"
3795   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3796         (zero_extend:DI
3797          (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r   ,m  ,r   ,m")))
3798    (clobber (reg:CC FLAGS_REG))]
3799   "!TARGET_64BIT"
3800   "@
3801    #
3802    #
3803    #
3804    movd\t{%1, %0|%0, %1}
3805    movd\t{%1, %0|%0, %1}
3806    %vmovd\t{%1, %0|%0, %1}
3807    %vmovd\t{%1, %0|%0, %1}"
3808   [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3809    (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3810    (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3811
3812 (define_insn "zero_extendsidi2_rex64"
3813   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
3814      (zero_extend:DI
3815        (match_operand:SI 1 "nonimmediate_operand"  "rm,0,r   ,m  ,r   ,m")))]
3816   "TARGET_64BIT"
3817   "@
3818    mov\t{%k1, %k0|%k0, %k1}
3819    #
3820    movd\t{%1, %0|%0, %1}
3821    movd\t{%1, %0|%0, %1}
3822    %vmovd\t{%1, %0|%0, %1}
3823    %vmovd\t{%1, %0|%0, %1}"
3824   [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3825    (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3826    (set_attr "prefix_0f" "0,*,*,*,*,*")
3827    (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3828
3829 (define_split
3830   [(set (match_operand:DI 0 "memory_operand" "")
3831      (zero_extend:DI (match_dup 0)))]
3832   "TARGET_64BIT"
3833   [(set (match_dup 4) (const_int 0))]
3834   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3835
3836 (define_split
3837   [(set (match_operand:DI 0 "register_operand" "")
3838         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3839    (clobber (reg:CC FLAGS_REG))]
3840   "!TARGET_64BIT && reload_completed
3841    && true_regnum (operands[0]) == true_regnum (operands[1])"
3842   [(set (match_dup 4) (const_int 0))]
3843   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3844
3845 (define_split
3846   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3847         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3848    (clobber (reg:CC FLAGS_REG))]
3849   "!TARGET_64BIT && reload_completed
3850    && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3851   [(set (match_dup 3) (match_dup 1))
3852    (set (match_dup 4) (const_int 0))]
3853   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3854
3855 (define_insn "zero_extendhidi2"
3856   [(set (match_operand:DI 0 "register_operand" "=r")
3857      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3858   "TARGET_64BIT"
3859   "movz{wl|x}\t{%1, %k0|%k0, %1}"
3860   [(set_attr "type" "imovx")
3861    (set_attr "mode" "SI")])
3862
3863 (define_insn "zero_extendqidi2"
3864   [(set (match_operand:DI 0 "register_operand" "=r")
3865      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3866   "TARGET_64BIT"
3867   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3868   [(set_attr "type" "imovx")
3869    (set_attr "mode" "SI")])
3870 \f
3871 ;; Sign extension instructions
3872
3873 (define_expand "extendsidi2"
3874   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3875                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3876               (clobber (reg:CC FLAGS_REG))
3877               (clobber (match_scratch:SI 2 ""))])]
3878   ""
3879 {
3880   if (TARGET_64BIT)
3881     {
3882       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3883       DONE;
3884     }
3885 })
3886
3887 (define_insn "*extendsidi2_1"
3888   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3889         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3890    (clobber (reg:CC FLAGS_REG))
3891    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3892   "!TARGET_64BIT"
3893   "#")
3894
3895 (define_insn "extendsidi2_rex64"
3896   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3897         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3898   "TARGET_64BIT"
3899   "@
3900    {cltq|cdqe}
3901    movs{lq|x}\t{%1, %0|%0, %1}"
3902   [(set_attr "type" "imovx")
3903    (set_attr "mode" "DI")
3904    (set_attr "prefix_0f" "0")
3905    (set_attr "modrm" "0,1")])
3906
3907 (define_insn "extendhidi2"
3908   [(set (match_operand:DI 0 "register_operand" "=r")
3909         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3910   "TARGET_64BIT"
3911   "movs{wq|x}\t{%1, %0|%0, %1}"
3912   [(set_attr "type" "imovx")
3913    (set_attr "mode" "DI")])
3914
3915 (define_insn "extendqidi2"
3916   [(set (match_operand:DI 0 "register_operand" "=r")
3917         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3918   "TARGET_64BIT"
3919   "movs{bq|x}\t{%1, %0|%0, %1}"
3920    [(set_attr "type" "imovx")
3921     (set_attr "mode" "DI")])
3922
3923 ;; Extend to memory case when source register does die.
3924 (define_split
3925   [(set (match_operand:DI 0 "memory_operand" "")
3926         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3927    (clobber (reg:CC FLAGS_REG))
3928    (clobber (match_operand:SI 2 "register_operand" ""))]
3929   "(reload_completed
3930     && dead_or_set_p (insn, operands[1])
3931     && !reg_mentioned_p (operands[1], operands[0]))"
3932   [(set (match_dup 3) (match_dup 1))
3933    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3934               (clobber (reg:CC FLAGS_REG))])
3935    (set (match_dup 4) (match_dup 1))]
3936   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3937
3938 ;; Extend to memory case when source register does not die.
3939 (define_split
3940   [(set (match_operand:DI 0 "memory_operand" "")
3941         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3942    (clobber (reg:CC FLAGS_REG))
3943    (clobber (match_operand:SI 2 "register_operand" ""))]
3944   "reload_completed"
3945   [(const_int 0)]
3946 {
3947   split_di (&operands[0], 1, &operands[3], &operands[4]);
3948
3949   emit_move_insn (operands[3], operands[1]);
3950
3951   /* Generate a cltd if possible and doing so it profitable.  */
3952   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3953       && true_regnum (operands[1]) == AX_REG
3954       && true_regnum (operands[2]) == DX_REG)
3955     {
3956       emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3957     }
3958   else
3959     {
3960       emit_move_insn (operands[2], operands[1]);
3961       emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3962     }
3963   emit_move_insn (operands[4], operands[2]);
3964   DONE;
3965 })
3966
3967 ;; Extend to register case.  Optimize case where source and destination
3968 ;; registers match and cases where we can use cltd.
3969 (define_split
3970   [(set (match_operand:DI 0 "register_operand" "")
3971         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3972    (clobber (reg:CC FLAGS_REG))
3973    (clobber (match_scratch:SI 2 ""))]
3974   "reload_completed"
3975   [(const_int 0)]
3976 {
3977   split_di (&operands[0], 1, &operands[3], &operands[4]);
3978
3979   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3980     emit_move_insn (operands[3], operands[1]);
3981
3982   /* Generate a cltd if possible and doing so it profitable.  */
3983   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3984       && true_regnum (operands[3]) == AX_REG
3985       && true_regnum (operands[4]) == DX_REG)
3986     {
3987       emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3988       DONE;
3989     }
3990
3991   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3992     emit_move_insn (operands[4], operands[1]);
3993
3994   emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3995   DONE;
3996 })
3997
3998 (define_insn "extendhisi2"
3999   [(set (match_operand:SI 0 "register_operand" "=*a,r")
4000         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4001   ""
4002 {
4003   switch (get_attr_prefix_0f (insn))
4004     {
4005     case 0:
4006       return "{cwtl|cwde}";
4007     default:
4008       return "movs{wl|x}\t{%1, %0|%0, %1}";
4009     }
4010 }
4011   [(set_attr "type" "imovx")
4012    (set_attr "mode" "SI")
4013    (set (attr "prefix_0f")
4014      ;; movsx is short decodable while cwtl is vector decoded.
4015      (if_then_else (and (eq_attr "cpu" "!k6")
4016                         (eq_attr "alternative" "0"))
4017         (const_string "0")
4018         (const_string "1")))
4019    (set (attr "modrm")
4020      (if_then_else (eq_attr "prefix_0f" "0")
4021         (const_string "0")
4022         (const_string "1")))])
4023
4024 (define_insn "*extendhisi2_zext"
4025   [(set (match_operand:DI 0 "register_operand" "=*a,r")
4026         (zero_extend:DI
4027           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4028   "TARGET_64BIT"
4029 {
4030   switch (get_attr_prefix_0f (insn))
4031     {
4032     case 0:
4033       return "{cwtl|cwde}";
4034     default:
4035       return "movs{wl|x}\t{%1, %k0|%k0, %1}";
4036     }
4037 }
4038   [(set_attr "type" "imovx")
4039    (set_attr "mode" "SI")
4040    (set (attr "prefix_0f")
4041      ;; movsx is short decodable while cwtl is vector decoded.
4042      (if_then_else (and (eq_attr "cpu" "!k6")
4043                         (eq_attr "alternative" "0"))
4044         (const_string "0")
4045         (const_string "1")))
4046    (set (attr "modrm")
4047      (if_then_else (eq_attr "prefix_0f" "0")
4048         (const_string "0")
4049         (const_string "1")))])
4050
4051 (define_insn "extendqihi2"
4052   [(set (match_operand:HI 0 "register_operand" "=*a,r")
4053         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4054   ""
4055 {
4056   switch (get_attr_prefix_0f (insn))
4057     {
4058     case 0:
4059       return "{cbtw|cbw}";
4060     default:
4061       return "movs{bw|x}\t{%1, %0|%0, %1}";
4062     }
4063 }
4064   [(set_attr "type" "imovx")
4065    (set_attr "mode" "HI")
4066    (set (attr "prefix_0f")
4067      ;; movsx is short decodable while cwtl is vector decoded.
4068      (if_then_else (and (eq_attr "cpu" "!k6")
4069                         (eq_attr "alternative" "0"))
4070         (const_string "0")
4071         (const_string "1")))
4072    (set (attr "modrm")
4073      (if_then_else (eq_attr "prefix_0f" "0")
4074         (const_string "0")
4075         (const_string "1")))])
4076
4077 (define_insn "extendqisi2"
4078   [(set (match_operand:SI 0 "register_operand" "=r")
4079         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4080   ""
4081   "movs{bl|x}\t{%1, %0|%0, %1}"
4082    [(set_attr "type" "imovx")
4083     (set_attr "mode" "SI")])
4084
4085 (define_insn "*extendqisi2_zext"
4086   [(set (match_operand:DI 0 "register_operand" "=r")
4087         (zero_extend:DI
4088           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4089   "TARGET_64BIT"
4090   "movs{bl|x}\t{%1, %k0|%k0, %1}"
4091    [(set_attr "type" "imovx")
4092     (set_attr "mode" "SI")])
4093 \f
4094 ;; Conversions between float and double.
4095
4096 ;; These are all no-ops in the model used for the 80387.  So just
4097 ;; emit moves.
4098
4099 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4100 (define_insn "*dummy_extendsfdf2"
4101   [(set (match_operand:DF 0 "push_operand" "=<")
4102         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY2")))]
4103   "0"
4104   "#")
4105
4106 (define_split
4107   [(set (match_operand:DF 0 "push_operand" "")
4108         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
4109   ""
4110   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4111    (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4112
4113 (define_insn "*dummy_extendsfxf2"
4114   [(set (match_operand:XF 0 "push_operand" "=<")
4115         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
4116   "0"
4117   "#")
4118
4119 (define_split
4120   [(set (match_operand:XF 0 "push_operand" "")
4121         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
4122   ""
4123   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4124    (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4125   "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
4126
4127 (define_split
4128   [(set (match_operand:XF 0 "push_operand" "")
4129         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
4130   ""
4131   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4132    (set (mem:DF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4133   "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
4134
4135 (define_expand "extendsfdf2"
4136   [(set (match_operand:DF 0 "nonimmediate_operand" "")
4137         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
4138   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4139 {
4140   /* ??? Needed for compress_float_constant since all fp constants
4141      are LEGITIMATE_CONSTANT_P.  */
4142   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4143     {
4144       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4145           && standard_80387_constant_p (operands[1]) > 0)
4146         {
4147           operands[1] = simplify_const_unary_operation
4148             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4149           emit_move_insn_1 (operands[0], operands[1]);
4150           DONE;
4151         }
4152       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4153     }
4154 })
4155
4156 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4157    cvtss2sd:
4158       unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4159       cvtps2pd xmm2,xmm1
4160    We do the conversion post reload to avoid producing of 128bit spills
4161    that might lead to ICE on 32bit target.  The sequence unlikely combine
4162    anyway.  */
4163 (define_split
4164   [(set (match_operand:DF 0 "register_operand" "")
4165         (float_extend:DF
4166           (match_operand:SF 1 "nonimmediate_operand" "")))]
4167   "TARGET_USE_VECTOR_FP_CONVERTS
4168    && optimize_insn_for_speed_p ()
4169    && reload_completed && SSE_REG_P (operands[0])"
4170    [(set (match_dup 2)
4171          (float_extend:V2DF
4172            (vec_select:V2SF
4173              (match_dup 3)
4174              (parallel [(const_int 0) (const_int 1)]))))]
4175 {
4176   operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4177   operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4178   /* Use movss for loading from memory, unpcklps reg, reg for registers.
4179      Try to avoid move when unpacking can be done in source.  */
4180   if (REG_P (operands[1]))
4181     {
4182       /* If it is unsafe to overwrite upper half of source, we need
4183          to move to destination and unpack there.  */
4184       if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4185            || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4186           && true_regnum (operands[0]) != true_regnum (operands[1]))
4187         {
4188           rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4189           emit_move_insn (tmp, operands[1]);
4190         }
4191       else
4192         operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4193       emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4194                                              operands[3]));
4195     }
4196   else
4197     emit_insn (gen_vec_setv4sf_0 (operands[3],
4198                                   CONST0_RTX (V4SFmode), operands[1]));
4199 })
4200
4201 (define_insn "*extendsfdf2_mixed"
4202   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4203         (float_extend:DF
4204           (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4205   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4206 {
4207   switch (which_alternative)
4208     {
4209     case 0:
4210     case 1:
4211       return output_387_reg_move (insn, operands);
4212
4213     case 2:
4214       return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4215
4216     default:
4217       gcc_unreachable ();
4218     }
4219 }
4220   [(set_attr "type" "fmov,fmov,ssecvt")
4221    (set_attr "prefix" "orig,orig,maybe_vex")
4222    (set_attr "mode" "SF,XF,DF")])
4223
4224 (define_insn "*extendsfdf2_sse"
4225   [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4226         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4227   "TARGET_SSE2 && TARGET_SSE_MATH"
4228   "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4229   [(set_attr "type" "ssecvt")
4230    (set_attr "prefix" "maybe_vex")
4231    (set_attr "mode" "DF")])
4232
4233 (define_insn "*extendsfdf2_i387"
4234   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4235         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4236   "TARGET_80387"
4237   "* return output_387_reg_move (insn, operands);"
4238   [(set_attr "type" "fmov")
4239    (set_attr "mode" "SF,XF")])
4240
4241 (define_expand "extend<mode>xf2"
4242   [(set (match_operand:XF 0 "nonimmediate_operand" "")
4243         (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4244   "TARGET_80387"
4245 {
4246   /* ??? Needed for compress_float_constant since all fp constants
4247      are LEGITIMATE_CONSTANT_P.  */
4248   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4249     {
4250       if (standard_80387_constant_p (operands[1]) > 0)
4251         {
4252           operands[1] = simplify_const_unary_operation
4253             (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4254           emit_move_insn_1 (operands[0], operands[1]);
4255           DONE;
4256         }
4257       operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4258     }
4259 })
4260
4261 (define_insn "*extend<mode>xf2_i387"
4262   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4263         (float_extend:XF
4264           (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4265   "TARGET_80387"
4266   "* return output_387_reg_move (insn, operands);"
4267   [(set_attr "type" "fmov")
4268    (set_attr "mode" "<MODE>,XF")])
4269
4270 ;; %%% This seems bad bad news.
4271 ;; This cannot output into an f-reg because there is no way to be sure
4272 ;; of truncating in that case.  Otherwise this is just like a simple move
4273 ;; insn.  So we pretend we can output to a reg in order to get better
4274 ;; register preferencing, but we really use a stack slot.
4275
4276 ;; Conversion from DFmode to SFmode.
4277
4278 (define_expand "truncdfsf2"
4279   [(set (match_operand:SF 0 "nonimmediate_operand" "")
4280         (float_truncate:SF
4281           (match_operand:DF 1 "nonimmediate_operand" "")))]
4282   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4283 {
4284   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4285     ;
4286   else if (flag_unsafe_math_optimizations)
4287     ;
4288   else
4289     {
4290       enum ix86_stack_slot slot = (virtuals_instantiated
4291                                    ? SLOT_TEMP
4292                                    : SLOT_VIRTUAL);
4293       rtx temp = assign_386_stack_local (SFmode, slot);
4294       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4295       DONE;
4296     }
4297 })
4298
4299 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4300    cvtsd2ss:
4301       unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4302       cvtpd2ps xmm2,xmm1
4303    We do the conversion post reload to avoid producing of 128bit spills
4304    that might lead to ICE on 32bit target.  The sequence unlikely combine
4305    anyway.  */
4306 (define_split
4307   [(set (match_operand:SF 0 "register_operand" "")
4308         (float_truncate:SF
4309           (match_operand:DF 1 "nonimmediate_operand" "")))]
4310   "TARGET_USE_VECTOR_FP_CONVERTS
4311    && optimize_insn_for_speed_p ()
4312    && reload_completed && SSE_REG_P (operands[0])"
4313    [(set (match_dup 2)
4314          (vec_concat:V4SF
4315            (float_truncate:V2SF
4316              (match_dup 4))
4317            (match_dup 3)))]
4318 {
4319   operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4320   operands[3] = CONST0_RTX (V2SFmode);
4321   operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4322   /* Use movsd for loading from memory, unpcklpd for registers.
4323      Try to avoid move when unpacking can be done in source, or SSE3
4324      movddup is available.  */
4325   if (REG_P (operands[1]))
4326     {
4327       if (!TARGET_SSE3
4328           && true_regnum (operands[0]) != true_regnum (operands[1])
4329           && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4330               || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4331         {
4332           rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4333           emit_move_insn (tmp, operands[1]);
4334           operands[1] = tmp;
4335         }
4336       else if (!TARGET_SSE3)
4337         operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4338       emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4339     }
4340   else
4341     emit_insn (gen_sse2_loadlpd (operands[4],
4342                                  CONST0_RTX (V2DFmode), operands[1]));
4343 })
4344
4345 (define_expand "truncdfsf2_with_temp"
4346   [(parallel [(set (match_operand:SF 0 "" "")
4347                    (float_truncate:SF (match_operand:DF 1 "" "")))
4348               (clobber (match_operand:SF 2 "" ""))])]
4349   "")
4350
4351 (define_insn "*truncdfsf_fast_mixed"
4352   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm,x")
4353         (float_truncate:SF
4354           (match_operand:DF 1 "nonimmediate_operand" "f  ,xm")))]
4355   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4356 {
4357   switch (which_alternative)
4358     {
4359     case 0:
4360       return output_387_reg_move (insn, operands);
4361     case 1:
4362       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4363     default:
4364       gcc_unreachable ();
4365     }
4366 }
4367   [(set_attr "type" "fmov,ssecvt")
4368    (set_attr "prefix" "orig,maybe_vex")
4369    (set_attr "mode" "SF")])
4370
4371 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4372 ;; because nothing we do here is unsafe.
4373 (define_insn "*truncdfsf_fast_sse"
4374   [(set (match_operand:SF 0 "nonimmediate_operand"   "=x")
4375         (float_truncate:SF
4376           (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4377   "TARGET_SSE2 && TARGET_SSE_MATH"
4378   "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4379   [(set_attr "type" "ssecvt")
4380    (set_attr "prefix" "maybe_vex")
4381    (set_attr "mode" "SF")])
4382
4383 (define_insn "*truncdfsf_fast_i387"
4384   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
4385         (float_truncate:SF
4386           (match_operand:DF 1 "nonimmediate_operand" "f")))]
4387   "TARGET_80387 && flag_unsafe_math_optimizations"
4388   "* return output_387_reg_move (insn, operands);"
4389   [(set_attr "type" "fmov")
4390    (set_attr "mode" "SF")])
4391
4392 (define_insn "*truncdfsf_mixed"
4393   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,Y2 ,?f,?x,?*r")
4394         (float_truncate:SF
4395           (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4396    (clobber (match_operand:SF 2 "memory_operand"     "=X,X  ,m ,m ,m"))]
4397   "TARGET_MIX_SSE_I387"
4398 {
4399   switch (which_alternative)
4400     {
4401     case 0:
4402       return output_387_reg_move (insn, operands);
4403     case 1:
4404       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4405
4406     default:
4407       return "#";
4408     }
4409 }
4410   [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4411    (set_attr "unit" "*,*,i387,i387,i387")
4412    (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4413    (set_attr "mode" "SF")])
4414
4415 (define_insn "*truncdfsf_i387"
4416   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?f,?x,?*r")
4417         (float_truncate:SF
4418           (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4419    (clobber (match_operand:SF 2 "memory_operand"     "=X,m ,m ,m"))]
4420   "TARGET_80387"
4421 {
4422   switch (which_alternative)
4423     {
4424     case 0:
4425       return output_387_reg_move (insn, operands);
4426
4427     default:
4428       return "#";
4429     }
4430 }
4431   [(set_attr "type" "fmov,multi,multi,multi")
4432    (set_attr "unit" "*,i387,i387,i387")
4433    (set_attr "mode" "SF")])
4434
4435 (define_insn "*truncdfsf2_i387_1"
4436   [(set (match_operand:SF 0 "memory_operand" "=m")
4437         (float_truncate:SF
4438           (match_operand:DF 1 "register_operand" "f")))]
4439   "TARGET_80387
4440    && !(TARGET_SSE2 && TARGET_SSE_MATH)
4441    && !TARGET_MIX_SSE_I387"
4442   "* return output_387_reg_move (insn, operands);"
4443   [(set_attr "type" "fmov")
4444    (set_attr "mode" "SF")])
4445
4446 (define_split
4447   [(set (match_operand:SF 0 "register_operand" "")
4448         (float_truncate:SF
4449          (match_operand:DF 1 "fp_register_operand" "")))
4450    (clobber (match_operand 2 "" ""))]
4451   "reload_completed"
4452   [(set (match_dup 2) (match_dup 1))
4453    (set (match_dup 0) (match_dup 2))]
4454 {
4455   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4456 })
4457
4458 ;; Conversion from XFmode to {SF,DF}mode
4459
4460 (define_expand "truncxf<mode>2"
4461   [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4462                    (float_truncate:MODEF
4463                      (match_operand:XF 1 "register_operand" "")))
4464               (clobber (match_dup 2))])]
4465   "TARGET_80387"
4466 {
4467   if (flag_unsafe_math_optimizations)
4468     {
4469       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4470       emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4471       if (reg != operands[0])
4472         emit_move_insn (operands[0], reg);
4473       DONE;
4474     }
4475   else
4476     {
4477      enum ix86_stack_slot slot = (virtuals_instantiated
4478                                   ? SLOT_TEMP
4479                                   : SLOT_VIRTUAL);
4480       operands[2] = assign_386_stack_local (<MODE>mode, slot);
4481     }
4482 })
4483
4484 (define_insn "*truncxfsf2_mixed"
4485   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4486         (float_truncate:SF
4487           (match_operand:XF 1 "register_operand"   "f ,f ,f ,f")))
4488    (clobber (match_operand:SF 2 "memory_operand"   "=X,m ,m ,m"))]
4489   "TARGET_80387"
4490 {
4491   gcc_assert (!which_alternative);
4492   return output_387_reg_move (insn, operands);
4493 }
4494   [(set_attr "type" "fmov,multi,multi,multi")
4495    (set_attr "unit" "*,i387,i387,i387")
4496    (set_attr "mode" "SF")])
4497
4498 (define_insn "*truncxfdf2_mixed"
4499   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4500         (float_truncate:DF
4501           (match_operand:XF 1 "register_operand"   "f ,f ,f  ,f")))
4502    (clobber (match_operand:DF 2 "memory_operand"   "=X,m ,m  ,m"))]
4503   "TARGET_80387"
4504 {
4505   gcc_assert (!which_alternative);
4506   return output_387_reg_move (insn, operands);
4507 }
4508   [(set_attr "type" "fmov,multi,multi,multi")
4509    (set_attr "unit" "*,i387,i387,i387")
4510    (set_attr "mode" "DF")])
4511
4512 (define_insn "truncxf<mode>2_i387_noop"
4513   [(set (match_operand:MODEF 0 "register_operand" "=f")
4514         (float_truncate:MODEF
4515           (match_operand:XF 1 "register_operand" "f")))]
4516   "TARGET_80387 && flag_unsafe_math_optimizations"
4517   "* return output_387_reg_move (insn, operands);"
4518   [(set_attr "type" "fmov")
4519    (set_attr "mode" "<MODE>")])
4520
4521 (define_insn "*truncxf<mode>2_i387"
4522   [(set (match_operand:MODEF 0 "memory_operand" "=m")
4523         (float_truncate:MODEF
4524           (match_operand:XF 1 "register_operand" "f")))]
4525   "TARGET_80387"
4526   "* return output_387_reg_move (insn, operands);"
4527   [(set_attr "type" "fmov")
4528    (set_attr "mode" "<MODE>")])
4529
4530 (define_split
4531   [(set (match_operand:MODEF 0 "register_operand" "")
4532         (float_truncate:MODEF
4533           (match_operand:XF 1 "register_operand" "")))
4534    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4535   "TARGET_80387 && reload_completed"
4536   [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4537    (set (match_dup 0) (match_dup 2))]
4538   "")
4539
4540 (define_split
4541   [(set (match_operand:MODEF 0 "memory_operand" "")
4542         (float_truncate:MODEF
4543           (match_operand:XF 1 "register_operand" "")))
4544    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4545   "TARGET_80387"
4546   [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]
4547   "")
4548 \f
4549 ;; Signed conversion to DImode.
4550
4551 (define_expand "fix_truncxfdi2"
4552   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4553                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4554               (clobber (reg:CC FLAGS_REG))])]
4555   "TARGET_80387"
4556 {
4557   if (TARGET_FISTTP)
4558    {
4559      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4560      DONE;
4561    }
4562 })
4563
4564 (define_expand "fix_trunc<mode>di2"
4565   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4566                    (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4567               (clobber (reg:CC FLAGS_REG))])]
4568   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4569 {
4570   if (TARGET_FISTTP
4571       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4572    {
4573      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4574      DONE;
4575    }
4576   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4577    {
4578      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4579      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4580      if (out != operands[0])
4581         emit_move_insn (operands[0], out);
4582      DONE;
4583    }
4584 })
4585
4586 ;; Signed conversion to SImode.
4587
4588 (define_expand "fix_truncxfsi2"
4589   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4590                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4591               (clobber (reg:CC FLAGS_REG))])]
4592   "TARGET_80387"
4593 {
4594   if (TARGET_FISTTP)
4595    {
4596      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4597      DONE;
4598    }
4599 })
4600
4601 (define_expand "fix_trunc<mode>si2"
4602   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4603                    (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4604               (clobber (reg:CC FLAGS_REG))])]
4605   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4606 {
4607   if (TARGET_FISTTP
4608       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4609    {
4610      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4611      DONE;
4612    }
4613   if (SSE_FLOAT_MODE_P (<MODE>mode))
4614    {
4615      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4616      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4617      if (out != operands[0])
4618         emit_move_insn (operands[0], out);
4619      DONE;
4620    }
4621 })
4622
4623 ;; Signed conversion to HImode.
4624
4625 (define_expand "fix_trunc<mode>hi2"
4626   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4627                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4628               (clobber (reg:CC FLAGS_REG))])]
4629   "TARGET_80387
4630    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4631 {
4632   if (TARGET_FISTTP)
4633    {
4634      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4635      DONE;
4636    }
4637 })
4638
4639 ;; Unsigned conversion to SImode.
4640
4641 (define_expand "fixuns_trunc<mode>si2"
4642   [(parallel
4643     [(set (match_operand:SI 0 "register_operand" "")
4644           (unsigned_fix:SI
4645             (match_operand:MODEF 1 "nonimmediate_operand" "")))
4646      (use (match_dup 2))
4647      (clobber (match_scratch:<ssevecmode> 3 ""))
4648      (clobber (match_scratch:<ssevecmode> 4 ""))])]
4649   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4650 {
4651   enum machine_mode mode = <MODE>mode;
4652   enum machine_mode vecmode = <ssevecmode>mode;
4653   REAL_VALUE_TYPE TWO31r;
4654   rtx two31;
4655
4656   if (optimize_insn_for_size_p ())
4657     FAIL;
4658
4659   real_ldexp (&TWO31r, &dconst1, 31);
4660   two31 = const_double_from_real_value (TWO31r, mode);
4661   two31 = ix86_build_const_vector (mode, true, two31);
4662   operands[2] = force_reg (vecmode, two31);
4663 })
4664
4665 (define_insn_and_split "*fixuns_trunc<mode>_1"
4666   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4667         (unsigned_fix:SI
4668           (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4669    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
4670    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4671    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4672   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4673    && optimize_function_for_speed_p (cfun)"
4674   "#"
4675   "&& reload_completed"
4676   [(const_int 0)]
4677 {
4678   ix86_split_convert_uns_si_sse (operands);
4679   DONE;
4680 })
4681
4682 ;; Unsigned conversion to HImode.
4683 ;; Without these patterns, we'll try the unsigned SI conversion which
4684 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4685
4686 (define_expand "fixuns_trunc<mode>hi2"
4687   [(set (match_dup 2)
4688         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4689    (set (match_operand:HI 0 "nonimmediate_operand" "")
4690         (subreg:HI (match_dup 2) 0))]
4691   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4692   "operands[2] = gen_reg_rtx (SImode);")
4693
4694 ;; When SSE is available, it is always faster to use it!
4695 (define_insn "fix_trunc<mode>di_sse"
4696   [(set (match_operand:DI 0 "register_operand" "=r,r")
4697         (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4698   "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4699    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4700   "%vcvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4701   [(set_attr "type" "sseicvt")
4702    (set_attr "prefix" "maybe_vex")
4703    (set_attr "prefix_rex" "1")
4704    (set_attr "mode" "<MODE>")
4705    (set_attr "athlon_decode" "double,vector")
4706    (set_attr "amdfam10_decode" "double,double")])
4707
4708 (define_insn "fix_trunc<mode>si_sse"
4709   [(set (match_operand:SI 0 "register_operand" "=r,r")
4710         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4711   "SSE_FLOAT_MODE_P (<MODE>mode)
4712    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4713   "%vcvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4714   [(set_attr "type" "sseicvt")
4715    (set_attr "prefix" "maybe_vex")
4716    (set_attr "mode" "<MODE>")
4717    (set_attr "athlon_decode" "double,vector")
4718    (set_attr "amdfam10_decode" "double,double")])
4719
4720 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4721 (define_peephole2
4722   [(set (match_operand:MODEF 0 "register_operand" "")
4723         (match_operand:MODEF 1 "memory_operand" ""))
4724    (set (match_operand:SSEMODEI24 2 "register_operand" "")
4725         (fix:SSEMODEI24 (match_dup 0)))]
4726   "TARGET_SHORTEN_X87_SSE
4727    && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4728    && peep2_reg_dead_p (2, operands[0])"
4729   [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4730   "")
4731
4732 ;; Avoid vector decoded forms of the instruction.
4733 (define_peephole2
4734   [(match_scratch:DF 2 "Y2")
4735    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4736         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4737   "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4738   [(set (match_dup 2) (match_dup 1))
4739    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4740   "")
4741
4742 (define_peephole2
4743   [(match_scratch:SF 2 "x")
4744    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4745         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4746   "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4747   [(set (match_dup 2) (match_dup 1))
4748    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4749   "")
4750
4751 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4752   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4753         (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4754   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4755    && TARGET_FISTTP
4756    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4757          && (TARGET_64BIT || <MODE>mode != DImode))
4758         && TARGET_SSE_MATH)
4759    && can_create_pseudo_p ()"
4760   "#"
4761   "&& 1"
4762   [(const_int 0)]
4763 {
4764   if (memory_operand (operands[0], VOIDmode))
4765     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4766   else
4767     {
4768       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4769       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4770                                                             operands[1],
4771                                                             operands[2]));
4772     }
4773   DONE;
4774 }
4775   [(set_attr "type" "fisttp")
4776    (set_attr "mode" "<MODE>")])
4777
4778 (define_insn "fix_trunc<mode>_i387_fisttp"
4779   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4780         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4781    (clobber (match_scratch:XF 2 "=&1f"))]
4782   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4783    && TARGET_FISTTP
4784    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4785          && (TARGET_64BIT || <MODE>mode != DImode))
4786         && TARGET_SSE_MATH)"
4787   "* return output_fix_trunc (insn, operands, 1);"
4788   [(set_attr "type" "fisttp")
4789    (set_attr "mode" "<MODE>")])
4790
4791 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4792   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4793         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4794    (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
4795    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4796   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4797    && TARGET_FISTTP
4798    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4799         && (TARGET_64BIT || <MODE>mode != DImode))
4800         && TARGET_SSE_MATH)"
4801   "#"
4802   [(set_attr "type" "fisttp")
4803    (set_attr "mode" "<MODE>")])
4804
4805 (define_split
4806   [(set (match_operand:X87MODEI 0 "register_operand" "")
4807         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4808    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4809    (clobber (match_scratch 3 ""))]
4810   "reload_completed"
4811   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4812               (clobber (match_dup 3))])
4813    (set (match_dup 0) (match_dup 2))]
4814   "")
4815
4816 (define_split
4817   [(set (match_operand:X87MODEI 0 "memory_operand" "")
4818         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4819    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4820    (clobber (match_scratch 3 ""))]
4821   "reload_completed"
4822   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4823               (clobber (match_dup 3))])]
4824   "")
4825
4826 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4827 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4828 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4829 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4830 ;; function in i386.c.
4831 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4832   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4833         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4834    (clobber (reg:CC FLAGS_REG))]
4835   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4836    && !TARGET_FISTTP
4837    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4838          && (TARGET_64BIT || <MODE>mode != DImode))
4839    && can_create_pseudo_p ()"
4840   "#"
4841   "&& 1"
4842   [(const_int 0)]
4843 {
4844   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4845
4846   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4847   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4848   if (memory_operand (operands[0], VOIDmode))
4849     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4850                                          operands[2], operands[3]));
4851   else
4852     {
4853       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4854       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4855                                                      operands[2], operands[3],
4856                                                      operands[4]));
4857     }
4858   DONE;
4859 }
4860   [(set_attr "type" "fistp")
4861    (set_attr "i387_cw" "trunc")
4862    (set_attr "mode" "<MODE>")])
4863
4864 (define_insn "fix_truncdi_i387"
4865   [(set (match_operand:DI 0 "memory_operand" "=m")
4866         (fix:DI (match_operand 1 "register_operand" "f")))
4867    (use (match_operand:HI 2 "memory_operand" "m"))
4868    (use (match_operand:HI 3 "memory_operand" "m"))
4869    (clobber (match_scratch:XF 4 "=&1f"))]
4870   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4871    && !TARGET_FISTTP
4872    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4873   "* return output_fix_trunc (insn, operands, 0);"
4874   [(set_attr "type" "fistp")
4875    (set_attr "i387_cw" "trunc")
4876    (set_attr "mode" "DI")])
4877
4878 (define_insn "fix_truncdi_i387_with_temp"
4879   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4880         (fix:DI (match_operand 1 "register_operand" "f,f")))
4881    (use (match_operand:HI 2 "memory_operand" "m,m"))
4882    (use (match_operand:HI 3 "memory_operand" "m,m"))
4883    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4884    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4885   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4886    && !TARGET_FISTTP
4887    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4888   "#"
4889   [(set_attr "type" "fistp")
4890    (set_attr "i387_cw" "trunc")
4891    (set_attr "mode" "DI")])
4892
4893 (define_split
4894   [(set (match_operand:DI 0 "register_operand" "")
4895         (fix:DI (match_operand 1 "register_operand" "")))
4896    (use (match_operand:HI 2 "memory_operand" ""))
4897    (use (match_operand:HI 3 "memory_operand" ""))
4898    (clobber (match_operand:DI 4 "memory_operand" ""))
4899    (clobber (match_scratch 5 ""))]
4900   "reload_completed"
4901   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4902               (use (match_dup 2))
4903               (use (match_dup 3))
4904               (clobber (match_dup 5))])
4905    (set (match_dup 0) (match_dup 4))]
4906   "")
4907
4908 (define_split
4909   [(set (match_operand:DI 0 "memory_operand" "")
4910         (fix:DI (match_operand 1 "register_operand" "")))
4911    (use (match_operand:HI 2 "memory_operand" ""))
4912    (use (match_operand:HI 3 "memory_operand" ""))
4913    (clobber (match_operand:DI 4 "memory_operand" ""))
4914    (clobber (match_scratch 5 ""))]
4915   "reload_completed"
4916   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4917               (use (match_dup 2))
4918               (use (match_dup 3))
4919               (clobber (match_dup 5))])]
4920   "")
4921
4922 (define_insn "fix_trunc<mode>_i387"
4923   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4924         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4925    (use (match_operand:HI 2 "memory_operand" "m"))
4926    (use (match_operand:HI 3 "memory_operand" "m"))]
4927   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4928    && !TARGET_FISTTP
4929    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4930   "* return output_fix_trunc (insn, operands, 0);"
4931   [(set_attr "type" "fistp")
4932    (set_attr "i387_cw" "trunc")
4933    (set_attr "mode" "<MODE>")])
4934
4935 (define_insn "fix_trunc<mode>_i387_with_temp"
4936   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4937         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4938    (use (match_operand:HI 2 "memory_operand" "m,m"))
4939    (use (match_operand:HI 3 "memory_operand" "m,m"))
4940    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
4941   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4942    && !TARGET_FISTTP
4943    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4944   "#"
4945   [(set_attr "type" "fistp")
4946    (set_attr "i387_cw" "trunc")
4947    (set_attr "mode" "<MODE>")])
4948
4949 (define_split
4950   [(set (match_operand:X87MODEI12 0 "register_operand" "")
4951         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4952    (use (match_operand:HI 2 "memory_operand" ""))
4953    (use (match_operand:HI 3 "memory_operand" ""))
4954    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4955   "reload_completed"
4956   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4957               (use (match_dup 2))
4958               (use (match_dup 3))])
4959    (set (match_dup 0) (match_dup 4))]
4960   "")
4961
4962 (define_split
4963   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4964         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4965    (use (match_operand:HI 2 "memory_operand" ""))
4966    (use (match_operand:HI 3 "memory_operand" ""))
4967    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4968   "reload_completed"
4969   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4970               (use (match_dup 2))
4971               (use (match_dup 3))])]
4972   "")
4973
4974 (define_insn "x86_fnstcw_1"
4975   [(set (match_operand:HI 0 "memory_operand" "=m")
4976         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4977   "TARGET_80387"
4978   "fnstcw\t%0"
4979   [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4980    (set_attr "mode" "HI")
4981    (set_attr "unit" "i387")])
4982
4983 (define_insn "x86_fldcw_1"
4984   [(set (reg:HI FPCR_REG)
4985         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4986   "TARGET_80387"
4987   "fldcw\t%0"
4988   [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4989    (set_attr "mode" "HI")
4990    (set_attr "unit" "i387")
4991    (set_attr "athlon_decode" "vector")
4992    (set_attr "amdfam10_decode" "vector")])
4993 \f
4994 ;; Conversion between fixed point and floating point.
4995
4996 ;; Even though we only accept memory inputs, the backend _really_
4997 ;; wants to be able to do this between registers.
4998
4999 (define_expand "floathi<mode>2"
5000   [(set (match_operand:X87MODEF 0 "register_operand" "")
5001         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
5002   "TARGET_80387
5003    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5004        || TARGET_MIX_SSE_I387)"
5005   "")
5006
5007 ;; Pre-reload splitter to add memory clobber to the pattern.
5008 (define_insn_and_split "*floathi<mode>2_1"
5009   [(set (match_operand:X87MODEF 0 "register_operand" "")
5010         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
5011   "TARGET_80387
5012    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5013        || TARGET_MIX_SSE_I387)
5014    && can_create_pseudo_p ()"
5015   "#"
5016   "&& 1"
5017   [(parallel [(set (match_dup 0)
5018               (float:X87MODEF (match_dup 1)))
5019    (clobber (match_dup 2))])]
5020   "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
5021
5022 (define_insn "*floathi<mode>2_i387_with_temp"
5023   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5024         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
5025   (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
5026   "TARGET_80387
5027    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5028        || TARGET_MIX_SSE_I387)"
5029   "#"
5030   [(set_attr "type" "fmov,multi")
5031    (set_attr "mode" "<MODE>")
5032    (set_attr "unit" "*,i387")
5033    (set_attr "fp_int_src" "true")])
5034
5035 (define_insn "*floathi<mode>2_i387"
5036   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5037         (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
5038   "TARGET_80387
5039    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5040        || TARGET_MIX_SSE_I387)"
5041   "fild%Z1\t%1"
5042   [(set_attr "type" "fmov")
5043    (set_attr "mode" "<MODE>")
5044    (set_attr "fp_int_src" "true")])
5045
5046 (define_split
5047   [(set (match_operand:X87MODEF 0 "register_operand" "")
5048         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
5049    (clobber (match_operand:HI 2 "memory_operand" ""))]
5050   "TARGET_80387
5051    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5052        || TARGET_MIX_SSE_I387)
5053    && reload_completed"
5054   [(set (match_dup 2) (match_dup 1))
5055    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5056   "")
5057
5058 (define_split
5059   [(set (match_operand:X87MODEF 0 "register_operand" "")
5060         (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
5061    (clobber (match_operand:HI 2 "memory_operand" ""))]
5062    "TARGET_80387
5063     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5064         || TARGET_MIX_SSE_I387)
5065     && reload_completed"
5066   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5067   "")
5068
5069 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
5070   [(set (match_operand:X87MODEF 0 "register_operand" "")
5071         (float:X87MODEF
5072           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
5073   "TARGET_80387
5074    || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5075        && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
5076 {
5077   if (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5078         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5079       && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode))
5080     {
5081       rtx reg = gen_reg_rtx (XFmode);
5082       rtx insn;
5083
5084       emit_insn (gen_float<SSEMODEI24:mode>xf2 (reg, operands[1]));
5085
5086       if (<X87MODEF:MODE>mode == SFmode)
5087         insn = gen_truncxfsf2 (operands[0], reg);
5088       else if (<X87MODEF:MODE>mode == DFmode)
5089         insn = gen_truncxfdf2 (operands[0], reg);
5090       else
5091         gcc_unreachable ();
5092
5093       emit_insn (insn);
5094       DONE;
5095     }
5096 })
5097
5098 ;; Pre-reload splitter to add memory clobber to the pattern.
5099 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
5100   [(set (match_operand:X87MODEF 0 "register_operand" "")
5101         (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
5102   "((TARGET_80387
5103      && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5104      && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5105            && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5106          || TARGET_MIX_SSE_I387))
5107     || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5108         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
5109         && ((<SSEMODEI24:MODE>mode == SImode
5110              && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
5111              && optimize_function_for_speed_p (cfun)
5112              && flag_trapping_math)
5113             || !(TARGET_INTER_UNIT_CONVERSIONS
5114                  || optimize_function_for_size_p (cfun)))))
5115    && can_create_pseudo_p ()"
5116   "#"
5117   "&& 1"
5118   [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
5119               (clobber (match_dup 2))])]
5120 {
5121   operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
5122
5123   /* Avoid store forwarding (partial memory) stall penalty
5124      by passing DImode value through XMM registers.  */
5125   if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
5126       && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5127       && optimize_function_for_speed_p (cfun))
5128     {
5129       emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
5130                                                             operands[1],
5131                                                             operands[2]));
5132       DONE;
5133     }
5134 })
5135
5136 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
5137   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
5138         (float:MODEF
5139           (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
5140    (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
5141   "TARGET_SSE2 && TARGET_MIX_SSE_I387
5142    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5143   "#"
5144   [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
5145    (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
5146    (set_attr "unit" "*,i387,*,*,*")
5147    (set_attr "athlon_decode" "*,*,double,direct,double")
5148    (set_attr "amdfam10_decode" "*,*,vector,double,double")
5149    (set_attr "fp_int_src" "true")])
5150
5151 (define_insn "*floatsi<mode>2_vector_mixed"
5152   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5153         (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
5154   "TARGET_SSE2 && TARGET_MIX_SSE_I387
5155    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5156   "@
5157    fild%Z1\t%1
5158    #"
5159   [(set_attr "type" "fmov,sseicvt")
5160    (set_attr "mode" "<MODE>,<ssevecmode>")
5161    (set_attr "unit" "i387,*")
5162    (set_attr "athlon_decode" "*,direct")
5163    (set_attr "amdfam10_decode" "*,double")
5164    (set_attr "fp_int_src" "true")])
5165
5166 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
5167   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
5168         (float:MODEF
5169           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
5170   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
5171   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5172    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
5173   "#"
5174   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5175    (set_attr "mode" "<MODEF:MODE>")
5176    (set_attr "unit" "*,i387,*,*")
5177    (set_attr "athlon_decode" "*,*,double,direct")
5178    (set_attr "amdfam10_decode" "*,*,vector,double")
5179    (set_attr "fp_int_src" "true")])
5180
5181 (define_split
5182   [(set (match_operand:MODEF 0 "register_operand" "")
5183         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5184    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5185   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5186    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5187    && TARGET_INTER_UNIT_CONVERSIONS
5188    && reload_completed
5189    && (SSE_REG_P (operands[0])
5190        || (GET_CODE (operands[0]) == SUBREG
5191            && SSE_REG_P (operands[0])))"
5192   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5193   "")
5194
5195 (define_split
5196   [(set (match_operand:MODEF 0 "register_operand" "")
5197         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5198    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5199   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5200    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5201    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5202    && reload_completed
5203    && (SSE_REG_P (operands[0])
5204        || (GET_CODE (operands[0]) == SUBREG
5205            && SSE_REG_P (operands[0])))"
5206   [(set (match_dup 2) (match_dup 1))
5207    (set (match_dup 0) (float:MODEF (match_dup 2)))]
5208   "")
5209
5210 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5211   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5212         (float:MODEF
5213           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
5214   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5215    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5216    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5217   "@
5218    fild%Z1\t%1
5219    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
5220    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5221   [(set_attr "type" "fmov,sseicvt,sseicvt")
5222    (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5223    (set_attr "mode" "<MODEF:MODE>")
5224    (set (attr "prefix_rex")
5225      (if_then_else
5226        (and (eq_attr "prefix" "maybe_vex")
5227             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5228        (const_string "1")
5229        (const_string "*")))
5230    (set_attr "unit" "i387,*,*")
5231    (set_attr "athlon_decode" "*,double,direct")
5232    (set_attr "amdfam10_decode" "*,vector,double")
5233    (set_attr "fp_int_src" "true")])
5234
5235 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5236   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5237         (float:MODEF
5238           (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5239   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5240    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5241    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5242   "@
5243    fild%Z1\t%1
5244    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5245   [(set_attr "type" "fmov,sseicvt")
5246    (set_attr "prefix" "orig,maybe_vex")
5247    (set_attr "mode" "<MODEF:MODE>")
5248    (set (attr "prefix_rex")
5249      (if_then_else
5250        (and (eq_attr "prefix" "maybe_vex")
5251             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5252        (const_string "1")
5253        (const_string "*")))
5254    (set_attr "athlon_decode" "*,direct")
5255    (set_attr "amdfam10_decode" "*,double")
5256    (set_attr "fp_int_src" "true")])
5257
5258 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5259   [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5260         (float:MODEF
5261           (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5262    (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5263   "TARGET_SSE2 && TARGET_SSE_MATH
5264    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5265   "#"
5266   [(set_attr "type" "sseicvt")
5267    (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5268    (set_attr "athlon_decode" "double,direct,double")
5269    (set_attr "amdfam10_decode" "vector,double,double")
5270    (set_attr "fp_int_src" "true")])
5271
5272 (define_insn "*floatsi<mode>2_vector_sse"
5273   [(set (match_operand:MODEF 0 "register_operand" "=x")
5274         (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5275   "TARGET_SSE2 && TARGET_SSE_MATH
5276    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5277   "#"
5278   [(set_attr "type" "sseicvt")
5279    (set_attr "mode" "<MODE>")
5280    (set_attr "athlon_decode" "direct")
5281    (set_attr "amdfam10_decode" "double")
5282    (set_attr "fp_int_src" "true")])
5283
5284 (define_split
5285   [(set (match_operand:MODEF 0 "register_operand" "")
5286         (float:MODEF (match_operand:SI 1 "register_operand" "")))
5287    (clobber (match_operand:SI 2 "memory_operand" ""))]
5288   "TARGET_SSE2 && TARGET_SSE_MATH
5289    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5290    && reload_completed
5291    && (SSE_REG_P (operands[0])
5292        || (GET_CODE (operands[0]) == SUBREG
5293            && SSE_REG_P (operands[0])))"
5294   [(const_int 0)]
5295 {
5296   rtx op1 = operands[1];
5297
5298   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5299                                      <MODE>mode, 0);
5300   if (GET_CODE (op1) == SUBREG)
5301     op1 = SUBREG_REG (op1);
5302
5303   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5304     {
5305       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5306       emit_insn (gen_sse2_loadld (operands[4],
5307                                   CONST0_RTX (V4SImode), operands[1]));
5308     }
5309   /* We can ignore possible trapping value in the
5310      high part of SSE register for non-trapping math. */
5311   else if (SSE_REG_P (op1) && !flag_trapping_math)
5312     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5313   else
5314     {
5315       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5316       emit_move_insn (operands[2], operands[1]);
5317       emit_insn (gen_sse2_loadld (operands[4],
5318                                   CONST0_RTX (V4SImode), operands[2]));
5319     }
5320   emit_insn
5321     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5322   DONE;
5323 })
5324
5325 (define_split
5326   [(set (match_operand:MODEF 0 "register_operand" "")
5327         (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5328    (clobber (match_operand:SI 2 "memory_operand" ""))]
5329   "TARGET_SSE2 && TARGET_SSE_MATH
5330    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5331    && reload_completed
5332    && (SSE_REG_P (operands[0])
5333        || (GET_CODE (operands[0]) == SUBREG
5334            && SSE_REG_P (operands[0])))"
5335   [(const_int 0)]
5336 {
5337   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5338                                      <MODE>mode, 0);
5339   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5340
5341   emit_insn (gen_sse2_loadld (operands[4],
5342                               CONST0_RTX (V4SImode), operands[1]));
5343   emit_insn
5344     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5345   DONE;
5346 })
5347
5348 (define_split
5349   [(set (match_operand:MODEF 0 "register_operand" "")
5350         (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5351   "TARGET_SSE2 && TARGET_SSE_MATH
5352    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5353    && reload_completed
5354    && (SSE_REG_P (operands[0])
5355        || (GET_CODE (operands[0]) == SUBREG
5356            && SSE_REG_P (operands[0])))"
5357   [(const_int 0)]
5358 {
5359   rtx op1 = operands[1];
5360
5361   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5362                                      <MODE>mode, 0);
5363   if (GET_CODE (op1) == SUBREG)
5364     op1 = SUBREG_REG (op1);
5365
5366   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5367     {
5368       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5369       emit_insn (gen_sse2_loadld (operands[4],
5370                                   CONST0_RTX (V4SImode), operands[1]));
5371     }
5372   /* We can ignore possible trapping value in the
5373      high part of SSE register for non-trapping math. */
5374   else if (SSE_REG_P (op1) && !flag_trapping_math)
5375     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5376   else
5377     gcc_unreachable ();
5378   emit_insn
5379     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5380   DONE;
5381 })
5382
5383 (define_split
5384   [(set (match_operand:MODEF 0 "register_operand" "")
5385         (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5386   "TARGET_SSE2 && TARGET_SSE_MATH
5387    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5388    && reload_completed
5389    && (SSE_REG_P (operands[0])
5390        || (GET_CODE (operands[0]) == SUBREG
5391            && SSE_REG_P (operands[0])))"
5392   [(const_int 0)]
5393 {
5394   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5395                                      <MODE>mode, 0);
5396   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5397
5398   emit_insn (gen_sse2_loadld (operands[4],
5399                               CONST0_RTX (V4SImode), operands[1]));
5400   emit_insn
5401     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5402   DONE;
5403 })
5404
5405 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5406   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5407         (float:MODEF
5408           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5409   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5410   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5411    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5412   "#"
5413   [(set_attr "type" "sseicvt")
5414    (set_attr "mode" "<MODEF:MODE>")
5415    (set_attr "athlon_decode" "double,direct")
5416    (set_attr "amdfam10_decode" "vector,double")
5417    (set_attr "fp_int_src" "true")])
5418
5419 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5420   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5421         (float:MODEF
5422           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5423   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5424    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5425    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5426   "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5427   [(set_attr "type" "sseicvt")
5428    (set_attr "prefix" "maybe_vex")
5429    (set_attr "mode" "<MODEF:MODE>")
5430    (set (attr "prefix_rex")
5431      (if_then_else
5432        (and (eq_attr "prefix" "maybe_vex")
5433             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5434        (const_string "1")
5435        (const_string "*")))
5436    (set_attr "athlon_decode" "double,direct")
5437    (set_attr "amdfam10_decode" "vector,double")
5438    (set_attr "fp_int_src" "true")])
5439
5440 (define_split
5441   [(set (match_operand:MODEF 0 "register_operand" "")
5442         (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5443    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5444   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5445    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5446    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5447    && reload_completed
5448    && (SSE_REG_P (operands[0])
5449        || (GET_CODE (operands[0]) == SUBREG
5450            && SSE_REG_P (operands[0])))"
5451   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5452   "")
5453
5454 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5455   [(set (match_operand:MODEF 0 "register_operand" "=x")
5456         (float:MODEF
5457           (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5458   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5459    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5460    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5461   "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5462   [(set_attr "type" "sseicvt")
5463    (set_attr "prefix" "maybe_vex")
5464    (set_attr "mode" "<MODEF:MODE>")
5465    (set (attr "prefix_rex")
5466      (if_then_else
5467        (and (eq_attr "prefix" "maybe_vex")
5468             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5469        (const_string "1")
5470        (const_string "*")))
5471    (set_attr "athlon_decode" "direct")
5472    (set_attr "amdfam10_decode" "double")
5473    (set_attr "fp_int_src" "true")])
5474
5475 (define_split
5476   [(set (match_operand:MODEF 0 "register_operand" "")
5477         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5478    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5479   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5480    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5481    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5482    && reload_completed
5483    && (SSE_REG_P (operands[0])
5484        || (GET_CODE (operands[0]) == SUBREG
5485            && SSE_REG_P (operands[0])))"
5486   [(set (match_dup 2) (match_dup 1))
5487    (set (match_dup 0) (float:MODEF (match_dup 2)))]
5488   "")
5489
5490 (define_split
5491   [(set (match_operand:MODEF 0 "register_operand" "")
5492         (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5493    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5494   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5495    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5496    && reload_completed
5497    && (SSE_REG_P (operands[0])
5498        || (GET_CODE (operands[0]) == SUBREG
5499            && SSE_REG_P (operands[0])))"
5500   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5501   "")
5502
5503 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5504   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5505         (float:X87MODEF
5506           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5507   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5508   "TARGET_80387
5509    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5510   "@
5511    fild%Z1\t%1
5512    #"
5513   [(set_attr "type" "fmov,multi")
5514    (set_attr "mode" "<X87MODEF:MODE>")
5515    (set_attr "unit" "*,i387")
5516    (set_attr "fp_int_src" "true")])
5517
5518 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5519   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5520         (float:X87MODEF
5521           (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5522   "TARGET_80387
5523    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5524   "fild%Z1\t%1"
5525   [(set_attr "type" "fmov")
5526    (set_attr "mode" "<X87MODEF:MODE>")
5527    (set_attr "fp_int_src" "true")])
5528
5529 (define_split
5530   [(set (match_operand:X87MODEF 0 "register_operand" "")
5531         (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5532    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5533   "TARGET_80387
5534    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5535    && reload_completed
5536    && FP_REG_P (operands[0])"
5537   [(set (match_dup 2) (match_dup 1))
5538    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5539   "")
5540
5541 (define_split
5542   [(set (match_operand:X87MODEF 0 "register_operand" "")
5543         (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5544    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5545   "TARGET_80387
5546    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5547    && reload_completed
5548    && FP_REG_P (operands[0])"
5549   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5550   "")
5551
5552 ;; Avoid store forwarding (partial memory) stall penalty
5553 ;; by passing DImode value through XMM registers.  */
5554
5555 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5556   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5557         (float:X87MODEF
5558           (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5559    (clobber (match_scratch:V4SI 3 "=X,x"))
5560    (clobber (match_scratch:V4SI 4 "=X,x"))
5561    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5562   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5563    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5564    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5565   "#"
5566   [(set_attr "type" "multi")
5567    (set_attr "mode" "<X87MODEF:MODE>")
5568    (set_attr "unit" "i387")
5569    (set_attr "fp_int_src" "true")])
5570
5571 (define_split
5572   [(set (match_operand:X87MODEF 0 "register_operand" "")
5573         (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5574    (clobber (match_scratch:V4SI 3 ""))
5575    (clobber (match_scratch:V4SI 4 ""))
5576    (clobber (match_operand:DI 2 "memory_operand" ""))]
5577   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5578    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5579    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5580    && reload_completed
5581    && FP_REG_P (operands[0])"
5582   [(set (match_dup 2) (match_dup 3))
5583    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5584 {
5585   /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5586      Assemble the 64-bit DImode value in an xmm register.  */
5587   emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5588                               gen_rtx_SUBREG (SImode, operands[1], 0)));
5589   emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5590                               gen_rtx_SUBREG (SImode, operands[1], 4)));
5591   emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5592                                          operands[4]));
5593
5594   operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5595 })
5596
5597 (define_split
5598   [(set (match_operand:X87MODEF 0 "register_operand" "")
5599         (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5600    (clobber (match_scratch:V4SI 3 ""))
5601    (clobber (match_scratch:V4SI 4 ""))
5602    (clobber (match_operand:DI 2 "memory_operand" ""))]
5603   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5604    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5605    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5606    && reload_completed
5607    && FP_REG_P (operands[0])"
5608   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5609   "")
5610
5611 ;; Avoid store forwarding (partial memory) stall penalty by extending
5612 ;; SImode value to DImode through XMM register instead of pushing two
5613 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5614 ;; targets benefit from this optimization. Also note that fild
5615 ;; loads from memory only.
5616
5617 (define_insn "*floatunssi<mode>2_1"
5618   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5619         (unsigned_float:X87MODEF
5620           (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5621    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5622    (clobber (match_scratch:SI 3 "=X,x"))]
5623   "!TARGET_64BIT
5624    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5625    && TARGET_SSE"
5626   "#"
5627   [(set_attr "type" "multi")
5628    (set_attr "mode" "<MODE>")])
5629
5630 (define_split
5631   [(set (match_operand:X87MODEF 0 "register_operand" "")
5632         (unsigned_float:X87MODEF
5633           (match_operand:SI 1 "register_operand" "")))
5634    (clobber (match_operand:DI 2 "memory_operand" ""))
5635    (clobber (match_scratch:SI 3 ""))]
5636   "!TARGET_64BIT
5637    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5638    && TARGET_SSE
5639    && reload_completed"
5640   [(set (match_dup 2) (match_dup 1))
5641    (set (match_dup 0)
5642         (float:X87MODEF (match_dup 2)))]
5643   "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5644
5645 (define_split
5646   [(set (match_operand:X87MODEF 0 "register_operand" "")
5647         (unsigned_float:X87MODEF
5648           (match_operand:SI 1 "memory_operand" "")))
5649    (clobber (match_operand:DI 2 "memory_operand" ""))
5650    (clobber (match_scratch:SI 3 ""))]
5651   "!TARGET_64BIT
5652    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5653    && TARGET_SSE
5654    && reload_completed"
5655   [(set (match_dup 2) (match_dup 3))
5656    (set (match_dup 0)
5657         (float:X87MODEF (match_dup 2)))]
5658 {
5659   emit_move_insn (operands[3], operands[1]);
5660   operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5661 })
5662
5663 (define_expand "floatunssi<mode>2"
5664   [(parallel
5665      [(set (match_operand:X87MODEF 0 "register_operand" "")
5666            (unsigned_float:X87MODEF
5667              (match_operand:SI 1 "nonimmediate_operand" "")))
5668       (clobber (match_dup 2))
5669       (clobber (match_scratch:SI 3 ""))])]
5670   "!TARGET_64BIT
5671    && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5672         && TARGET_SSE)
5673        || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5674 {
5675   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5676     {
5677       ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5678       DONE;
5679     }
5680   else
5681     {
5682       enum ix86_stack_slot slot = (virtuals_instantiated
5683                                    ? SLOT_TEMP
5684                                    : SLOT_VIRTUAL);
5685       operands[2] = assign_386_stack_local (DImode, slot);
5686     }
5687 })
5688
5689 (define_expand "floatunsdisf2"
5690   [(use (match_operand:SF 0 "register_operand" ""))
5691    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5692   "TARGET_64BIT && TARGET_SSE_MATH"
5693   "x86_emit_floatuns (operands); DONE;")
5694
5695 (define_expand "floatunsdidf2"
5696   [(use (match_operand:DF 0 "register_operand" ""))
5697    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5698   "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5699    && TARGET_SSE2 && TARGET_SSE_MATH"
5700 {
5701   if (TARGET_64BIT)
5702     x86_emit_floatuns (operands);
5703   else
5704     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5705   DONE;
5706 })
5707 \f
5708 ;; Add instructions
5709
5710 (define_expand "add<mode>3"
5711   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5712         (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5713                     (match_operand:SDWIM 2 "<general_operand>" "")))]
5714   ""
5715   "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5716
5717 (define_insn_and_split "*add<dwi>3_doubleword"
5718   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5719         (plus:<DWI>
5720           (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5721           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5722    (clobber (reg:CC FLAGS_REG))]
5723   "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5724   "#"
5725   "reload_completed"
5726   [(parallel [(set (reg:CC FLAGS_REG)
5727                    (unspec:CC [(match_dup 1) (match_dup 2)]
5728                               UNSPEC_ADD_CARRY))
5729               (set (match_dup 0)
5730                    (plus:DWIH (match_dup 1) (match_dup 2)))])
5731    (parallel [(set (match_dup 3)
5732                    (plus:DWIH
5733                      (match_dup 4)
5734                      (plus:DWIH
5735                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5736                        (match_dup 5))))
5737               (clobber (reg:CC FLAGS_REG))])]
5738   "split_<dwi> (&operands[0], 3, &operands[0], &operands[3]);")
5739
5740 (define_insn "*add<mode>3_cc"
5741   [(set (reg:CC FLAGS_REG)
5742         (unspec:CC
5743           [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5744            (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5745           UNSPEC_ADD_CARRY))
5746    (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5747         (plus:SWI48 (match_dup 1) (match_dup 2)))]
5748   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5749   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5750   [(set_attr "type" "alu")
5751    (set_attr "mode" "<MODE>")])
5752
5753 (define_insn "addqi3_cc"
5754   [(set (reg:CC FLAGS_REG)
5755         (unspec:CC
5756           [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5757            (match_operand:QI 2 "general_operand" "qn,qm")]
5758           UNSPEC_ADD_CARRY))
5759    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5760         (plus:QI (match_dup 1) (match_dup 2)))]
5761   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5762   "add{b}\t{%2, %0|%0, %2}"
5763   [(set_attr "type" "alu")
5764    (set_attr "mode" "QI")])
5765
5766 (define_insn "*lea_1"
5767   [(set (match_operand:DWIH 0 "register_operand" "=r")
5768         (match_operand:DWIH 1 "no_seg_address_operand" "p"))]
5769   ""
5770   "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
5771   [(set_attr "type" "lea")
5772    (set_attr "mode" "<MODE>")])
5773
5774 (define_insn "*lea_2"
5775   [(set (match_operand:SI 0 "register_operand" "=r")
5776         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5777   "TARGET_64BIT"
5778   "lea{l}\t{%a1, %0|%0, %a1}"
5779   [(set_attr "type" "lea")
5780    (set_attr "mode" "SI")])
5781
5782 (define_insn "*lea_2_zext"
5783   [(set (match_operand:DI 0 "register_operand" "=r")
5784         (zero_extend:DI
5785           (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5786   "TARGET_64BIT"
5787   "lea{l}\t{%a1, %k0|%k0, %a1}"
5788   [(set_attr "type" "lea")
5789    (set_attr "mode" "SI")])
5790
5791 (define_insn "*add<mode>_1"
5792   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5793         (plus:SWI48
5794           (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5795           (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,0,l<i>")))
5796    (clobber (reg:CC FLAGS_REG))]
5797   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5798 {
5799   switch (get_attr_type (insn))
5800     {
5801     case TYPE_LEA:
5802       return "#";
5803
5804     case TYPE_INCDEC:
5805       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5806       if (operands[2] == const1_rtx)
5807         return "inc{<imodesuffix>}\t%0";
5808       else
5809         {
5810           gcc_assert (operands[2] == constm1_rtx);
5811           return "dec{<imodesuffix>}\t%0";
5812         }
5813
5814     default:
5815       /* For most processors, ADD is faster than LEA.  This alternative
5816          was added to use ADD as much as possible.  */
5817       if (which_alternative == 2)
5818         {
5819           rtx tmp;
5820           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5821         }
5822         
5823       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5824       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5825         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5826
5827       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5828     }
5829 }
5830   [(set (attr "type")
5831      (cond [(eq_attr "alternative" "3")
5832               (const_string "lea")
5833             (match_operand:SWI48 2 "incdec_operand" "")
5834               (const_string "incdec")
5835            ]
5836            (const_string "alu")))
5837    (set (attr "length_immediate")
5838       (if_then_else
5839         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5840         (const_string "1")
5841         (const_string "*")))
5842    (set_attr "mode" "<MODE>")])
5843
5844 ;; It may seem that nonimmediate operand is proper one for operand 1.
5845 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5846 ;; we take care in ix86_binary_operator_ok to not allow two memory
5847 ;; operands so proper swapping will be done in reload.  This allow
5848 ;; patterns constructed from addsi_1 to match.
5849
5850 (define_insn "*addsi_1_zext"
5851   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5852         (zero_extend:DI
5853           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5854                    (match_operand:SI 2 "general_operand" "g,0,li"))))
5855    (clobber (reg:CC FLAGS_REG))]
5856   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5857 {
5858   switch (get_attr_type (insn))
5859     {
5860     case TYPE_LEA:
5861       return "#";
5862
5863     case TYPE_INCDEC:
5864       if (operands[2] == const1_rtx)
5865         return "inc{l}\t%k0";
5866       else
5867         {
5868           gcc_assert (operands[2] == constm1_rtx);
5869           return "dec{l}\t%k0";
5870         }
5871
5872     default:
5873       /* For most processors, ADD is faster than LEA.  This alternative
5874          was added to use ADD as much as possible.  */
5875       if (which_alternative == 1)
5876         {
5877           rtx tmp;
5878           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5879         }
5880
5881       if (x86_maybe_negate_const_int (&operands[2], SImode))
5882         return "sub{l}\t{%2, %k0|%k0, %2}";
5883
5884       return "add{l}\t{%2, %k0|%k0, %2}";
5885     }
5886 }
5887   [(set (attr "type")
5888      (cond [(eq_attr "alternative" "2")
5889               (const_string "lea")
5890             (match_operand:SI 2 "incdec_operand" "")
5891               (const_string "incdec")
5892            ]
5893            (const_string "alu")))
5894    (set (attr "length_immediate")
5895       (if_then_else
5896         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5897         (const_string "1")
5898         (const_string "*")))
5899    (set_attr "mode" "SI")])
5900
5901 (define_insn "*addhi_1"
5902   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5903         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5904                  (match_operand:HI 2 "general_operand" "rn,rm")))
5905    (clobber (reg:CC FLAGS_REG))]
5906   "TARGET_PARTIAL_REG_STALL
5907    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5908 {
5909   switch (get_attr_type (insn))
5910     {
5911     case TYPE_INCDEC:
5912       if (operands[2] == const1_rtx)
5913         return "inc{w}\t%0";
5914       else
5915         {
5916           gcc_assert (operands[2] == constm1_rtx);
5917           return "dec{w}\t%0";
5918         }
5919
5920     default:
5921       if (x86_maybe_negate_const_int (&operands[2], HImode))
5922         return "sub{w}\t{%2, %0|%0, %2}";
5923
5924       return "add{w}\t{%2, %0|%0, %2}";
5925     }
5926 }
5927   [(set (attr "type")
5928      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5929         (const_string "incdec")
5930         (const_string "alu")))
5931    (set (attr "length_immediate")
5932       (if_then_else
5933         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5934         (const_string "1")
5935         (const_string "*")))
5936    (set_attr "mode" "HI")])
5937
5938 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5939 ;; type optimizations enabled by define-splits.  This is not important
5940 ;; for PII, and in fact harmful because of partial register stalls.
5941
5942 (define_insn "*addhi_1_lea"
5943   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm,r,r")
5944         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,r")
5945                  (match_operand:HI 2 "general_operand" "rmn,rn,0,ln")))
5946    (clobber (reg:CC FLAGS_REG))]
5947   "!TARGET_PARTIAL_REG_STALL
5948    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5949 {
5950   switch (get_attr_type (insn))
5951     {
5952     case TYPE_LEA:
5953       return "#";
5954
5955     case TYPE_INCDEC:
5956       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5957       if (operands[2] == const1_rtx)
5958         return "inc{w}\t%0";
5959       else
5960         {
5961           gcc_assert (operands[2] == constm1_rtx);
5962           return "dec{w}\t%0";
5963         }
5964
5965     default:
5966       /* For most processors, ADD is faster than LEA.  This alternative
5967          was added to use ADD as much as possible.  */
5968       if (which_alternative == 2)
5969         {
5970           rtx tmp;
5971           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5972         }
5973
5974       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5975       if (x86_maybe_negate_const_int (&operands[2], HImode))
5976         return "sub{w}\t{%2, %0|%0, %2}";
5977
5978       return "add{w}\t{%2, %0|%0, %2}";
5979     }
5980 }
5981   [(set (attr "type")
5982      (cond [(eq_attr "alternative" "3")
5983               (const_string "lea")
5984             (match_operand:HI 2 "incdec_operand" "")
5985               (const_string "incdec")
5986            ]
5987            (const_string "alu")))
5988    (set (attr "length_immediate")
5989       (if_then_else
5990         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5991         (const_string "1")
5992         (const_string "*")))
5993    (set_attr "mode" "HI,HI,HI,SI")])
5994
5995 ;; %%% Potential partial reg stall on alternative 2.  What to do?
5996 (define_insn "*addqi_1"
5997   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
5998         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
5999                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6000    (clobber (reg:CC FLAGS_REG))]
6001   "TARGET_PARTIAL_REG_STALL
6002    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6003 {
6004   int widen = (which_alternative == 2);
6005   switch (get_attr_type (insn))
6006     {
6007     case TYPE_INCDEC:
6008       if (operands[2] == const1_rtx)
6009         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6010       else
6011         {
6012           gcc_assert (operands[2] == constm1_rtx);
6013           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6014         }
6015
6016     default:
6017       if (x86_maybe_negate_const_int (&operands[2], QImode))
6018         {
6019           if (widen)
6020             return "sub{l}\t{%2, %k0|%k0, %2}";
6021           else
6022             return "sub{b}\t{%2, %0|%0, %2}";
6023         }
6024       if (widen)
6025         return "add{l}\t{%k2, %k0|%k0, %k2}";
6026       else
6027         return "add{b}\t{%2, %0|%0, %2}";
6028     }
6029 }
6030   [(set (attr "type")
6031      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6032         (const_string "incdec")
6033         (const_string "alu")))
6034    (set (attr "length_immediate")
6035       (if_then_else
6036         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6037         (const_string "1")
6038         (const_string "*")))
6039    (set_attr "mode" "QI,QI,SI")])
6040
6041 ;; %%% Potential partial reg stall on alternatives 3 and 4.  What to do?
6042 (define_insn "*addqi_1_lea"
6043   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,q,r,r,r")
6044         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,r")
6045                  (match_operand:QI 2 "general_operand" "qmn,qn,0,rn,0,ln")))
6046    (clobber (reg:CC FLAGS_REG))]
6047   "!TARGET_PARTIAL_REG_STALL
6048    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6049 {
6050   int widen = (which_alternative == 3 || which_alternative == 4);
6051
6052   switch (get_attr_type (insn))
6053     {
6054     case TYPE_LEA:
6055       return "#";
6056
6057     case TYPE_INCDEC:
6058       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6059       if (operands[2] == const1_rtx)
6060         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6061       else
6062         {
6063           gcc_assert (operands[2] == constm1_rtx);
6064           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6065         }
6066
6067     default:
6068       /* For most processors, ADD is faster than LEA.  These alternatives
6069          were added to use ADD as much as possible.  */
6070       if (which_alternative == 2 || which_alternative == 4)
6071         {
6072           rtx tmp;
6073           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
6074         }
6075
6076       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6077       if (x86_maybe_negate_const_int (&operands[2], QImode))
6078         {
6079           if (widen)
6080             return "sub{l}\t{%2, %k0|%k0, %2}";
6081           else
6082             return "sub{b}\t{%2, %0|%0, %2}";
6083         }
6084       if (widen)
6085         return "add{l}\t{%k2, %k0|%k0, %k2}";
6086       else
6087         return "add{b}\t{%2, %0|%0, %2}";
6088     }
6089 }
6090   [(set (attr "type")
6091      (cond [(eq_attr "alternative" "5")
6092               (const_string "lea")
6093             (match_operand:QI 2 "incdec_operand" "")
6094               (const_string "incdec")
6095            ]
6096            (const_string "alu")))
6097    (set (attr "length_immediate")
6098       (if_then_else
6099         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6100         (const_string "1")
6101         (const_string "*")))
6102    (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
6103
6104 (define_insn "*addqi_1_slp"
6105   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6106         (plus:QI (match_dup 0)
6107                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6108    (clobber (reg:CC FLAGS_REG))]
6109   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6110    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6111 {
6112   switch (get_attr_type (insn))
6113     {
6114     case TYPE_INCDEC:
6115       if (operands[1] == const1_rtx)
6116         return "inc{b}\t%0";
6117       else
6118         {
6119           gcc_assert (operands[1] == constm1_rtx);
6120           return "dec{b}\t%0";
6121         }
6122
6123     default:
6124       if (x86_maybe_negate_const_int (&operands[1], QImode))
6125         return "sub{b}\t{%1, %0|%0, %1}";
6126
6127       return "add{b}\t{%1, %0|%0, %1}";
6128     }
6129 }
6130   [(set (attr "type")
6131      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6132         (const_string "incdec")
6133         (const_string "alu1")))
6134    (set (attr "memory")
6135      (if_then_else (match_operand 1 "memory_operand" "")
6136         (const_string "load")
6137         (const_string "none")))
6138    (set_attr "mode" "QI")])
6139
6140 (define_insn "*add<mode>_2"
6141   [(set (reg FLAGS_REG)
6142         (compare
6143           (plus:SWI
6144             (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6145             (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
6146           (const_int 0)))
6147    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
6148         (plus:SWI (match_dup 1) (match_dup 2)))]
6149   "ix86_match_ccmode (insn, CCGOCmode)
6150    && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6151 {
6152   switch (get_attr_type (insn))
6153     {
6154     case TYPE_INCDEC:
6155       if (operands[2] == const1_rtx)
6156         return "inc{<imodesuffix>}\t%0";
6157       else
6158         {
6159           gcc_assert (operands[2] == constm1_rtx);
6160           return "dec{<imodesuffix>}\t%0";
6161         }
6162
6163     default:
6164       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6165         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6166
6167       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6168     }
6169 }
6170   [(set (attr "type")
6171      (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6172         (const_string "incdec")
6173         (const_string "alu")))
6174    (set (attr "length_immediate")
6175       (if_then_else
6176         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6177         (const_string "1")
6178         (const_string "*")))
6179    (set_attr "mode" "<MODE>")])
6180
6181 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6182 (define_insn "*addsi_2_zext"
6183   [(set (reg FLAGS_REG)
6184         (compare
6185           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6186                    (match_operand:SI 2 "general_operand" "g"))
6187           (const_int 0)))
6188    (set (match_operand:DI 0 "register_operand" "=r")
6189         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6190   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6191    && ix86_binary_operator_ok (PLUS, SImode, operands)"
6192 {
6193   switch (get_attr_type (insn))
6194     {
6195     case TYPE_INCDEC:
6196       if (operands[2] == const1_rtx)
6197         return "inc{l}\t%k0";
6198       else
6199         {
6200           gcc_assert (operands[2] == constm1_rtx);
6201           return "dec{l}\t%k0";
6202         }
6203
6204     default:
6205       if (x86_maybe_negate_const_int (&operands[2], SImode))
6206         return "sub{l}\t{%2, %k0|%k0, %2}";
6207
6208       return "add{l}\t{%2, %k0|%k0, %2}";
6209     }
6210 }
6211   [(set (attr "type")
6212      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6213         (const_string "incdec")
6214         (const_string "alu")))
6215    (set (attr "length_immediate")
6216       (if_then_else
6217         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6218         (const_string "1")
6219         (const_string "*")))
6220    (set_attr "mode" "SI")])
6221
6222 (define_insn "*add<mode>_3"
6223   [(set (reg FLAGS_REG)
6224         (compare
6225           (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>"))
6226           (match_operand:SWI 1 "nonimmediate_operand" "%0")))
6227    (clobber (match_scratch:SWI 0 "=<r>"))]
6228   "ix86_match_ccmode (insn, CCZmode)
6229    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6230 {
6231   switch (get_attr_type (insn))
6232     {
6233     case TYPE_INCDEC:
6234       if (operands[2] == const1_rtx)
6235         return "inc{<imodesuffix>}\t%0";
6236       else
6237         {
6238           gcc_assert (operands[2] == constm1_rtx);
6239           return "dec{<imodesuffix>}\t%0";
6240         }
6241
6242     default:
6243       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6244         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6245
6246       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6247     }
6248 }
6249   [(set (attr "type")
6250      (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6251         (const_string "incdec")
6252         (const_string "alu")))
6253    (set (attr "length_immediate")
6254       (if_then_else
6255         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6256         (const_string "1")
6257         (const_string "*")))
6258    (set_attr "mode" "<MODE>")])
6259
6260 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6261 (define_insn "*addsi_3_zext"
6262   [(set (reg FLAGS_REG)
6263         (compare
6264           (neg:SI (match_operand:SI 2 "general_operand" "g"))
6265           (match_operand:SI 1 "nonimmediate_operand" "%0")))
6266    (set (match_operand:DI 0 "register_operand" "=r")
6267         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6268   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6269    && ix86_binary_operator_ok (PLUS, SImode, operands)"
6270 {
6271   switch (get_attr_type (insn))
6272     {
6273     case TYPE_INCDEC:
6274       if (operands[2] == const1_rtx)
6275         return "inc{l}\t%k0";
6276       else
6277         {
6278           gcc_assert (operands[2] == constm1_rtx);
6279           return "dec{l}\t%k0";
6280         }
6281
6282     default:
6283       if (x86_maybe_negate_const_int (&operands[2], SImode))
6284         return "sub{l}\t{%2, %k0|%k0, %2}";
6285
6286       return "add{l}\t{%2, %k0|%k0, %2}";
6287     }
6288 }
6289   [(set (attr "type")
6290      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6291         (const_string "incdec")
6292         (const_string "alu")))
6293    (set (attr "length_immediate")
6294       (if_then_else
6295         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6296         (const_string "1")
6297         (const_string "*")))
6298    (set_attr "mode" "SI")])
6299
6300 ; For comparisons against 1, -1 and 128, we may generate better code
6301 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6302 ; is matched then.  We can't accept general immediate, because for
6303 ; case of overflows,  the result is messed up.
6304 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6305 ; only for comparisons not depending on it.
6306
6307 (define_insn "*adddi_4"
6308   [(set (reg FLAGS_REG)
6309         (compare
6310           (match_operand:DI 1 "nonimmediate_operand" "0")
6311           (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6312    (clobber (match_scratch:DI 0 "=rm"))]
6313   "TARGET_64BIT
6314    && ix86_match_ccmode (insn, CCGCmode)"
6315 {
6316   switch (get_attr_type (insn))
6317     {
6318     case TYPE_INCDEC:
6319       if (operands[2] == constm1_rtx)
6320         return "inc{q}\t%0";
6321       else
6322         {
6323           gcc_assert (operands[2] == const1_rtx);
6324           return "dec{q}\t%0";
6325         }
6326
6327     default:
6328       if (x86_maybe_negate_const_int (&operands[2], DImode))
6329         return "add{q}\t{%2, %0|%0, %2}";
6330
6331       return "sub{q}\t{%2, %0|%0, %2}";
6332     }
6333 }
6334   [(set (attr "type")
6335      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6336         (const_string "incdec")
6337         (const_string "alu")))
6338    (set (attr "length_immediate")
6339       (if_then_else
6340         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6341         (const_string "1")
6342         (const_string "*")))
6343    (set_attr "mode" "DI")])
6344
6345 ; For comparisons against 1, -1 and 128, we may generate better code
6346 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6347 ; is matched then.  We can't accept general immediate, because for
6348 ; case of overflows,  the result is messed up.
6349 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6350 ; only for comparisons not depending on it.
6351
6352 (define_insn "*add<mode>_4"
6353   [(set (reg FLAGS_REG)
6354         (compare
6355           (match_operand:SWI124 1 "nonimmediate_operand" "0")
6356           (match_operand:SWI124 2 "const_int_operand" "n")))
6357    (clobber (match_scratch:SWI124 0 "=<r>m"))]
6358   "ix86_match_ccmode (insn, CCGCmode)"
6359 {
6360   switch (get_attr_type (insn))
6361     {
6362     case TYPE_INCDEC:
6363       if (operands[2] == constm1_rtx)
6364         return "inc{<imodesuffix>}\t%0";
6365       else
6366         {
6367           gcc_assert (operands[2] == const1_rtx);
6368           return "dec{<imodesuffix>}\t%0";
6369         }
6370
6371     default:
6372       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6373         return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6374
6375       return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6376     }
6377 }
6378   [(set (attr "type")
6379      (if_then_else (match_operand:<MODE> 2 "incdec_operand" "")
6380         (const_string "incdec")
6381         (const_string "alu")))
6382    (set (attr "length_immediate")
6383       (if_then_else
6384         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6385         (const_string "1")
6386         (const_string "*")))
6387    (set_attr "mode" "<MODE>")])
6388
6389 (define_insn "*add<mode>_5"
6390   [(set (reg FLAGS_REG)
6391         (compare
6392           (plus:SWI
6393             (match_operand:SWI 1 "nonimmediate_operand" "%0")
6394             (match_operand:SWI 2 "<general_operand>" "<g>"))
6395           (const_int 0)))
6396    (clobber (match_scratch:SWI 0 "=<r>"))]
6397   "ix86_match_ccmode (insn, CCGOCmode)
6398    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6399 {
6400   switch (get_attr_type (insn))
6401     {
6402     case TYPE_INCDEC:
6403       if (operands[2] == const1_rtx)
6404         return "inc{<imodesuffix>}\t%0";
6405       else
6406         {
6407           gcc_assert (operands[2] == constm1_rtx);
6408           return "dec{<imodesuffix>}\t%0";
6409         }
6410
6411     default:
6412       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6413         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6414
6415       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6416     }
6417 }
6418   [(set (attr "type")
6419      (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6420         (const_string "incdec")
6421         (const_string "alu")))
6422    (set (attr "length_immediate")
6423       (if_then_else
6424         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6425         (const_string "1")
6426         (const_string "*")))
6427    (set_attr "mode" "<MODE>")])
6428
6429 (define_insn "*addqi_ext_1_rex64"
6430   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6431                          (const_int 8)
6432                          (const_int 8))
6433         (plus:SI
6434           (zero_extract:SI
6435             (match_operand 1 "ext_register_operand" "0")
6436             (const_int 8)
6437             (const_int 8))
6438           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6439    (clobber (reg:CC FLAGS_REG))]
6440   "TARGET_64BIT"
6441 {
6442   switch (get_attr_type (insn))
6443     {
6444     case TYPE_INCDEC:
6445       if (operands[2] == const1_rtx)
6446         return "inc{b}\t%h0";
6447       else
6448         {
6449           gcc_assert (operands[2] == constm1_rtx);
6450           return "dec{b}\t%h0";
6451         }
6452
6453     default:
6454       return "add{b}\t{%2, %h0|%h0, %2}";
6455     }
6456 }
6457   [(set (attr "type")
6458      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6459         (const_string "incdec")
6460         (const_string "alu")))
6461    (set_attr "modrm" "1")
6462    (set_attr "mode" "QI")])
6463
6464 (define_insn "addqi_ext_1"
6465   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6466                          (const_int 8)
6467                          (const_int 8))
6468         (plus:SI
6469           (zero_extract:SI
6470             (match_operand 1 "ext_register_operand" "0")
6471             (const_int 8)
6472             (const_int 8))
6473           (match_operand:QI 2 "general_operand" "Qmn")))
6474    (clobber (reg:CC FLAGS_REG))]
6475   "!TARGET_64BIT"
6476 {
6477   switch (get_attr_type (insn))
6478     {
6479     case TYPE_INCDEC:
6480       if (operands[2] == const1_rtx)
6481         return "inc{b}\t%h0";
6482       else
6483         {
6484           gcc_assert (operands[2] == constm1_rtx);
6485           return "dec{b}\t%h0";
6486         }
6487
6488     default:
6489       return "add{b}\t{%2, %h0|%h0, %2}";
6490     }
6491 }
6492   [(set (attr "type")
6493      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6494         (const_string "incdec")
6495         (const_string "alu")))
6496    (set_attr "modrm" "1")
6497    (set_attr "mode" "QI")])
6498
6499 (define_insn "*addqi_ext_2"
6500   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6501                          (const_int 8)
6502                          (const_int 8))
6503         (plus:SI
6504           (zero_extract:SI
6505             (match_operand 1 "ext_register_operand" "%0")
6506             (const_int 8)
6507             (const_int 8))
6508           (zero_extract:SI
6509             (match_operand 2 "ext_register_operand" "Q")
6510             (const_int 8)
6511             (const_int 8))))
6512    (clobber (reg:CC FLAGS_REG))]
6513   ""
6514   "add{b}\t{%h2, %h0|%h0, %h2}"
6515   [(set_attr "type" "alu")
6516    (set_attr "mode" "QI")])
6517
6518 ;; The lea patterns for non-Pmodes needs to be matched by
6519 ;; several insns converted to real lea by splitters.
6520
6521 (define_insn_and_split "*lea_general_1"
6522   [(set (match_operand 0 "register_operand" "=r")
6523         (plus (plus (match_operand 1 "index_register_operand" "l")
6524                     (match_operand 2 "register_operand" "r"))
6525               (match_operand 3 "immediate_operand" "i")))]
6526   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6527     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6528    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6529    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6530    && GET_MODE (operands[0]) == GET_MODE (operands[2])
6531    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6532        || GET_MODE (operands[3]) == VOIDmode)"
6533   "#"
6534   "&& reload_completed"
6535   [(const_int 0)]
6536 {
6537   rtx pat;
6538   operands[0] = gen_lowpart (SImode, operands[0]);
6539   operands[1] = gen_lowpart (Pmode, operands[1]);
6540   operands[2] = gen_lowpart (Pmode, operands[2]);
6541   operands[3] = gen_lowpart (Pmode, operands[3]);
6542   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
6543                       operands[3]);
6544   if (Pmode != SImode)
6545     pat = gen_rtx_SUBREG (SImode, pat, 0);
6546   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6547   DONE;
6548 }
6549   [(set_attr "type" "lea")
6550    (set_attr "mode" "SI")])
6551
6552 (define_insn_and_split "*lea_general_1_zext"
6553   [(set (match_operand:DI 0 "register_operand" "=r")
6554         (zero_extend:DI
6555           (plus:SI (plus:SI
6556                      (match_operand:SI 1 "index_register_operand" "l")
6557                      (match_operand:SI 2 "register_operand" "r"))
6558                    (match_operand:SI 3 "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 (match_dup 1)
6564                                                      (match_dup 2))
6565                                             (match_dup 3)) 0)))]
6566 {
6567   operands[1] = gen_lowpart (Pmode, operands[1]);
6568   operands[2] = gen_lowpart (Pmode, operands[2]);
6569   operands[3] = gen_lowpart (Pmode, operands[3]);
6570 }
6571   [(set_attr "type" "lea")
6572    (set_attr "mode" "SI")])
6573
6574 (define_insn_and_split "*lea_general_2"
6575   [(set (match_operand 0 "register_operand" "=r")
6576         (plus (mult (match_operand 1 "index_register_operand" "l")
6577                     (match_operand 2 "const248_operand" "i"))
6578               (match_operand 3 "nonmemory_operand" "ri")))]
6579   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6580     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6581    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6582    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6583    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6584        || GET_MODE (operands[3]) == VOIDmode)"
6585   "#"
6586   "&& reload_completed"
6587   [(const_int 0)]
6588 {
6589   rtx pat;
6590   operands[0] = gen_lowpart (SImode, operands[0]);
6591   operands[1] = gen_lowpart (Pmode, operands[1]);
6592   operands[3] = gen_lowpart (Pmode, operands[3]);
6593   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
6594                       operands[3]);
6595   if (Pmode != SImode)
6596     pat = gen_rtx_SUBREG (SImode, pat, 0);
6597   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6598   DONE;
6599 }
6600   [(set_attr "type" "lea")
6601    (set_attr "mode" "SI")])
6602
6603 (define_insn_and_split "*lea_general_2_zext"
6604   [(set (match_operand:DI 0 "register_operand" "=r")
6605         (zero_extend:DI
6606           (plus:SI (mult:SI
6607                      (match_operand:SI 1 "index_register_operand" "l")
6608                      (match_operand:SI 2 "const248_operand" "n"))
6609                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
6610   "TARGET_64BIT"
6611   "#"
6612   "&& reload_completed"
6613   [(set (match_dup 0)
6614         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
6615                                                      (match_dup 2))
6616                                             (match_dup 3)) 0)))]
6617 {
6618   operands[1] = gen_lowpart (Pmode, operands[1]);
6619   operands[3] = gen_lowpart (Pmode, operands[3]);
6620 }
6621   [(set_attr "type" "lea")
6622    (set_attr "mode" "SI")])
6623
6624 (define_insn_and_split "*lea_general_3"
6625   [(set (match_operand 0 "register_operand" "=r")
6626         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6627                           (match_operand 2 "const248_operand" "i"))
6628                     (match_operand 3 "register_operand" "r"))
6629               (match_operand 4 "immediate_operand" "i")))]
6630   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6631     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6632    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6633    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6634    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6635   "#"
6636   "&& reload_completed"
6637   [(const_int 0)]
6638 {
6639   rtx pat;
6640   operands[0] = gen_lowpart (SImode, operands[0]);
6641   operands[1] = gen_lowpart (Pmode, operands[1]);
6642   operands[3] = gen_lowpart (Pmode, operands[3]);
6643   operands[4] = gen_lowpart (Pmode, operands[4]);
6644   pat = gen_rtx_PLUS (Pmode,
6645                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
6646                                                          operands[2]),
6647                                     operands[3]),
6648                       operands[4]);
6649   if (Pmode != SImode)
6650     pat = gen_rtx_SUBREG (SImode, pat, 0);
6651   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6652   DONE;
6653 }
6654   [(set_attr "type" "lea")
6655    (set_attr "mode" "SI")])
6656
6657 (define_insn_and_split "*lea_general_3_zext"
6658   [(set (match_operand:DI 0 "register_operand" "=r")
6659         (zero_extend:DI
6660           (plus:SI (plus:SI
6661                      (mult:SI
6662                        (match_operand:SI 1 "index_register_operand" "l")
6663                        (match_operand:SI 2 "const248_operand" "n"))
6664                      (match_operand:SI 3 "register_operand" "r"))
6665                    (match_operand:SI 4 "immediate_operand" "i"))))]
6666   "TARGET_64BIT"
6667   "#"
6668   "&& reload_completed"
6669   [(set (match_dup 0)
6670         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
6671                                                               (match_dup 2))
6672                                                      (match_dup 3))
6673                                             (match_dup 4)) 0)))]
6674 {
6675   operands[1] = gen_lowpart (Pmode, operands[1]);
6676   operands[3] = gen_lowpart (Pmode, operands[3]);
6677   operands[4] = gen_lowpart (Pmode, operands[4]);
6678 }
6679   [(set_attr "type" "lea")
6680    (set_attr "mode" "SI")])
6681
6682 ;; Convert lea to the lea pattern to avoid flags dependency.
6683 (define_split
6684   [(set (match_operand:DI 0 "register_operand" "")
6685         (plus:DI (match_operand:DI 1 "register_operand" "")
6686                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
6687    (clobber (reg:CC FLAGS_REG))]
6688   "TARGET_64BIT && reload_completed 
6689    && ix86_lea_for_add_ok (insn, operands)"
6690   [(set (match_dup 0)
6691         (plus:DI (match_dup 1)
6692                  (match_dup 2)))]
6693   "")
6694
6695 ;; Convert lea to the lea pattern to avoid flags dependency.
6696 (define_split
6697   [(set (match_operand 0 "register_operand" "")
6698         (plus (match_operand 1 "register_operand" "")
6699               (match_operand 2 "nonmemory_operand" "")))
6700    (clobber (reg:CC FLAGS_REG))]
6701   "reload_completed && ix86_lea_for_add_ok (insn, operands)" 
6702   [(const_int 0)]
6703 {
6704   rtx pat;
6705   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
6706      may confuse gen_lowpart.  */
6707   if (GET_MODE (operands[0]) != Pmode)
6708     {
6709       operands[1] = gen_lowpart (Pmode, operands[1]);
6710       operands[2] = gen_lowpart (Pmode, operands[2]);
6711     }
6712   operands[0] = gen_lowpart (SImode, operands[0]);
6713   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
6714   if (Pmode != SImode)
6715     pat = gen_rtx_SUBREG (SImode, pat, 0);
6716   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6717   DONE;
6718 })
6719
6720 ;; Convert lea to the lea pattern to avoid flags dependency.
6721 (define_split
6722   [(set (match_operand:DI 0 "register_operand" "")
6723         (zero_extend:DI
6724           (plus:SI (match_operand:SI 1 "register_operand" "")
6725                    (match_operand:SI 2 "nonmemory_operand" ""))))
6726    (clobber (reg:CC FLAGS_REG))]
6727   "TARGET_64BIT && reload_completed
6728    && true_regnum (operands[0]) != true_regnum (operands[1])"
6729   [(set (match_dup 0)
6730         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
6731 {
6732   operands[1] = gen_lowpart (Pmode, operands[1]);
6733   operands[2] = gen_lowpart (Pmode, operands[2]);
6734 })
6735 \f
6736 ;; Subtract instructions
6737
6738 (define_expand "sub<mode>3"
6739   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
6740         (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6741                      (match_operand:SDWIM 2 "<general_operand>" "")))]
6742   ""
6743   "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6744
6745 (define_insn_and_split "*sub<dwi>3_doubleword"
6746   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6747         (minus:<DWI>
6748           (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6749           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6750    (clobber (reg:CC FLAGS_REG))]
6751   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6752   "#"
6753   "reload_completed"
6754   [(parallel [(set (reg:CC FLAGS_REG)
6755                    (compare:CC (match_dup 1) (match_dup 2)))
6756               (set (match_dup 0)
6757                    (minus:DWIH (match_dup 1) (match_dup 2)))])
6758    (parallel [(set (match_dup 3)
6759                    (minus:DWIH
6760                      (match_dup 4)
6761                      (plus:DWIH
6762                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6763                        (match_dup 5))))
6764               (clobber (reg:CC FLAGS_REG))])]
6765   "split_<dwi> (&operands[0], 3, &operands[0], &operands[3]);")
6766
6767 (define_insn "*sub<mode>_1"
6768   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6769         (minus:SWI
6770           (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6771           (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6772    (clobber (reg:CC FLAGS_REG))]
6773   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6774   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6775   [(set_attr "type" "alu")
6776    (set_attr "mode" "<MODE>")])
6777
6778 (define_insn "*subsi_1_zext"
6779   [(set (match_operand:DI 0 "register_operand" "=r")
6780         (zero_extend:DI
6781           (minus:SI (match_operand:SI 1 "register_operand" "0")
6782                     (match_operand:SI 2 "general_operand" "g"))))
6783    (clobber (reg:CC FLAGS_REG))]
6784   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6785   "sub{l}\t{%2, %k0|%k0, %2}"
6786   [(set_attr "type" "alu")
6787    (set_attr "mode" "SI")])
6788
6789 (define_insn "*subqi_1_slp"
6790   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6791         (minus:QI (match_dup 0)
6792                   (match_operand:QI 1 "general_operand" "qn,qm")))
6793    (clobber (reg:CC FLAGS_REG))]
6794   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6795    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6796   "sub{b}\t{%1, %0|%0, %1}"
6797   [(set_attr "type" "alu1")
6798    (set_attr "mode" "QI")])
6799
6800 (define_insn "*sub<mode>_2"
6801   [(set (reg FLAGS_REG)
6802         (compare
6803           (minus:SWI
6804             (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6805             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6806           (const_int 0)))
6807    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6808         (minus:SWI (match_dup 1) (match_dup 2)))]
6809   "ix86_match_ccmode (insn, CCGOCmode)
6810    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6811   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6812   [(set_attr "type" "alu")
6813    (set_attr "mode" "<MODE>")])
6814
6815 (define_insn "*subsi_2_zext"
6816   [(set (reg FLAGS_REG)
6817         (compare
6818           (minus:SI (match_operand:SI 1 "register_operand" "0")
6819                     (match_operand:SI 2 "general_operand" "g"))
6820           (const_int 0)))
6821    (set (match_operand:DI 0 "register_operand" "=r")
6822         (zero_extend:DI
6823           (minus:SI (match_dup 1)
6824                     (match_dup 2))))]
6825   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6826    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6827   "sub{l}\t{%2, %k0|%k0, %2}"
6828   [(set_attr "type" "alu")
6829    (set_attr "mode" "SI")])
6830
6831 (define_insn "*sub<mode>_3"
6832   [(set (reg FLAGS_REG)
6833         (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6834                  (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6835    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6836         (minus:SWI (match_dup 1) (match_dup 2)))]
6837   "ix86_match_ccmode (insn, CCmode)
6838    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6839   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6840   [(set_attr "type" "alu")
6841    (set_attr "mode" "<MODE>")])
6842
6843 (define_insn "*subsi_3_zext"
6844   [(set (reg FLAGS_REG)
6845         (compare (match_operand:SI 1 "register_operand" "0")
6846                  (match_operand:SI 2 "general_operand" "g")))
6847    (set (match_operand:DI 0 "register_operand" "=r")
6848         (zero_extend:DI
6849           (minus:SI (match_dup 1)
6850                     (match_dup 2))))]
6851   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6852    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6853   "sub{l}\t{%2, %1|%1, %2}"
6854   [(set_attr "type" "alu")
6855    (set_attr "mode" "SI")])
6856 \f
6857 ;; Add with carry and subtract with borrow
6858
6859 (define_expand "<plusminus_insn><mode>3_carry"
6860   [(parallel
6861     [(set (match_operand:SWI 0 "nonimmediate_operand" "")
6862           (plusminus:SWI
6863             (match_operand:SWI 1 "nonimmediate_operand" "")
6864             (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6865                        [(match_operand 3 "flags_reg_operand" "")
6866                         (const_int 0)])
6867                       (match_operand:SWI 2 "<general_operand>" ""))))
6868      (clobber (reg:CC FLAGS_REG))])]
6869   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6870   "")
6871
6872 (define_insn "*<plusminus_insn><mode>3_carry"
6873   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6874         (plusminus:SWI
6875           (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6876           (plus:SWI
6877             (match_operator 3 "ix86_carry_flag_operator"
6878              [(reg FLAGS_REG) (const_int 0)])
6879             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6880    (clobber (reg:CC FLAGS_REG))]
6881   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6882   "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6883   [(set_attr "type" "alu")
6884    (set_attr "use_carry" "1")
6885    (set_attr "pent_pair" "pu")
6886    (set_attr "mode" "<MODE>")])
6887
6888 (define_insn "*addsi3_carry_zext"
6889   [(set (match_operand:DI 0 "register_operand" "=r")
6890         (zero_extend:DI
6891           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6892                    (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6893                              [(reg FLAGS_REG) (const_int 0)])
6894                             (match_operand:SI 2 "general_operand" "g")))))
6895    (clobber (reg:CC FLAGS_REG))]
6896   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6897   "adc{l}\t{%2, %k0|%k0, %2}"
6898   [(set_attr "type" "alu")
6899    (set_attr "use_carry" "1")
6900    (set_attr "pent_pair" "pu")
6901    (set_attr "mode" "SI")])
6902
6903 (define_insn "*subsi3_carry_zext"
6904   [(set (match_operand:DI 0 "register_operand" "=r")
6905         (zero_extend:DI
6906           (minus:SI (match_operand:SI 1 "register_operand" "0")
6907                     (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6908                               [(reg FLAGS_REG) (const_int 0)])
6909                              (match_operand:SI 2 "general_operand" "g")))))
6910    (clobber (reg:CC FLAGS_REG))]
6911   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6912   "sbb{l}\t{%2, %k0|%k0, %2}"
6913   [(set_attr "type" "alu")
6914    (set_attr "pent_pair" "pu")
6915    (set_attr "mode" "SI")])
6916 \f
6917 ;; Overflow setting add and subtract instructions
6918
6919 (define_insn "*add<mode>3_cconly_overflow"
6920   [(set (reg:CCC FLAGS_REG)
6921         (compare:CCC
6922           (plus:SWI
6923             (match_operand:SWI 1 "nonimmediate_operand" "%0")
6924             (match_operand:SWI 2 "<general_operand>" "<g>"))
6925           (match_dup 1)))
6926    (clobber (match_scratch:SWI 0 "=<r>"))]
6927   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6928   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6929   [(set_attr "type" "alu")
6930    (set_attr "mode" "<MODE>")])
6931
6932 (define_insn "*sub<mode>3_cconly_overflow"
6933   [(set (reg:CCC FLAGS_REG)
6934         (compare:CCC
6935           (minus:SWI
6936             (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6937             (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6938           (match_dup 0)))]
6939   ""
6940   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6941   [(set_attr "type" "icmp")
6942    (set_attr "mode" "<MODE>")])
6943
6944 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6945   [(set (reg:CCC FLAGS_REG)
6946         (compare:CCC
6947             (plusminus:SWI
6948                 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6949                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6950             (match_dup 1)))
6951    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6952         (plusminus:SWI (match_dup 1) (match_dup 2)))]
6953   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6954   "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6955   [(set_attr "type" "alu")
6956    (set_attr "mode" "<MODE>")])
6957
6958 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6959   [(set (reg:CCC FLAGS_REG)
6960         (compare:CCC
6961           (plusminus:SI
6962             (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6963             (match_operand:SI 2 "general_operand" "g"))
6964           (match_dup 1)))
6965    (set (match_operand:DI 0 "register_operand" "=r")
6966         (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6967   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6968   "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6969   [(set_attr "type" "alu")
6970    (set_attr "mode" "SI")])
6971
6972 ;; The patterns that match these are at the end of this file.
6973
6974 (define_expand "<plusminus_insn>xf3"
6975   [(set (match_operand:XF 0 "register_operand" "")
6976         (plusminus:XF
6977           (match_operand:XF 1 "register_operand" "")
6978           (match_operand:XF 2 "register_operand" "")))]
6979   "TARGET_80387"
6980   "")
6981
6982 (define_expand "<plusminus_insn><mode>3"
6983   [(set (match_operand:MODEF 0 "register_operand" "")
6984         (plusminus:MODEF
6985           (match_operand:MODEF 1 "register_operand" "")
6986           (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6987   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6988     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
6989   "")
6990 \f
6991 ;; Multiply instructions
6992
6993 (define_expand "mul<mode>3"
6994   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
6995                    (mult:SWIM248
6996                      (match_operand:SWIM248 1 "register_operand" "")
6997                      (match_operand:SWIM248 2 "<general_operand>" "")))
6998               (clobber (reg:CC FLAGS_REG))])]
6999   ""
7000   "")
7001
7002 (define_expand "mulqi3"
7003   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7004                    (mult:QI
7005                      (match_operand:QI 1 "register_operand" "")
7006                      (match_operand:QI 2 "nonimmediate_operand" "")))
7007               (clobber (reg:CC FLAGS_REG))])]
7008   "TARGET_QIMODE_MATH"
7009   "")
7010
7011 ;; On AMDFAM10
7012 ;; IMUL reg32/64, reg32/64, imm8        Direct
7013 ;; IMUL reg32/64, mem32/64, imm8        VectorPath
7014 ;; IMUL reg32/64, reg32/64, imm32       Direct
7015 ;; IMUL reg32/64, mem32/64, imm32       VectorPath
7016 ;; IMUL reg32/64, reg32/64              Direct
7017 ;; IMUL reg32/64, mem32/64              Direct
7018
7019 (define_insn "*mul<mode>3_1"
7020   [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
7021         (mult:SWI48
7022           (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
7023           (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
7024    (clobber (reg:CC FLAGS_REG))]
7025   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7026   "@
7027    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7028    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7029    imul{<imodesuffix>}\t{%2, %0|%0, %2}"
7030   [(set_attr "type" "imul")
7031    (set_attr "prefix_0f" "0,0,1")
7032    (set (attr "athlon_decode")
7033         (cond [(eq_attr "cpu" "athlon")
7034                   (const_string "vector")
7035                (eq_attr "alternative" "1")
7036                   (const_string "vector")
7037                (and (eq_attr "alternative" "2")
7038                     (match_operand 1 "memory_operand" ""))
7039                   (const_string "vector")]
7040               (const_string "direct")))
7041    (set (attr "amdfam10_decode")
7042         (cond [(and (eq_attr "alternative" "0,1")
7043                     (match_operand 1 "memory_operand" ""))
7044                   (const_string "vector")]
7045               (const_string "direct")))
7046    (set_attr "mode" "<MODE>")])
7047
7048 (define_insn "*mulsi3_1_zext"
7049   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7050         (zero_extend:DI
7051           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7052                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
7053    (clobber (reg:CC FLAGS_REG))]
7054   "TARGET_64BIT
7055    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7056   "@
7057    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7058    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7059    imul{l}\t{%2, %k0|%k0, %2}"
7060   [(set_attr "type" "imul")
7061    (set_attr "prefix_0f" "0,0,1")
7062    (set (attr "athlon_decode")
7063         (cond [(eq_attr "cpu" "athlon")
7064                   (const_string "vector")
7065                (eq_attr "alternative" "1")
7066                   (const_string "vector")
7067                (and (eq_attr "alternative" "2")
7068                     (match_operand 1 "memory_operand" ""))
7069                   (const_string "vector")]
7070               (const_string "direct")))
7071    (set (attr "amdfam10_decode")
7072         (cond [(and (eq_attr "alternative" "0,1")
7073                     (match_operand 1 "memory_operand" ""))
7074                   (const_string "vector")]
7075               (const_string "direct")))
7076    (set_attr "mode" "SI")])
7077
7078 ;; On AMDFAM10
7079 ;; IMUL reg16, reg16, imm8      VectorPath
7080 ;; IMUL reg16, mem16, imm8      VectorPath
7081 ;; IMUL reg16, reg16, imm16     VectorPath
7082 ;; IMUL reg16, mem16, imm16     VectorPath
7083 ;; IMUL reg16, reg16            Direct
7084 ;; IMUL reg16, mem16            Direct
7085
7086 (define_insn "*mulhi3_1"
7087   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7088         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7089                  (match_operand:HI 2 "general_operand" "K,n,mr")))
7090    (clobber (reg:CC FLAGS_REG))]
7091   "TARGET_HIMODE_MATH
7092    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7093   "@
7094    imul{w}\t{%2, %1, %0|%0, %1, %2}
7095    imul{w}\t{%2, %1, %0|%0, %1, %2}
7096    imul{w}\t{%2, %0|%0, %2}"
7097   [(set_attr "type" "imul")
7098    (set_attr "prefix_0f" "0,0,1")
7099    (set (attr "athlon_decode")
7100         (cond [(eq_attr "cpu" "athlon")
7101                   (const_string "vector")
7102                (eq_attr "alternative" "1,2")
7103                   (const_string "vector")]
7104               (const_string "direct")))
7105    (set (attr "amdfam10_decode")
7106         (cond [(eq_attr "alternative" "0,1")
7107                   (const_string "vector")]
7108               (const_string "direct")))
7109    (set_attr "mode" "HI")])
7110
7111 ;;On AMDFAM10
7112 ;; MUL reg8     Direct
7113 ;; MUL mem8     Direct
7114
7115 (define_insn "*mulqi3_1"
7116   [(set (match_operand:QI 0 "register_operand" "=a")
7117         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7118                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7119    (clobber (reg:CC FLAGS_REG))]
7120   "TARGET_QIMODE_MATH
7121    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7122   "mul{b}\t%2"
7123   [(set_attr "type" "imul")
7124    (set_attr "length_immediate" "0")
7125    (set (attr "athlon_decode")
7126      (if_then_else (eq_attr "cpu" "athlon")
7127         (const_string "vector")
7128         (const_string "direct")))
7129    (set_attr "amdfam10_decode" "direct")
7130    (set_attr "mode" "QI")])
7131
7132 (define_expand "<u>mul<mode><dwi>3"
7133   [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
7134                    (mult:<DWI>
7135                      (any_extend:<DWI>
7136                        (match_operand:DWIH 1 "nonimmediate_operand" ""))
7137                      (any_extend:<DWI>
7138                        (match_operand:DWIH 2 "register_operand" ""))))
7139               (clobber (reg:CC FLAGS_REG))])]
7140   ""
7141   "")
7142
7143 (define_expand "<u>mulqihi3"
7144   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7145                    (mult:HI
7146                      (any_extend:HI
7147                        (match_operand:QI 1 "nonimmediate_operand" ""))
7148                      (any_extend:HI
7149                        (match_operand:QI 2 "register_operand" ""))))
7150               (clobber (reg:CC FLAGS_REG))])]
7151   "TARGET_QIMODE_MATH"
7152   "")
7153
7154 (define_insn "*<u>mul<mode><dwi>3_1"
7155   [(set (match_operand:<DWI> 0 "register_operand" "=A")
7156         (mult:<DWI>
7157           (any_extend:<DWI>
7158             (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
7159           (any_extend:<DWI>
7160             (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7161    (clobber (reg:CC FLAGS_REG))]
7162   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7163   "<sgnprefix>mul{<imodesuffix>}\t%2"
7164   [(set_attr "type" "imul")
7165    (set_attr "length_immediate" "0")
7166    (set (attr "athlon_decode")
7167      (if_then_else (eq_attr "cpu" "athlon")
7168         (const_string "vector")
7169         (const_string "double")))
7170    (set_attr "amdfam10_decode" "double")
7171    (set_attr "mode" "<MODE>")])
7172
7173 (define_insn "*<u>mulqihi3_1"
7174   [(set (match_operand:HI 0 "register_operand" "=a")
7175         (mult:HI
7176           (any_extend:HI
7177             (match_operand:QI 1 "nonimmediate_operand" "%0"))
7178           (any_extend:HI
7179             (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7180    (clobber (reg:CC FLAGS_REG))]
7181   "TARGET_QIMODE_MATH
7182    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7183   "<sgnprefix>mul{b}\t%2"
7184   [(set_attr "type" "imul")
7185    (set_attr "length_immediate" "0")
7186    (set (attr "athlon_decode")
7187      (if_then_else (eq_attr "cpu" "athlon")
7188         (const_string "vector")
7189         (const_string "direct")))
7190    (set_attr "amdfam10_decode" "direct")
7191    (set_attr "mode" "QI")])
7192
7193 (define_expand "<s>mul<mode>3_highpart"
7194   [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
7195                    (truncate:SWI48
7196                      (lshiftrt:<DWI>
7197                        (mult:<DWI>
7198                          (any_extend:<DWI>
7199                            (match_operand:SWI48 1 "nonimmediate_operand" ""))
7200                          (any_extend:<DWI>
7201                            (match_operand:SWI48 2 "register_operand" "")))
7202                        (match_dup 4))))
7203               (clobber (match_scratch:SWI48 3 ""))
7204               (clobber (reg:CC FLAGS_REG))])]
7205   ""
7206   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7207
7208 (define_insn "*<s>muldi3_highpart_1"
7209   [(set (match_operand:DI 0 "register_operand" "=d")
7210         (truncate:DI
7211           (lshiftrt:TI
7212             (mult:TI
7213               (any_extend:TI
7214                 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7215               (any_extend:TI
7216                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7217             (const_int 64))))
7218    (clobber (match_scratch:DI 3 "=1"))
7219    (clobber (reg:CC FLAGS_REG))]
7220   "TARGET_64BIT
7221    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7222   "<sgnprefix>mul{q}\t%2"
7223   [(set_attr "type" "imul")
7224    (set_attr "length_immediate" "0")
7225    (set (attr "athlon_decode")
7226      (if_then_else (eq_attr "cpu" "athlon")
7227         (const_string "vector")
7228         (const_string "double")))
7229    (set_attr "amdfam10_decode" "double")
7230    (set_attr "mode" "DI")])
7231
7232 (define_insn "*<s>mulsi3_highpart_1"
7233   [(set (match_operand:SI 0 "register_operand" "=d")
7234         (truncate:SI
7235           (lshiftrt:DI
7236             (mult:DI
7237               (any_extend:DI
7238                 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7239               (any_extend:DI
7240                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7241             (const_int 32))))
7242    (clobber (match_scratch:SI 3 "=1"))
7243    (clobber (reg:CC FLAGS_REG))]
7244   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7245   "<sgnprefix>mul{l}\t%2"
7246   [(set_attr "type" "imul")
7247    (set_attr "length_immediate" "0")
7248    (set (attr "athlon_decode")
7249      (if_then_else (eq_attr "cpu" "athlon")
7250         (const_string "vector")
7251         (const_string "double")))
7252    (set_attr "amdfam10_decode" "double")
7253    (set_attr "mode" "SI")])
7254
7255 (define_insn "*<s>mulsi3_highpart_zext"
7256   [(set (match_operand:DI 0 "register_operand" "=d")
7257         (zero_extend:DI (truncate:SI
7258           (lshiftrt:DI
7259             (mult:DI (any_extend:DI
7260                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7261                      (any_extend:DI
7262                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7263             (const_int 32)))))
7264    (clobber (match_scratch:SI 3 "=1"))
7265    (clobber (reg:CC FLAGS_REG))]
7266   "TARGET_64BIT
7267    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7268   "<sgnprefix>mul{l}\t%2"
7269   [(set_attr "type" "imul")
7270    (set_attr "length_immediate" "0")
7271    (set (attr "athlon_decode")
7272      (if_then_else (eq_attr "cpu" "athlon")
7273         (const_string "vector")
7274         (const_string "double")))
7275    (set_attr "amdfam10_decode" "double")
7276    (set_attr "mode" "SI")])
7277
7278 ;; The patterns that match these are at the end of this file.
7279
7280 (define_expand "mulxf3"
7281   [(set (match_operand:XF 0 "register_operand" "")
7282         (mult:XF (match_operand:XF 1 "register_operand" "")
7283                  (match_operand:XF 2 "register_operand" "")))]
7284   "TARGET_80387"
7285   "")
7286
7287 (define_expand "mul<mode>3"
7288   [(set (match_operand:MODEF 0 "register_operand" "")
7289         (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
7290                     (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7291   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7292     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7293   "")
7294 \f
7295 ;; Divide instructions
7296
7297 ;; The patterns that match these are at the end of this file.
7298
7299 (define_expand "divxf3"
7300   [(set (match_operand:XF 0 "register_operand" "")
7301         (div:XF (match_operand:XF 1 "register_operand" "")
7302                 (match_operand:XF 2 "register_operand" "")))]
7303   "TARGET_80387"
7304   "")
7305
7306 (define_expand "divdf3"
7307   [(set (match_operand:DF 0 "register_operand" "")
7308         (div:DF (match_operand:DF 1 "register_operand" "")
7309                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7310    "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7311     || (TARGET_SSE2 && TARGET_SSE_MATH)"
7312    "")
7313
7314 (define_expand "divsf3"
7315   [(set (match_operand:SF 0 "register_operand" "")
7316         (div:SF (match_operand:SF 1 "register_operand" "")
7317                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7318   "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7319     || TARGET_SSE_MATH"
7320 {
7321   if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
7322       && flag_finite_math_only && !flag_trapping_math
7323       && flag_unsafe_math_optimizations)
7324     {
7325       ix86_emit_swdivsf (operands[0], operands[1],
7326                          operands[2], SFmode);
7327       DONE;
7328     }
7329 })
7330 \f
7331 ;; Divmod instructions.
7332
7333 (define_expand "divmodqi4"
7334   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7335                    (div:QI
7336                      (match_operand:QI 1 "register_operand" "")
7337                      (match_operand:QI 2 "nonimmediate_operand" "")))
7338               (set (match_operand:QI 3 "register_operand" "")
7339                    (mod:QI (match_dup 1) (match_dup 2)))
7340               (clobber (reg:CC FLAGS_REG))])]
7341   "TARGET_QIMODE_MATH"
7342 {
7343   rtx div, mod, insn;
7344   rtx tmp0, tmp1;
7345   
7346   tmp0 = gen_reg_rtx (HImode);
7347   tmp1 = gen_reg_rtx (HImode);
7348
7349   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is
7350      in AX.  */
7351   emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7352   emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7353
7354   /* Extract remainder from AH.  */
7355   tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7356   insn = emit_move_insn (operands[3], tmp1);
7357
7358   mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7359   set_unique_reg_note (insn, REG_EQUAL, mod);
7360
7361   /* Extract quotient from AL.  */
7362   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7363
7364   div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7365   set_unique_reg_note (insn, REG_EQUAL, div);
7366
7367   DONE;
7368 })
7369
7370 (define_expand "udivmodqi4"
7371   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7372                    (udiv:QI
7373                      (match_operand:QI 1 "register_operand" "")
7374                      (match_operand:QI 2 "nonimmediate_operand" "")))
7375               (set (match_operand:QI 3 "register_operand" "")
7376                    (umod:QI (match_dup 1) (match_dup 2)))
7377               (clobber (reg:CC FLAGS_REG))])]
7378   "TARGET_QIMODE_MATH"
7379 {
7380   rtx div, mod, insn;
7381   rtx tmp0, tmp1;
7382   
7383   tmp0 = gen_reg_rtx (HImode);
7384   tmp1 = gen_reg_rtx (HImode);
7385
7386   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is
7387      in AX.  */
7388   emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7389   emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7390
7391   /* Extract remainder from AH.  */
7392   tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7393   tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7394   insn = emit_move_insn (operands[3], tmp1);
7395
7396   mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7397   set_unique_reg_note (insn, REG_EQUAL, mod);
7398
7399   /* Extract quotient from AL.  */
7400   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7401
7402   div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7403   set_unique_reg_note (insn, REG_EQUAL, div);
7404
7405   DONE;
7406 })
7407
7408 ;; Divide AX by r/m8, with result stored in
7409 ;; AL <- Quotient
7410 ;; AH <- Remainder
7411 ;; Change div/mod to HImode and extend the second argument to HImode
7412 ;; so that mode of div/mod matches with mode of arguments.  Otherwise
7413 ;; combine may fail.
7414 (define_insn "divmodhiqi3"
7415   [(set (match_operand:HI 0 "register_operand" "=a")
7416         (ior:HI
7417           (ashift:HI
7418             (zero_extend:HI
7419               (truncate:QI
7420                 (mod:HI (match_operand:HI 1 "register_operand" "0")
7421                         (sign_extend:HI
7422                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7423             (const_int 8))
7424           (zero_extend:HI
7425             (truncate:QI
7426               (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7427    (clobber (reg:CC FLAGS_REG))]
7428   "TARGET_QIMODE_MATH"
7429   "idiv{b}\t%2"
7430   [(set_attr "type" "idiv")
7431    (set_attr "mode" "QI")])
7432
7433 (define_insn "udivmodhiqi3"
7434   [(set (match_operand:HI 0 "register_operand" "=a")
7435         (ior:HI
7436           (ashift:HI
7437             (zero_extend:HI
7438               (truncate:QI
7439                 (mod:HI (match_operand:HI 1 "register_operand" "0")
7440                         (zero_extend:HI
7441                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7442             (const_int 8))
7443           (zero_extend:HI
7444             (truncate:QI
7445               (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7446    (clobber (reg:CC FLAGS_REG))]
7447   "TARGET_QIMODE_MATH"
7448   "div{b}\t%2"
7449   [(set_attr "type" "idiv")
7450    (set_attr "mode" "QI")])
7451
7452 (define_expand "divmod<mode>4"
7453   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7454                    (div:SWIM248
7455                      (match_operand:SWIM248 1 "register_operand" "")
7456                      (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7457               (set (match_operand:SWIM248 3 "register_operand" "")
7458                    (mod:SWIM248 (match_dup 1) (match_dup 2)))
7459               (clobber (reg:CC FLAGS_REG))])]
7460   ""
7461   "")
7462
7463 (define_insn_and_split "*divmod<mode>4"
7464   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7465         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7466                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7467    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7468         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7469    (clobber (reg:CC FLAGS_REG))]
7470   ""
7471   "#"
7472   "reload_completed"
7473   [(parallel [(set (match_dup 1)
7474                    (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7475               (clobber (reg:CC FLAGS_REG))])
7476    (parallel [(set (match_dup 0)
7477                    (div:SWIM248 (match_dup 2) (match_dup 3)))
7478               (set (match_dup 1)
7479                    (mod:SWIM248 (match_dup 2) (match_dup 3)))
7480               (use (match_dup 1))
7481               (clobber (reg:CC FLAGS_REG))])]
7482 {
7483   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7484
7485   if (<MODE>mode != HImode
7486       && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7487     operands[4] = operands[2];
7488   else
7489     {
7490       /* Avoid use of cltd in favor of a mov+shift.  */
7491       emit_move_insn (operands[1], operands[2]);
7492       operands[4] = operands[1];
7493     }
7494 }
7495   [(set_attr "type" "multi")
7496    (set_attr "mode" "<MODE>")])
7497
7498 (define_insn "*divmod<mode>4_noext"
7499   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7500         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7501                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7502    (set (match_operand:SWIM248 1 "register_operand" "=d")
7503         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7504    (use (match_operand:SWIM248 4 "register_operand" "1"))
7505    (clobber (reg:CC FLAGS_REG))]
7506   ""
7507   "idiv{<imodesuffix>}\t%3"
7508   [(set_attr "type" "idiv")
7509    (set_attr "mode" "<MODE>")])
7510
7511 (define_expand "udivmod<mode>4"
7512   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7513                    (udiv:SWIM248
7514                      (match_operand:SWIM248 1 "register_operand" "")
7515                      (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7516               (set (match_operand:SWIM248 3 "register_operand" "")
7517                    (umod:SWIM248 (match_dup 1) (match_dup 2)))
7518               (clobber (reg:CC FLAGS_REG))])]
7519   ""
7520   "")
7521
7522 (define_insn_and_split "*udivmod<mode>4"
7523   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7524         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7525                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7526    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7527         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7528    (clobber (reg:CC FLAGS_REG))]
7529   ""
7530   "#"
7531   "reload_completed"
7532   [(set (match_dup 1) (const_int 0))
7533    (parallel [(set (match_dup 0)
7534                    (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7535               (set (match_dup 1)
7536                    (umod:SWIM248 (match_dup 2) (match_dup 3)))
7537               (use (match_dup 1))
7538               (clobber (reg:CC FLAGS_REG))])]
7539   ""
7540   [(set_attr "type" "multi")
7541    (set_attr "mode" "<MODE>")])
7542
7543 (define_insn "*udivmod<mode>4_noext"
7544   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7545         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7546                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7547    (set (match_operand:SWIM248 1 "register_operand" "=d")
7548         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7549    (use (match_operand:SWIM248 4 "register_operand" "1"))
7550    (clobber (reg:CC FLAGS_REG))]
7551   ""
7552   "div{<imodesuffix>}\t%3"
7553   [(set_attr "type" "idiv")
7554    (set_attr "mode" "<MODE>")])
7555
7556 ;; We cannot use div/idiv for double division, because it causes
7557 ;; "division by zero" on the overflow and that's not what we expect
7558 ;; from truncate.  Because true (non truncating) double division is
7559 ;; never generated, we can't create this insn anyway.
7560 ;
7561 ;(define_insn ""
7562 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7563 ;       (truncate:SI
7564 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7565 ;                  (zero_extend:DI
7566 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7567 ;   (set (match_operand:SI 3 "register_operand" "=d")
7568 ;       (truncate:SI
7569 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7570 ;   (clobber (reg:CC FLAGS_REG))]
7571 ;  ""
7572 ;  "div{l}\t{%2, %0|%0, %2}"
7573 ;  [(set_attr "type" "idiv")])
7574 \f
7575 ;;- Logical AND instructions
7576
7577 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7578 ;; Note that this excludes ah.
7579
7580 (define_expand "testsi_ccno_1"
7581   [(set (reg:CCNO FLAGS_REG)
7582         (compare:CCNO
7583           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7584                   (match_operand:SI 1 "nonmemory_operand" ""))
7585           (const_int 0)))]
7586   ""
7587   "")
7588
7589 (define_expand "testqi_ccz_1"
7590   [(set (reg:CCZ FLAGS_REG)
7591         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7592                              (match_operand:QI 1 "nonmemory_operand" ""))
7593                  (const_int 0)))]
7594   ""
7595   "")
7596
7597 (define_insn "*testdi_1"
7598   [(set (reg FLAGS_REG)
7599         (compare
7600          (and:DI
7601           (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7602           (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7603          (const_int 0)))]
7604   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7605    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7606   "@
7607    test{l}\t{%k1, %k0|%k0, %k1}
7608    test{l}\t{%k1, %k0|%k0, %k1}
7609    test{q}\t{%1, %0|%0, %1}
7610    test{q}\t{%1, %0|%0, %1}
7611    test{q}\t{%1, %0|%0, %1}"
7612   [(set_attr "type" "test")
7613    (set_attr "modrm" "0,1,0,1,1")
7614    (set_attr "mode" "SI,SI,DI,DI,DI")])
7615
7616 (define_insn "*testqi_1_maybe_si"
7617   [(set (reg FLAGS_REG)
7618         (compare
7619           (and:QI
7620             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7621             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7622           (const_int 0)))]
7623    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7624     && ix86_match_ccmode (insn,
7625                          CONST_INT_P (operands[1])
7626                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7627 {
7628   if (which_alternative == 3)
7629     {
7630       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7631         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7632       return "test{l}\t{%1, %k0|%k0, %1}";
7633     }
7634   return "test{b}\t{%1, %0|%0, %1}";
7635 }
7636   [(set_attr "type" "test")
7637    (set_attr "modrm" "0,1,1,1")
7638    (set_attr "mode" "QI,QI,QI,SI")
7639    (set_attr "pent_pair" "uv,np,uv,np")])
7640
7641 (define_insn "*test<mode>_1"
7642   [(set (reg FLAGS_REG)
7643         (compare
7644          (and:SWI124
7645           (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7646           (match_operand:SWI124 1 "general_operand" "<i>,<i>,<r><i>"))
7647          (const_int 0)))]
7648   "ix86_match_ccmode (insn, CCNOmode)
7649    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7650   "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7651   [(set_attr "type" "test")
7652    (set_attr "modrm" "0,1,1")
7653    (set_attr "mode" "<MODE>")
7654    (set_attr "pent_pair" "uv,np,uv")])
7655
7656 (define_expand "testqi_ext_ccno_0"
7657   [(set (reg:CCNO FLAGS_REG)
7658         (compare:CCNO
7659           (and:SI
7660             (zero_extract:SI
7661               (match_operand 0 "ext_register_operand" "")
7662               (const_int 8)
7663               (const_int 8))
7664             (match_operand 1 "const_int_operand" ""))
7665           (const_int 0)))]
7666   ""
7667   "")
7668
7669 (define_insn "*testqi_ext_0"
7670   [(set (reg FLAGS_REG)
7671         (compare
7672           (and:SI
7673             (zero_extract:SI
7674               (match_operand 0 "ext_register_operand" "Q")
7675               (const_int 8)
7676               (const_int 8))
7677             (match_operand 1 "const_int_operand" "n"))
7678           (const_int 0)))]
7679   "ix86_match_ccmode (insn, CCNOmode)"
7680   "test{b}\t{%1, %h0|%h0, %1}"
7681   [(set_attr "type" "test")
7682    (set_attr "mode" "QI")
7683    (set_attr "length_immediate" "1")
7684    (set_attr "modrm" "1")
7685    (set_attr "pent_pair" "np")])
7686
7687 (define_insn "*testqi_ext_1_rex64"
7688   [(set (reg FLAGS_REG)
7689         (compare
7690           (and:SI
7691             (zero_extract:SI
7692               (match_operand 0 "ext_register_operand" "Q")
7693               (const_int 8)
7694               (const_int 8))
7695             (zero_extend:SI
7696               (match_operand:QI 1 "register_operand" "Q")))
7697           (const_int 0)))]
7698   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7699   "test{b}\t{%1, %h0|%h0, %1}"
7700   [(set_attr "type" "test")
7701    (set_attr "mode" "QI")])
7702
7703 (define_insn "*testqi_ext_1"
7704   [(set (reg FLAGS_REG)
7705         (compare
7706           (and:SI
7707             (zero_extract:SI
7708               (match_operand 0 "ext_register_operand" "Q")
7709               (const_int 8)
7710               (const_int 8))
7711             (zero_extend:SI
7712               (match_operand:QI 1 "general_operand" "Qm")))
7713           (const_int 0)))]
7714   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7715   "test{b}\t{%1, %h0|%h0, %1}"
7716   [(set_attr "type" "test")
7717    (set_attr "mode" "QI")])
7718
7719 (define_insn "*testqi_ext_2"
7720   [(set (reg FLAGS_REG)
7721         (compare
7722           (and:SI
7723             (zero_extract:SI
7724               (match_operand 0 "ext_register_operand" "Q")
7725               (const_int 8)
7726               (const_int 8))
7727             (zero_extract:SI
7728               (match_operand 1 "ext_register_operand" "Q")
7729               (const_int 8)
7730               (const_int 8)))
7731           (const_int 0)))]
7732   "ix86_match_ccmode (insn, CCNOmode)"
7733   "test{b}\t{%h1, %h0|%h0, %h1}"
7734   [(set_attr "type" "test")
7735    (set_attr "mode" "QI")])
7736
7737 (define_insn "*testqi_ext_3_rex64"
7738   [(set (reg FLAGS_REG)
7739         (compare (zero_extract:DI
7740                    (match_operand 0 "nonimmediate_operand" "rm")
7741                    (match_operand:DI 1 "const_int_operand" "")
7742                    (match_operand:DI 2 "const_int_operand" ""))
7743                  (const_int 0)))]
7744   "TARGET_64BIT
7745    && ix86_match_ccmode (insn, CCNOmode)
7746    && INTVAL (operands[1]) > 0
7747    && INTVAL (operands[2]) >= 0
7748    /* Ensure that resulting mask is zero or sign extended operand.  */
7749    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7750        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7751            && INTVAL (operands[1]) > 32))
7752    && (GET_MODE (operands[0]) == SImode
7753        || GET_MODE (operands[0]) == DImode
7754        || GET_MODE (operands[0]) == HImode
7755        || GET_MODE (operands[0]) == QImode)"
7756   "#")
7757
7758 ;; Combine likes to form bit extractions for some tests.  Humor it.
7759 (define_insn "*testqi_ext_3"
7760   [(set (reg FLAGS_REG)
7761         (compare (zero_extract:SI
7762                    (match_operand 0 "nonimmediate_operand" "rm")
7763                    (match_operand:SI 1 "const_int_operand" "")
7764                    (match_operand:SI 2 "const_int_operand" ""))
7765                  (const_int 0)))]
7766   "ix86_match_ccmode (insn, CCNOmode)
7767    && INTVAL (operands[1]) > 0
7768    && INTVAL (operands[2]) >= 0
7769    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7770    && (GET_MODE (operands[0]) == SImode
7771        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7772        || GET_MODE (operands[0]) == HImode
7773        || GET_MODE (operands[0]) == QImode)"
7774   "#")
7775
7776 (define_split
7777   [(set (match_operand 0 "flags_reg_operand" "")
7778         (match_operator 1 "compare_operator"
7779           [(zero_extract
7780              (match_operand 2 "nonimmediate_operand" "")
7781              (match_operand 3 "const_int_operand" "")
7782              (match_operand 4 "const_int_operand" ""))
7783            (const_int 0)]))]
7784   "ix86_match_ccmode (insn, CCNOmode)"
7785   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7786 {
7787   rtx val = operands[2];
7788   HOST_WIDE_INT len = INTVAL (operands[3]);
7789   HOST_WIDE_INT pos = INTVAL (operands[4]);
7790   HOST_WIDE_INT mask;
7791   enum machine_mode mode, submode;
7792
7793   mode = GET_MODE (val);
7794   if (MEM_P (val))
7795     {
7796       /* ??? Combine likes to put non-volatile mem extractions in QImode
7797          no matter the size of the test.  So find a mode that works.  */
7798       if (! MEM_VOLATILE_P (val))
7799         {
7800           mode = smallest_mode_for_size (pos + len, MODE_INT);
7801           val = adjust_address (val, mode, 0);
7802         }
7803     }
7804   else if (GET_CODE (val) == SUBREG
7805            && (submode = GET_MODE (SUBREG_REG (val)),
7806                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7807            && pos + len <= GET_MODE_BITSIZE (submode)
7808            && GET_MODE_CLASS (submode) == MODE_INT)
7809     {
7810       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
7811       mode = submode;
7812       val = SUBREG_REG (val);
7813     }
7814   else if (mode == HImode && pos + len <= 8)
7815     {
7816       /* Small HImode tests can be converted to QImode.  */
7817       mode = QImode;
7818       val = gen_lowpart (QImode, val);
7819     }
7820
7821   if (len == HOST_BITS_PER_WIDE_INT)
7822     mask = -1;
7823   else
7824     mask = ((HOST_WIDE_INT)1 << len) - 1;
7825   mask <<= pos;
7826
7827   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7828 })
7829
7830 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7831 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7832 ;; this is relatively important trick.
7833 ;; Do the conversion only post-reload to avoid limiting of the register class
7834 ;; to QI regs.
7835 (define_split
7836   [(set (match_operand 0 "flags_reg_operand" "")
7837         (match_operator 1 "compare_operator"
7838           [(and (match_operand 2 "register_operand" "")
7839                 (match_operand 3 "const_int_operand" ""))
7840            (const_int 0)]))]
7841    "reload_completed
7842     && QI_REG_P (operands[2])
7843     && GET_MODE (operands[2]) != QImode
7844     && ((ix86_match_ccmode (insn, CCZmode)
7845          && !(INTVAL (operands[3]) & ~(255 << 8)))
7846         || (ix86_match_ccmode (insn, CCNOmode)
7847             && !(INTVAL (operands[3]) & ~(127 << 8))))"
7848   [(set (match_dup 0)
7849         (match_op_dup 1
7850           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7851                    (match_dup 3))
7852            (const_int 0)]))]
7853   "operands[2] = gen_lowpart (SImode, operands[2]);
7854    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7855
7856 (define_split
7857   [(set (match_operand 0 "flags_reg_operand" "")
7858         (match_operator 1 "compare_operator"
7859           [(and (match_operand 2 "nonimmediate_operand" "")
7860                 (match_operand 3 "const_int_operand" ""))
7861            (const_int 0)]))]
7862    "reload_completed
7863     && GET_MODE (operands[2]) != QImode
7864     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7865     && ((ix86_match_ccmode (insn, CCZmode)
7866          && !(INTVAL (operands[3]) & ~255))
7867         || (ix86_match_ccmode (insn, CCNOmode)
7868             && !(INTVAL (operands[3]) & ~127)))"
7869   [(set (match_dup 0)
7870         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7871                          (const_int 0)]))]
7872   "operands[2] = gen_lowpart (QImode, operands[2]);
7873    operands[3] = gen_lowpart (QImode, operands[3]);")
7874
7875 ;; %%% This used to optimize known byte-wide and operations to memory,
7876 ;; and sometimes to QImode registers.  If this is considered useful,
7877 ;; it should be done with splitters.
7878
7879 (define_expand "and<mode>3"
7880   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
7881         (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
7882                   (match_operand:SWIM 2 "<general_szext_operand>" "")))]
7883   ""
7884   "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
7885
7886 (define_insn "*anddi_1"
7887   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7888         (and:DI
7889          (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7890          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7891    (clobber (reg:CC FLAGS_REG))]
7892   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7893 {
7894   switch (get_attr_type (insn))
7895     {
7896     case TYPE_IMOVX:
7897       {
7898         enum machine_mode mode;
7899
7900         gcc_assert (CONST_INT_P (operands[2]));
7901         if (INTVAL (operands[2]) == 0xff)
7902           mode = QImode;
7903         else
7904           {
7905             gcc_assert (INTVAL (operands[2]) == 0xffff);
7906             mode = HImode;
7907           }
7908
7909         operands[1] = gen_lowpart (mode, operands[1]);
7910         if (mode == QImode)
7911           return "movz{bl|x}\t{%1, %k0|%k0, %1}";
7912         else
7913           return "movz{wl|x}\t{%1, %k0|%k0, %1}";
7914       }
7915
7916     default:
7917       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7918       if (get_attr_mode (insn) == MODE_SI)
7919         return "and{l}\t{%k2, %k0|%k0, %k2}";
7920       else
7921         return "and{q}\t{%2, %0|%0, %2}";
7922     }
7923 }
7924   [(set_attr "type" "alu,alu,alu,imovx")
7925    (set_attr "length_immediate" "*,*,*,0")
7926    (set (attr "prefix_rex")
7927      (if_then_else
7928        (and (eq_attr "type" "imovx")
7929             (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7930                  (match_operand 1 "ext_QIreg_nomode_operand" "")))
7931        (const_string "1")
7932        (const_string "*")))
7933    (set_attr "mode" "SI,DI,DI,SI")])
7934
7935 (define_insn "*andsi_1"
7936   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7937         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7938                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
7939    (clobber (reg:CC FLAGS_REG))]
7940   "ix86_binary_operator_ok (AND, SImode, operands)"
7941 {
7942   switch (get_attr_type (insn))
7943     {
7944     case TYPE_IMOVX:
7945       {
7946         enum machine_mode mode;
7947
7948         gcc_assert (CONST_INT_P (operands[2]));
7949         if (INTVAL (operands[2]) == 0xff)
7950           mode = QImode;
7951         else
7952           {
7953             gcc_assert (INTVAL (operands[2]) == 0xffff);
7954             mode = HImode;
7955           }
7956
7957         operands[1] = gen_lowpart (mode, operands[1]);
7958         if (mode == QImode)
7959           return "movz{bl|x}\t{%1, %0|%0, %1}";
7960         else
7961           return "movz{wl|x}\t{%1, %0|%0, %1}";
7962       }
7963
7964     default:
7965       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7966       return "and{l}\t{%2, %0|%0, %2}";
7967     }
7968 }
7969   [(set_attr "type" "alu,alu,imovx")
7970    (set (attr "prefix_rex")
7971      (if_then_else
7972        (and (eq_attr "type" "imovx")
7973             (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7974                  (match_operand 1 "ext_QIreg_nomode_operand" "")))
7975        (const_string "1")
7976        (const_string "*")))
7977    (set_attr "length_immediate" "*,*,0")
7978    (set_attr "mode" "SI")])
7979
7980 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7981 (define_insn "*andsi_1_zext"
7982   [(set (match_operand:DI 0 "register_operand" "=r")
7983         (zero_extend:DI
7984           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7985                   (match_operand:SI 2 "general_operand" "g"))))
7986    (clobber (reg:CC FLAGS_REG))]
7987   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7988   "and{l}\t{%2, %k0|%k0, %2}"
7989   [(set_attr "type" "alu")
7990    (set_attr "mode" "SI")])
7991
7992 (define_insn "*andhi_1"
7993   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
7994         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7995                 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7996    (clobber (reg:CC FLAGS_REG))]
7997   "ix86_binary_operator_ok (AND, HImode, operands)"
7998 {
7999   switch (get_attr_type (insn))
8000     {
8001     case TYPE_IMOVX:
8002       gcc_assert (CONST_INT_P (operands[2]));
8003       gcc_assert (INTVAL (operands[2]) == 0xff);
8004       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8005
8006     default:
8007       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8008
8009       return "and{w}\t{%2, %0|%0, %2}";
8010     }
8011 }
8012   [(set_attr "type" "alu,alu,imovx")
8013    (set_attr "length_immediate" "*,*,0")
8014    (set (attr "prefix_rex")
8015      (if_then_else
8016        (and (eq_attr "type" "imovx")
8017             (match_operand 1 "ext_QIreg_nomode_operand" ""))
8018        (const_string "1")
8019        (const_string "*")))
8020    (set_attr "mode" "HI,HI,SI")])
8021
8022 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8023 (define_insn "*andqi_1"
8024   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8025         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8026                 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
8027    (clobber (reg:CC FLAGS_REG))]
8028   "ix86_binary_operator_ok (AND, QImode, operands)"
8029   "@
8030    and{b}\t{%2, %0|%0, %2}
8031    and{b}\t{%2, %0|%0, %2}
8032    and{l}\t{%k2, %k0|%k0, %k2}"
8033   [(set_attr "type" "alu")
8034    (set_attr "mode" "QI,QI,SI")])
8035
8036 (define_insn "*andqi_1_slp"
8037   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8038         (and:QI (match_dup 0)
8039                 (match_operand:QI 1 "general_operand" "qn,qmn")))
8040    (clobber (reg:CC FLAGS_REG))]
8041   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8042    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8043   "and{b}\t{%1, %0|%0, %1}"
8044   [(set_attr "type" "alu1")
8045    (set_attr "mode" "QI")])
8046
8047 (define_split
8048   [(set (match_operand 0 "register_operand" "")
8049         (and (match_dup 0)
8050              (const_int -65536)))
8051    (clobber (reg:CC FLAGS_REG))]
8052   "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
8053     || optimize_function_for_size_p (cfun)"
8054   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8055   "operands[1] = gen_lowpart (HImode, operands[0]);")
8056
8057 (define_split
8058   [(set (match_operand 0 "ext_register_operand" "")
8059         (and (match_dup 0)
8060              (const_int -256)))
8061    (clobber (reg:CC FLAGS_REG))]
8062   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8063    && reload_completed"
8064   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8065   "operands[1] = gen_lowpart (QImode, operands[0]);")
8066
8067 (define_split
8068   [(set (match_operand 0 "ext_register_operand" "")
8069         (and (match_dup 0)
8070              (const_int -65281)))
8071    (clobber (reg:CC FLAGS_REG))]
8072   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8073    && reload_completed"
8074   [(parallel [(set (zero_extract:SI (match_dup 0)
8075                                     (const_int 8)
8076                                     (const_int 8))
8077                    (xor:SI
8078                      (zero_extract:SI (match_dup 0)
8079                                       (const_int 8)
8080                                       (const_int 8))
8081                      (zero_extract:SI (match_dup 0)
8082                                       (const_int 8)
8083                                       (const_int 8))))
8084               (clobber (reg:CC FLAGS_REG))])]
8085   "operands[0] = gen_lowpart (SImode, operands[0]);")
8086
8087 (define_insn "*anddi_2"
8088   [(set (reg FLAGS_REG)
8089         (compare
8090          (and:DI
8091           (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8092           (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8093          (const_int 0)))
8094    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8095         (and:DI (match_dup 1) (match_dup 2)))]
8096   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8097    && ix86_binary_operator_ok (AND, DImode, operands)"
8098   "@
8099    and{l}\t{%k2, %k0|%k0, %k2}
8100    and{q}\t{%2, %0|%0, %2}
8101    and{q}\t{%2, %0|%0, %2}"
8102   [(set_attr "type" "alu")
8103    (set_attr "mode" "SI,DI,DI")])
8104
8105 (define_insn "*andqi_2_maybe_si"
8106   [(set (reg FLAGS_REG)
8107         (compare (and:QI
8108                   (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8109                   (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8110                  (const_int 0)))
8111    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8112         (and:QI (match_dup 1) (match_dup 2)))]
8113   "ix86_binary_operator_ok (AND, QImode, operands)
8114    && ix86_match_ccmode (insn,
8115                          CONST_INT_P (operands[2])
8116                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8117 {
8118   if (which_alternative == 2)
8119     {
8120       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8121         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8122       return "and{l}\t{%2, %k0|%k0, %2}";
8123     }
8124   return "and{b}\t{%2, %0|%0, %2}";
8125 }
8126   [(set_attr "type" "alu")
8127    (set_attr "mode" "QI,QI,SI")])
8128
8129 (define_insn "*and<mode>_2"
8130   [(set (reg FLAGS_REG)
8131         (compare (and:SWI124
8132                   (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8133                   (match_operand:SWI124 2 "general_operand" "<g>,<r><i>"))
8134                  (const_int 0)))
8135    (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8136         (and:SWI124 (match_dup 1) (match_dup 2)))]
8137   "ix86_match_ccmode (insn, CCNOmode)
8138    && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8139   "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8140   [(set_attr "type" "alu")
8141    (set_attr "mode" "<MODE>")])
8142
8143 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8144 (define_insn "*andsi_2_zext"
8145   [(set (reg FLAGS_REG)
8146         (compare (and:SI
8147                   (match_operand:SI 1 "nonimmediate_operand" "%0")
8148                   (match_operand:SI 2 "general_operand" "g"))
8149                  (const_int 0)))
8150    (set (match_operand:DI 0 "register_operand" "=r")
8151         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8152   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8153    && ix86_binary_operator_ok (AND, SImode, operands)"
8154   "and{l}\t{%2, %k0|%k0, %2}"
8155   [(set_attr "type" "alu")
8156    (set_attr "mode" "SI")])
8157
8158 (define_insn "*andqi_2_slp"
8159   [(set (reg FLAGS_REG)
8160         (compare (and:QI
8161                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8162                    (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8163                  (const_int 0)))
8164    (set (strict_low_part (match_dup 0))
8165         (and:QI (match_dup 0) (match_dup 1)))]
8166   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8167    && ix86_match_ccmode (insn, CCNOmode)
8168    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8169   "and{b}\t{%1, %0|%0, %1}"
8170   [(set_attr "type" "alu1")
8171    (set_attr "mode" "QI")])
8172
8173 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8174 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8175 ;; for a QImode operand, which of course failed.
8176 (define_insn "andqi_ext_0"
8177   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8178                          (const_int 8)
8179                          (const_int 8))
8180         (and:SI
8181           (zero_extract:SI
8182             (match_operand 1 "ext_register_operand" "0")
8183             (const_int 8)
8184             (const_int 8))
8185           (match_operand 2 "const_int_operand" "n")))
8186    (clobber (reg:CC FLAGS_REG))]
8187   ""
8188   "and{b}\t{%2, %h0|%h0, %2}"
8189   [(set_attr "type" "alu")
8190    (set_attr "length_immediate" "1")
8191    (set_attr "modrm" "1")
8192    (set_attr "mode" "QI")])
8193
8194 ;; Generated by peephole translating test to and.  This shows up
8195 ;; often in fp comparisons.
8196 (define_insn "*andqi_ext_0_cc"
8197   [(set (reg FLAGS_REG)
8198         (compare
8199           (and:SI
8200             (zero_extract:SI
8201               (match_operand 1 "ext_register_operand" "0")
8202               (const_int 8)
8203               (const_int 8))
8204             (match_operand 2 "const_int_operand" "n"))
8205           (const_int 0)))
8206    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8207                          (const_int 8)
8208                          (const_int 8))
8209         (and:SI
8210           (zero_extract:SI
8211             (match_dup 1)
8212             (const_int 8)
8213             (const_int 8))
8214           (match_dup 2)))]
8215   "ix86_match_ccmode (insn, CCNOmode)"
8216   "and{b}\t{%2, %h0|%h0, %2}"
8217   [(set_attr "type" "alu")
8218    (set_attr "length_immediate" "1")
8219    (set_attr "modrm" "1")
8220    (set_attr "mode" "QI")])
8221
8222 (define_insn "*andqi_ext_1_rex64"
8223   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8224                          (const_int 8)
8225                          (const_int 8))
8226         (and:SI
8227           (zero_extract:SI
8228             (match_operand 1 "ext_register_operand" "0")
8229             (const_int 8)
8230             (const_int 8))
8231           (zero_extend:SI
8232             (match_operand 2 "ext_register_operand" "Q"))))
8233    (clobber (reg:CC FLAGS_REG))]
8234   "TARGET_64BIT"
8235   "and{b}\t{%2, %h0|%h0, %2}"
8236   [(set_attr "type" "alu")
8237    (set_attr "length_immediate" "0")
8238    (set_attr "mode" "QI")])
8239
8240 (define_insn "*andqi_ext_1"
8241   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8242                          (const_int 8)
8243                          (const_int 8))
8244         (and:SI
8245           (zero_extract:SI
8246             (match_operand 1 "ext_register_operand" "0")
8247             (const_int 8)
8248             (const_int 8))
8249           (zero_extend:SI
8250             (match_operand:QI 2 "general_operand" "Qm"))))
8251    (clobber (reg:CC FLAGS_REG))]
8252   "!TARGET_64BIT"
8253   "and{b}\t{%2, %h0|%h0, %2}"
8254   [(set_attr "type" "alu")
8255    (set_attr "length_immediate" "0")
8256    (set_attr "mode" "QI")])
8257
8258 (define_insn "*andqi_ext_2"
8259   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8260                          (const_int 8)
8261                          (const_int 8))
8262         (and:SI
8263           (zero_extract:SI
8264             (match_operand 1 "ext_register_operand" "%0")
8265             (const_int 8)
8266             (const_int 8))
8267           (zero_extract:SI
8268             (match_operand 2 "ext_register_operand" "Q")
8269             (const_int 8)
8270             (const_int 8))))
8271    (clobber (reg:CC FLAGS_REG))]
8272   ""
8273   "and{b}\t{%h2, %h0|%h0, %h2}"
8274   [(set_attr "type" "alu")
8275    (set_attr "length_immediate" "0")
8276    (set_attr "mode" "QI")])
8277
8278 ;; Convert wide AND instructions with immediate operand to shorter QImode
8279 ;; equivalents when possible.
8280 ;; Don't do the splitting with memory operands, since it introduces risk
8281 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8282 ;; for size, but that can (should?) be handled by generic code instead.
8283 (define_split
8284   [(set (match_operand 0 "register_operand" "")
8285         (and (match_operand 1 "register_operand" "")
8286              (match_operand 2 "const_int_operand" "")))
8287    (clobber (reg:CC FLAGS_REG))]
8288    "reload_completed
8289     && QI_REG_P (operands[0])
8290     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8291     && !(~INTVAL (operands[2]) & ~(255 << 8))
8292     && GET_MODE (operands[0]) != QImode"
8293   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8294                    (and:SI (zero_extract:SI (match_dup 1)
8295                                             (const_int 8) (const_int 8))
8296                            (match_dup 2)))
8297               (clobber (reg:CC FLAGS_REG))])]
8298   "operands[0] = gen_lowpart (SImode, operands[0]);
8299    operands[1] = gen_lowpart (SImode, operands[1]);
8300    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8301
8302 ;; Since AND can be encoded with sign extended immediate, this is only
8303 ;; profitable when 7th bit is not set.
8304 (define_split
8305   [(set (match_operand 0 "register_operand" "")
8306         (and (match_operand 1 "general_operand" "")
8307              (match_operand 2 "const_int_operand" "")))
8308    (clobber (reg:CC FLAGS_REG))]
8309    "reload_completed
8310     && ANY_QI_REG_P (operands[0])
8311     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8312     && !(~INTVAL (operands[2]) & ~255)
8313     && !(INTVAL (operands[2]) & 128)
8314     && GET_MODE (operands[0]) != QImode"
8315   [(parallel [(set (strict_low_part (match_dup 0))
8316                    (and:QI (match_dup 1)
8317                            (match_dup 2)))
8318               (clobber (reg:CC FLAGS_REG))])]
8319   "operands[0] = gen_lowpart (QImode, operands[0]);
8320    operands[1] = gen_lowpart (QImode, operands[1]);
8321    operands[2] = gen_lowpart (QImode, operands[2]);")
8322 \f
8323 ;; Logical inclusive and exclusive OR instructions
8324
8325 ;; %%% This used to optimize known byte-wide and operations to memory.
8326 ;; If this is considered useful, it should be done with splitters.
8327
8328 (define_expand "<code><mode>3"
8329   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8330         (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8331                      (match_operand:SWIM 2 "<general_operand>" "")))]
8332   ""
8333   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8334
8335 (define_insn "*<code><mode>_1"
8336   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8337         (any_or:SWI248
8338          (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8339          (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8340    (clobber (reg:CC FLAGS_REG))]
8341   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8342   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8343   [(set_attr "type" "alu")
8344    (set_attr "mode" "<MODE>")])
8345
8346 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8347 (define_insn "*<code>qi_1"
8348   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8349         (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8350                    (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8351    (clobber (reg:CC FLAGS_REG))]
8352   "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8353   "@
8354    <logic>{b}\t{%2, %0|%0, %2}
8355    <logic>{b}\t{%2, %0|%0, %2}
8356    <logic>{l}\t{%k2, %k0|%k0, %k2}"
8357   [(set_attr "type" "alu")
8358    (set_attr "mode" "QI,QI,SI")])
8359
8360 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8361 (define_insn "*<code>si_1_zext"
8362   [(set (match_operand:DI 0 "register_operand" "=r")
8363         (zero_extend:DI
8364          (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8365                     (match_operand:SI 2 "general_operand" "g"))))
8366    (clobber (reg:CC FLAGS_REG))]
8367   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8368   "<logic>{l}\t{%2, %k0|%k0, %2}"
8369   [(set_attr "type" "alu")
8370    (set_attr "mode" "SI")])
8371
8372 (define_insn "*<code>si_1_zext_imm"
8373   [(set (match_operand:DI 0 "register_operand" "=r")
8374         (any_or:DI
8375          (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8376          (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8377    (clobber (reg:CC FLAGS_REG))]
8378   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8379   "<logic>{l}\t{%2, %k0|%k0, %2}"
8380   [(set_attr "type" "alu")
8381    (set_attr "mode" "SI")])
8382
8383 (define_insn "*<code>qi_1_slp"
8384   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8385         (any_or:QI (match_dup 0)
8386                    (match_operand:QI 1 "general_operand" "qmn,qn")))
8387    (clobber (reg:CC FLAGS_REG))]
8388   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8389    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8390   "<logic>{b}\t{%1, %0|%0, %1}"
8391   [(set_attr "type" "alu1")
8392    (set_attr "mode" "QI")])
8393
8394 (define_insn "*<code><mode>_2"
8395   [(set (reg FLAGS_REG)
8396         (compare (any_or:SWI
8397                   (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8398                   (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8399                  (const_int 0)))
8400    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8401         (any_or:SWI (match_dup 1) (match_dup 2)))]
8402   "ix86_match_ccmode (insn, CCNOmode)
8403    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8404   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8405   [(set_attr "type" "alu")
8406    (set_attr "mode" "<MODE>")])
8407
8408 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8409 ;; ??? Special case for immediate operand is missing - it is tricky.
8410 (define_insn "*<code>si_2_zext"
8411   [(set (reg FLAGS_REG)
8412         (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8413                             (match_operand:SI 2 "general_operand" "g"))
8414                  (const_int 0)))
8415    (set (match_operand:DI 0 "register_operand" "=r")
8416         (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8417   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8418    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8419   "<logic>{l}\t{%2, %k0|%k0, %2}"
8420   [(set_attr "type" "alu")
8421    (set_attr "mode" "SI")])
8422
8423 (define_insn "*<code>si_2_zext_imm"
8424   [(set (reg FLAGS_REG)
8425         (compare (any_or:SI
8426                   (match_operand:SI 1 "nonimmediate_operand" "%0")
8427                   (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8428                  (const_int 0)))
8429    (set (match_operand:DI 0 "register_operand" "=r")
8430         (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8431   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8432    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8433   "<logic>{l}\t{%2, %k0|%k0, %2}"
8434   [(set_attr "type" "alu")
8435    (set_attr "mode" "SI")])
8436
8437 (define_insn "*<code>qi_2_slp"
8438   [(set (reg FLAGS_REG)
8439         (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8440                             (match_operand:QI 1 "general_operand" "qmn,qn"))
8441                  (const_int 0)))
8442    (set (strict_low_part (match_dup 0))
8443         (any_or:QI (match_dup 0) (match_dup 1)))]
8444   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8445    && ix86_match_ccmode (insn, CCNOmode)
8446    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8447   "<logic>{b}\t{%1, %0|%0, %1}"
8448   [(set_attr "type" "alu1")
8449    (set_attr "mode" "QI")])
8450
8451 (define_insn "*<code><mode>_3"
8452   [(set (reg FLAGS_REG)
8453         (compare (any_or:SWI
8454                   (match_operand:SWI 1 "nonimmediate_operand" "%0")
8455                   (match_operand:SWI 2 "<general_operand>" "<g>"))
8456                  (const_int 0)))
8457    (clobber (match_scratch:SWI 0 "=<r>"))]
8458   "ix86_match_ccmode (insn, CCNOmode)
8459    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8460   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8461   [(set_attr "type" "alu")
8462    (set_attr "mode" "<MODE>")])
8463
8464 (define_insn "*<code>qi_ext_0"
8465   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8466                          (const_int 8)
8467                          (const_int 8))
8468         (any_or:SI
8469           (zero_extract:SI
8470             (match_operand 1 "ext_register_operand" "0")
8471             (const_int 8)
8472             (const_int 8))
8473           (match_operand 2 "const_int_operand" "n")))
8474    (clobber (reg:CC FLAGS_REG))]
8475   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8476   "<logic>{b}\t{%2, %h0|%h0, %2}"
8477   [(set_attr "type" "alu")
8478    (set_attr "length_immediate" "1")
8479    (set_attr "modrm" "1")
8480    (set_attr "mode" "QI")])
8481
8482 (define_insn "*<code>qi_ext_1_rex64"
8483   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8484                          (const_int 8)
8485                          (const_int 8))
8486         (any_or:SI
8487           (zero_extract:SI
8488             (match_operand 1 "ext_register_operand" "0")
8489             (const_int 8)
8490             (const_int 8))
8491           (zero_extend:SI
8492             (match_operand 2 "ext_register_operand" "Q"))))
8493    (clobber (reg:CC FLAGS_REG))]
8494   "TARGET_64BIT
8495    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8496   "<logic>{b}\t{%2, %h0|%h0, %2}"
8497   [(set_attr "type" "alu")
8498    (set_attr "length_immediate" "0")
8499    (set_attr "mode" "QI")])
8500
8501 (define_insn "*<code>qi_ext_1"
8502   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8503                          (const_int 8)
8504                          (const_int 8))
8505         (any_or:SI
8506           (zero_extract:SI
8507             (match_operand 1 "ext_register_operand" "0")
8508             (const_int 8)
8509             (const_int 8))
8510           (zero_extend:SI
8511             (match_operand:QI 2 "general_operand" "Qm"))))
8512    (clobber (reg:CC FLAGS_REG))]
8513   "!TARGET_64BIT
8514    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8515   "<logic>{b}\t{%2, %h0|%h0, %2}"
8516   [(set_attr "type" "alu")
8517    (set_attr "length_immediate" "0")
8518    (set_attr "mode" "QI")])
8519
8520 (define_insn "*<code>qi_ext_2"
8521   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8522                          (const_int 8)
8523                          (const_int 8))
8524         (any_or:SI
8525           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8526                            (const_int 8)
8527                            (const_int 8))
8528           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8529                            (const_int 8)
8530                            (const_int 8))))
8531    (clobber (reg:CC FLAGS_REG))]
8532   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8533   "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8534   [(set_attr "type" "alu")
8535    (set_attr "length_immediate" "0")
8536    (set_attr "mode" "QI")])
8537
8538 (define_split
8539   [(set (match_operand 0 "register_operand" "")
8540         (any_or (match_operand 1 "register_operand" "")
8541                 (match_operand 2 "const_int_operand" "")))
8542    (clobber (reg:CC FLAGS_REG))]
8543    "reload_completed
8544     && QI_REG_P (operands[0])
8545     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8546     && !(INTVAL (operands[2]) & ~(255 << 8))
8547     && GET_MODE (operands[0]) != QImode"
8548   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8549                    (any_or:SI (zero_extract:SI (match_dup 1)
8550                                                (const_int 8) (const_int 8))
8551                               (match_dup 2)))
8552               (clobber (reg:CC FLAGS_REG))])]
8553   "operands[0] = gen_lowpart (SImode, operands[0]);
8554    operands[1] = gen_lowpart (SImode, operands[1]);
8555    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8556
8557 ;; Since OR can be encoded with sign extended immediate, this is only
8558 ;; profitable when 7th bit is set.
8559 (define_split
8560   [(set (match_operand 0 "register_operand" "")
8561         (any_or (match_operand 1 "general_operand" "")
8562                 (match_operand 2 "const_int_operand" "")))
8563    (clobber (reg:CC FLAGS_REG))]
8564    "reload_completed
8565     && ANY_QI_REG_P (operands[0])
8566     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8567     && !(INTVAL (operands[2]) & ~255)
8568     && (INTVAL (operands[2]) & 128)
8569     && GET_MODE (operands[0]) != QImode"
8570   [(parallel [(set (strict_low_part (match_dup 0))
8571                    (any_or:QI (match_dup 1)
8572                               (match_dup 2)))
8573               (clobber (reg:CC FLAGS_REG))])]
8574   "operands[0] = gen_lowpart (QImode, operands[0]);
8575    operands[1] = gen_lowpart (QImode, operands[1]);
8576    operands[2] = gen_lowpart (QImode, operands[2]);")
8577
8578 (define_expand "xorqi_cc_ext_1"
8579   [(parallel [
8580      (set (reg:CCNO FLAGS_REG)
8581           (compare:CCNO
8582             (xor:SI
8583               (zero_extract:SI
8584                 (match_operand 1 "ext_register_operand" "")
8585                 (const_int 8)
8586                 (const_int 8))
8587               (match_operand:QI 2 "general_operand" ""))
8588             (const_int 0)))
8589      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8590                            (const_int 8)
8591                            (const_int 8))
8592           (xor:SI
8593             (zero_extract:SI
8594              (match_dup 1)
8595              (const_int 8)
8596              (const_int 8))
8597             (match_dup 2)))])]
8598   ""
8599   "")
8600
8601 (define_insn "*xorqi_cc_ext_1_rex64"
8602   [(set (reg FLAGS_REG)
8603         (compare
8604           (xor:SI
8605             (zero_extract:SI
8606               (match_operand 1 "ext_register_operand" "0")
8607               (const_int 8)
8608               (const_int 8))
8609             (match_operand:QI 2 "nonmemory_operand" "Qn"))
8610           (const_int 0)))
8611    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8612                          (const_int 8)
8613                          (const_int 8))
8614         (xor:SI
8615           (zero_extract:SI
8616            (match_dup 1)
8617            (const_int 8)
8618            (const_int 8))
8619           (match_dup 2)))]
8620   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8621   "xor{b}\t{%2, %h0|%h0, %2}"
8622   [(set_attr "type" "alu")
8623    (set_attr "modrm" "1")
8624    (set_attr "mode" "QI")])
8625
8626 (define_insn "*xorqi_cc_ext_1"
8627   [(set (reg FLAGS_REG)
8628         (compare
8629           (xor:SI
8630             (zero_extract:SI
8631               (match_operand 1 "ext_register_operand" "0")
8632               (const_int 8)
8633               (const_int 8))
8634             (match_operand:QI 2 "general_operand" "qmn"))
8635           (const_int 0)))
8636    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8637                          (const_int 8)
8638                          (const_int 8))
8639         (xor:SI
8640           (zero_extract:SI
8641            (match_dup 1)
8642            (const_int 8)
8643            (const_int 8))
8644           (match_dup 2)))]
8645   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8646   "xor{b}\t{%2, %h0|%h0, %2}"
8647   [(set_attr "type" "alu")
8648    (set_attr "modrm" "1")
8649    (set_attr "mode" "QI")])
8650 \f
8651 ;; Negation instructions
8652
8653 (define_expand "neg<mode>2"
8654   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
8655         (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
8656   ""
8657   "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8658
8659 (define_insn_and_split "*neg<dwi>2_doubleword"
8660   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8661         (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8662    (clobber (reg:CC FLAGS_REG))]
8663   "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8664   "#"
8665   "reload_completed"
8666   [(parallel
8667     [(set (reg:CCZ FLAGS_REG)
8668           (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8669      (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8670    (parallel
8671     [(set (match_dup 2)
8672           (plus:DWIH (match_dup 3)
8673                      (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8674                                 (const_int 0))))
8675      (clobber (reg:CC FLAGS_REG))])
8676    (parallel
8677     [(set (match_dup 2)
8678           (neg:DWIH (match_dup 2)))
8679      (clobber (reg:CC FLAGS_REG))])]
8680   "split_<dwi> (&operands[0], 2, &operands[0], &operands[2]);")
8681
8682 (define_insn "*neg<mode>2_1"
8683   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8684         (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8685    (clobber (reg:CC FLAGS_REG))]
8686   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8687   "neg{<imodesuffix>}\t%0"
8688   [(set_attr "type" "negnot")
8689    (set_attr "mode" "<MODE>")])
8690
8691 ;; Combine is quite creative about this pattern.
8692 (define_insn "*negsi2_1_zext"
8693   [(set (match_operand:DI 0 "register_operand" "=r")
8694         (lshiftrt:DI
8695           (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8696                              (const_int 32)))
8697         (const_int 32)))
8698    (clobber (reg:CC FLAGS_REG))]
8699   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8700   "neg{l}\t%k0"
8701   [(set_attr "type" "negnot")
8702    (set_attr "mode" "SI")])
8703
8704 ;; The problem with neg is that it does not perform (compare x 0),
8705 ;; it really performs (compare 0 x), which leaves us with the zero
8706 ;; flag being the only useful item.
8707
8708 (define_insn "*neg<mode>2_cmpz"
8709   [(set (reg:CCZ FLAGS_REG)
8710         (compare:CCZ
8711           (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8712                    (const_int 0)))
8713    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8714         (neg:SWI (match_dup 1)))]
8715   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8716   "neg{<imodesuffix>}\t%0"
8717   [(set_attr "type" "negnot")
8718    (set_attr "mode" "<MODE>")])
8719
8720 (define_insn "*negsi2_cmpz_zext"
8721   [(set (reg:CCZ FLAGS_REG)
8722         (compare:CCZ
8723           (lshiftrt:DI
8724             (neg:DI (ashift:DI
8725                       (match_operand:DI 1 "register_operand" "0")
8726                       (const_int 32)))
8727             (const_int 32))
8728           (const_int 0)))
8729    (set (match_operand:DI 0 "register_operand" "=r")
8730         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8731                                         (const_int 32)))
8732                      (const_int 32)))]
8733   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8734   "neg{l}\t%k0"
8735   [(set_attr "type" "negnot")
8736    (set_attr "mode" "SI")])
8737
8738 ;; Changing of sign for FP values is doable using integer unit too.
8739
8740 (define_expand "<code><mode>2"
8741   [(set (match_operand:X87MODEF 0 "register_operand" "")
8742         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
8743   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8744   "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8745
8746 (define_insn "*absneg<mode>2_mixed"
8747   [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8748         (match_operator:MODEF 3 "absneg_operator"
8749           [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8750    (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8751    (clobber (reg:CC FLAGS_REG))]
8752   "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8753   "#")
8754
8755 (define_insn "*absneg<mode>2_sse"
8756   [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8757         (match_operator:MODEF 3 "absneg_operator"
8758           [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8759    (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8760    (clobber (reg:CC FLAGS_REG))]
8761   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8762   "#")
8763
8764 (define_insn "*absneg<mode>2_i387"
8765   [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8766         (match_operator:X87MODEF 3 "absneg_operator"
8767           [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8768    (use (match_operand 2 "" ""))
8769    (clobber (reg:CC FLAGS_REG))]
8770   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8771   "#")
8772
8773 (define_expand "<code>tf2"
8774   [(set (match_operand:TF 0 "register_operand" "")
8775         (absneg:TF (match_operand:TF 1 "register_operand" "")))]
8776   "TARGET_SSE2"
8777   "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8778
8779 (define_insn "*absnegtf2_sse"
8780   [(set (match_operand:TF 0 "register_operand" "=x,x")
8781         (match_operator:TF 3 "absneg_operator"
8782           [(match_operand:TF 1 "register_operand" "0,x")]))
8783    (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8784    (clobber (reg:CC FLAGS_REG))]
8785   "TARGET_SSE2"
8786   "#")
8787
8788 ;; Splitters for fp abs and neg.
8789
8790 (define_split
8791   [(set (match_operand 0 "fp_register_operand" "")
8792         (match_operator 1 "absneg_operator" [(match_dup 0)]))
8793    (use (match_operand 2 "" ""))
8794    (clobber (reg:CC FLAGS_REG))]
8795   "reload_completed"
8796   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8797
8798 (define_split
8799   [(set (match_operand 0 "register_operand" "")
8800         (match_operator 3 "absneg_operator"
8801           [(match_operand 1 "register_operand" "")]))
8802    (use (match_operand 2 "nonimmediate_operand" ""))
8803    (clobber (reg:CC FLAGS_REG))]
8804   "reload_completed && SSE_REG_P (operands[0])"
8805   [(set (match_dup 0) (match_dup 3))]
8806 {
8807   enum machine_mode mode = GET_MODE (operands[0]);
8808   enum machine_mode vmode = GET_MODE (operands[2]);
8809   rtx tmp;
8810
8811   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8812   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8813   if (operands_match_p (operands[0], operands[2]))
8814     {
8815       tmp = operands[1];
8816       operands[1] = operands[2];
8817       operands[2] = tmp;
8818     }
8819   if (GET_CODE (operands[3]) == ABS)
8820     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8821   else
8822     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8823   operands[3] = tmp;
8824 })
8825
8826 (define_split
8827   [(set (match_operand:SF 0 "register_operand" "")
8828         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8829    (use (match_operand:V4SF 2 "" ""))
8830    (clobber (reg:CC FLAGS_REG))]
8831   "reload_completed"
8832   [(parallel [(set (match_dup 0) (match_dup 1))
8833               (clobber (reg:CC FLAGS_REG))])]
8834 {
8835   rtx tmp;
8836   operands[0] = gen_lowpart (SImode, operands[0]);
8837   if (GET_CODE (operands[1]) == ABS)
8838     {
8839       tmp = gen_int_mode (0x7fffffff, SImode);
8840       tmp = gen_rtx_AND (SImode, operands[0], tmp);
8841     }
8842   else
8843     {
8844       tmp = gen_int_mode (0x80000000, SImode);
8845       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8846     }
8847   operands[1] = tmp;
8848 })
8849
8850 (define_split
8851   [(set (match_operand:DF 0 "register_operand" "")
8852         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8853    (use (match_operand 2 "" ""))
8854    (clobber (reg:CC FLAGS_REG))]
8855   "reload_completed"
8856   [(parallel [(set (match_dup 0) (match_dup 1))
8857               (clobber (reg:CC FLAGS_REG))])]
8858 {
8859   rtx tmp;
8860   if (TARGET_64BIT)
8861     {
8862       tmp = gen_lowpart (DImode, operands[0]);
8863       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8864       operands[0] = tmp;
8865
8866       if (GET_CODE (operands[1]) == ABS)
8867         tmp = const0_rtx;
8868       else
8869         tmp = gen_rtx_NOT (DImode, tmp);
8870     }
8871   else
8872     {
8873       operands[0] = gen_highpart (SImode, operands[0]);
8874       if (GET_CODE (operands[1]) == ABS)
8875         {
8876           tmp = gen_int_mode (0x7fffffff, SImode);
8877           tmp = gen_rtx_AND (SImode, operands[0], tmp);
8878         }
8879       else
8880         {
8881           tmp = gen_int_mode (0x80000000, SImode);
8882           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8883         }
8884     }
8885   operands[1] = tmp;
8886 })
8887
8888 (define_split
8889   [(set (match_operand:XF 0 "register_operand" "")
8890         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8891    (use (match_operand 2 "" ""))
8892    (clobber (reg:CC FLAGS_REG))]
8893   "reload_completed"
8894   [(parallel [(set (match_dup 0) (match_dup 1))
8895               (clobber (reg:CC FLAGS_REG))])]
8896 {
8897   rtx tmp;
8898   operands[0] = gen_rtx_REG (SImode,
8899                              true_regnum (operands[0])
8900                              + (TARGET_64BIT ? 1 : 2));
8901   if (GET_CODE (operands[1]) == ABS)
8902     {
8903       tmp = GEN_INT (0x7fff);
8904       tmp = gen_rtx_AND (SImode, operands[0], tmp);
8905     }
8906   else
8907     {
8908       tmp = GEN_INT (0x8000);
8909       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8910     }
8911   operands[1] = tmp;
8912 })
8913
8914 ;; Conditionalize these after reload. If they match before reload, we
8915 ;; lose the clobber and ability to use integer instructions.
8916
8917 (define_insn "*<code><mode>2_1"
8918   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8919         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8920   "TARGET_80387
8921    && (reload_completed
8922        || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8923   "f<absneg_mnemonic>"
8924   [(set_attr "type" "fsgn")
8925    (set_attr "mode" "<MODE>")])
8926
8927 (define_insn "*<code>extendsfdf2"
8928   [(set (match_operand:DF 0 "register_operand" "=f")
8929         (absneg:DF (float_extend:DF
8930                      (match_operand:SF 1 "register_operand" "0"))))]
8931   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8932   "f<absneg_mnemonic>"
8933   [(set_attr "type" "fsgn")
8934    (set_attr "mode" "DF")])
8935
8936 (define_insn "*<code>extendsfxf2"
8937   [(set (match_operand:XF 0 "register_operand" "=f")
8938         (absneg:XF (float_extend:XF
8939                      (match_operand:SF 1 "register_operand" "0"))))]
8940   "TARGET_80387"
8941   "f<absneg_mnemonic>"
8942   [(set_attr "type" "fsgn")
8943    (set_attr "mode" "XF")])
8944
8945 (define_insn "*<code>extenddfxf2"
8946   [(set (match_operand:XF 0 "register_operand" "=f")
8947         (absneg:XF (float_extend:XF
8948                      (match_operand:DF 1 "register_operand" "0"))))]
8949   "TARGET_80387"
8950   "f<absneg_mnemonic>"
8951   [(set_attr "type" "fsgn")
8952    (set_attr "mode" "XF")])
8953
8954 ;; Copysign instructions
8955
8956 (define_mode_iterator CSGNMODE [SF DF TF])
8957 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8958
8959 (define_expand "copysign<mode>3"
8960   [(match_operand:CSGNMODE 0 "register_operand" "")
8961    (match_operand:CSGNMODE 1 "nonmemory_operand" "")
8962    (match_operand:CSGNMODE 2 "register_operand" "")]
8963   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8964    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8965 {
8966   ix86_expand_copysign (operands);
8967   DONE;
8968 })
8969
8970 (define_insn_and_split "copysign<mode>3_const"
8971   [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8972         (unspec:CSGNMODE
8973           [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8974            (match_operand:CSGNMODE 2 "register_operand" "0")
8975            (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8976           UNSPEC_COPYSIGN))]
8977   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8978    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8979   "#"
8980   "&& reload_completed"
8981   [(const_int 0)]
8982 {
8983   ix86_split_copysign_const (operands);
8984   DONE;
8985 })
8986
8987 (define_insn "copysign<mode>3_var"
8988   [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8989         (unspec:CSGNMODE
8990           [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8991            (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8992            (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8993            (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8994           UNSPEC_COPYSIGN))
8995    (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8996   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8997    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8998   "#")
8999
9000 (define_split
9001   [(set (match_operand:CSGNMODE 0 "register_operand" "")
9002         (unspec:CSGNMODE
9003           [(match_operand:CSGNMODE 2 "register_operand" "")
9004            (match_operand:CSGNMODE 3 "register_operand" "")
9005            (match_operand:<CSGNVMODE> 4 "" "")
9006            (match_operand:<CSGNVMODE> 5 "" "")]
9007           UNSPEC_COPYSIGN))
9008    (clobber (match_scratch:<CSGNVMODE> 1 ""))]
9009   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9010     || (TARGET_SSE2 && (<MODE>mode == TFmode)))
9011    && reload_completed"
9012   [(const_int 0)]
9013 {
9014   ix86_split_copysign_var (operands);
9015   DONE;
9016 })
9017 \f
9018 ;; One complement instructions
9019
9020 (define_expand "one_cmpl<mode>2"
9021   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
9022         (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
9023   ""
9024   "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
9025
9026 (define_insn "*one_cmpl<mode>2_1"
9027   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
9028         (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
9029   "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9030   "not{<imodesuffix>}\t%0"
9031   [(set_attr "type" "negnot")
9032    (set_attr "mode" "<MODE>")])
9033
9034 ;; %%% Potential partial reg stall on alternative 1.  What to do?
9035 (define_insn "*one_cmplqi2_1"
9036   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9037         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
9038   "ix86_unary_operator_ok (NOT, QImode, operands)"
9039   "@
9040    not{b}\t%0
9041    not{l}\t%k0"
9042   [(set_attr "type" "negnot")
9043    (set_attr "mode" "QI,SI")])
9044
9045 ;; ??? Currently never generated - xor is used instead.
9046 (define_insn "*one_cmplsi2_1_zext"
9047   [(set (match_operand:DI 0 "register_operand" "=r")
9048         (zero_extend:DI
9049           (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9050   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9051   "not{l}\t%k0"
9052   [(set_attr "type" "negnot")
9053    (set_attr "mode" "SI")])
9054
9055 (define_insn "*one_cmpl<mode>2_2"
9056   [(set (reg FLAGS_REG)
9057         (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9058                  (const_int 0)))
9059    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9060         (not:SWI (match_dup 1)))]
9061   "ix86_match_ccmode (insn, CCNOmode)
9062    && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9063   "#"
9064   [(set_attr "type" "alu1")
9065    (set_attr "mode" "<MODE>")])
9066
9067 (define_split
9068   [(set (match_operand 0 "flags_reg_operand" "")
9069         (match_operator 2 "compare_operator"
9070           [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
9071            (const_int 0)]))
9072    (set (match_operand:SWI 1 "nonimmediate_operand" "")
9073         (not:SWI (match_dup 3)))]
9074   "ix86_match_ccmode (insn, CCNOmode)"
9075   [(parallel [(set (match_dup 0)
9076                    (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9077                                     (const_int 0)]))
9078               (set (match_dup 1)
9079                    (xor:SWI (match_dup 3) (const_int -1)))])]
9080   "")
9081
9082 ;; ??? Currently never generated - xor is used instead.
9083 (define_insn "*one_cmplsi2_2_zext"
9084   [(set (reg FLAGS_REG)
9085         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9086                  (const_int 0)))
9087    (set (match_operand:DI 0 "register_operand" "=r")
9088         (zero_extend:DI (not:SI (match_dup 1))))]
9089   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9090    && ix86_unary_operator_ok (NOT, SImode, operands)"
9091   "#"
9092   [(set_attr "type" "alu1")
9093    (set_attr "mode" "SI")])
9094
9095 (define_split
9096   [(set (match_operand 0 "flags_reg_operand" "")
9097         (match_operator 2 "compare_operator"
9098           [(not:SI (match_operand:SI 3 "register_operand" ""))
9099            (const_int 0)]))
9100    (set (match_operand:DI 1 "register_operand" "")
9101         (zero_extend:DI (not:SI (match_dup 3))))]
9102   "ix86_match_ccmode (insn, CCNOmode)"
9103   [(parallel [(set (match_dup 0)
9104                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9105                                     (const_int 0)]))
9106               (set (match_dup 1)
9107                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
9108   "")
9109 \f
9110 ;; Shift instructions
9111
9112 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9113 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
9114 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9115 ;; from the assembler input.
9116 ;;
9117 ;; This instruction shifts the target reg/mem as usual, but instead of
9118 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
9119 ;; is a left shift double, bits are taken from the high order bits of
9120 ;; reg, else if the insn is a shift right double, bits are taken from the
9121 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
9122 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9123 ;;
9124 ;; Since sh[lr]d does not change the `reg' operand, that is done
9125 ;; separately, making all shifts emit pairs of shift double and normal
9126 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
9127 ;; support a 63 bit shift, each shift where the count is in a reg expands
9128 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9129 ;;
9130 ;; If the shift count is a constant, we need never emit more than one
9131 ;; shift pair, instead using moves and sign extension for counts greater
9132 ;; than 31.
9133
9134 (define_expand "ashl<mode>3"
9135   [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9136         (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
9137                       (match_operand:QI 2 "nonmemory_operand" "")))]
9138   ""
9139   "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9140
9141 (define_insn "*ashl<mode>3_doubleword"
9142   [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9143         (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9144                     (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9145    (clobber (reg:CC FLAGS_REG))]
9146   ""
9147   "#"
9148   [(set_attr "type" "multi")])
9149
9150 (define_split
9151   [(set (match_operand:DWI 0 "register_operand" "")
9152         (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
9153                     (match_operand:QI 2 "nonmemory_operand" "")))
9154    (clobber (reg:CC FLAGS_REG))]
9155   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9156   [(const_int 0)]
9157   "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9158
9159 ;; By default we don't ask for a scratch register, because when DWImode
9160 ;; values are manipulated, registers are already at a premium.  But if
9161 ;; we have one handy, we won't turn it away.
9162
9163 (define_peephole2
9164   [(match_scratch:DWIH 3 "r")
9165    (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9166                    (ashift:<DWI>
9167                      (match_operand:<DWI> 1 "nonmemory_operand" "")
9168                      (match_operand:QI 2 "nonmemory_operand" "")))
9169               (clobber (reg:CC FLAGS_REG))])
9170    (match_dup 3)]
9171   "TARGET_CMOVE"
9172   [(const_int 0)]
9173   "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9174
9175 (define_insn "x86_64_shld"
9176   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9177         (ior:DI (ashift:DI (match_dup 0)
9178                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
9179                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9180                   (minus:QI (const_int 64) (match_dup 2)))))
9181    (clobber (reg:CC FLAGS_REG))]
9182   "TARGET_64BIT"
9183   "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9184   [(set_attr "type" "ishift")
9185    (set_attr "prefix_0f" "1")
9186    (set_attr "mode" "DI")
9187    (set_attr "athlon_decode" "vector")
9188    (set_attr "amdfam10_decode" "vector")])
9189
9190 (define_insn "x86_shld"
9191   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9192         (ior:SI (ashift:SI (match_dup 0)
9193                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
9194                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9195                   (minus:QI (const_int 32) (match_dup 2)))))
9196    (clobber (reg:CC FLAGS_REG))]
9197   ""
9198   "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9199   [(set_attr "type" "ishift")
9200    (set_attr "prefix_0f" "1")
9201    (set_attr "mode" "SI")
9202    (set_attr "pent_pair" "np")
9203    (set_attr "athlon_decode" "vector")
9204    (set_attr "amdfam10_decode" "vector")])
9205
9206 (define_expand "x86_shift<mode>_adj_1"
9207   [(set (reg:CCZ FLAGS_REG)
9208         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
9209                              (match_dup 4))
9210                      (const_int 0)))
9211    (set (match_operand:SWI48 0 "register_operand" "")
9212         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9213                             (match_operand:SWI48 1 "register_operand" "")
9214                             (match_dup 0)))
9215    (set (match_dup 1)
9216         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9217                             (match_operand:SWI48 3 "register_operand" "r")
9218                             (match_dup 1)))]
9219   "TARGET_CMOVE"
9220   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9221
9222 (define_expand "x86_shift<mode>_adj_2"
9223   [(use (match_operand:SWI48 0 "register_operand" ""))
9224    (use (match_operand:SWI48 1 "register_operand" ""))
9225    (use (match_operand:QI 2 "register_operand" ""))]
9226   ""
9227 {
9228   rtx label = gen_label_rtx ();
9229   rtx tmp;
9230
9231   emit_insn (gen_testqi_ccz_1 (operands[2],
9232                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9233
9234   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9235   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9236   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9237                               gen_rtx_LABEL_REF (VOIDmode, label),
9238                               pc_rtx);
9239   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9240   JUMP_LABEL (tmp) = label;
9241
9242   emit_move_insn (operands[0], operands[1]);
9243   ix86_expand_clear (operands[1]);
9244
9245   emit_label (label);
9246   LABEL_NUSES (label) = 1;
9247
9248   DONE;
9249 })
9250
9251 (define_insn "*ashl<mode>3_1"
9252   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9253         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l")
9254                       (match_operand:QI 2 "nonmemory_operand" "c<S>,M")))
9255    (clobber (reg:CC FLAGS_REG))]
9256   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9257 {
9258   switch (get_attr_type (insn))
9259     {
9260     case TYPE_LEA:
9261       return "#";
9262
9263     case TYPE_ALU:
9264       gcc_assert (operands[2] == const1_rtx);
9265       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9266       return "add{<imodesuffix>}\t%0, %0";
9267
9268     default:
9269       if (operands[2] == const1_rtx
9270           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9271         return "sal{<imodesuffix>}\t%0";
9272       else
9273         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9274     }
9275 }
9276   [(set (attr "type")
9277      (cond [(eq_attr "alternative" "1")
9278               (const_string "lea")
9279             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9280                           (const_int 0))
9281                       (match_operand 0 "register_operand" ""))
9282                  (match_operand 2 "const1_operand" ""))
9283               (const_string "alu")
9284            ]
9285            (const_string "ishift")))
9286    (set (attr "length_immediate")
9287      (if_then_else
9288        (ior (eq_attr "type" "alu")
9289             (and (eq_attr "type" "ishift")
9290                  (and (match_operand 2 "const1_operand" "")
9291                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9292                           (const_int 0)))))
9293        (const_string "0")
9294        (const_string "*")))
9295    (set_attr "mode" "<MODE>")])
9296
9297 (define_insn "*ashlsi3_1_zext"
9298   [(set (match_operand:DI 0 "register_operand" "=r,r")
9299         (zero_extend:DI
9300           (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
9301                      (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
9302    (clobber (reg:CC FLAGS_REG))]
9303   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9304 {
9305   switch (get_attr_type (insn))
9306     {
9307     case TYPE_LEA:
9308       return "#";
9309
9310     case TYPE_ALU:
9311       gcc_assert (operands[2] == const1_rtx);
9312       return "add{l}\t%k0, %k0";
9313
9314     default:
9315       if (operands[2] == const1_rtx
9316           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9317         return "sal{l}\t%k0";
9318       else
9319         return "sal{l}\t{%2, %k0|%k0, %2}";
9320     }
9321 }
9322   [(set (attr "type")
9323      (cond [(eq_attr "alternative" "1")
9324               (const_string "lea")
9325             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9326                      (const_int 0))
9327                  (match_operand 2 "const1_operand" ""))
9328               (const_string "alu")
9329            ]
9330            (const_string "ishift")))
9331    (set (attr "length_immediate")
9332      (if_then_else
9333        (ior (eq_attr "type" "alu")
9334             (and (eq_attr "type" "ishift")
9335                  (and (match_operand 2 "const1_operand" "")
9336                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9337                           (const_int 0)))))
9338        (const_string "0")
9339        (const_string "*")))
9340    (set_attr "mode" "SI")])
9341
9342 (define_insn "*ashlhi3_1"
9343   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9344         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
9345                    (match_operand:QI 2 "nonmemory_operand" "cI")))
9346    (clobber (reg:CC FLAGS_REG))]
9347   "TARGET_PARTIAL_REG_STALL
9348    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9349 {
9350   switch (get_attr_type (insn))
9351     {
9352     case TYPE_ALU:
9353       gcc_assert (operands[2] == const1_rtx);
9354       return "add{w}\t%0, %0";
9355
9356     default:
9357       if (operands[2] == const1_rtx
9358           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9359         return "sal{w}\t%0";
9360       else
9361         return "sal{w}\t{%2, %0|%0, %2}";
9362     }
9363 }
9364   [(set (attr "type")
9365      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9366                           (const_int 0))
9367                       (match_operand 0 "register_operand" ""))
9368                  (match_operand 2 "const1_operand" ""))
9369               (const_string "alu")
9370            ]
9371            (const_string "ishift")))
9372    (set (attr "length_immediate")
9373      (if_then_else
9374        (ior (eq_attr "type" "alu")
9375             (and (eq_attr "type" "ishift")
9376                  (and (match_operand 2 "const1_operand" "")
9377                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9378                           (const_int 0)))))
9379        (const_string "0")
9380        (const_string "*")))
9381    (set_attr "mode" "HI")])
9382
9383 (define_insn "*ashlhi3_1_lea"
9384   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
9385         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9386                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9387    (clobber (reg:CC FLAGS_REG))]
9388   "!TARGET_PARTIAL_REG_STALL
9389    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9390 {
9391   switch (get_attr_type (insn))
9392     {
9393     case TYPE_LEA:
9394       return "#";
9395
9396     case TYPE_ALU:
9397       gcc_assert (operands[2] == const1_rtx);
9398       return "add{w}\t%0, %0";
9399
9400     default:
9401       if (operands[2] == const1_rtx
9402           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9403         return "sal{w}\t%0";
9404       else
9405         return "sal{w}\t{%2, %0|%0, %2}";
9406     }
9407 }
9408   [(set (attr "type")
9409      (cond [(eq_attr "alternative" "1")
9410               (const_string "lea")
9411             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9412                           (const_int 0))
9413                       (match_operand 0 "register_operand" ""))
9414                  (match_operand 2 "const1_operand" ""))
9415               (const_string "alu")
9416            ]
9417            (const_string "ishift")))
9418    (set (attr "length_immediate")
9419      (if_then_else
9420        (ior (eq_attr "type" "alu")
9421             (and (eq_attr "type" "ishift")
9422                  (and (match_operand 2 "const1_operand" "")
9423                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9424                           (const_int 0)))))
9425        (const_string "0")
9426        (const_string "*")))
9427    (set_attr "mode" "HI,SI")])
9428
9429 (define_insn "*ashlqi3_1"
9430   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9431         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
9432                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
9433    (clobber (reg:CC FLAGS_REG))]
9434   "TARGET_PARTIAL_REG_STALL
9435    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9436 {
9437   switch (get_attr_type (insn))
9438     {
9439     case TYPE_ALU:
9440       gcc_assert (operands[2] == const1_rtx);
9441       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9442         return "add{l}\t%k0, %k0";
9443       else
9444         return "add{b}\t%0, %0";
9445
9446     default:
9447       if (operands[2] == const1_rtx
9448           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9449         {
9450           if (get_attr_mode (insn) == MODE_SI)
9451             return "sal{l}\t%k0";
9452           else
9453             return "sal{b}\t%0";
9454         }
9455       else
9456         {
9457           if (get_attr_mode (insn) == MODE_SI)
9458             return "sal{l}\t{%2, %k0|%k0, %2}";
9459           else
9460             return "sal{b}\t{%2, %0|%0, %2}";
9461         }
9462     }
9463 }
9464   [(set (attr "type")
9465      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9466                           (const_int 0))
9467                       (match_operand 0 "register_operand" ""))
9468                  (match_operand 2 "const1_operand" ""))
9469               (const_string "alu")
9470            ]
9471            (const_string "ishift")))
9472    (set (attr "length_immediate")
9473      (if_then_else
9474        (ior (eq_attr "type" "alu")
9475             (and (eq_attr "type" "ishift")
9476                  (and (match_operand 2 "const1_operand" "")
9477                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9478                           (const_int 0)))))
9479        (const_string "0")
9480        (const_string "*")))
9481    (set_attr "mode" "QI,SI")])
9482
9483 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9484 (define_insn "*ashlqi3_1_lea"
9485   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
9486         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9487                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9488    (clobber (reg:CC FLAGS_REG))]
9489   "!TARGET_PARTIAL_REG_STALL
9490    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9491 {
9492   switch (get_attr_type (insn))
9493     {
9494     case TYPE_LEA:
9495       return "#";
9496
9497     case TYPE_ALU:
9498       gcc_assert (operands[2] == const1_rtx);
9499       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9500         return "add{l}\t%k0, %k0";
9501       else
9502         return "add{b}\t%0, %0";
9503
9504     default:
9505       if (operands[2] == const1_rtx
9506           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9507         {
9508           if (get_attr_mode (insn) == MODE_SI)
9509             return "sal{l}\t%k0";
9510           else
9511             return "sal{b}\t%0";
9512         }
9513       else
9514         {
9515           if (get_attr_mode (insn) == MODE_SI)
9516             return "sal{l}\t{%2, %k0|%k0, %2}";
9517           else
9518             return "sal{b}\t{%2, %0|%0, %2}";
9519         }
9520     }
9521 }
9522   [(set (attr "type")
9523      (cond [(eq_attr "alternative" "2")
9524               (const_string "lea")
9525             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9526                           (const_int 0))
9527                       (match_operand 0 "register_operand" ""))
9528                  (match_operand 2 "const1_operand" ""))
9529               (const_string "alu")
9530            ]
9531            (const_string "ishift")))
9532    (set (attr "length_immediate")
9533      (if_then_else
9534        (ior (eq_attr "type" "alu")
9535             (and (eq_attr "type" "ishift")
9536                  (and (match_operand 2 "const1_operand" "")
9537                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9538                           (const_int 0)))))
9539        (const_string "0")
9540        (const_string "*")))
9541    (set_attr "mode" "QI,SI,SI")])
9542
9543 (define_insn "*ashlqi3_1_slp"
9544   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9545         (ashift:QI (match_dup 0)
9546                    (match_operand:QI 1 "nonmemory_operand" "cI")))
9547    (clobber (reg:CC FLAGS_REG))]
9548   "(optimize_function_for_size_p (cfun)
9549     || !TARGET_PARTIAL_FLAG_REG_STALL
9550     || (operands[1] == const1_rtx
9551         && (TARGET_SHIFT1
9552             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9553 {
9554   switch (get_attr_type (insn))
9555     {
9556     case TYPE_ALU:
9557       gcc_assert (operands[1] == const1_rtx);
9558       return "add{b}\t%0, %0";
9559
9560     default:
9561       if (operands[1] == const1_rtx
9562           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9563         return "sal{b}\t%0";
9564       else
9565         return "sal{b}\t{%1, %0|%0, %1}";
9566     }
9567 }
9568   [(set (attr "type")
9569      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9570                           (const_int 0))
9571                       (match_operand 0 "register_operand" ""))
9572                  (match_operand 1 "const1_operand" ""))
9573               (const_string "alu")
9574            ]
9575            (const_string "ishift1")))
9576    (set (attr "length_immediate")
9577      (if_then_else
9578        (ior (eq_attr "type" "alu")
9579             (and (eq_attr "type" "ishift1")
9580                  (and (match_operand 1 "const1_operand" "")
9581                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9582                           (const_int 0)))))
9583        (const_string "0")
9584        (const_string "*")))
9585    (set_attr "mode" "QI")])
9586
9587 ;; Convert lea to the lea pattern to avoid flags dependency.
9588 (define_split
9589   [(set (match_operand:DI 0 "register_operand" "")
9590         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
9591                    (match_operand:QI 2 "const_int_operand" "")))
9592    (clobber (reg:CC FLAGS_REG))]
9593   "TARGET_64BIT && reload_completed
9594    && true_regnum (operands[0]) != true_regnum (operands[1])"
9595   [(set (match_dup 0)
9596         (mult:DI (match_dup 1)
9597                  (match_dup 2)))]
9598   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
9599
9600 ;; Convert lea to the lea pattern to avoid flags dependency.
9601 (define_split
9602   [(set (match_operand 0 "register_operand" "")
9603         (ashift (match_operand 1 "index_register_operand" "")
9604                 (match_operand:QI 2 "const_int_operand" "")))
9605    (clobber (reg:CC FLAGS_REG))]
9606   "reload_completed
9607    && true_regnum (operands[0]) != true_regnum (operands[1])
9608    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
9609   [(const_int 0)]
9610 {
9611   rtx pat;
9612   enum machine_mode mode = GET_MODE (operands[0]);
9613
9614   if (GET_MODE_SIZE (mode) < 4)
9615     operands[0] = gen_lowpart (SImode, operands[0]);
9616   if (mode != Pmode)
9617     operands[1] = gen_lowpart (Pmode, operands[1]);
9618   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
9619
9620   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
9621   if (Pmode != SImode)
9622     pat = gen_rtx_SUBREG (SImode, pat, 0);
9623   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9624   DONE;
9625 })
9626
9627 ;; Rare case of shifting RSP is handled by generating move and shift
9628 (define_split
9629   [(set (match_operand 0 "register_operand" "")
9630         (ashift (match_operand 1 "register_operand" "")
9631                 (match_operand:QI 2 "const_int_operand" "")))
9632    (clobber (reg:CC FLAGS_REG))]
9633   "reload_completed
9634    && true_regnum (operands[0]) != true_regnum (operands[1])"
9635   [(const_int 0)]
9636 {
9637   rtx pat, clob;
9638   emit_move_insn (operands[0], operands[1]);
9639   pat = gen_rtx_SET (VOIDmode, operands[0],
9640                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
9641                                      operands[0], operands[2]));
9642   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
9643   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
9644   DONE;
9645 })
9646
9647 ;; Convert lea to the lea pattern to avoid flags dependency.
9648 (define_split
9649   [(set (match_operand:DI 0 "register_operand" "")
9650         (zero_extend:DI
9651           (ashift:SI (match_operand:SI 1 "register_operand" "")
9652                      (match_operand:QI 2 "const_int_operand" ""))))
9653    (clobber (reg:CC FLAGS_REG))]
9654   "TARGET_64BIT && reload_completed
9655    && true_regnum (operands[0]) != true_regnum (operands[1])"
9656   [(set (match_dup 0)
9657         (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9658 {
9659   operands[1] = gen_lowpart (Pmode, operands[1]);
9660   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
9661 })
9662
9663 ;; This pattern can't accept a variable shift count, since shifts by
9664 ;; zero don't affect the flags.  We assume that shifts by constant
9665 ;; zero are optimized away.
9666 (define_insn "*ashl<mode>3_cmp"
9667   [(set (reg FLAGS_REG)
9668         (compare
9669           (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9670                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9671           (const_int 0)))
9672    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9673         (ashift:SWI (match_dup 1) (match_dup 2)))]
9674   "(optimize_function_for_size_p (cfun)
9675     || !TARGET_PARTIAL_FLAG_REG_STALL
9676     || (operands[2] == const1_rtx
9677         && (TARGET_SHIFT1
9678             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9679    && ix86_match_ccmode (insn, CCGOCmode)
9680    && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9681 {
9682   switch (get_attr_type (insn))
9683     {
9684     case TYPE_ALU:
9685       gcc_assert (operands[2] == const1_rtx);
9686       return "add{<imodesuffix>}\t%0, %0";
9687
9688     default:
9689       if (operands[2] == const1_rtx
9690           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9691         return "sal{<imodesuffix>}\t%0";
9692       else
9693         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9694     }
9695 }
9696   [(set (attr "type")
9697      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9698                           (const_int 0))
9699                       (match_operand 0 "register_operand" ""))
9700                  (match_operand 2 "const1_operand" ""))
9701               (const_string "alu")
9702            ]
9703            (const_string "ishift")))
9704    (set (attr "length_immediate")
9705      (if_then_else
9706        (ior (eq_attr "type" "alu")
9707             (and (eq_attr "type" "ishift")
9708                  (and (match_operand 2 "const1_operand" "")
9709                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9710                           (const_int 0)))))
9711        (const_string "0")
9712        (const_string "*")))
9713    (set_attr "mode" "<MODE>")])
9714
9715 (define_insn "*ashlsi3_cmp_zext"
9716   [(set (reg FLAGS_REG)
9717         (compare
9718           (ashift:SI (match_operand:SI 1 "register_operand" "0")
9719                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
9720           (const_int 0)))
9721    (set (match_operand:DI 0 "register_operand" "=r")
9722         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9723   "TARGET_64BIT
9724    && (optimize_function_for_size_p (cfun)
9725        || !TARGET_PARTIAL_FLAG_REG_STALL
9726        || (operands[2] == const1_rtx
9727            && (TARGET_SHIFT1
9728                || TARGET_DOUBLE_WITH_ADD)))
9729    && ix86_match_ccmode (insn, CCGOCmode)
9730    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9731 {
9732   switch (get_attr_type (insn))
9733     {
9734     case TYPE_ALU:
9735       gcc_assert (operands[2] == const1_rtx);
9736       return "add{l}\t%k0, %k0";
9737
9738     default:
9739       if (operands[2] == const1_rtx
9740           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9741         return "sal{l}\t%k0";
9742       else
9743         return "sal{l}\t{%2, %k0|%k0, %2}";
9744     }
9745 }
9746   [(set (attr "type")
9747      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9748                      (const_int 0))
9749                  (match_operand 2 "const1_operand" ""))
9750               (const_string "alu")
9751            ]
9752            (const_string "ishift")))
9753    (set (attr "length_immediate")
9754      (if_then_else
9755        (ior (eq_attr "type" "alu")
9756             (and (eq_attr "type" "ishift")
9757                  (and (match_operand 2 "const1_operand" "")
9758                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9759                           (const_int 0)))))
9760        (const_string "0")
9761        (const_string "*")))
9762    (set_attr "mode" "SI")])
9763
9764 (define_insn "*ashl<mode>3_cconly"
9765   [(set (reg FLAGS_REG)
9766         (compare
9767           (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9768                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9769           (const_int 0)))
9770    (clobber (match_scratch:SWI 0 "=<r>"))]
9771   "(optimize_function_for_size_p (cfun)
9772     || !TARGET_PARTIAL_FLAG_REG_STALL
9773     || (operands[2] == const1_rtx
9774         && (TARGET_SHIFT1
9775             || TARGET_DOUBLE_WITH_ADD)))
9776    && ix86_match_ccmode (insn, CCGOCmode)
9777    && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9778 {
9779   switch (get_attr_type (insn))
9780     {
9781     case TYPE_ALU:
9782       gcc_assert (operands[2] == const1_rtx);
9783       return "add{<imodesuffix>}\t%0, %0";
9784
9785     default:
9786       if (operands[2] == const1_rtx
9787           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9788         return "sal{<imodesuffix>}\t%0";
9789       else
9790         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9791     }
9792 }
9793   [(set (attr "type")
9794      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9795                           (const_int 0))
9796                       (match_operand 0 "register_operand" ""))
9797                  (match_operand 2 "const1_operand" ""))
9798               (const_string "alu")
9799            ]
9800            (const_string "ishift")))
9801    (set (attr "length_immediate")
9802      (if_then_else
9803        (ior (eq_attr "type" "alu")
9804             (and (eq_attr "type" "ishift")
9805                  (and (match_operand 2 "const1_operand" "")
9806                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9807                           (const_int 0)))))
9808        (const_string "0")
9809        (const_string "*")))
9810    (set_attr "mode" "<MODE>")])
9811
9812 ;; See comment above `ashl<mode>3' about how this works.
9813
9814 (define_expand "<shiftrt_insn><mode>3"
9815   [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9816         (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
9817                            (match_operand:QI 2 "nonmemory_operand" "")))]
9818   ""
9819   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9820
9821 (define_insn_and_split "*<shiftrt_insn><mode>3_doubleword"
9822   [(set (match_operand:DWI 0 "register_operand" "=r")
9823         (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9824                          (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9825    (clobber (reg:CC FLAGS_REG))]
9826   ""
9827   "#"
9828   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9829   [(const_int 0)]
9830   "ix86_split_<shiftrt_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9831   [(set_attr "type" "multi")])
9832
9833 ;; By default we don't ask for a scratch register, because when DWImode
9834 ;; values are manipulated, registers are already at a premium.  But if
9835 ;; we have one handy, we won't turn it away.
9836
9837 (define_peephole2
9838   [(match_scratch:DWIH 3 "r")
9839    (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9840                    (any_shiftrt:<DWI>
9841                      (match_operand:<DWI> 1 "register_operand" "")
9842                      (match_operand:QI 2 "nonmemory_operand" "")))
9843               (clobber (reg:CC FLAGS_REG))])
9844    (match_dup 3)]
9845   "TARGET_CMOVE"
9846   [(const_int 0)]
9847   "ix86_split_<shiftrt_insn> (operands, operands[3], <DWI>mode); DONE;")
9848
9849 (define_insn "x86_64_shrd"
9850   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9851         (ior:DI (ashiftrt:DI (match_dup 0)
9852                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
9853                 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9854                   (minus:QI (const_int 64) (match_dup 2)))))
9855    (clobber (reg:CC FLAGS_REG))]
9856   "TARGET_64BIT"
9857   "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9858   [(set_attr "type" "ishift")
9859    (set_attr "prefix_0f" "1")
9860    (set_attr "mode" "DI")
9861    (set_attr "athlon_decode" "vector")
9862    (set_attr "amdfam10_decode" "vector")])
9863
9864 (define_insn "x86_shrd"
9865   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9866         (ior:SI (ashiftrt:SI (match_dup 0)
9867                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
9868                 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9869                   (minus:QI (const_int 32) (match_dup 2)))))
9870    (clobber (reg:CC FLAGS_REG))]
9871   ""
9872   "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9873   [(set_attr "type" "ishift")
9874    (set_attr "prefix_0f" "1")
9875    (set_attr "mode" "SI")
9876    (set_attr "pent_pair" "np")
9877    (set_attr "athlon_decode" "vector")
9878    (set_attr "amdfam10_decode" "vector")])
9879
9880 (define_insn "ashrdi3_cvt"
9881   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9882         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9883                      (match_operand:QI 2 "const_int_operand" "")))
9884    (clobber (reg:CC FLAGS_REG))]
9885   "TARGET_64BIT && INTVAL (operands[2]) == 63
9886    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9887    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9888   "@
9889    {cqto|cqo}
9890    sar{q}\t{%2, %0|%0, %2}"
9891   [(set_attr "type" "imovx,ishift")
9892    (set_attr "prefix_0f" "0,*")
9893    (set_attr "length_immediate" "0,*")
9894    (set_attr "modrm" "0,1")
9895    (set_attr "mode" "DI")])
9896
9897 (define_insn "ashrsi3_cvt"
9898   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9899         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9900                      (match_operand:QI 2 "const_int_operand" "")))
9901    (clobber (reg:CC FLAGS_REG))]
9902   "INTVAL (operands[2]) == 31
9903    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9904    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9905   "@
9906    {cltd|cdq}
9907    sar{l}\t{%2, %0|%0, %2}"
9908   [(set_attr "type" "imovx,ishift")
9909    (set_attr "prefix_0f" "0,*")
9910    (set_attr "length_immediate" "0,*")
9911    (set_attr "modrm" "0,1")
9912    (set_attr "mode" "SI")])
9913
9914 (define_insn "*ashrsi3_cvt_zext"
9915   [(set (match_operand:DI 0 "register_operand" "=*d,r")
9916         (zero_extend:DI
9917           (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9918                        (match_operand:QI 2 "const_int_operand" ""))))
9919    (clobber (reg:CC FLAGS_REG))]
9920   "TARGET_64BIT && INTVAL (operands[2]) == 31
9921    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9922    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9923   "@
9924    {cltd|cdq}
9925    sar{l}\t{%2, %k0|%k0, %2}"
9926   [(set_attr "type" "imovx,ishift")
9927    (set_attr "prefix_0f" "0,*")
9928    (set_attr "length_immediate" "0,*")
9929    (set_attr "modrm" "0,1")
9930    (set_attr "mode" "SI")])
9931
9932 (define_expand "x86_shift<mode>_adj_3"
9933   [(use (match_operand:SWI48 0 "register_operand" ""))
9934    (use (match_operand:SWI48 1 "register_operand" ""))
9935    (use (match_operand:QI 2 "register_operand" ""))]
9936   ""
9937 {
9938   rtx label = gen_label_rtx ();
9939   rtx tmp;
9940
9941   emit_insn (gen_testqi_ccz_1 (operands[2],
9942                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9943
9944   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9945   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9946   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9947                               gen_rtx_LABEL_REF (VOIDmode, label),
9948                               pc_rtx);
9949   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9950   JUMP_LABEL (tmp) = label;
9951
9952   emit_move_insn (operands[0], operands[1]);
9953   emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9954                                   GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9955   emit_label (label);
9956   LABEL_NUSES (label) = 1;
9957
9958   DONE;
9959 })
9960
9961 (define_insn "*<shiftrt_insn><mode>3_1"
9962   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9963         (any_shiftrt:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9964                          (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9965    (clobber (reg:CC FLAGS_REG))]
9966   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9967 {
9968   if (operands[2] == const1_rtx
9969       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9970     return "<shiftrt>{<imodesuffix>}\t%0";
9971   else
9972     return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9973 }
9974   [(set_attr "type" "ishift")
9975    (set (attr "length_immediate")
9976      (if_then_else
9977        (and (match_operand 2 "const1_operand" "")
9978             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9979                 (const_int 0)))
9980        (const_string "0")
9981        (const_string "*")))
9982    (set_attr "mode" "<MODE>")])
9983
9984 (define_insn "*<shiftrt_insn>si3_1_zext"
9985   [(set (match_operand:DI 0 "register_operand" "=r")
9986         (zero_extend:DI
9987           (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9988                           (match_operand:QI 2 "nonmemory_operand" "cI"))))
9989    (clobber (reg:CC FLAGS_REG))]
9990   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9991 {
9992   if (operands[2] == const1_rtx
9993       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9994     return "<shiftrt>{l}\t%k0";
9995   else
9996     return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
9997 }
9998   [(set_attr "type" "ishift")
9999    (set (attr "length_immediate")
10000      (if_then_else
10001        (and (match_operand 2 "const1_operand" "")
10002             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10003                 (const_int 0)))
10004        (const_string "0")
10005        (const_string "*")))
10006    (set_attr "mode" "SI")])
10007
10008 (define_insn "*<shiftrt_insn>qi3_1_slp"
10009   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10010         (any_shiftrt:QI (match_dup 0)
10011                         (match_operand:QI 1 "nonmemory_operand" "cI")))
10012    (clobber (reg:CC FLAGS_REG))]
10013   "(optimize_function_for_size_p (cfun)
10014     || !TARGET_PARTIAL_REG_STALL
10015     || (operands[1] == const1_rtx
10016         && TARGET_SHIFT1))"
10017 {
10018   if (operands[1] == const1_rtx
10019       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10020     return "<shiftrt>{b}\t%0";
10021   else
10022     return "<shiftrt>{b}\t{%1, %0|%0, %1}";
10023 }
10024   [(set_attr "type" "ishift1")
10025    (set (attr "length_immediate")
10026      (if_then_else
10027        (and (match_operand 1 "const1_operand" "")
10028             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10029                 (const_int 0)))
10030        (const_string "0")
10031        (const_string "*")))
10032    (set_attr "mode" "QI")])
10033
10034 ;; This pattern can't accept a variable shift count, since shifts by
10035 ;; zero don't affect the flags.  We assume that shifts by constant
10036 ;; zero are optimized away.
10037 (define_insn "*<shiftrt_insn><mode>3_cmp"
10038   [(set (reg FLAGS_REG)
10039         (compare
10040           (any_shiftrt:SWI
10041             (match_operand:SWI 1 "nonimmediate_operand" "0")
10042             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10043           (const_int 0)))
10044    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10045         (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
10046   "(optimize_function_for_size_p (cfun)
10047     || !TARGET_PARTIAL_FLAG_REG_STALL
10048     || (operands[2] == const1_rtx
10049         && TARGET_SHIFT1))
10050    && ix86_match_ccmode (insn, CCGOCmode)
10051    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10052 {
10053   if (operands[2] == const1_rtx
10054       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10055     return "<shiftrt>{<imodesuffix>}\t%0";
10056   else
10057     return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
10058 }
10059   [(set_attr "type" "ishift")
10060    (set (attr "length_immediate")
10061      (if_then_else
10062        (and (match_operand 2 "const1_operand" "")
10063             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10064                 (const_int 0)))
10065        (const_string "0")
10066        (const_string "*")))
10067    (set_attr "mode" "<MODE>")])
10068
10069 (define_insn "*<shiftrt_insn>si3_cmp_zext"
10070   [(set (reg FLAGS_REG)
10071         (compare
10072           (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10073                           (match_operand:QI 2 "const_1_to_31_operand" "I"))
10074           (const_int 0)))
10075    (set (match_operand:DI 0 "register_operand" "=r")
10076         (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10077   "TARGET_64BIT
10078    && (optimize_function_for_size_p (cfun)
10079        || !TARGET_PARTIAL_FLAG_REG_STALL
10080        || (operands[2] == const1_rtx
10081            && TARGET_SHIFT1))
10082    && ix86_match_ccmode (insn, CCGOCmode)
10083    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10084 {
10085   if (operands[2] == const1_rtx
10086       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10087     return "<shiftrt>{l}\t%k0";
10088   else
10089     return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
10090 }
10091   [(set_attr "type" "ishift")
10092    (set (attr "length_immediate")
10093      (if_then_else
10094        (and (match_operand 2 "const1_operand" "")
10095             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10096                 (const_int 0)))
10097        (const_string "0")
10098        (const_string "*")))
10099    (set_attr "mode" "SI")])
10100
10101 (define_insn "*<shiftrt_insn><mode>3_cconly"
10102   [(set (reg FLAGS_REG)
10103         (compare
10104           (any_shiftrt:SWI
10105             (match_operand:SWI 1 "nonimmediate_operand" "0")
10106             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10107           (const_int 0)))
10108    (clobber (match_scratch:SWI 0 "=<r>"))]
10109   "(optimize_function_for_size_p (cfun)
10110     || !TARGET_PARTIAL_FLAG_REG_STALL
10111     || (operands[2] == const1_rtx
10112         && TARGET_SHIFT1))
10113    && ix86_match_ccmode (insn, CCGOCmode)
10114    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10115 {
10116   if (operands[2] == const1_rtx
10117       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10118     return "<shiftrt>{<imodesuffix>}\t%0";
10119   else
10120     return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
10121 }
10122   [(set_attr "type" "ishift")
10123    (set (attr "length_immediate")
10124      (if_then_else
10125        (and (match_operand 2 "const1_operand" "")
10126             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10127                 (const_int 0)))
10128        (const_string "0")
10129        (const_string "*")))
10130    (set_attr "mode" "<MODE>")])
10131 \f
10132 ;; Rotate instructions
10133
10134 (define_expand "<rotate_insn>ti3"
10135   [(set (match_operand:TI 0 "register_operand" "")
10136         (any_rotate:TI (match_operand:TI 1 "register_operand" "")
10137                        (match_operand:QI 2 "nonmemory_operand" "")))]
10138   "TARGET_64BIT"
10139 {
10140   if (const_1_to_63_operand (operands[2], VOIDmode))
10141     emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10142                 (operands[0], operands[1], operands[2]));
10143   else
10144     FAIL;
10145
10146   DONE;
10147 })
10148
10149 (define_expand "<rotate_insn>di3"
10150   [(set (match_operand:DI 0 "shiftdi_operand" "")
10151         (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
10152                        (match_operand:QI 2 "nonmemory_operand" "")))]
10153  ""
10154 {
10155   if (TARGET_64BIT)
10156     ix86_expand_binary_operator (<CODE>, DImode, operands);
10157   else if (const_1_to_31_operand (operands[2], VOIDmode))
10158     emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10159                 (operands[0], operands[1], operands[2]));
10160   else
10161     FAIL;
10162
10163   DONE;
10164 })
10165
10166 (define_expand "<rotate_insn><mode>3"
10167   [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
10168         (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
10169                             (match_operand:QI 2 "nonmemory_operand" "")))]
10170   ""
10171   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10172
10173 ;; Implement rotation using two double-precision
10174 ;; shift instructions and a scratch register.
10175
10176 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10177  [(set (match_operand:<DWI> 0 "register_operand" "=r")
10178        (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10179                      (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10180   (clobber (reg:CC FLAGS_REG))
10181   (clobber (match_scratch:DWIH 3 "=&r"))]
10182  ""
10183  "#"
10184  "reload_completed"
10185  [(set (match_dup 3) (match_dup 4))
10186   (parallel
10187    [(set (match_dup 4)
10188          (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10189                    (lshiftrt:DWIH (match_dup 5)
10190                                   (minus:QI (match_dup 6) (match_dup 2)))))
10191     (clobber (reg:CC FLAGS_REG))])
10192   (parallel
10193    [(set (match_dup 5)
10194          (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10195                    (lshiftrt:DWIH (match_dup 3)
10196                                   (minus:QI (match_dup 6) (match_dup 2)))))
10197     (clobber (reg:CC FLAGS_REG))])]
10198 {
10199   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10200
10201   split_<dwi> (&operands[0], 1, &operands[4], &operands[5]);
10202 })
10203
10204 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10205  [(set (match_operand:<DWI> 0 "register_operand" "=r")
10206        (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10207                        (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10208   (clobber (reg:CC FLAGS_REG))
10209   (clobber (match_scratch:DWIH 3 "=&r"))]
10210  ""
10211  "#"
10212  "reload_completed"
10213  [(set (match_dup 3) (match_dup 4))
10214   (parallel
10215    [(set (match_dup 4)
10216          (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10217                    (ashift:DWIH (match_dup 5)
10218                                 (minus:QI (match_dup 6) (match_dup 2)))))
10219     (clobber (reg:CC FLAGS_REG))])
10220   (parallel
10221    [(set (match_dup 5)
10222          (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10223                    (ashift:DWIH (match_dup 3)
10224                                 (minus:QI (match_dup 6) (match_dup 2)))))
10225     (clobber (reg:CC FLAGS_REG))])]
10226 {
10227   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10228
10229   split_<dwi> (&operands[0], 1, &operands[4], &operands[5]);
10230 })
10231
10232 (define_insn "*<rotate_insn><mode>3_1"
10233   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10234         (any_rotate:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10235                         (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10236    (clobber (reg:CC FLAGS_REG))]
10237   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10238 {
10239   if (operands[2] == const1_rtx
10240       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10241     return "<rotate>{<imodesuffix>}\t%0";
10242   else
10243     return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10244 }
10245   [(set_attr "type" "rotate")
10246    (set (attr "length_immediate")
10247      (if_then_else
10248        (and (match_operand 2 "const1_operand" "")
10249             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10250                 (const_int 0)))
10251        (const_string "0")
10252        (const_string "*")))
10253    (set_attr "mode" "<MODE>")])
10254
10255 (define_insn "*<rotate_insn>si3_1_zext"
10256   [(set (match_operand:DI 0 "register_operand" "=r")
10257         (zero_extend:DI
10258           (any_rotate:SI (match_operand:SI 1 "register_operand" "0")
10259                          (match_operand:QI 2 "nonmemory_operand" "cI"))))
10260    (clobber (reg:CC FLAGS_REG))]
10261   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10262 {
10263     if (operands[2] == const1_rtx
10264         && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10265     return "<rotate>{l}\t%k0";
10266   else
10267     return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10268 }
10269   [(set_attr "type" "rotate")
10270    (set (attr "length_immediate")
10271      (if_then_else
10272        (and (match_operand 2 "const1_operand" "")
10273             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10274                 (const_int 0)))
10275        (const_string "0")
10276        (const_string "*")))
10277    (set_attr "mode" "SI")])
10278
10279 (define_insn "*<rotate_insn>qi3_1_slp"
10280   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10281         (any_rotate:QI (match_dup 0)
10282                        (match_operand:QI 1 "nonmemory_operand" "cI")))
10283    (clobber (reg:CC FLAGS_REG))]
10284   "(optimize_function_for_size_p (cfun)
10285     || !TARGET_PARTIAL_REG_STALL
10286     || (operands[1] == const1_rtx
10287         && TARGET_SHIFT1))"
10288 {
10289   if (operands[1] == const1_rtx
10290       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10291     return "<rotate>{b}\t%0";
10292   else
10293     return "<rotate>{b}\t{%1, %0|%0, %1}";
10294 }
10295   [(set_attr "type" "rotate1")
10296    (set (attr "length_immediate")
10297      (if_then_else
10298        (and (match_operand 1 "const1_operand" "")
10299             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10300                 (const_int 0)))
10301        (const_string "0")
10302        (const_string "*")))
10303    (set_attr "mode" "QI")])
10304
10305 (define_split
10306  [(set (match_operand:HI 0 "register_operand" "")
10307        (any_rotate:HI (match_dup 0) (const_int 8)))
10308   (clobber (reg:CC FLAGS_REG))]
10309  "reload_completed
10310   && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10311  [(parallel [(set (strict_low_part (match_dup 0))
10312                   (bswap:HI (match_dup 0)))
10313              (clobber (reg:CC FLAGS_REG))])]
10314  "")
10315 \f
10316 ;; Bit set / bit test instructions
10317
10318 (define_expand "extv"
10319   [(set (match_operand:SI 0 "register_operand" "")
10320         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10321                          (match_operand:SI 2 "const8_operand" "")
10322                          (match_operand:SI 3 "const8_operand" "")))]
10323   ""
10324 {
10325   /* Handle extractions from %ah et al.  */
10326   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10327     FAIL;
10328
10329   /* From mips.md: extract_bit_field doesn't verify that our source
10330      matches the predicate, so check it again here.  */
10331   if (! ext_register_operand (operands[1], VOIDmode))
10332     FAIL;
10333 })
10334
10335 (define_expand "extzv"
10336   [(set (match_operand:SI 0 "register_operand" "")
10337         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10338                          (match_operand:SI 2 "const8_operand" "")
10339                          (match_operand:SI 3 "const8_operand" "")))]
10340   ""
10341 {
10342   /* Handle extractions from %ah et al.  */
10343   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10344     FAIL;
10345
10346   /* From mips.md: extract_bit_field doesn't verify that our source
10347      matches the predicate, so check it again here.  */
10348   if (! ext_register_operand (operands[1], VOIDmode))
10349     FAIL;
10350 })
10351
10352 (define_expand "insv"
10353   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
10354                       (match_operand 1 "const8_operand" "")
10355                       (match_operand 2 "const8_operand" ""))
10356         (match_operand 3 "register_operand" ""))]
10357   ""
10358 {
10359   rtx (*gen_mov_insv_1) (rtx, rtx);
10360
10361   /* Handle insertions to %ah et al.  */
10362   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10363     FAIL;
10364
10365   /* From mips.md: insert_bit_field doesn't verify that our source
10366      matches the predicate, so check it again here.  */
10367   if (! ext_register_operand (operands[0], VOIDmode))
10368     FAIL;
10369
10370   gen_mov_insv_1 = (TARGET_64BIT
10371                     ? gen_movdi_insv_1 : gen_movsi_insv_1);
10372
10373   emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10374   DONE;
10375 })
10376
10377 ;; %%% bts, btr, btc, bt.
10378 ;; In general these instructions are *slow* when applied to memory,
10379 ;; since they enforce atomic operation.  When applied to registers,
10380 ;; it depends on the cpu implementation.  They're never faster than
10381 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10382 ;; no point.  But in 64-bit, we can't hold the relevant immediates
10383 ;; within the instruction itself, so operating on bits in the high
10384 ;; 32-bits of a register becomes easier.
10385 ;;
10386 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
10387 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10388 ;; negdf respectively, so they can never be disabled entirely.
10389
10390 (define_insn "*btsq"
10391   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10392                          (const_int 1)
10393                          (match_operand:DI 1 "const_0_to_63_operand" ""))
10394         (const_int 1))
10395    (clobber (reg:CC FLAGS_REG))]
10396   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10397   "bts{q}\t{%1, %0|%0, %1}"
10398   [(set_attr "type" "alu1")
10399    (set_attr "prefix_0f" "1")
10400    (set_attr "mode" "DI")])
10401
10402 (define_insn "*btrq"
10403   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10404                          (const_int 1)
10405                          (match_operand:DI 1 "const_0_to_63_operand" ""))
10406         (const_int 0))
10407    (clobber (reg:CC FLAGS_REG))]
10408   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10409   "btr{q}\t{%1, %0|%0, %1}"
10410   [(set_attr "type" "alu1")
10411    (set_attr "prefix_0f" "1")
10412    (set_attr "mode" "DI")])
10413
10414 (define_insn "*btcq"
10415   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10416                          (const_int 1)
10417                          (match_operand:DI 1 "const_0_to_63_operand" ""))
10418         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10419    (clobber (reg:CC FLAGS_REG))]
10420   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10421   "btc{q}\t{%1, %0|%0, %1}"
10422   [(set_attr "type" "alu1")
10423    (set_attr "prefix_0f" "1")
10424    (set_attr "mode" "DI")])
10425
10426 ;; Allow Nocona to avoid these instructions if a register is available.
10427
10428 (define_peephole2
10429   [(match_scratch:DI 2 "r")
10430    (parallel [(set (zero_extract:DI
10431                      (match_operand:DI 0 "register_operand" "")
10432                      (const_int 1)
10433                      (match_operand:DI 1 "const_0_to_63_operand" ""))
10434                    (const_int 1))
10435               (clobber (reg:CC FLAGS_REG))])]
10436   "TARGET_64BIT && !TARGET_USE_BT"
10437   [(const_int 0)]
10438 {
10439   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10440   rtx op1;
10441
10442   if (HOST_BITS_PER_WIDE_INT >= 64)
10443     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10444   else if (i < HOST_BITS_PER_WIDE_INT)
10445     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10446   else
10447     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10448
10449   op1 = immed_double_const (lo, hi, DImode);
10450   if (i >= 31)
10451     {
10452       emit_move_insn (operands[2], op1);
10453       op1 = operands[2];
10454     }
10455
10456   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10457   DONE;
10458 })
10459
10460 (define_peephole2
10461   [(match_scratch:DI 2 "r")
10462    (parallel [(set (zero_extract:DI
10463                      (match_operand:DI 0 "register_operand" "")
10464                      (const_int 1)
10465                      (match_operand:DI 1 "const_0_to_63_operand" ""))
10466                    (const_int 0))
10467               (clobber (reg:CC FLAGS_REG))])]
10468   "TARGET_64BIT && !TARGET_USE_BT"
10469   [(const_int 0)]
10470 {
10471   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10472   rtx op1;
10473
10474   if (HOST_BITS_PER_WIDE_INT >= 64)
10475     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10476   else if (i < HOST_BITS_PER_WIDE_INT)
10477     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10478   else
10479     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10480
10481   op1 = immed_double_const (~lo, ~hi, DImode);
10482   if (i >= 32)
10483     {
10484       emit_move_insn (operands[2], op1);
10485       op1 = operands[2];
10486     }
10487
10488   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10489   DONE;
10490 })
10491
10492 (define_peephole2
10493   [(match_scratch:DI 2 "r")
10494    (parallel [(set (zero_extract:DI
10495                      (match_operand:DI 0 "register_operand" "")
10496                      (const_int 1)
10497                      (match_operand:DI 1 "const_0_to_63_operand" ""))
10498               (not:DI (zero_extract:DI
10499                         (match_dup 0) (const_int 1) (match_dup 1))))
10500               (clobber (reg:CC FLAGS_REG))])]
10501   "TARGET_64BIT && !TARGET_USE_BT"
10502   [(const_int 0)]
10503 {
10504   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10505   rtx op1;
10506
10507   if (HOST_BITS_PER_WIDE_INT >= 64)
10508     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10509   else if (i < HOST_BITS_PER_WIDE_INT)
10510     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10511   else
10512     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10513
10514   op1 = immed_double_const (lo, hi, DImode);
10515   if (i >= 31)
10516     {
10517       emit_move_insn (operands[2], op1);
10518       op1 = operands[2];
10519     }
10520
10521   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10522   DONE;
10523 })
10524
10525 (define_insn "*bt<mode>"
10526   [(set (reg:CCC FLAGS_REG)
10527         (compare:CCC
10528           (zero_extract:SWI48
10529             (match_operand:SWI48 0 "register_operand" "r")
10530             (const_int 1)
10531             (match_operand:SWI48 1 "nonmemory_operand" "rN"))
10532           (const_int 0)))]
10533   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10534   "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10535   [(set_attr "type" "alu1")
10536    (set_attr "prefix_0f" "1")
10537    (set_attr "mode" "<MODE>")])
10538 \f
10539 ;; Store-flag instructions.
10540
10541 ;; For all sCOND expanders, also expand the compare or test insn that
10542 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
10543
10544 (define_insn_and_split "*setcc_di_1"
10545   [(set (match_operand:DI 0 "register_operand" "=q")
10546         (match_operator:DI 1 "ix86_comparison_operator"
10547           [(reg FLAGS_REG) (const_int 0)]))]
10548   "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10549   "#"
10550   "&& reload_completed"
10551   [(set (match_dup 2) (match_dup 1))
10552    (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10553 {
10554   PUT_MODE (operands[1], QImode);
10555   operands[2] = gen_lowpart (QImode, operands[0]);
10556 })
10557
10558 (define_insn_and_split "*setcc_si_1_and"
10559   [(set (match_operand:SI 0 "register_operand" "=q")
10560         (match_operator:SI 1 "ix86_comparison_operator"
10561           [(reg FLAGS_REG) (const_int 0)]))
10562    (clobber (reg:CC FLAGS_REG))]
10563   "!TARGET_PARTIAL_REG_STALL
10564    && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10565   "#"
10566   "&& reload_completed"
10567   [(set (match_dup 2) (match_dup 1))
10568    (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10569               (clobber (reg:CC FLAGS_REG))])]
10570 {
10571   PUT_MODE (operands[1], QImode);
10572   operands[2] = gen_lowpart (QImode, operands[0]);
10573 })
10574
10575 (define_insn_and_split "*setcc_si_1_movzbl"
10576   [(set (match_operand:SI 0 "register_operand" "=q")
10577         (match_operator:SI 1 "ix86_comparison_operator"
10578           [(reg FLAGS_REG) (const_int 0)]))]
10579   "!TARGET_PARTIAL_REG_STALL
10580    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10581   "#"
10582   "&& reload_completed"
10583   [(set (match_dup 2) (match_dup 1))
10584    (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10585 {
10586   PUT_MODE (operands[1], QImode);
10587   operands[2] = gen_lowpart (QImode, operands[0]);
10588 })
10589
10590 (define_insn "*setcc_qi"
10591   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10592         (match_operator:QI 1 "ix86_comparison_operator"
10593           [(reg FLAGS_REG) (const_int 0)]))]
10594   ""
10595   "set%C1\t%0"
10596   [(set_attr "type" "setcc")
10597    (set_attr "mode" "QI")])
10598
10599 (define_insn "*setcc_qi_slp"
10600   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10601         (match_operator:QI 1 "ix86_comparison_operator"
10602           [(reg FLAGS_REG) (const_int 0)]))]
10603   ""
10604   "set%C1\t%0"
10605   [(set_attr "type" "setcc")
10606    (set_attr "mode" "QI")])
10607
10608 ;; In general it is not safe to assume too much about CCmode registers,
10609 ;; so simplify-rtx stops when it sees a second one.  Under certain
10610 ;; conditions this is safe on x86, so help combine not create
10611 ;;
10612 ;;      seta    %al
10613 ;;      testb   %al, %al
10614 ;;      sete    %al
10615
10616 (define_split
10617   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10618         (ne:QI (match_operator 1 "ix86_comparison_operator"
10619                  [(reg FLAGS_REG) (const_int 0)])
10620             (const_int 0)))]
10621   ""
10622   [(set (match_dup 0) (match_dup 1))]
10623 {
10624   PUT_MODE (operands[1], QImode);
10625 })
10626
10627 (define_split
10628   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10629         (ne:QI (match_operator 1 "ix86_comparison_operator"
10630                  [(reg FLAGS_REG) (const_int 0)])
10631             (const_int 0)))]
10632   ""
10633   [(set (match_dup 0) (match_dup 1))]
10634 {
10635   PUT_MODE (operands[1], QImode);
10636 })
10637
10638 (define_split
10639   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10640         (eq:QI (match_operator 1 "ix86_comparison_operator"
10641                  [(reg FLAGS_REG) (const_int 0)])
10642             (const_int 0)))]
10643   ""
10644   [(set (match_dup 0) (match_dup 1))]
10645 {
10646   rtx new_op1 = copy_rtx (operands[1]);
10647   operands[1] = new_op1;
10648   PUT_MODE (new_op1, QImode);
10649   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10650                                              GET_MODE (XEXP (new_op1, 0))));
10651
10652   /* Make sure that (a) the CCmode we have for the flags is strong
10653      enough for the reversed compare or (b) we have a valid FP compare.  */
10654   if (! ix86_comparison_operator (new_op1, VOIDmode))
10655     FAIL;
10656 })
10657
10658 (define_split
10659   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10660         (eq:QI (match_operator 1 "ix86_comparison_operator"
10661                  [(reg FLAGS_REG) (const_int 0)])
10662             (const_int 0)))]
10663   ""
10664   [(set (match_dup 0) (match_dup 1))]
10665 {
10666   rtx new_op1 = copy_rtx (operands[1]);
10667   operands[1] = new_op1;
10668   PUT_MODE (new_op1, QImode);
10669   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10670                                              GET_MODE (XEXP (new_op1, 0))));
10671
10672   /* Make sure that (a) the CCmode we have for the flags is strong
10673      enough for the reversed compare or (b) we have a valid FP compare.  */
10674   if (! ix86_comparison_operator (new_op1, VOIDmode))
10675     FAIL;
10676 })
10677
10678 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10679 ;; subsequent logical operations are used to imitate conditional moves.
10680 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10681 ;; it directly.
10682
10683 (define_insn "*avx_setcc<mode>"
10684   [(set (match_operand:MODEF 0 "register_operand" "=x")
10685         (match_operator:MODEF 1 "avx_comparison_float_operator"
10686           [(match_operand:MODEF 2 "register_operand" "x")
10687            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
10688   "TARGET_AVX"
10689   "vcmp%D1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
10690   [(set_attr "type" "ssecmp")
10691    (set_attr "prefix" "vex")
10692    (set_attr "length_immediate" "1")
10693    (set_attr "mode" "<MODE>")])
10694
10695 (define_insn "*sse_setcc<mode>"
10696   [(set (match_operand:MODEF 0 "register_operand" "=x")
10697         (match_operator:MODEF 1 "sse_comparison_operator"
10698           [(match_operand:MODEF 2 "register_operand" "0")
10699            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
10700   "SSE_FLOAT_MODE_P (<MODE>mode)"
10701   "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
10702   [(set_attr "type" "ssecmp")
10703    (set_attr "length_immediate" "1")
10704    (set_attr "mode" "<MODE>")])
10705 \f
10706 ;; Basic conditional jump instructions.
10707 ;; We ignore the overflow flag for signed branch instructions.
10708
10709 (define_insn "*jcc_1"
10710   [(set (pc)
10711         (if_then_else (match_operator 1 "ix86_comparison_operator"
10712                                       [(reg FLAGS_REG) (const_int 0)])
10713                       (label_ref (match_operand 0 "" ""))
10714                       (pc)))]
10715   ""
10716   "%+j%C1\t%l0"
10717   [(set_attr "type" "ibr")
10718    (set_attr "modrm" "0")
10719    (set (attr "length")
10720            (if_then_else (and (ge (minus (match_dup 0) (pc))
10721                                   (const_int -126))
10722                               (lt (minus (match_dup 0) (pc))
10723                                   (const_int 128)))
10724              (const_int 2)
10725              (const_int 6)))])
10726
10727 (define_insn "*jcc_2"
10728   [(set (pc)
10729         (if_then_else (match_operator 1 "ix86_comparison_operator"
10730                                       [(reg FLAGS_REG) (const_int 0)])
10731                       (pc)
10732                       (label_ref (match_operand 0 "" ""))))]
10733   ""
10734   "%+j%c1\t%l0"
10735   [(set_attr "type" "ibr")
10736    (set_attr "modrm" "0")
10737    (set (attr "length")
10738            (if_then_else (and (ge (minus (match_dup 0) (pc))
10739                                   (const_int -126))
10740                               (lt (minus (match_dup 0) (pc))
10741                                   (const_int 128)))
10742              (const_int 2)
10743              (const_int 6)))])
10744
10745 ;; In general it is not safe to assume too much about CCmode registers,
10746 ;; so simplify-rtx stops when it sees a second one.  Under certain
10747 ;; conditions this is safe on x86, so help combine not create
10748 ;;
10749 ;;      seta    %al
10750 ;;      testb   %al, %al
10751 ;;      je      Lfoo
10752
10753 (define_split
10754   [(set (pc)
10755         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10756                                       [(reg FLAGS_REG) (const_int 0)])
10757                           (const_int 0))
10758                       (label_ref (match_operand 1 "" ""))
10759                       (pc)))]
10760   ""
10761   [(set (pc)
10762         (if_then_else (match_dup 0)
10763                       (label_ref (match_dup 1))
10764                       (pc)))]
10765 {
10766   PUT_MODE (operands[0], VOIDmode);
10767 })
10768
10769 (define_split
10770   [(set (pc)
10771         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10772                                       [(reg FLAGS_REG) (const_int 0)])
10773                           (const_int 0))
10774                       (label_ref (match_operand 1 "" ""))
10775                       (pc)))]
10776   ""
10777   [(set (pc)
10778         (if_then_else (match_dup 0)
10779                       (label_ref (match_dup 1))
10780                       (pc)))]
10781 {
10782   rtx new_op0 = copy_rtx (operands[0]);
10783   operands[0] = new_op0;
10784   PUT_MODE (new_op0, VOIDmode);
10785   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10786                                              GET_MODE (XEXP (new_op0, 0))));
10787
10788   /* Make sure that (a) the CCmode we have for the flags is strong
10789      enough for the reversed compare or (b) we have a valid FP compare.  */
10790   if (! ix86_comparison_operator (new_op0, VOIDmode))
10791     FAIL;
10792 })
10793
10794 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10795 ;; pass generates from shift insn with QImode operand.  Actually, the mode
10796 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10797 ;; appropriate modulo of the bit offset value.
10798
10799 (define_insn_and_split "*jcc_bt<mode>"
10800   [(set (pc)
10801         (if_then_else (match_operator 0 "bt_comparison_operator"
10802                         [(zero_extract:SWI48
10803                            (match_operand:SWI48 1 "register_operand" "r")
10804                            (const_int 1)
10805                            (zero_extend:SI
10806                              (match_operand:QI 2 "register_operand" "r")))
10807                          (const_int 0)])
10808                       (label_ref (match_operand 3 "" ""))
10809                       (pc)))
10810    (clobber (reg:CC FLAGS_REG))]
10811   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10812   "#"
10813   "&& 1"
10814   [(set (reg:CCC FLAGS_REG)
10815         (compare:CCC
10816           (zero_extract:SWI48
10817             (match_dup 1)
10818             (const_int 1)
10819             (match_dup 2))
10820           (const_int 0)))
10821    (set (pc)
10822         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10823                       (label_ref (match_dup 3))
10824                       (pc)))]
10825 {
10826   operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10827
10828   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10829 })
10830
10831 ;; Avoid useless masking of bit offset operand.  "and" in SImode is correct
10832 ;; also for DImode, this is what combine produces.
10833 (define_insn_and_split "*jcc_bt<mode>_mask"
10834   [(set (pc)
10835         (if_then_else (match_operator 0 "bt_comparison_operator"
10836                         [(zero_extract:SWI48
10837                            (match_operand:SWI48 1 "register_operand" "r")
10838                            (const_int 1)
10839                            (and:SI
10840                              (match_operand:SI 2 "register_operand" "r")
10841                              (match_operand:SI 3 "const_int_operand" "n")))])
10842                       (label_ref (match_operand 4 "" ""))
10843                       (pc)))
10844    (clobber (reg:CC FLAGS_REG))]
10845   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10846    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10847       == GET_MODE_BITSIZE (<MODE>mode)-1"
10848   "#"
10849   "&& 1"
10850   [(set (reg:CCC FLAGS_REG)
10851         (compare:CCC
10852           (zero_extract:SWI48
10853             (match_dup 1)
10854             (const_int 1)
10855             (match_dup 2))
10856           (const_int 0)))
10857    (set (pc)
10858         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10859                       (label_ref (match_dup 4))
10860                       (pc)))]
10861 {
10862   operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10863
10864   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10865 })
10866
10867 (define_insn_and_split "*jcc_btsi_1"
10868   [(set (pc)
10869         (if_then_else (match_operator 0 "bt_comparison_operator"
10870                         [(and:SI
10871                            (lshiftrt:SI
10872                              (match_operand:SI 1 "register_operand" "r")
10873                              (match_operand:QI 2 "register_operand" "r"))
10874                            (const_int 1))
10875                          (const_int 0)])
10876                       (label_ref (match_operand 3 "" ""))
10877                       (pc)))
10878    (clobber (reg:CC FLAGS_REG))]
10879   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10880   "#"
10881   "&& 1"
10882   [(set (reg:CCC FLAGS_REG)
10883         (compare:CCC
10884           (zero_extract:SI
10885             (match_dup 1)
10886             (const_int 1)
10887             (match_dup 2))
10888           (const_int 0)))
10889    (set (pc)
10890         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10891                       (label_ref (match_dup 3))
10892                       (pc)))]
10893 {
10894   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10895
10896   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10897 })
10898
10899 ;; avoid useless masking of bit offset operand
10900 (define_insn_and_split "*jcc_btsi_mask_1"
10901   [(set (pc)
10902         (if_then_else
10903           (match_operator 0 "bt_comparison_operator"
10904             [(and:SI
10905                (lshiftrt:SI
10906                  (match_operand:SI 1 "register_operand" "r")
10907                  (subreg:QI
10908                    (and:SI
10909                      (match_operand:SI 2 "register_operand" "r")
10910                      (match_operand:SI 3 "const_int_operand" "n")) 0))
10911                (const_int 1))
10912              (const_int 0)])
10913           (label_ref (match_operand 4 "" ""))
10914           (pc)))
10915    (clobber (reg:CC FLAGS_REG))]
10916   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10917    && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10918   "#"
10919   "&& 1"
10920   [(set (reg:CCC FLAGS_REG)
10921         (compare:CCC
10922           (zero_extract:SI
10923             (match_dup 1)
10924             (const_int 1)
10925             (match_dup 2))
10926           (const_int 0)))
10927    (set (pc)
10928         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10929                       (label_ref (match_dup 4))
10930                       (pc)))]
10931   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10932
10933 ;; Define combination compare-and-branch fp compare instructions to help
10934 ;; combine.
10935
10936 (define_insn "*fp_jcc_1_387"
10937   [(set (pc)
10938         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10939                         [(match_operand 1 "register_operand" "f")
10940                          (match_operand 2 "nonimmediate_operand" "fm")])
10941           (label_ref (match_operand 3 "" ""))
10942           (pc)))
10943    (clobber (reg:CCFP FPSR_REG))
10944    (clobber (reg:CCFP FLAGS_REG))
10945    (clobber (match_scratch:HI 4 "=a"))]
10946   "TARGET_80387
10947    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10948    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10949    && SELECT_CC_MODE (GET_CODE (operands[0]),
10950                       operands[1], operands[2]) == CCFPmode
10951    && !TARGET_CMOVE"
10952   "#")
10953
10954 (define_insn "*fp_jcc_1r_387"
10955   [(set (pc)
10956         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10957                         [(match_operand 1 "register_operand" "f")
10958                          (match_operand 2 "nonimmediate_operand" "fm")])
10959           (pc)
10960           (label_ref (match_operand 3 "" ""))))
10961    (clobber (reg:CCFP FPSR_REG))
10962    (clobber (reg:CCFP FLAGS_REG))
10963    (clobber (match_scratch:HI 4 "=a"))]
10964   "TARGET_80387
10965    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10966    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10967    && SELECT_CC_MODE (GET_CODE (operands[0]),
10968                       operands[1], operands[2]) == CCFPmode
10969    && !TARGET_CMOVE"
10970   "#")
10971
10972 (define_insn "*fp_jcc_2_387"
10973   [(set (pc)
10974         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10975                         [(match_operand 1 "register_operand" "f")
10976                          (match_operand 2 "register_operand" "f")])
10977           (label_ref (match_operand 3 "" ""))
10978           (pc)))
10979    (clobber (reg:CCFP FPSR_REG))
10980    (clobber (reg:CCFP FLAGS_REG))
10981    (clobber (match_scratch:HI 4 "=a"))]
10982   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10983    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10984    && !TARGET_CMOVE"
10985   "#")
10986
10987 (define_insn "*fp_jcc_2r_387"
10988   [(set (pc)
10989         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10990                         [(match_operand 1 "register_operand" "f")
10991                          (match_operand 2 "register_operand" "f")])
10992           (pc)
10993           (label_ref (match_operand 3 "" ""))))
10994    (clobber (reg:CCFP FPSR_REG))
10995    (clobber (reg:CCFP FLAGS_REG))
10996    (clobber (match_scratch:HI 4 "=a"))]
10997   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10998    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10999    && !TARGET_CMOVE"
11000   "#")
11001
11002 (define_insn "*fp_jcc_3_387"
11003   [(set (pc)
11004         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11005                         [(match_operand 1 "register_operand" "f")
11006                          (match_operand 2 "const0_operand" "")])
11007           (label_ref (match_operand 3 "" ""))
11008           (pc)))
11009    (clobber (reg:CCFP FPSR_REG))
11010    (clobber (reg:CCFP FLAGS_REG))
11011    (clobber (match_scratch:HI 4 "=a"))]
11012   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11013    && GET_MODE (operands[1]) == GET_MODE (operands[2])
11014    && SELECT_CC_MODE (GET_CODE (operands[0]),
11015                       operands[1], operands[2]) == CCFPmode
11016    && !TARGET_CMOVE"
11017   "#")
11018
11019 (define_split
11020   [(set (pc)
11021         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11022                         [(match_operand 1 "register_operand" "")
11023                          (match_operand 2 "nonimmediate_operand" "")])
11024           (match_operand 3 "" "")
11025           (match_operand 4 "" "")))
11026    (clobber (reg:CCFP FPSR_REG))
11027    (clobber (reg:CCFP FLAGS_REG))]
11028   "reload_completed"
11029   [(const_int 0)]
11030 {
11031   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11032                         operands[3], operands[4], NULL_RTX, NULL_RTX);
11033   DONE;
11034 })
11035
11036 (define_split
11037   [(set (pc)
11038         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11039                         [(match_operand 1 "register_operand" "")
11040                          (match_operand 2 "general_operand" "")])
11041           (match_operand 3 "" "")
11042           (match_operand 4 "" "")))
11043    (clobber (reg:CCFP FPSR_REG))
11044    (clobber (reg:CCFP FLAGS_REG))
11045    (clobber (match_scratch:HI 5 "=a"))]
11046   "reload_completed"
11047   [(const_int 0)]
11048 {
11049   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11050                         operands[3], operands[4], operands[5], NULL_RTX);
11051   DONE;
11052 })
11053
11054 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
11055 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11056 ;; with a precedence over other operators and is always put in the first
11057 ;; place. Swap condition and operands to match ficom instruction.
11058
11059 (define_insn "*fp_jcc_4_<mode>_387"
11060   [(set (pc)
11061         (if_then_else
11062           (match_operator 0 "ix86_swapped_fp_comparison_operator"
11063             [(match_operator 1 "float_operator"
11064               [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
11065              (match_operand 3 "register_operand" "f,f")])
11066           (label_ref (match_operand 4 "" ""))
11067           (pc)))
11068    (clobber (reg:CCFP FPSR_REG))
11069    (clobber (reg:CCFP FLAGS_REG))
11070    (clobber (match_scratch:HI 5 "=a,a"))]
11071   "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
11072    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
11073    && GET_MODE (operands[1]) == GET_MODE (operands[3])
11074    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
11075    && !TARGET_CMOVE"
11076   "#")
11077
11078 (define_split
11079   [(set (pc)
11080         (if_then_else
11081           (match_operator 0 "ix86_swapped_fp_comparison_operator"
11082             [(match_operator 1 "float_operator"
11083               [(match_operand:X87MODEI12 2 "memory_operand" "")])
11084              (match_operand 3 "register_operand" "")])
11085           (match_operand 4 "" "")
11086           (match_operand 5 "" "")))
11087    (clobber (reg:CCFP FPSR_REG))
11088    (clobber (reg:CCFP FLAGS_REG))
11089    (clobber (match_scratch:HI 6 "=a"))]
11090   "reload_completed"
11091   [(const_int 0)]
11092 {
11093   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
11094
11095   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11096                         operands[3], operands[7],
11097                         operands[4], operands[5], operands[6], NULL_RTX);
11098   DONE;
11099 })
11100
11101 ;; %%% Kill this when reload knows how to do it.
11102 (define_split
11103   [(set (pc)
11104         (if_then_else
11105           (match_operator 0 "ix86_swapped_fp_comparison_operator"
11106             [(match_operator 1 "float_operator"
11107               [(match_operand:X87MODEI12 2 "register_operand" "")])
11108              (match_operand 3 "register_operand" "")])
11109           (match_operand 4 "" "")
11110           (match_operand 5 "" "")))
11111    (clobber (reg:CCFP FPSR_REG))
11112    (clobber (reg:CCFP FLAGS_REG))
11113    (clobber (match_scratch:HI 6 "=a"))]
11114   "reload_completed"
11115   [(const_int 0)]
11116 {
11117   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11118   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
11119
11120   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11121                         operands[3], operands[7],
11122                         operands[4], operands[5], operands[6], operands[2]);
11123   DONE;
11124 })
11125 \f
11126 ;; Unconditional and other jump instructions
11127
11128 (define_insn "jump"
11129   [(set (pc)
11130         (label_ref (match_operand 0 "" "")))]
11131   ""
11132   "jmp\t%l0"
11133   [(set_attr "type" "ibr")
11134    (set (attr "length")
11135            (if_then_else (and (ge (minus (match_dup 0) (pc))
11136                                   (const_int -126))
11137                               (lt (minus (match_dup 0) (pc))
11138                                   (const_int 128)))
11139              (const_int 2)
11140              (const_int 5)))
11141    (set_attr "modrm" "0")])
11142
11143 (define_expand "indirect_jump"
11144   [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
11145   ""
11146   "")
11147
11148 (define_insn "*indirect_jump"
11149   [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
11150   ""
11151   "jmp\t%A0"
11152   [(set_attr "type" "ibr")
11153    (set_attr "length_immediate" "0")])
11154
11155 (define_expand "tablejump"
11156   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
11157               (use (label_ref (match_operand 1 "" "")))])]
11158   ""
11159 {
11160   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11161      relative.  Convert the relative address to an absolute address.  */
11162   if (flag_pic)
11163     {
11164       rtx op0, op1;
11165       enum rtx_code code;
11166
11167       /* We can't use @GOTOFF for text labels on VxWorks;
11168          see gotoff_operand.  */
11169       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11170         {
11171           code = PLUS;
11172           op0 = operands[0];
11173           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11174         }
11175       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11176         {
11177           code = PLUS;
11178           op0 = operands[0];
11179           op1 = pic_offset_table_rtx;
11180         }
11181       else
11182         {
11183           code = MINUS;
11184           op0 = pic_offset_table_rtx;
11185           op1 = operands[0];
11186         }
11187
11188       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11189                                          OPTAB_DIRECT);
11190     }
11191 })
11192
11193 (define_insn "*tablejump_1"
11194   [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
11195    (use (label_ref (match_operand 1 "" "")))]
11196   ""
11197   "jmp\t%A0"
11198   [(set_attr "type" "ibr")
11199    (set_attr "length_immediate" "0")])
11200 \f
11201 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11202
11203 (define_peephole2
11204   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11205    (set (match_operand:QI 1 "register_operand" "")
11206         (match_operator:QI 2 "ix86_comparison_operator"
11207           [(reg FLAGS_REG) (const_int 0)]))
11208    (set (match_operand 3 "q_regs_operand" "")
11209         (zero_extend (match_dup 1)))]
11210   "(peep2_reg_dead_p (3, operands[1])
11211     || operands_match_p (operands[1], operands[3]))
11212    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11213   [(set (match_dup 4) (match_dup 0))
11214    (set (strict_low_part (match_dup 5))
11215         (match_dup 2))]
11216 {
11217   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11218   operands[5] = gen_lowpart (QImode, operands[3]);
11219   ix86_expand_clear (operands[3]);
11220 })
11221
11222 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
11223
11224 (define_peephole2
11225   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11226    (set (match_operand:QI 1 "register_operand" "")
11227         (match_operator:QI 2 "ix86_comparison_operator"
11228           [(reg FLAGS_REG) (const_int 0)]))
11229    (parallel [(set (match_operand 3 "q_regs_operand" "")
11230                    (zero_extend (match_dup 1)))
11231               (clobber (reg:CC FLAGS_REG))])]
11232   "(peep2_reg_dead_p (3, operands[1])
11233     || operands_match_p (operands[1], operands[3]))
11234    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11235   [(set (match_dup 4) (match_dup 0))
11236    (set (strict_low_part (match_dup 5))
11237         (match_dup 2))]
11238 {
11239   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11240   operands[5] = gen_lowpart (QImode, operands[3]);
11241   ix86_expand_clear (operands[3]);
11242 })
11243 \f
11244 ;; Call instructions.
11245
11246 ;; The predicates normally associated with named expanders are not properly
11247 ;; checked for calls.  This is a bug in the generic code, but it isn't that
11248 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
11249
11250 ;; P6 processors will jump to the address after the decrement when %esp
11251 ;; is used as a call operand, so they will execute return address as a code.
11252 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11253  
11254 ;; Call subroutine returning no value.
11255
11256 (define_expand "call_pop"
11257   [(parallel [(call (match_operand:QI 0 "" "")
11258                     (match_operand:SI 1 "" ""))
11259               (set (reg:SI SP_REG)
11260                    (plus:SI (reg:SI SP_REG)
11261                             (match_operand:SI 3 "" "")))])]
11262   "!TARGET_64BIT"
11263 {
11264   ix86_expand_call (NULL, operands[0], operands[1],
11265                     operands[2], operands[3], 0);
11266   DONE;
11267 })
11268
11269 (define_insn "*call_pop_0"
11270   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
11271          (match_operand:SI 1 "" ""))
11272    (set (reg:SI SP_REG)
11273         (plus:SI (reg:SI SP_REG)
11274                  (match_operand:SI 2 "immediate_operand" "")))]
11275   "!TARGET_64BIT"
11276 {
11277   if (SIBLING_CALL_P (insn))
11278     return "jmp\t%P0";
11279   else
11280     return "call\t%P0";
11281 }
11282   [(set_attr "type" "call")])
11283
11284 (define_insn "*call_pop_1"
11285   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11286          (match_operand:SI 1 "" ""))
11287    (set (reg:SI SP_REG)
11288         (plus:SI (reg:SI SP_REG)
11289                  (match_operand:SI 2 "immediate_operand" "i")))]
11290   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11291 {
11292   if (constant_call_address_operand (operands[0], Pmode))
11293     return "call\t%P0";
11294   return "call\t%A0";
11295 }
11296   [(set_attr "type" "call")])
11297
11298 (define_insn "*sibcall_pop_1"
11299   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11300          (match_operand:SI 1 "" ""))
11301    (set (reg:SI SP_REG)
11302         (plus:SI (reg:SI SP_REG)
11303                  (match_operand:SI 2 "immediate_operand" "i,i")))]
11304   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11305   "@
11306    jmp\t%P0
11307    jmp\t%A0"
11308   [(set_attr "type" "call")])
11309
11310 (define_expand "call"
11311   [(call (match_operand:QI 0 "" "")
11312          (match_operand 1 "" ""))
11313    (use (match_operand 2 "" ""))]
11314   ""
11315 {
11316   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
11317   DONE;
11318 })
11319
11320 (define_expand "sibcall"
11321   [(call (match_operand:QI 0 "" "")
11322          (match_operand 1 "" ""))
11323    (use (match_operand 2 "" ""))]
11324   ""
11325 {
11326   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
11327   DONE;
11328 })
11329
11330 (define_insn "*call_0"
11331   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
11332          (match_operand 1 "" ""))]
11333   ""
11334 {
11335   if (SIBLING_CALL_P (insn))
11336     return "jmp\t%P0";
11337   else
11338     return "call\t%P0";
11339 }
11340   [(set_attr "type" "call")])
11341
11342 (define_insn "*call_1"
11343   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11344          (match_operand 1 "" ""))]
11345   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11346 {
11347   if (constant_call_address_operand (operands[0], Pmode))
11348     return "call\t%P0";
11349   return "call\t%A0";
11350 }
11351   [(set_attr "type" "call")])
11352
11353 (define_insn "*sibcall_1"
11354   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11355          (match_operand 1 "" ""))]
11356   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11357   "@
11358    jmp\t%P0
11359    jmp\t%A0"
11360   [(set_attr "type" "call")])
11361
11362 (define_insn "*call_1_rex64"
11363   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11364          (match_operand 1 "" ""))]
11365   "TARGET_64BIT && !SIBLING_CALL_P (insn)
11366    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
11367 {
11368   if (constant_call_address_operand (operands[0], Pmode))
11369     return "call\t%P0";
11370   return "call\t%A0";
11371 }
11372   [(set_attr "type" "call")])
11373
11374 (define_insn "*call_1_rex64_ms_sysv"
11375   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11376          (match_operand 1 "" ""))
11377    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11378    (clobber (reg:TI XMM6_REG))
11379    (clobber (reg:TI XMM7_REG))
11380    (clobber (reg:TI XMM8_REG))
11381    (clobber (reg:TI XMM9_REG))
11382    (clobber (reg:TI XMM10_REG))
11383    (clobber (reg:TI XMM11_REG))
11384    (clobber (reg:TI XMM12_REG))
11385    (clobber (reg:TI XMM13_REG))
11386    (clobber (reg:TI XMM14_REG))
11387    (clobber (reg:TI XMM15_REG))
11388    (clobber (reg:DI SI_REG))
11389    (clobber (reg:DI DI_REG))]
11390   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11391 {
11392   if (constant_call_address_operand (operands[0], Pmode))
11393     return "call\t%P0";
11394   return "call\t%A0";
11395 }
11396   [(set_attr "type" "call")])
11397
11398 (define_insn "*call_1_rex64_large"
11399   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
11400          (match_operand 1 "" ""))]
11401   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11402   "call\t%A0"
11403   [(set_attr "type" "call")])
11404
11405 (define_insn "*sibcall_1_rex64"
11406   [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
11407          (match_operand 1 "" ""))]
11408   "TARGET_64BIT && SIBLING_CALL_P (insn)"
11409   "@
11410    jmp\t%P0
11411    jmp\t%A0"
11412   [(set_attr "type" "call")])
11413
11414 ;; Call subroutine, returning value in operand 0
11415 (define_expand "call_value_pop"
11416   [(parallel [(set (match_operand 0 "" "")
11417                    (call (match_operand:QI 1 "" "")
11418                          (match_operand:SI 2 "" "")))
11419               (set (reg:SI SP_REG)
11420                    (plus:SI (reg:SI SP_REG)
11421                             (match_operand:SI 4 "" "")))])]
11422   "!TARGET_64BIT"
11423 {
11424   ix86_expand_call (operands[0], operands[1], operands[2],
11425                     operands[3], operands[4], 0);
11426   DONE;
11427 })
11428
11429 (define_expand "call_value"
11430   [(set (match_operand 0 "" "")
11431         (call (match_operand:QI 1 "" "")
11432               (match_operand:SI 2 "" "")))
11433    (use (match_operand:SI 3 "" ""))]
11434   ;; Operand 3 is not used on the i386.
11435   ""
11436 {
11437   ix86_expand_call (operands[0], operands[1], operands[2],
11438                     operands[3], NULL, 0);
11439   DONE;
11440 })
11441
11442 (define_expand "sibcall_value"
11443   [(set (match_operand 0 "" "")
11444         (call (match_operand:QI 1 "" "")
11445               (match_operand:SI 2 "" "")))
11446    (use (match_operand:SI 3 "" ""))]
11447   ;; Operand 3 is not used on the i386.
11448   ""
11449 {
11450   ix86_expand_call (operands[0], operands[1], operands[2],
11451                     operands[3], NULL, 1);
11452   DONE;
11453 })
11454
11455 ;; Call subroutine returning any type.
11456
11457 (define_expand "untyped_call"
11458   [(parallel [(call (match_operand 0 "" "")
11459                     (const_int 0))
11460               (match_operand 1 "" "")
11461               (match_operand 2 "" "")])]
11462   ""
11463 {
11464   int i;
11465
11466   /* In order to give reg-stack an easier job in validating two
11467      coprocessor registers as containing a possible return value,
11468      simply pretend the untyped call returns a complex long double
11469      value. 
11470
11471      We can't use SSE_REGPARM_MAX here since callee is unprototyped
11472      and should have the default ABI.  */
11473
11474   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11475                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11476                     operands[0], const0_rtx,
11477                     GEN_INT ((TARGET_64BIT
11478                               ? (ix86_abi == SYSV_ABI
11479                                  ? X86_64_SSE_REGPARM_MAX
11480                                  : X86_64_MS_SSE_REGPARM_MAX)
11481                               : X86_32_SSE_REGPARM_MAX)
11482                              - 1),
11483                     NULL, 0);
11484
11485   for (i = 0; i < XVECLEN (operands[2], 0); i++)
11486     {
11487       rtx set = XVECEXP (operands[2], 0, i);
11488       emit_move_insn (SET_DEST (set), SET_SRC (set));
11489     }
11490
11491   /* The optimizer does not know that the call sets the function value
11492      registers we stored in the result block.  We avoid problems by
11493      claiming that all hard registers are used and clobbered at this
11494      point.  */
11495   emit_insn (gen_blockage ());
11496
11497   DONE;
11498 })
11499 \f
11500 ;; Prologue and epilogue instructions
11501
11502 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11503 ;; all of memory.  This blocks insns from being moved across this point.
11504
11505 (define_insn "blockage"
11506   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11507   ""
11508   ""
11509   [(set_attr "length" "0")])
11510
11511 ;; Do not schedule instructions accessing memory across this point.
11512
11513 (define_expand "memory_blockage"
11514   [(set (match_dup 0)
11515         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11516   ""
11517 {
11518   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11519   MEM_VOLATILE_P (operands[0]) = 1;
11520 })
11521
11522 (define_insn "*memory_blockage"
11523   [(set (match_operand:BLK 0 "" "")
11524         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11525   ""
11526   ""
11527   [(set_attr "length" "0")])
11528
11529 ;; As USE insns aren't meaningful after reload, this is used instead
11530 ;; to prevent deleting instructions setting registers for PIC code
11531 (define_insn "prologue_use"
11532   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11533   ""
11534   ""
11535   [(set_attr "length" "0")])
11536
11537 ;; Insn emitted into the body of a function to return from a function.
11538 ;; This is only done if the function's epilogue is known to be simple.
11539 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11540
11541 (define_expand "return"
11542   [(return)]
11543   "ix86_can_use_return_insn_p ()"
11544 {
11545   if (crtl->args.pops_args)
11546     {
11547       rtx popc = GEN_INT (crtl->args.pops_args);
11548       emit_jump_insn (gen_return_pop_internal (popc));
11549       DONE;
11550     }
11551 })
11552
11553 (define_insn "return_internal"
11554   [(return)]
11555   "reload_completed"
11556   "ret"
11557   [(set_attr "length" "1")
11558    (set_attr "atom_unit" "jeu")
11559    (set_attr "length_immediate" "0")
11560    (set_attr "modrm" "0")])
11561
11562 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11563 ;; instruction Athlon and K8 have.
11564
11565 (define_insn "return_internal_long"
11566   [(return)
11567    (unspec [(const_int 0)] UNSPEC_REP)]
11568   "reload_completed"
11569   "rep\;ret"
11570   [(set_attr "length" "2")
11571    (set_attr "atom_unit" "jeu")
11572    (set_attr "length_immediate" "0")
11573    (set_attr "prefix_rep" "1")
11574    (set_attr "modrm" "0")])
11575
11576 (define_insn "return_pop_internal"
11577   [(return)
11578    (use (match_operand:SI 0 "const_int_operand" ""))]
11579   "reload_completed"
11580   "ret\t%0"
11581   [(set_attr "length" "3")
11582    (set_attr "atom_unit" "jeu")
11583    (set_attr "length_immediate" "2")
11584    (set_attr "modrm" "0")])
11585
11586 (define_insn "return_indirect_internal"
11587   [(return)
11588    (use (match_operand:SI 0 "register_operand" "r"))]
11589   "reload_completed"
11590   "jmp\t%A0"
11591   [(set_attr "type" "ibr")
11592    (set_attr "length_immediate" "0")])
11593
11594 (define_insn "nop"
11595   [(const_int 0)]
11596   ""
11597   "nop"
11598   [(set_attr "length" "1")
11599    (set_attr "length_immediate" "0")
11600    (set_attr "modrm" "0")])
11601
11602 ;; Pad to 16-byte boundary, max skip in op0.  Used to avoid
11603 ;; branch prediction penalty for the third jump in a 16-byte
11604 ;; block on K8.
11605
11606 (define_insn "pad"
11607   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
11608   ""
11609 {
11610 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11611   ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11612 #else
11613   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11614      The align insn is used to avoid 3 jump instructions in the row to improve
11615      branch prediction and the benefits hardly outweigh the cost of extra 8
11616      nops on the average inserted by full alignment pseudo operation.  */
11617 #endif
11618   return "";
11619 }
11620   [(set_attr "length" "16")])
11621
11622 (define_expand "prologue"
11623   [(const_int 0)]
11624   ""
11625   "ix86_expand_prologue (); DONE;")
11626
11627 (define_insn "set_got"
11628   [(set (match_operand:SI 0 "register_operand" "=r")
11629         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11630    (clobber (reg:CC FLAGS_REG))]
11631   "!TARGET_64BIT"
11632   { return output_set_got (operands[0], NULL_RTX); }
11633   [(set_attr "type" "multi")
11634    (set_attr "length" "12")])
11635
11636 (define_insn "set_got_labelled"
11637   [(set (match_operand:SI 0 "register_operand" "=r")
11638         (unspec:SI [(label_ref (match_operand 1 "" ""))]
11639          UNSPEC_SET_GOT))
11640    (clobber (reg:CC FLAGS_REG))]
11641   "!TARGET_64BIT"
11642   { return output_set_got (operands[0], operands[1]); }
11643   [(set_attr "type" "multi")
11644    (set_attr "length" "12")])
11645
11646 (define_insn "set_got_rex64"
11647   [(set (match_operand:DI 0 "register_operand" "=r")
11648         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11649   "TARGET_64BIT"
11650   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11651   [(set_attr "type" "lea")
11652    (set_attr "length_address" "4")
11653    (set_attr "mode" "DI")])
11654
11655 (define_insn "set_rip_rex64"
11656   [(set (match_operand:DI 0 "register_operand" "=r")
11657         (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
11658   "TARGET_64BIT"
11659   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11660   [(set_attr "type" "lea")
11661    (set_attr "length_address" "4")
11662    (set_attr "mode" "DI")])
11663
11664 (define_insn "set_got_offset_rex64"
11665   [(set (match_operand:DI 0 "register_operand" "=r")
11666         (unspec:DI
11667           [(label_ref (match_operand 1 "" ""))]
11668           UNSPEC_SET_GOT_OFFSET))]
11669   "TARGET_64BIT"
11670   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11671   [(set_attr "type" "imov")
11672    (set_attr "length_immediate" "0")
11673    (set_attr "length_address" "8")
11674    (set_attr "mode" "DI")])
11675
11676 (define_expand "epilogue"
11677   [(const_int 0)]
11678   ""
11679   "ix86_expand_epilogue (1); DONE;")
11680
11681 (define_expand "sibcall_epilogue"
11682   [(const_int 0)]
11683   ""
11684   "ix86_expand_epilogue (0); DONE;")
11685
11686 (define_expand "eh_return"
11687   [(use (match_operand 0 "register_operand" ""))]
11688   ""
11689 {
11690   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11691
11692   /* Tricky bit: we write the address of the handler to which we will
11693      be returning into someone else's stack frame, one word below the
11694      stack address we wish to restore.  */
11695   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11696   tmp = plus_constant (tmp, -UNITS_PER_WORD);
11697   tmp = gen_rtx_MEM (Pmode, tmp);
11698   emit_move_insn (tmp, ra);
11699
11700   emit_jump_insn (gen_eh_return_internal ());
11701   emit_barrier ();
11702   DONE;
11703 })
11704
11705 (define_insn_and_split "eh_return_internal"
11706   [(eh_return)]
11707   ""
11708   "#"
11709   "epilogue_completed"
11710   [(const_int 0)]
11711   "ix86_expand_epilogue (2); DONE;")
11712
11713 (define_insn "leave"
11714   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11715    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11716    (clobber (mem:BLK (scratch)))]
11717   "!TARGET_64BIT"
11718   "leave"
11719   [(set_attr "type" "leave")])
11720
11721 (define_insn "leave_rex64"
11722   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11723    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11724    (clobber (mem:BLK (scratch)))]
11725   "TARGET_64BIT"
11726   "leave"
11727   [(set_attr "type" "leave")])
11728 \f
11729 ;; Bit manipulation instructions.
11730
11731 (define_expand "ffs<mode>2"
11732   [(set (match_dup 2) (const_int -1))
11733    (parallel [(set (reg:CCZ FLAGS_REG)
11734                    (compare:CCZ
11735                      (match_operand:SWI48 1 "nonimmediate_operand" "")
11736                      (const_int 0)))
11737               (set (match_operand:SWI48 0 "register_operand" "")
11738                    (ctz:SWI48 (match_dup 1)))])
11739    (set (match_dup 0) (if_then_else:SWI48
11740                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
11741                         (match_dup 2)
11742                         (match_dup 0)))
11743    (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11744               (clobber (reg:CC FLAGS_REG))])]
11745   ""
11746 {
11747   if (<MODE>mode == SImode && !TARGET_CMOVE)
11748     {
11749       emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
11750       DONE;
11751     }
11752   operands[2] = gen_reg_rtx (<MODE>mode);
11753 })
11754
11755 (define_insn_and_split "ffssi2_no_cmove"
11756   [(set (match_operand:SI 0 "register_operand" "=r")
11757         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
11758    (clobber (match_scratch:SI 2 "=&q"))
11759    (clobber (reg:CC FLAGS_REG))]
11760   "!TARGET_CMOVE"
11761   "#"
11762   "&& reload_completed"
11763   [(parallel [(set (reg:CCZ FLAGS_REG)
11764                    (compare:CCZ (match_dup 1) (const_int 0)))
11765               (set (match_dup 0) (ctz:SI (match_dup 1)))])
11766    (set (strict_low_part (match_dup 3))
11767         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
11768    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
11769               (clobber (reg:CC FLAGS_REG))])
11770    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
11771               (clobber (reg:CC FLAGS_REG))])
11772    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
11773               (clobber (reg:CC FLAGS_REG))])]
11774 {
11775   operands[3] = gen_lowpart (QImode, operands[2]);
11776   ix86_expand_clear (operands[2]);
11777 })
11778
11779 (define_insn "*ffs<mode>_1"
11780   [(set (reg:CCZ FLAGS_REG)
11781         (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11782                      (const_int 0)))
11783    (set (match_operand:SWI48 0 "register_operand" "=r")
11784         (ctz:SWI48 (match_dup 1)))]
11785   ""
11786   "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
11787   [(set_attr "type" "alu1")
11788    (set_attr "prefix_0f" "1")
11789    (set_attr "mode" "<MODE>")])
11790
11791 (define_insn "ctz<mode>2"
11792   [(set (match_operand:SWI48 0 "register_operand" "=r")
11793         (ctz:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
11794    (clobber (reg:CC FLAGS_REG))]
11795   ""
11796   "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
11797   [(set_attr "type" "alu1")
11798    (set_attr "prefix_0f" "1")
11799    (set_attr "mode" "<MODE>")])
11800
11801 (define_expand "clz<mode>2"
11802   [(parallel
11803      [(set (match_operand:SWI248 0 "register_operand" "")
11804            (minus:SWI248
11805              (match_dup 2)
11806              (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
11807       (clobber (reg:CC FLAGS_REG))])
11808    (parallel
11809      [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
11810       (clobber (reg:CC FLAGS_REG))])]
11811   ""
11812 {
11813   if (TARGET_ABM)
11814     {
11815       emit_insn (gen_clz<mode>2_abm (operands[0], operands[1]));
11816       DONE;
11817     }
11818   operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
11819 })
11820
11821 (define_insn "clz<mode>2_abm"
11822   [(set (match_operand:SWI248 0 "register_operand" "=r")
11823         (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11824    (clobber (reg:CC FLAGS_REG))]
11825   "TARGET_ABM"
11826   "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
11827   [(set_attr "prefix_rep" "1")
11828    (set_attr "type" "bitmanip")
11829    (set_attr "mode" "<MODE>")])
11830
11831 (define_insn "bsr_rex64"
11832   [(set (match_operand:DI 0 "register_operand" "=r")
11833         (minus:DI (const_int 63)
11834                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
11835    (clobber (reg:CC FLAGS_REG))]
11836   "TARGET_64BIT"
11837   "bsr{q}\t{%1, %0|%0, %1}"
11838   [(set_attr "type" "alu1")
11839    (set_attr "prefix_0f" "1")
11840    (set_attr "mode" "DI")])
11841
11842 (define_insn "bsr"
11843   [(set (match_operand:SI 0 "register_operand" "=r")
11844         (minus:SI (const_int 31)
11845                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
11846    (clobber (reg:CC FLAGS_REG))]
11847   ""
11848   "bsr{l}\t{%1, %0|%0, %1}"
11849   [(set_attr "type" "alu1")
11850    (set_attr "prefix_0f" "1")
11851    (set_attr "mode" "SI")])
11852
11853 (define_insn "*bsrhi"
11854   [(set (match_operand:HI 0 "register_operand" "=r")
11855         (minus:HI (const_int 15)
11856                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
11857    (clobber (reg:CC FLAGS_REG))]
11858   ""
11859   "bsr{w}\t{%1, %0|%0, %1}"
11860   [(set_attr "type" "alu1")
11861    (set_attr "prefix_0f" "1")
11862    (set_attr "mode" "HI")])
11863
11864 (define_insn "popcount<mode>2"
11865   [(set (match_operand:SWI248 0 "register_operand" "=r")
11866         (popcount:SWI248
11867           (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11868    (clobber (reg:CC FLAGS_REG))]
11869   "TARGET_POPCNT"
11870 {
11871 #if TARGET_MACHO
11872   return "popcnt\t{%1, %0|%0, %1}";
11873 #else
11874   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
11875 #endif
11876 }
11877   [(set_attr "prefix_rep" "1")
11878    (set_attr "type" "bitmanip")
11879    (set_attr "mode" "<MODE>")])
11880
11881 (define_insn "*popcount<mode>2_cmp"
11882   [(set (reg FLAGS_REG)
11883         (compare
11884           (popcount:SWI248
11885             (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
11886           (const_int 0)))
11887    (set (match_operand:SWI248 0 "register_operand" "=r")
11888         (popcount:SWI248 (match_dup 1)))]
11889   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
11890 {
11891 #if TARGET_MACHO
11892   return "popcnt\t{%1, %0|%0, %1}";
11893 #else
11894   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
11895 #endif
11896 }
11897   [(set_attr "prefix_rep" "1")
11898    (set_attr "type" "bitmanip")
11899    (set_attr "mode" "<MODE>")])
11900
11901 (define_insn "*popcountsi2_cmp_zext"
11902   [(set (reg FLAGS_REG)
11903         (compare
11904           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
11905           (const_int 0)))
11906    (set (match_operand:DI 0 "register_operand" "=r")
11907         (zero_extend:DI(popcount:SI (match_dup 1))))]
11908   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
11909 {
11910 #if TARGET_MACHO
11911   return "popcnt\t{%1, %0|%0, %1}";
11912 #else
11913   return "popcnt{l}\t{%1, %0|%0, %1}";
11914 #endif
11915 }
11916   [(set_attr "prefix_rep" "1")
11917    (set_attr "type" "bitmanip")
11918    (set_attr "mode" "SI")])
11919
11920 (define_expand "bswap<mode>2"
11921   [(set (match_operand:SWI48 0 "register_operand" "")
11922         (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
11923   ""
11924 {
11925   if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
11926     {
11927       rtx x = operands[0];
11928
11929       emit_move_insn (x, operands[1]);
11930       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
11931       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
11932       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
11933       DONE;
11934     }
11935 })
11936
11937 (define_insn "*bswap<mode>2_movbe"
11938   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
11939         (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
11940   "TARGET_MOVBE
11941    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
11942   "@
11943     bswap\t%0
11944     movbe\t{%1, %0|%0, %1}
11945     movbe\t{%1, %0|%0, %1}"
11946   [(set_attr "type" "bitmanip,imov,imov")
11947    (set_attr "modrm" "0,1,1")
11948    (set_attr "prefix_0f" "*,1,1")
11949    (set_attr "prefix_extra" "*,1,1")
11950    (set_attr "mode" "<MODE>")])
11951
11952 (define_insn "*bswap<mode>2_1"
11953   [(set (match_operand:SWI48 0 "register_operand" "=r")
11954         (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
11955   "TARGET_BSWAP"
11956   "bswap\t%0"
11957   [(set_attr "type" "bitmanip")
11958    (set_attr "modrm" "0")
11959    (set_attr "mode" "<MODE>")])
11960
11961 (define_insn "*bswaphi_lowpart_1"
11962   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
11963         (bswap:HI (match_dup 0)))
11964    (clobber (reg:CC FLAGS_REG))]
11965   "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
11966   "@
11967     xchg{b}\t{%h0, %b0|%b0, %h0}
11968     rol{w}\t{$8, %0|%0, 8}"
11969   [(set_attr "length" "2,4")
11970    (set_attr "mode" "QI,HI")])
11971
11972 (define_insn "bswaphi_lowpart"
11973   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
11974         (bswap:HI (match_dup 0)))
11975    (clobber (reg:CC FLAGS_REG))]
11976   ""
11977   "rol{w}\t{$8, %0|%0, 8}"
11978   [(set_attr "length" "4")
11979    (set_attr "mode" "HI")])
11980
11981 (define_expand "paritydi2"
11982   [(set (match_operand:DI 0 "register_operand" "")
11983         (parity:DI (match_operand:DI 1 "register_operand" "")))]
11984   "! TARGET_POPCNT"
11985 {
11986   rtx scratch = gen_reg_rtx (QImode);
11987   rtx cond;
11988
11989   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
11990                                 NULL_RTX, operands[1]));
11991
11992   cond = gen_rtx_fmt_ee (ORDERED, QImode,
11993                          gen_rtx_REG (CCmode, FLAGS_REG),
11994                          const0_rtx);
11995   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
11996
11997   if (TARGET_64BIT)
11998     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
11999   else
12000     {
12001       rtx tmp = gen_reg_rtx (SImode);
12002
12003       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12004       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12005     }
12006   DONE;
12007 })
12008
12009 (define_expand "paritysi2"
12010   [(set (match_operand:SI 0 "register_operand" "")
12011         (parity:SI (match_operand:SI 1 "register_operand" "")))]
12012   "! TARGET_POPCNT"
12013 {
12014   rtx scratch = gen_reg_rtx (QImode);
12015   rtx cond;
12016
12017   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12018
12019   cond = gen_rtx_fmt_ee (ORDERED, QImode,
12020                          gen_rtx_REG (CCmode, FLAGS_REG),
12021                          const0_rtx);
12022   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12023
12024   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12025   DONE;
12026 })
12027
12028 (define_insn_and_split "paritydi2_cmp"
12029   [(set (reg:CC FLAGS_REG)
12030         (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12031                    UNSPEC_PARITY))
12032    (clobber (match_scratch:DI 0 "=r"))
12033    (clobber (match_scratch:SI 1 "=&r"))
12034    (clobber (match_scratch:HI 2 "=Q"))]
12035   "! TARGET_POPCNT"
12036   "#"
12037   "&& reload_completed"
12038   [(parallel
12039      [(set (match_dup 1)
12040            (xor:SI (match_dup 1) (match_dup 4)))
12041       (clobber (reg:CC FLAGS_REG))])
12042    (parallel
12043      [(set (reg:CC FLAGS_REG)
12044            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12045       (clobber (match_dup 1))
12046       (clobber (match_dup 2))])]
12047 {
12048   operands[4] = gen_lowpart (SImode, operands[3]);
12049
12050   if (TARGET_64BIT)
12051     {
12052       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12053       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12054     }
12055   else
12056     operands[1] = gen_highpart (SImode, operands[3]);
12057 })
12058
12059 (define_insn_and_split "paritysi2_cmp"
12060   [(set (reg:CC FLAGS_REG)
12061         (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12062                    UNSPEC_PARITY))
12063    (clobber (match_scratch:SI 0 "=r"))
12064    (clobber (match_scratch:HI 1 "=&Q"))]
12065   "! TARGET_POPCNT"
12066   "#"
12067   "&& reload_completed"
12068   [(parallel
12069      [(set (match_dup 1)
12070            (xor:HI (match_dup 1) (match_dup 3)))
12071       (clobber (reg:CC FLAGS_REG))])
12072    (parallel
12073      [(set (reg:CC FLAGS_REG)
12074            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12075       (clobber (match_dup 1))])]
12076 {
12077   operands[3] = gen_lowpart (HImode, operands[2]);
12078
12079   emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12080   emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12081 })
12082
12083 (define_insn "*parityhi2_cmp"
12084   [(set (reg:CC FLAGS_REG)
12085         (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12086                    UNSPEC_PARITY))
12087    (clobber (match_scratch:HI 0 "=Q"))]
12088   "! TARGET_POPCNT"
12089   "xor{b}\t{%h0, %b0|%b0, %h0}"
12090   [(set_attr "length" "2")
12091    (set_attr "mode" "HI")])
12092 \f
12093 ;; Thread-local storage patterns for ELF.
12094 ;;
12095 ;; Note that these code sequences must appear exactly as shown
12096 ;; in order to allow linker relaxation.
12097
12098 (define_insn "*tls_global_dynamic_32_gnu"
12099   [(set (match_operand:SI 0 "register_operand" "=a")
12100         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12101                     (match_operand:SI 2 "tls_symbolic_operand" "")
12102                     (match_operand:SI 3 "call_insn_operand" "")]
12103                     UNSPEC_TLS_GD))
12104    (clobber (match_scratch:SI 4 "=d"))
12105    (clobber (match_scratch:SI 5 "=c"))
12106    (clobber (reg:CC FLAGS_REG))]
12107   "!TARGET_64BIT && TARGET_GNU_TLS"
12108   "lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}\;call\t%P3"
12109   [(set_attr "type" "multi")
12110    (set_attr "length" "12")])
12111
12112 (define_expand "tls_global_dynamic_32"
12113   [(parallel [(set (match_operand:SI 0 "register_operand" "")
12114                    (unspec:SI
12115                     [(match_dup 2)
12116                      (match_operand:SI 1 "tls_symbolic_operand" "")
12117                      (match_dup 3)]
12118                     UNSPEC_TLS_GD))
12119               (clobber (match_scratch:SI 4 ""))
12120               (clobber (match_scratch:SI 5 ""))
12121               (clobber (reg:CC FLAGS_REG))])]
12122   ""
12123 {
12124   if (flag_pic)
12125     operands[2] = pic_offset_table_rtx;
12126   else
12127     {
12128       operands[2] = gen_reg_rtx (Pmode);
12129       emit_insn (gen_set_got (operands[2]));
12130     }
12131   if (TARGET_GNU2_TLS)
12132     {
12133        emit_insn (gen_tls_dynamic_gnu2_32
12134                   (operands[0], operands[1], operands[2]));
12135        DONE;
12136     }
12137   operands[3] = ix86_tls_get_addr ();
12138 })
12139
12140 (define_insn "*tls_global_dynamic_64"
12141   [(set (match_operand:DI 0 "register_operand" "=a")
12142         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
12143                  (match_operand:DI 3 "" "")))
12144    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12145               UNSPEC_TLS_GD)]
12146   "TARGET_64BIT"
12147   { 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"; }
12148   [(set_attr "type" "multi")
12149    (set_attr "length" "16")])
12150
12151 (define_expand "tls_global_dynamic_64"
12152   [(parallel [(set (match_operand:DI 0 "register_operand" "")
12153                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
12154               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12155                          UNSPEC_TLS_GD)])]
12156   ""
12157 {
12158   if (TARGET_GNU2_TLS)
12159     {
12160        emit_insn (gen_tls_dynamic_gnu2_64
12161                   (operands[0], operands[1]));
12162        DONE;
12163     }
12164   operands[2] = ix86_tls_get_addr ();
12165 })
12166
12167 (define_insn "*tls_local_dynamic_base_32_gnu"
12168   [(set (match_operand:SI 0 "register_operand" "=a")
12169         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12170                     (match_operand:SI 2 "call_insn_operand" "")]
12171                    UNSPEC_TLS_LD_BASE))
12172    (clobber (match_scratch:SI 3 "=d"))
12173    (clobber (match_scratch:SI 4 "=c"))
12174    (clobber (reg:CC FLAGS_REG))]
12175   "!TARGET_64BIT && TARGET_GNU_TLS"
12176   "lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}\;call\t%P2"
12177   [(set_attr "type" "multi")
12178    (set_attr "length" "11")])
12179
12180 (define_expand "tls_local_dynamic_base_32"
12181   [(parallel [(set (match_operand:SI 0 "register_operand" "")
12182                    (unspec:SI [(match_dup 1) (match_dup 2)]
12183                               UNSPEC_TLS_LD_BASE))
12184               (clobber (match_scratch:SI 3 ""))
12185               (clobber (match_scratch:SI 4 ""))
12186               (clobber (reg:CC FLAGS_REG))])]
12187   ""
12188 {
12189   if (flag_pic)
12190     operands[1] = pic_offset_table_rtx;
12191   else
12192     {
12193       operands[1] = gen_reg_rtx (Pmode);
12194       emit_insn (gen_set_got (operands[1]));
12195     }
12196   if (TARGET_GNU2_TLS)
12197     {
12198        emit_insn (gen_tls_dynamic_gnu2_32
12199                   (operands[0], ix86_tls_module_base (), operands[1]));
12200        DONE;
12201     }
12202   operands[2] = ix86_tls_get_addr ();
12203 })
12204
12205 (define_insn "*tls_local_dynamic_base_64"
12206   [(set (match_operand:DI 0 "register_operand" "=a")
12207         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
12208                  (match_operand:DI 2 "" "")))
12209    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12210   "TARGET_64BIT"
12211   "lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}\;call\t%P1"
12212   [(set_attr "type" "multi")
12213    (set_attr "length" "12")])
12214
12215 (define_expand "tls_local_dynamic_base_64"
12216   [(parallel [(set (match_operand:DI 0 "register_operand" "")
12217                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
12218               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
12219   ""
12220 {
12221   if (TARGET_GNU2_TLS)
12222     {
12223        emit_insn (gen_tls_dynamic_gnu2_64
12224                   (operands[0], ix86_tls_module_base ()));
12225        DONE;
12226     }
12227   operands[1] = ix86_tls_get_addr ();
12228 })
12229
12230 ;; Local dynamic of a single variable is a lose.  Show combine how
12231 ;; to convert that back to global dynamic.
12232
12233 (define_insn_and_split "*tls_local_dynamic_32_once"
12234   [(set (match_operand:SI 0 "register_operand" "=a")
12235         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12236                              (match_operand:SI 2 "call_insn_operand" "")]
12237                             UNSPEC_TLS_LD_BASE)
12238                  (const:SI (unspec:SI
12239                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
12240                             UNSPEC_DTPOFF))))
12241    (clobber (match_scratch:SI 4 "=d"))
12242    (clobber (match_scratch:SI 5 "=c"))
12243    (clobber (reg:CC FLAGS_REG))]
12244   ""
12245   "#"
12246   ""
12247   [(parallel [(set (match_dup 0)
12248                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12249                               UNSPEC_TLS_GD))
12250               (clobber (match_dup 4))
12251               (clobber (match_dup 5))
12252               (clobber (reg:CC FLAGS_REG))])]
12253   "")
12254
12255 ;; Load and add the thread base pointer from %gs:0.
12256
12257 (define_insn "*load_tp_si"
12258   [(set (match_operand:SI 0 "register_operand" "=r")
12259         (unspec:SI [(const_int 0)] UNSPEC_TP))]
12260   "!TARGET_64BIT"
12261   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
12262   [(set_attr "type" "imov")
12263    (set_attr "modrm" "0")
12264    (set_attr "length" "7")
12265    (set_attr "memory" "load")
12266    (set_attr "imm_disp" "false")])
12267
12268 (define_insn "*add_tp_si"
12269   [(set (match_operand:SI 0 "register_operand" "=r")
12270         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12271                  (match_operand:SI 1 "register_operand" "0")))
12272    (clobber (reg:CC FLAGS_REG))]
12273   "!TARGET_64BIT"
12274   "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
12275   [(set_attr "type" "alu")
12276    (set_attr "modrm" "0")
12277    (set_attr "length" "7")
12278    (set_attr "memory" "load")
12279    (set_attr "imm_disp" "false")])
12280
12281 (define_insn "*load_tp_di"
12282   [(set (match_operand:DI 0 "register_operand" "=r")
12283         (unspec:DI [(const_int 0)] UNSPEC_TP))]
12284   "TARGET_64BIT"
12285   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
12286   [(set_attr "type" "imov")
12287    (set_attr "modrm" "0")
12288    (set_attr "length" "7")
12289    (set_attr "memory" "load")
12290    (set_attr "imm_disp" "false")])
12291
12292 (define_insn "*add_tp_di"
12293   [(set (match_operand:DI 0 "register_operand" "=r")
12294         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
12295                  (match_operand:DI 1 "register_operand" "0")))
12296    (clobber (reg:CC FLAGS_REG))]
12297   "TARGET_64BIT"
12298   "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
12299   [(set_attr "type" "alu")
12300    (set_attr "modrm" "0")
12301    (set_attr "length" "7")
12302    (set_attr "memory" "load")
12303    (set_attr "imm_disp" "false")])
12304
12305 ;; GNU2 TLS patterns can be split.
12306
12307 (define_expand "tls_dynamic_gnu2_32"
12308   [(set (match_dup 3)
12309         (plus:SI (match_operand:SI 2 "register_operand" "")
12310                  (const:SI
12311                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12312                              UNSPEC_TLSDESC))))
12313    (parallel
12314     [(set (match_operand:SI 0 "register_operand" "")
12315           (unspec:SI [(match_dup 1) (match_dup 3)
12316                       (match_dup 2) (reg:SI SP_REG)]
12317                       UNSPEC_TLSDESC))
12318      (clobber (reg:CC FLAGS_REG))])]
12319   "!TARGET_64BIT && TARGET_GNU2_TLS"
12320 {
12321   operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12322   ix86_tls_descriptor_calls_expanded_in_cfun = true;
12323 })
12324
12325 (define_insn "*tls_dynamic_lea_32"
12326   [(set (match_operand:SI 0 "register_operand" "=r")
12327         (plus:SI (match_operand:SI 1 "register_operand" "b")
12328                  (const:SI
12329                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12330                               UNSPEC_TLSDESC))))]
12331   "!TARGET_64BIT && TARGET_GNU2_TLS"
12332   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
12333   [(set_attr "type" "lea")
12334    (set_attr "mode" "SI")
12335    (set_attr "length" "6")
12336    (set_attr "length_address" "4")])
12337
12338 (define_insn "*tls_dynamic_call_32"
12339   [(set (match_operand:SI 0 "register_operand" "=a")
12340         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12341                     (match_operand:SI 2 "register_operand" "0")
12342                     ;; we have to make sure %ebx still points to the GOT
12343                     (match_operand:SI 3 "register_operand" "b")
12344                     (reg:SI SP_REG)]
12345                    UNSPEC_TLSDESC))
12346    (clobber (reg:CC FLAGS_REG))]
12347   "!TARGET_64BIT && TARGET_GNU2_TLS"
12348   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12349   [(set_attr "type" "call")
12350    (set_attr "length" "2")
12351    (set_attr "length_address" "0")])
12352
12353 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12354   [(set (match_operand:SI 0 "register_operand" "=&a")
12355         (plus:SI
12356          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12357                      (match_operand:SI 4 "" "")
12358                      (match_operand:SI 2 "register_operand" "b")
12359                      (reg:SI SP_REG)]
12360                     UNSPEC_TLSDESC)
12361          (const:SI (unspec:SI
12362                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
12363                     UNSPEC_DTPOFF))))
12364    (clobber (reg:CC FLAGS_REG))]
12365   "!TARGET_64BIT && TARGET_GNU2_TLS"
12366   "#"
12367   ""
12368   [(set (match_dup 0) (match_dup 5))]
12369 {
12370   operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12371   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12372 })
12373
12374 (define_expand "tls_dynamic_gnu2_64"
12375   [(set (match_dup 2)
12376         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12377                    UNSPEC_TLSDESC))
12378    (parallel
12379     [(set (match_operand:DI 0 "register_operand" "")
12380           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12381                      UNSPEC_TLSDESC))
12382      (clobber (reg:CC FLAGS_REG))])]
12383   "TARGET_64BIT && TARGET_GNU2_TLS"
12384 {
12385   operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12386   ix86_tls_descriptor_calls_expanded_in_cfun = true;
12387 })
12388
12389 (define_insn "*tls_dynamic_lea_64"
12390   [(set (match_operand:DI 0 "register_operand" "=r")
12391         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12392                    UNSPEC_TLSDESC))]
12393   "TARGET_64BIT && TARGET_GNU2_TLS"
12394   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
12395   [(set_attr "type" "lea")
12396    (set_attr "mode" "DI")
12397    (set_attr "length" "7")
12398    (set_attr "length_address" "4")])
12399
12400 (define_insn "*tls_dynamic_call_64"
12401   [(set (match_operand:DI 0 "register_operand" "=a")
12402         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
12403                     (match_operand:DI 2 "register_operand" "0")
12404                     (reg:DI SP_REG)]
12405                    UNSPEC_TLSDESC))
12406    (clobber (reg:CC FLAGS_REG))]
12407   "TARGET_64BIT && TARGET_GNU2_TLS"
12408   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12409   [(set_attr "type" "call")
12410    (set_attr "length" "2")
12411    (set_attr "length_address" "0")])
12412
12413 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12414   [(set (match_operand:DI 0 "register_operand" "=&a")
12415         (plus:DI
12416          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12417                      (match_operand:DI 3 "" "")
12418                      (reg:DI SP_REG)]
12419                     UNSPEC_TLSDESC)
12420          (const:DI (unspec:DI
12421                     [(match_operand:DI 1 "tls_symbolic_operand" "")]
12422                     UNSPEC_DTPOFF))))
12423    (clobber (reg:CC FLAGS_REG))]
12424   "TARGET_64BIT && TARGET_GNU2_TLS"
12425   "#"
12426   ""
12427   [(set (match_dup 0) (match_dup 4))]
12428 {
12429   operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12430   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12431 })
12432
12433 ;;
12434 \f
12435 ;; These patterns match the binary 387 instructions for addM3, subM3,
12436 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
12437 ;; SFmode.  The first is the normal insn, the second the same insn but
12438 ;; with one operand a conversion, and the third the same insn but with
12439 ;; the other operand a conversion.  The conversion may be SFmode or
12440 ;; SImode if the target mode DFmode, but only SImode if the target mode
12441 ;; is SFmode.
12442
12443 ;; Gcc is slightly more smart about handling normal two address instructions
12444 ;; so use special patterns for add and mull.
12445
12446 (define_insn "*fop_<mode>_comm_mixed_avx"
12447   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
12448         (match_operator:MODEF 3 "binary_fp_operator"
12449           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
12450            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
12451   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12452    && COMMUTATIVE_ARITH_P (operands[3])
12453    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12454   "* return output_387_binary_op (insn, operands);"
12455   [(set (attr "type")
12456         (if_then_else (eq_attr "alternative" "1")
12457            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12458               (const_string "ssemul")
12459               (const_string "sseadd"))
12460            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12461               (const_string "fmul")
12462               (const_string "fop"))))
12463    (set_attr "prefix" "orig,maybe_vex")
12464    (set_attr "mode" "<MODE>")])
12465
12466 (define_insn "*fop_<mode>_comm_mixed"
12467   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
12468         (match_operator:MODEF 3 "binary_fp_operator"
12469           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
12470            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
12471   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12472    && COMMUTATIVE_ARITH_P (operands[3])
12473    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12474   "* return output_387_binary_op (insn, operands);"
12475   [(set (attr "type")
12476         (if_then_else (eq_attr "alternative" "1")
12477            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12478               (const_string "ssemul")
12479               (const_string "sseadd"))
12480            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12481               (const_string "fmul")
12482               (const_string "fop"))))
12483    (set_attr "mode" "<MODE>")])
12484
12485 (define_insn "*fop_<mode>_comm_avx"
12486   [(set (match_operand:MODEF 0 "register_operand" "=x")
12487         (match_operator:MODEF 3 "binary_fp_operator"
12488           [(match_operand:MODEF 1 "nonimmediate_operand" "%x")
12489            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12490   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12491    && COMMUTATIVE_ARITH_P (operands[3])
12492    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12493   "* return output_387_binary_op (insn, operands);"
12494   [(set (attr "type")
12495         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12496            (const_string "ssemul")
12497            (const_string "sseadd")))
12498    (set_attr "prefix" "vex")
12499    (set_attr "mode" "<MODE>")])
12500
12501 (define_insn "*fop_<mode>_comm_sse"
12502   [(set (match_operand:MODEF 0 "register_operand" "=x")
12503         (match_operator:MODEF 3 "binary_fp_operator"
12504           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12505            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12506   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12507    && COMMUTATIVE_ARITH_P (operands[3])
12508    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12509   "* return output_387_binary_op (insn, operands);"
12510   [(set (attr "type")
12511         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12512            (const_string "ssemul")
12513            (const_string "sseadd")))
12514    (set_attr "mode" "<MODE>")])
12515
12516 (define_insn "*fop_<mode>_comm_i387"
12517   [(set (match_operand:MODEF 0 "register_operand" "=f")
12518         (match_operator:MODEF 3 "binary_fp_operator"
12519           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12520            (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
12521   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12522    && COMMUTATIVE_ARITH_P (operands[3])
12523    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12524   "* return output_387_binary_op (insn, operands);"
12525   [(set (attr "type")
12526         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12527            (const_string "fmul")
12528            (const_string "fop")))
12529    (set_attr "mode" "<MODE>")])
12530
12531 (define_insn "*fop_<mode>_1_mixed_avx"
12532   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
12533         (match_operator:MODEF 3 "binary_fp_operator"
12534           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,x")
12535            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
12536   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12537    && !COMMUTATIVE_ARITH_P (operands[3])
12538    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12539   "* return output_387_binary_op (insn, operands);"
12540   [(set (attr "type")
12541         (cond [(and (eq_attr "alternative" "2")
12542                     (match_operand:MODEF 3 "mult_operator" ""))
12543                  (const_string "ssemul")
12544                (and (eq_attr "alternative" "2")
12545                     (match_operand:MODEF 3 "div_operator" ""))
12546                  (const_string "ssediv")
12547                (eq_attr "alternative" "2")
12548                  (const_string "sseadd")
12549                (match_operand:MODEF 3 "mult_operator" "")
12550                  (const_string "fmul")
12551                (match_operand:MODEF 3 "div_operator" "")
12552                  (const_string "fdiv")
12553               ]
12554               (const_string "fop")))
12555    (set_attr "prefix" "orig,orig,maybe_vex")
12556    (set_attr "mode" "<MODE>")])
12557
12558 (define_insn "*fop_<mode>_1_mixed"
12559   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
12560         (match_operator:MODEF 3 "binary_fp_operator"
12561           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
12562            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
12563   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12564    && !COMMUTATIVE_ARITH_P (operands[3])
12565    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12566   "* return output_387_binary_op (insn, operands);"
12567   [(set (attr "type")
12568         (cond [(and (eq_attr "alternative" "2")
12569                     (match_operand:MODEF 3 "mult_operator" ""))
12570                  (const_string "ssemul")
12571                (and (eq_attr "alternative" "2")
12572                     (match_operand:MODEF 3 "div_operator" ""))
12573                  (const_string "ssediv")
12574                (eq_attr "alternative" "2")
12575                  (const_string "sseadd")
12576                (match_operand:MODEF 3 "mult_operator" "")
12577                  (const_string "fmul")
12578                (match_operand:MODEF 3 "div_operator" "")
12579                  (const_string "fdiv")
12580               ]
12581               (const_string "fop")))
12582    (set_attr "mode" "<MODE>")])
12583
12584 (define_insn "*rcpsf2_sse"
12585   [(set (match_operand:SF 0 "register_operand" "=x")
12586         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
12587                    UNSPEC_RCP))]
12588   "TARGET_SSE_MATH"
12589   "%vrcpss\t{%1, %d0|%d0, %1}"
12590   [(set_attr "type" "sse")
12591    (set_attr "atom_sse_attr" "rcp")
12592    (set_attr "prefix" "maybe_vex")
12593    (set_attr "mode" "SF")])
12594
12595 (define_insn "*fop_<mode>_1_avx"
12596   [(set (match_operand:MODEF 0 "register_operand" "=x")
12597         (match_operator:MODEF 3 "binary_fp_operator"
12598           [(match_operand:MODEF 1 "register_operand" "x")
12599            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12600   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12601    && !COMMUTATIVE_ARITH_P (operands[3])"
12602   "* return output_387_binary_op (insn, operands);"
12603   [(set (attr "type")
12604         (cond [(match_operand:MODEF 3 "mult_operator" "")
12605                  (const_string "ssemul")
12606                (match_operand:MODEF 3 "div_operator" "")
12607                  (const_string "ssediv")
12608               ]
12609               (const_string "sseadd")))
12610    (set_attr "prefix" "vex")
12611    (set_attr "mode" "<MODE>")])
12612
12613 (define_insn "*fop_<mode>_1_sse"
12614   [(set (match_operand:MODEF 0 "register_operand" "=x")
12615         (match_operator:MODEF 3 "binary_fp_operator"
12616           [(match_operand:MODEF 1 "register_operand" "0")
12617            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12618   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12619    && !COMMUTATIVE_ARITH_P (operands[3])"
12620   "* return output_387_binary_op (insn, operands);"
12621   [(set (attr "type")
12622         (cond [(match_operand:MODEF 3 "mult_operator" "")
12623                  (const_string "ssemul")
12624                (match_operand:MODEF 3 "div_operator" "")
12625                  (const_string "ssediv")
12626               ]
12627               (const_string "sseadd")))
12628    (set_attr "mode" "<MODE>")])
12629
12630 ;; This pattern is not fully shadowed by the pattern above.
12631 (define_insn "*fop_<mode>_1_i387"
12632   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12633         (match_operator:MODEF 3 "binary_fp_operator"
12634           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
12635            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
12636   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12637    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
12638    && !COMMUTATIVE_ARITH_P (operands[3])
12639    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12640   "* return output_387_binary_op (insn, operands);"
12641   [(set (attr "type")
12642         (cond [(match_operand:MODEF 3 "mult_operator" "")
12643                  (const_string "fmul")
12644                (match_operand:MODEF 3 "div_operator" "")
12645                  (const_string "fdiv")
12646               ]
12647               (const_string "fop")))
12648    (set_attr "mode" "<MODE>")])
12649
12650 ;; ??? Add SSE splitters for these!
12651 (define_insn "*fop_<MODEF:mode>_2_i387"
12652   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12653         (match_operator:MODEF 3 "binary_fp_operator"
12654           [(float:MODEF
12655              (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
12656            (match_operand:MODEF 2 "register_operand" "0,0")]))]
12657   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
12658    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12659    && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12660   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12661   [(set (attr "type")
12662         (cond [(match_operand:MODEF 3 "mult_operator" "")
12663                  (const_string "fmul")
12664                (match_operand:MODEF 3 "div_operator" "")
12665                  (const_string "fdiv")
12666               ]
12667               (const_string "fop")))
12668    (set_attr "fp_int_src" "true")
12669    (set_attr "mode" "<X87MODEI12:MODE>")])
12670
12671 (define_insn "*fop_<MODEF:mode>_3_i387"
12672   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12673         (match_operator:MODEF 3 "binary_fp_operator"
12674           [(match_operand:MODEF 1 "register_operand" "0,0")
12675            (float:MODEF
12676              (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
12677   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
12678    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12679    && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12680   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12681   [(set (attr "type")
12682         (cond [(match_operand:MODEF 3 "mult_operator" "")
12683                  (const_string "fmul")
12684                (match_operand:MODEF 3 "div_operator" "")
12685                  (const_string "fdiv")
12686               ]
12687               (const_string "fop")))
12688    (set_attr "fp_int_src" "true")
12689    (set_attr "mode" "<MODE>")])
12690
12691 (define_insn "*fop_df_4_i387"
12692   [(set (match_operand:DF 0 "register_operand" "=f,f")
12693         (match_operator:DF 3 "binary_fp_operator"
12694            [(float_extend:DF
12695              (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
12696             (match_operand:DF 2 "register_operand" "0,f")]))]
12697   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12698    && !(TARGET_SSE2 && TARGET_SSE_MATH)
12699    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12700   "* return output_387_binary_op (insn, operands);"
12701   [(set (attr "type")
12702         (cond [(match_operand:DF 3 "mult_operator" "")
12703                  (const_string "fmul")
12704                (match_operand:DF 3 "div_operator" "")
12705                  (const_string "fdiv")
12706               ]
12707               (const_string "fop")))
12708    (set_attr "mode" "SF")])
12709
12710 (define_insn "*fop_df_5_i387"
12711   [(set (match_operand:DF 0 "register_operand" "=f,f")
12712         (match_operator:DF 3 "binary_fp_operator"
12713           [(match_operand:DF 1 "register_operand" "0,f")
12714            (float_extend:DF
12715             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12716   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12717    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12718   "* return output_387_binary_op (insn, operands);"
12719   [(set (attr "type")
12720         (cond [(match_operand:DF 3 "mult_operator" "")
12721                  (const_string "fmul")
12722                (match_operand:DF 3 "div_operator" "")
12723                  (const_string "fdiv")
12724               ]
12725               (const_string "fop")))
12726    (set_attr "mode" "SF")])
12727
12728 (define_insn "*fop_df_6_i387"
12729   [(set (match_operand:DF 0 "register_operand" "=f,f")
12730         (match_operator:DF 3 "binary_fp_operator"
12731           [(float_extend:DF
12732             (match_operand:SF 1 "register_operand" "0,f"))
12733            (float_extend:DF
12734             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12735   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12736    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12737   "* return output_387_binary_op (insn, operands);"
12738   [(set (attr "type")
12739         (cond [(match_operand:DF 3 "mult_operator" "")
12740                  (const_string "fmul")
12741                (match_operand:DF 3 "div_operator" "")
12742                  (const_string "fdiv")
12743               ]
12744               (const_string "fop")))
12745    (set_attr "mode" "SF")])
12746
12747 (define_insn "*fop_xf_comm_i387"
12748   [(set (match_operand:XF 0 "register_operand" "=f")
12749         (match_operator:XF 3 "binary_fp_operator"
12750                         [(match_operand:XF 1 "register_operand" "%0")
12751                          (match_operand:XF 2 "register_operand" "f")]))]
12752   "TARGET_80387
12753    && COMMUTATIVE_ARITH_P (operands[3])"
12754   "* return output_387_binary_op (insn, operands);"
12755   [(set (attr "type")
12756         (if_then_else (match_operand:XF 3 "mult_operator" "")
12757            (const_string "fmul")
12758            (const_string "fop")))
12759    (set_attr "mode" "XF")])
12760
12761 (define_insn "*fop_xf_1_i387"
12762   [(set (match_operand:XF 0 "register_operand" "=f,f")
12763         (match_operator:XF 3 "binary_fp_operator"
12764                         [(match_operand:XF 1 "register_operand" "0,f")
12765                          (match_operand:XF 2 "register_operand" "f,0")]))]
12766   "TARGET_80387
12767    && !COMMUTATIVE_ARITH_P (operands[3])"
12768   "* return output_387_binary_op (insn, operands);"
12769   [(set (attr "type")
12770         (cond [(match_operand:XF 3 "mult_operator" "")
12771                  (const_string "fmul")
12772                (match_operand:XF 3 "div_operator" "")
12773                  (const_string "fdiv")
12774               ]
12775               (const_string "fop")))
12776    (set_attr "mode" "XF")])
12777
12778 (define_insn "*fop_xf_2_i387"
12779   [(set (match_operand:XF 0 "register_operand" "=f,f")
12780         (match_operator:XF 3 "binary_fp_operator"
12781           [(float:XF
12782              (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
12783            (match_operand:XF 2 "register_operand" "0,0")]))]
12784   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12785   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12786   [(set (attr "type")
12787         (cond [(match_operand:XF 3 "mult_operator" "")
12788                  (const_string "fmul")
12789                (match_operand:XF 3 "div_operator" "")
12790                  (const_string "fdiv")
12791               ]
12792               (const_string "fop")))
12793    (set_attr "fp_int_src" "true")
12794    (set_attr "mode" "<MODE>")])
12795
12796 (define_insn "*fop_xf_3_i387"
12797   [(set (match_operand:XF 0 "register_operand" "=f,f")
12798         (match_operator:XF 3 "binary_fp_operator"
12799           [(match_operand:XF 1 "register_operand" "0,0")
12800            (float:XF
12801              (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
12802   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12803   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12804   [(set (attr "type")
12805         (cond [(match_operand:XF 3 "mult_operator" "")
12806                  (const_string "fmul")
12807                (match_operand:XF 3 "div_operator" "")
12808                  (const_string "fdiv")
12809               ]
12810               (const_string "fop")))
12811    (set_attr "fp_int_src" "true")
12812    (set_attr "mode" "<MODE>")])
12813
12814 (define_insn "*fop_xf_4_i387"
12815   [(set (match_operand:XF 0 "register_operand" "=f,f")
12816         (match_operator:XF 3 "binary_fp_operator"
12817            [(float_extend:XF
12818               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
12819             (match_operand:XF 2 "register_operand" "0,f")]))]
12820   "TARGET_80387"
12821   "* return output_387_binary_op (insn, operands);"
12822   [(set (attr "type")
12823         (cond [(match_operand:XF 3 "mult_operator" "")
12824                  (const_string "fmul")
12825                (match_operand:XF 3 "div_operator" "")
12826                  (const_string "fdiv")
12827               ]
12828               (const_string "fop")))
12829    (set_attr "mode" "<MODE>")])
12830
12831 (define_insn "*fop_xf_5_i387"
12832   [(set (match_operand:XF 0 "register_operand" "=f,f")
12833         (match_operator:XF 3 "binary_fp_operator"
12834           [(match_operand:XF 1 "register_operand" "0,f")
12835            (float_extend:XF
12836              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
12837   "TARGET_80387"
12838   "* return output_387_binary_op (insn, operands);"
12839   [(set (attr "type")
12840         (cond [(match_operand:XF 3 "mult_operator" "")
12841                  (const_string "fmul")
12842                (match_operand:XF 3 "div_operator" "")
12843                  (const_string "fdiv")
12844               ]
12845               (const_string "fop")))
12846    (set_attr "mode" "<MODE>")])
12847
12848 (define_insn "*fop_xf_6_i387"
12849   [(set (match_operand:XF 0 "register_operand" "=f,f")
12850         (match_operator:XF 3 "binary_fp_operator"
12851           [(float_extend:XF
12852              (match_operand:MODEF 1 "register_operand" "0,f"))
12853            (float_extend:XF
12854              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
12855   "TARGET_80387"
12856   "* return output_387_binary_op (insn, operands);"
12857   [(set (attr "type")
12858         (cond [(match_operand:XF 3 "mult_operator" "")
12859                  (const_string "fmul")
12860                (match_operand:XF 3 "div_operator" "")
12861                  (const_string "fdiv")
12862               ]
12863               (const_string "fop")))
12864    (set_attr "mode" "<MODE>")])
12865
12866 (define_split
12867   [(set (match_operand 0 "register_operand" "")
12868         (match_operator 3 "binary_fp_operator"
12869            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
12870             (match_operand 2 "register_operand" "")]))]
12871   "reload_completed
12872    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
12873    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
12874   [(const_int 0)]
12875 {
12876   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
12877   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
12878   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
12879                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
12880                                           GET_MODE (operands[3]),
12881                                           operands[4],
12882                                           operands[2])));
12883   ix86_free_from_memory (GET_MODE (operands[1]));
12884   DONE;
12885 })
12886
12887 (define_split
12888   [(set (match_operand 0 "register_operand" "")
12889         (match_operator 3 "binary_fp_operator"
12890            [(match_operand 1 "register_operand" "")
12891             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
12892   "reload_completed
12893    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
12894    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
12895   [(const_int 0)]
12896 {
12897   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
12898   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
12899   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
12900                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
12901                                           GET_MODE (operands[3]),
12902                                           operands[1],
12903                                           operands[4])));
12904   ix86_free_from_memory (GET_MODE (operands[2]));
12905   DONE;
12906 })
12907 \f
12908 ;; FPU special functions.
12909
12910 ;; This pattern implements a no-op XFmode truncation for
12911 ;; all fancy i386 XFmode math functions.
12912
12913 (define_insn "truncxf<mode>2_i387_noop_unspec"
12914   [(set (match_operand:MODEF 0 "register_operand" "=f")
12915         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
12916         UNSPEC_TRUNC_NOOP))]
12917   "TARGET_USE_FANCY_MATH_387"
12918   "* return output_387_reg_move (insn, operands);"
12919   [(set_attr "type" "fmov")
12920    (set_attr "mode" "<MODE>")])
12921
12922 (define_insn "sqrtxf2"
12923   [(set (match_operand:XF 0 "register_operand" "=f")
12924         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
12925   "TARGET_USE_FANCY_MATH_387"
12926   "fsqrt"
12927   [(set_attr "type" "fpspc")
12928    (set_attr "mode" "XF")
12929    (set_attr "athlon_decode" "direct")
12930    (set_attr "amdfam10_decode" "direct")])
12931
12932 (define_insn "sqrt_extend<mode>xf2_i387"
12933   [(set (match_operand:XF 0 "register_operand" "=f")
12934         (sqrt:XF
12935           (float_extend:XF
12936             (match_operand:MODEF 1 "register_operand" "0"))))]
12937   "TARGET_USE_FANCY_MATH_387"
12938   "fsqrt"
12939   [(set_attr "type" "fpspc")
12940    (set_attr "mode" "XF")
12941    (set_attr "athlon_decode" "direct")
12942    (set_attr "amdfam10_decode" "direct")])
12943
12944 (define_insn "*rsqrtsf2_sse"
12945   [(set (match_operand:SF 0 "register_operand" "=x")
12946         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
12947                    UNSPEC_RSQRT))]
12948   "TARGET_SSE_MATH"
12949   "%vrsqrtss\t{%1, %d0|%d0, %1}"
12950   [(set_attr "type" "sse")
12951    (set_attr "atom_sse_attr" "rcp")
12952    (set_attr "prefix" "maybe_vex")
12953    (set_attr "mode" "SF")])
12954
12955 (define_expand "rsqrtsf2"
12956   [(set (match_operand:SF 0 "register_operand" "")
12957         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
12958                    UNSPEC_RSQRT))]
12959   "TARGET_SSE_MATH"
12960 {
12961   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
12962   DONE;
12963 })
12964
12965 (define_insn "*sqrt<mode>2_sse"
12966   [(set (match_operand:MODEF 0 "register_operand" "=x")
12967         (sqrt:MODEF
12968           (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
12969   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
12970   "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}"
12971   [(set_attr "type" "sse")
12972    (set_attr "atom_sse_attr" "sqrt")
12973    (set_attr "prefix" "maybe_vex")
12974    (set_attr "mode" "<MODE>")
12975    (set_attr "athlon_decode" "*")
12976    (set_attr "amdfam10_decode" "*")])
12977
12978 (define_expand "sqrt<mode>2"
12979   [(set (match_operand:MODEF 0 "register_operand" "")
12980         (sqrt:MODEF
12981           (match_operand:MODEF 1 "nonimmediate_operand" "")))]
12982   "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
12983    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
12984 {
12985   if (<MODE>mode == SFmode
12986       && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
12987       && flag_finite_math_only && !flag_trapping_math
12988       && flag_unsafe_math_optimizations)
12989     {
12990       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
12991       DONE;
12992     }
12993
12994   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
12995     {
12996       rtx op0 = gen_reg_rtx (XFmode);
12997       rtx op1 = force_reg (<MODE>mode, operands[1]);
12998
12999       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13000       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13001       DONE;
13002    }
13003 })
13004
13005 (define_insn "fpremxf4_i387"
13006   [(set (match_operand:XF 0 "register_operand" "=f")
13007         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13008                     (match_operand:XF 3 "register_operand" "1")]
13009                    UNSPEC_FPREM_F))
13010    (set (match_operand:XF 1 "register_operand" "=u")
13011         (unspec:XF [(match_dup 2) (match_dup 3)]
13012                    UNSPEC_FPREM_U))
13013    (set (reg:CCFP FPSR_REG)
13014         (unspec:CCFP [(match_dup 2) (match_dup 3)]
13015                      UNSPEC_C2_FLAG))]
13016   "TARGET_USE_FANCY_MATH_387"
13017   "fprem"
13018   [(set_attr "type" "fpspc")
13019    (set_attr "mode" "XF")])
13020
13021 (define_expand "fmodxf3"
13022   [(use (match_operand:XF 0 "register_operand" ""))
13023    (use (match_operand:XF 1 "general_operand" ""))
13024    (use (match_operand:XF 2 "general_operand" ""))]
13025   "TARGET_USE_FANCY_MATH_387"
13026 {
13027   rtx label = gen_label_rtx ();
13028
13029   rtx op1 = gen_reg_rtx (XFmode);
13030   rtx op2 = gen_reg_rtx (XFmode);
13031
13032   emit_move_insn (op2, operands[2]);
13033   emit_move_insn (op1, operands[1]);
13034
13035   emit_label (label);
13036   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13037   ix86_emit_fp_unordered_jump (label);
13038   LABEL_NUSES (label) = 1;
13039
13040   emit_move_insn (operands[0], op1);
13041   DONE;
13042 })
13043
13044 (define_expand "fmod<mode>3"
13045   [(use (match_operand:MODEF 0 "register_operand" ""))
13046    (use (match_operand:MODEF 1 "general_operand" ""))
13047    (use (match_operand:MODEF 2 "general_operand" ""))]
13048   "TARGET_USE_FANCY_MATH_387"
13049 {
13050   rtx (*gen_truncxf) (rtx, rtx);
13051
13052   rtx label = gen_label_rtx ();
13053
13054   rtx op1 = gen_reg_rtx (XFmode);
13055   rtx op2 = gen_reg_rtx (XFmode);
13056
13057   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13058   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13059
13060   emit_label (label);
13061   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13062   ix86_emit_fp_unordered_jump (label);
13063   LABEL_NUSES (label) = 1;
13064
13065   /* Truncate the result properly for strict SSE math.  */
13066   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13067       && !TARGET_MIX_SSE_I387)
13068     gen_truncxf = gen_truncxf<mode>2;
13069   else
13070     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13071
13072   emit_insn (gen_truncxf (operands[0], op1));
13073   DONE;
13074 })
13075
13076 (define_insn "fprem1xf4_i387"
13077   [(set (match_operand:XF 0 "register_operand" "=f")
13078         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13079                     (match_operand:XF 3 "register_operand" "1")]
13080                    UNSPEC_FPREM1_F))
13081    (set (match_operand:XF 1 "register_operand" "=u")
13082         (unspec:XF [(match_dup 2) (match_dup 3)]
13083                    UNSPEC_FPREM1_U))
13084    (set (reg:CCFP FPSR_REG)
13085         (unspec:CCFP [(match_dup 2) (match_dup 3)]
13086                      UNSPEC_C2_FLAG))]
13087   "TARGET_USE_FANCY_MATH_387"
13088   "fprem1"
13089   [(set_attr "type" "fpspc")
13090    (set_attr "mode" "XF")])
13091
13092 (define_expand "remainderxf3"
13093   [(use (match_operand:XF 0 "register_operand" ""))
13094    (use (match_operand:XF 1 "general_operand" ""))
13095    (use (match_operand:XF 2 "general_operand" ""))]
13096   "TARGET_USE_FANCY_MATH_387"
13097 {
13098   rtx label = gen_label_rtx ();
13099
13100   rtx op1 = gen_reg_rtx (XFmode);
13101   rtx op2 = gen_reg_rtx (XFmode);
13102
13103   emit_move_insn (op2, operands[2]);
13104   emit_move_insn (op1, operands[1]);
13105
13106   emit_label (label);
13107   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13108   ix86_emit_fp_unordered_jump (label);
13109   LABEL_NUSES (label) = 1;
13110
13111   emit_move_insn (operands[0], op1);
13112   DONE;
13113 })
13114
13115 (define_expand "remainder<mode>3"
13116   [(use (match_operand:MODEF 0 "register_operand" ""))
13117    (use (match_operand:MODEF 1 "general_operand" ""))
13118    (use (match_operand:MODEF 2 "general_operand" ""))]
13119   "TARGET_USE_FANCY_MATH_387"
13120 {
13121   rtx (*gen_truncxf) (rtx, rtx);
13122
13123   rtx label = gen_label_rtx ();
13124
13125   rtx op1 = gen_reg_rtx (XFmode);
13126   rtx op2 = gen_reg_rtx (XFmode);
13127
13128   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13129   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13130
13131   emit_label (label);
13132
13133   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13134   ix86_emit_fp_unordered_jump (label);
13135   LABEL_NUSES (label) = 1;
13136
13137   /* Truncate the result properly for strict SSE math.  */
13138   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13139       && !TARGET_MIX_SSE_I387)
13140     gen_truncxf = gen_truncxf<mode>2;
13141   else
13142     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13143
13144   emit_insn (gen_truncxf (operands[0], op1));
13145   DONE;
13146 })
13147
13148 (define_insn "*sinxf2_i387"
13149   [(set (match_operand:XF 0 "register_operand" "=f")
13150         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13151   "TARGET_USE_FANCY_MATH_387
13152    && flag_unsafe_math_optimizations"
13153   "fsin"
13154   [(set_attr "type" "fpspc")
13155    (set_attr "mode" "XF")])
13156
13157 (define_insn "*sin_extend<mode>xf2_i387"
13158   [(set (match_operand:XF 0 "register_operand" "=f")
13159         (unspec:XF [(float_extend:XF
13160                       (match_operand:MODEF 1 "register_operand" "0"))]
13161                    UNSPEC_SIN))]
13162   "TARGET_USE_FANCY_MATH_387
13163    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13164        || TARGET_MIX_SSE_I387)
13165    && flag_unsafe_math_optimizations"
13166   "fsin"
13167   [(set_attr "type" "fpspc")
13168    (set_attr "mode" "XF")])
13169
13170 (define_insn "*cosxf2_i387"
13171   [(set (match_operand:XF 0 "register_operand" "=f")
13172         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13173   "TARGET_USE_FANCY_MATH_387
13174    && flag_unsafe_math_optimizations"
13175   "fcos"
13176   [(set_attr "type" "fpspc")
13177    (set_attr "mode" "XF")])
13178
13179 (define_insn "*cos_extend<mode>xf2_i387"
13180   [(set (match_operand:XF 0 "register_operand" "=f")
13181         (unspec:XF [(float_extend:XF
13182                       (match_operand:MODEF 1 "register_operand" "0"))]
13183                    UNSPEC_COS))]
13184   "TARGET_USE_FANCY_MATH_387
13185    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13186        || TARGET_MIX_SSE_I387)
13187    && flag_unsafe_math_optimizations"
13188   "fcos"
13189   [(set_attr "type" "fpspc")
13190    (set_attr "mode" "XF")])
13191
13192 ;; When sincos pattern is defined, sin and cos builtin functions will be
13193 ;; expanded to sincos pattern with one of its outputs left unused.
13194 ;; CSE pass will figure out if two sincos patterns can be combined,
13195 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13196 ;; depending on the unused output.
13197
13198 (define_insn "sincosxf3"
13199   [(set (match_operand:XF 0 "register_operand" "=f")
13200         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13201                    UNSPEC_SINCOS_COS))
13202    (set (match_operand:XF 1 "register_operand" "=u")
13203         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13204   "TARGET_USE_FANCY_MATH_387
13205    && flag_unsafe_math_optimizations"
13206   "fsincos"
13207   [(set_attr "type" "fpspc")
13208    (set_attr "mode" "XF")])
13209
13210 (define_split
13211   [(set (match_operand:XF 0 "register_operand" "")
13212         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13213                    UNSPEC_SINCOS_COS))
13214    (set (match_operand:XF 1 "register_operand" "")
13215         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13216   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13217    && !(reload_completed || reload_in_progress)"
13218   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
13219   "")
13220
13221 (define_split
13222   [(set (match_operand:XF 0 "register_operand" "")
13223         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13224                    UNSPEC_SINCOS_COS))
13225    (set (match_operand:XF 1 "register_operand" "")
13226         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13227   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13228    && !(reload_completed || reload_in_progress)"
13229   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
13230   "")
13231
13232 (define_insn "sincos_extend<mode>xf3_i387"
13233   [(set (match_operand:XF 0 "register_operand" "=f")
13234         (unspec:XF [(float_extend:XF
13235                       (match_operand:MODEF 2 "register_operand" "0"))]
13236                    UNSPEC_SINCOS_COS))
13237    (set (match_operand:XF 1 "register_operand" "=u")
13238         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13239   "TARGET_USE_FANCY_MATH_387
13240    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13241        || TARGET_MIX_SSE_I387)
13242    && flag_unsafe_math_optimizations"
13243   "fsincos"
13244   [(set_attr "type" "fpspc")
13245    (set_attr "mode" "XF")])
13246
13247 (define_split
13248   [(set (match_operand:XF 0 "register_operand" "")
13249         (unspec:XF [(float_extend:XF
13250                       (match_operand:MODEF 2 "register_operand" ""))]
13251                    UNSPEC_SINCOS_COS))
13252    (set (match_operand:XF 1 "register_operand" "")
13253         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13254   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13255    && !(reload_completed || reload_in_progress)"
13256   [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
13257   "")
13258
13259 (define_split
13260   [(set (match_operand:XF 0 "register_operand" "")
13261         (unspec:XF [(float_extend:XF
13262                       (match_operand:MODEF 2 "register_operand" ""))]
13263                    UNSPEC_SINCOS_COS))
13264    (set (match_operand:XF 1 "register_operand" "")
13265         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13266   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13267    && !(reload_completed || reload_in_progress)"
13268   [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
13269   "")
13270
13271 (define_expand "sincos<mode>3"
13272   [(use (match_operand:MODEF 0 "register_operand" ""))
13273    (use (match_operand:MODEF 1 "register_operand" ""))
13274    (use (match_operand:MODEF 2 "register_operand" ""))]
13275   "TARGET_USE_FANCY_MATH_387
13276    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13277        || TARGET_MIX_SSE_I387)
13278    && flag_unsafe_math_optimizations"
13279 {
13280   rtx op0 = gen_reg_rtx (XFmode);
13281   rtx op1 = gen_reg_rtx (XFmode);
13282
13283   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13284   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13285   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13286   DONE;
13287 })
13288
13289 (define_insn "fptanxf4_i387"
13290   [(set (match_operand:XF 0 "register_operand" "=f")
13291         (match_operand:XF 3 "const_double_operand" "F"))
13292    (set (match_operand:XF 1 "register_operand" "=u")
13293         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13294                    UNSPEC_TAN))]
13295   "TARGET_USE_FANCY_MATH_387
13296    && flag_unsafe_math_optimizations
13297    && standard_80387_constant_p (operands[3]) == 2"
13298   "fptan"
13299   [(set_attr "type" "fpspc")
13300    (set_attr "mode" "XF")])
13301
13302 (define_insn "fptan_extend<mode>xf4_i387"
13303   [(set (match_operand:MODEF 0 "register_operand" "=f")
13304         (match_operand:MODEF 3 "const_double_operand" "F"))
13305    (set (match_operand:XF 1 "register_operand" "=u")
13306         (unspec:XF [(float_extend:XF
13307                       (match_operand:MODEF 2 "register_operand" "0"))]
13308                    UNSPEC_TAN))]
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    && standard_80387_constant_p (operands[3]) == 2"
13314   "fptan"
13315   [(set_attr "type" "fpspc")
13316    (set_attr "mode" "XF")])
13317
13318 (define_expand "tanxf2"
13319   [(use (match_operand:XF 0 "register_operand" ""))
13320    (use (match_operand:XF 1 "register_operand" ""))]
13321   "TARGET_USE_FANCY_MATH_387
13322    && flag_unsafe_math_optimizations"
13323 {
13324   rtx one = gen_reg_rtx (XFmode);
13325   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13326
13327   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13328   DONE;
13329 })
13330
13331 (define_expand "tan<mode>2"
13332   [(use (match_operand:MODEF 0 "register_operand" ""))
13333    (use (match_operand:MODEF 1 "register_operand" ""))]
13334   "TARGET_USE_FANCY_MATH_387
13335    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13336        || TARGET_MIX_SSE_I387)
13337    && flag_unsafe_math_optimizations"
13338 {
13339   rtx op0 = gen_reg_rtx (XFmode);
13340
13341   rtx one = gen_reg_rtx (<MODE>mode);
13342   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13343
13344   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13345                                              operands[1], op2));
13346   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13347   DONE;
13348 })
13349
13350 (define_insn "*fpatanxf3_i387"
13351   [(set (match_operand:XF 0 "register_operand" "=f")
13352         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13353                     (match_operand:XF 2 "register_operand" "u")]
13354                    UNSPEC_FPATAN))
13355    (clobber (match_scratch:XF 3 "=2"))]
13356   "TARGET_USE_FANCY_MATH_387
13357    && flag_unsafe_math_optimizations"
13358   "fpatan"
13359   [(set_attr "type" "fpspc")
13360    (set_attr "mode" "XF")])
13361
13362 (define_insn "fpatan_extend<mode>xf3_i387"
13363   [(set (match_operand:XF 0 "register_operand" "=f")
13364         (unspec:XF [(float_extend:XF
13365                       (match_operand:MODEF 1 "register_operand" "0"))
13366                     (float_extend:XF
13367                       (match_operand:MODEF 2 "register_operand" "u"))]
13368                    UNSPEC_FPATAN))
13369    (clobber (match_scratch:XF 3 "=2"))]
13370   "TARGET_USE_FANCY_MATH_387
13371    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13372        || TARGET_MIX_SSE_I387)
13373    && flag_unsafe_math_optimizations"
13374   "fpatan"
13375   [(set_attr "type" "fpspc")
13376    (set_attr "mode" "XF")])
13377
13378 (define_expand "atan2xf3"
13379   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13380                    (unspec:XF [(match_operand:XF 2 "register_operand" "")
13381                                (match_operand:XF 1 "register_operand" "")]
13382                               UNSPEC_FPATAN))
13383               (clobber (match_scratch:XF 3 ""))])]
13384   "TARGET_USE_FANCY_MATH_387
13385    && flag_unsafe_math_optimizations"
13386   "")
13387
13388 (define_expand "atan2<mode>3"
13389   [(use (match_operand:MODEF 0 "register_operand" ""))
13390    (use (match_operand:MODEF 1 "register_operand" ""))
13391    (use (match_operand:MODEF 2 "register_operand" ""))]
13392   "TARGET_USE_FANCY_MATH_387
13393    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13394        || TARGET_MIX_SSE_I387)
13395    && flag_unsafe_math_optimizations"
13396 {
13397   rtx op0 = gen_reg_rtx (XFmode);
13398
13399   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13400   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13401   DONE;
13402 })
13403
13404 (define_expand "atanxf2"
13405   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13406                    (unspec:XF [(match_dup 2)
13407                                (match_operand:XF 1 "register_operand" "")]
13408                               UNSPEC_FPATAN))
13409               (clobber (match_scratch:XF 3 ""))])]
13410   "TARGET_USE_FANCY_MATH_387
13411    && flag_unsafe_math_optimizations"
13412 {
13413   operands[2] = gen_reg_rtx (XFmode);
13414   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
13415 })
13416
13417 (define_expand "atan<mode>2"
13418   [(use (match_operand:MODEF 0 "register_operand" ""))
13419    (use (match_operand:MODEF 1 "register_operand" ""))]
13420   "TARGET_USE_FANCY_MATH_387
13421    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13422        || TARGET_MIX_SSE_I387)
13423    && flag_unsafe_math_optimizations"
13424 {
13425   rtx op0 = gen_reg_rtx (XFmode);
13426
13427   rtx op2 = gen_reg_rtx (<MODE>mode);
13428   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
13429
13430   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13431   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13432   DONE;
13433 })
13434
13435 (define_expand "asinxf2"
13436   [(set (match_dup 2)
13437         (mult:XF (match_operand:XF 1 "register_operand" "")
13438                  (match_dup 1)))
13439    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13440    (set (match_dup 5) (sqrt:XF (match_dup 4)))
13441    (parallel [(set (match_operand:XF 0 "register_operand" "")
13442                    (unspec:XF [(match_dup 5) (match_dup 1)]
13443                               UNSPEC_FPATAN))
13444               (clobber (match_scratch:XF 6 ""))])]
13445   "TARGET_USE_FANCY_MATH_387
13446    && flag_unsafe_math_optimizations"
13447 {
13448   int i;
13449
13450   if (optimize_insn_for_size_p ())
13451     FAIL;
13452
13453   for (i = 2; i < 6; i++)
13454     operands[i] = gen_reg_rtx (XFmode);
13455
13456   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
13457 })
13458
13459 (define_expand "asin<mode>2"
13460   [(use (match_operand:MODEF 0 "register_operand" ""))
13461    (use (match_operand:MODEF 1 "general_operand" ""))]
13462  "TARGET_USE_FANCY_MATH_387
13463    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13464        || TARGET_MIX_SSE_I387)
13465    && flag_unsafe_math_optimizations"
13466 {
13467   rtx op0 = gen_reg_rtx (XFmode);
13468   rtx op1 = gen_reg_rtx (XFmode);
13469
13470   if (optimize_insn_for_size_p ())
13471     FAIL;
13472
13473   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13474   emit_insn (gen_asinxf2 (op0, op1));
13475   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13476   DONE;
13477 })
13478
13479 (define_expand "acosxf2"
13480   [(set (match_dup 2)
13481         (mult:XF (match_operand:XF 1 "register_operand" "")
13482                  (match_dup 1)))
13483    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13484    (set (match_dup 5) (sqrt:XF (match_dup 4)))
13485    (parallel [(set (match_operand:XF 0 "register_operand" "")
13486                    (unspec:XF [(match_dup 1) (match_dup 5)]
13487                               UNSPEC_FPATAN))
13488               (clobber (match_scratch:XF 6 ""))])]
13489   "TARGET_USE_FANCY_MATH_387
13490    && flag_unsafe_math_optimizations"
13491 {
13492   int i;
13493
13494   if (optimize_insn_for_size_p ())
13495     FAIL;
13496
13497   for (i = 2; i < 6; i++)
13498     operands[i] = gen_reg_rtx (XFmode);
13499
13500   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
13501 })
13502
13503 (define_expand "acos<mode>2"
13504   [(use (match_operand:MODEF 0 "register_operand" ""))
13505    (use (match_operand:MODEF 1 "general_operand" ""))]
13506  "TARGET_USE_FANCY_MATH_387
13507    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13508        || TARGET_MIX_SSE_I387)
13509    && flag_unsafe_math_optimizations"
13510 {
13511   rtx op0 = gen_reg_rtx (XFmode);
13512   rtx op1 = gen_reg_rtx (XFmode);
13513
13514   if (optimize_insn_for_size_p ())
13515     FAIL;
13516
13517   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13518   emit_insn (gen_acosxf2 (op0, op1));
13519   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13520   DONE;
13521 })
13522
13523 (define_insn "fyl2xxf3_i387"
13524   [(set (match_operand:XF 0 "register_operand" "=f")
13525         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13526                     (match_operand:XF 2 "register_operand" "u")]
13527                    UNSPEC_FYL2X))
13528    (clobber (match_scratch:XF 3 "=2"))]
13529   "TARGET_USE_FANCY_MATH_387
13530    && flag_unsafe_math_optimizations"
13531   "fyl2x"
13532   [(set_attr "type" "fpspc")
13533    (set_attr "mode" "XF")])
13534
13535 (define_insn "fyl2x_extend<mode>xf3_i387"
13536   [(set (match_operand:XF 0 "register_operand" "=f")
13537         (unspec:XF [(float_extend:XF
13538                       (match_operand:MODEF 1 "register_operand" "0"))
13539                     (match_operand:XF 2 "register_operand" "u")]
13540                    UNSPEC_FYL2X))
13541    (clobber (match_scratch:XF 3 "=2"))]
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   "fyl2x"
13547   [(set_attr "type" "fpspc")
13548    (set_attr "mode" "XF")])
13549
13550 (define_expand "logxf2"
13551   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13552                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
13553                                (match_dup 2)] UNSPEC_FYL2X))
13554               (clobber (match_scratch:XF 3 ""))])]
13555   "TARGET_USE_FANCY_MATH_387
13556    && flag_unsafe_math_optimizations"
13557 {
13558   operands[2] = gen_reg_rtx (XFmode);
13559   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
13560 })
13561
13562 (define_expand "log<mode>2"
13563   [(use (match_operand:MODEF 0 "register_operand" ""))
13564    (use (match_operand:MODEF 1 "register_operand" ""))]
13565   "TARGET_USE_FANCY_MATH_387
13566    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13567        || TARGET_MIX_SSE_I387)
13568    && flag_unsafe_math_optimizations"
13569 {
13570   rtx op0 = gen_reg_rtx (XFmode);
13571
13572   rtx op2 = gen_reg_rtx (XFmode);
13573   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
13574
13575   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13576   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13577   DONE;
13578 })
13579
13580 (define_expand "log10xf2"
13581   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13582                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
13583                                (match_dup 2)] UNSPEC_FYL2X))
13584               (clobber (match_scratch:XF 3 ""))])]
13585   "TARGET_USE_FANCY_MATH_387
13586    && flag_unsafe_math_optimizations"
13587 {
13588   operands[2] = gen_reg_rtx (XFmode);
13589   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
13590 })
13591
13592 (define_expand "log10<mode>2"
13593   [(use (match_operand:MODEF 0 "register_operand" ""))
13594    (use (match_operand:MODEF 1 "register_operand" ""))]
13595   "TARGET_USE_FANCY_MATH_387
13596    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13597        || TARGET_MIX_SSE_I387)
13598    && flag_unsafe_math_optimizations"
13599 {
13600   rtx op0 = gen_reg_rtx (XFmode);
13601
13602   rtx op2 = gen_reg_rtx (XFmode);
13603   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
13604
13605   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13606   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13607   DONE;
13608 })
13609
13610 (define_expand "log2xf2"
13611   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13612                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
13613                                (match_dup 2)] UNSPEC_FYL2X))
13614               (clobber (match_scratch:XF 3 ""))])]
13615   "TARGET_USE_FANCY_MATH_387
13616    && flag_unsafe_math_optimizations"
13617 {
13618   operands[2] = gen_reg_rtx (XFmode);
13619   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13620 })
13621
13622 (define_expand "log2<mode>2"
13623   [(use (match_operand:MODEF 0 "register_operand" ""))
13624    (use (match_operand:MODEF 1 "register_operand" ""))]
13625   "TARGET_USE_FANCY_MATH_387
13626    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13627        || TARGET_MIX_SSE_I387)
13628    && flag_unsafe_math_optimizations"
13629 {
13630   rtx op0 = gen_reg_rtx (XFmode);
13631
13632   rtx op2 = gen_reg_rtx (XFmode);
13633   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
13634
13635   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13636   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13637   DONE;
13638 })
13639
13640 (define_insn "fyl2xp1xf3_i387"
13641   [(set (match_operand:XF 0 "register_operand" "=f")
13642         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13643                     (match_operand:XF 2 "register_operand" "u")]
13644                    UNSPEC_FYL2XP1))
13645    (clobber (match_scratch:XF 3 "=2"))]
13646   "TARGET_USE_FANCY_MATH_387
13647    && flag_unsafe_math_optimizations"
13648   "fyl2xp1"
13649   [(set_attr "type" "fpspc")
13650    (set_attr "mode" "XF")])
13651
13652 (define_insn "fyl2xp1_extend<mode>xf3_i387"
13653   [(set (match_operand:XF 0 "register_operand" "=f")
13654         (unspec:XF [(float_extend:XF
13655                       (match_operand:MODEF 1 "register_operand" "0"))
13656                     (match_operand:XF 2 "register_operand" "u")]
13657                    UNSPEC_FYL2XP1))
13658    (clobber (match_scratch:XF 3 "=2"))]
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   "fyl2xp1"
13664   [(set_attr "type" "fpspc")
13665    (set_attr "mode" "XF")])
13666
13667 (define_expand "log1pxf2"
13668   [(use (match_operand:XF 0 "register_operand" ""))
13669    (use (match_operand:XF 1 "register_operand" ""))]
13670   "TARGET_USE_FANCY_MATH_387
13671    && flag_unsafe_math_optimizations"
13672 {
13673   if (optimize_insn_for_size_p ())
13674     FAIL;
13675
13676   ix86_emit_i387_log1p (operands[0], operands[1]);
13677   DONE;
13678 })
13679
13680 (define_expand "log1p<mode>2"
13681   [(use (match_operand:MODEF 0 "register_operand" ""))
13682    (use (match_operand:MODEF 1 "register_operand" ""))]
13683   "TARGET_USE_FANCY_MATH_387
13684    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13685        || TARGET_MIX_SSE_I387)
13686    && flag_unsafe_math_optimizations"
13687 {
13688   rtx op0;
13689
13690   if (optimize_insn_for_size_p ())
13691     FAIL;
13692
13693   op0 = gen_reg_rtx (XFmode);
13694
13695   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
13696
13697   ix86_emit_i387_log1p (op0, operands[1]);
13698   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13699   DONE;
13700 })
13701
13702 (define_insn "fxtractxf3_i387"
13703   [(set (match_operand:XF 0 "register_operand" "=f")
13704         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13705                    UNSPEC_XTRACT_FRACT))
13706    (set (match_operand:XF 1 "register_operand" "=u")
13707         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
13708   "TARGET_USE_FANCY_MATH_387
13709    && flag_unsafe_math_optimizations"
13710   "fxtract"
13711   [(set_attr "type" "fpspc")
13712    (set_attr "mode" "XF")])
13713
13714 (define_insn "fxtract_extend<mode>xf3_i387"
13715   [(set (match_operand:XF 0 "register_operand" "=f")
13716         (unspec:XF [(float_extend:XF
13717                       (match_operand:MODEF 2 "register_operand" "0"))]
13718                    UNSPEC_XTRACT_FRACT))
13719    (set (match_operand:XF 1 "register_operand" "=u")
13720         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
13721   "TARGET_USE_FANCY_MATH_387
13722    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13723        || TARGET_MIX_SSE_I387)
13724    && flag_unsafe_math_optimizations"
13725   "fxtract"
13726   [(set_attr "type" "fpspc")
13727    (set_attr "mode" "XF")])
13728
13729 (define_expand "logbxf2"
13730   [(parallel [(set (match_dup 2)
13731                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
13732                               UNSPEC_XTRACT_FRACT))
13733               (set (match_operand:XF 0 "register_operand" "")
13734                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
13735   "TARGET_USE_FANCY_MATH_387
13736    && flag_unsafe_math_optimizations"
13737 {
13738   operands[2] = gen_reg_rtx (XFmode);
13739 })
13740
13741 (define_expand "logb<mode>2"
13742   [(use (match_operand:MODEF 0 "register_operand" ""))
13743    (use (match_operand:MODEF 1 "register_operand" ""))]
13744   "TARGET_USE_FANCY_MATH_387
13745    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13746        || TARGET_MIX_SSE_I387)
13747    && flag_unsafe_math_optimizations"
13748 {
13749   rtx op0 = gen_reg_rtx (XFmode);
13750   rtx op1 = gen_reg_rtx (XFmode);
13751
13752   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13753   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
13754   DONE;
13755 })
13756
13757 (define_expand "ilogbxf2"
13758   [(use (match_operand:SI 0 "register_operand" ""))
13759    (use (match_operand:XF 1 "register_operand" ""))]
13760   "TARGET_USE_FANCY_MATH_387
13761    && flag_unsafe_math_optimizations"
13762 {
13763   rtx op0, op1;
13764
13765   if (optimize_insn_for_size_p ())
13766     FAIL;
13767
13768   op0 = gen_reg_rtx (XFmode);
13769   op1 = gen_reg_rtx (XFmode);
13770
13771   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
13772   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13773   DONE;
13774 })
13775
13776 (define_expand "ilogb<mode>2"
13777   [(use (match_operand:SI 0 "register_operand" ""))
13778    (use (match_operand:MODEF 1 "register_operand" ""))]
13779   "TARGET_USE_FANCY_MATH_387
13780    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13781        || TARGET_MIX_SSE_I387)
13782    && flag_unsafe_math_optimizations"
13783 {
13784   rtx op0, op1;
13785
13786   if (optimize_insn_for_size_p ())
13787     FAIL;
13788
13789   op0 = gen_reg_rtx (XFmode);
13790   op1 = gen_reg_rtx (XFmode);
13791
13792   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13793   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13794   DONE;
13795 })
13796
13797 (define_insn "*f2xm1xf2_i387"
13798   [(set (match_operand:XF 0 "register_operand" "=f")
13799         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13800                    UNSPEC_F2XM1))]
13801   "TARGET_USE_FANCY_MATH_387
13802    && flag_unsafe_math_optimizations"
13803   "f2xm1"
13804   [(set_attr "type" "fpspc")
13805    (set_attr "mode" "XF")])
13806
13807 (define_insn "*fscalexf4_i387"
13808   [(set (match_operand:XF 0 "register_operand" "=f")
13809         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13810                     (match_operand:XF 3 "register_operand" "1")]
13811                    UNSPEC_FSCALE_FRACT))
13812    (set (match_operand:XF 1 "register_operand" "=u")
13813         (unspec:XF [(match_dup 2) (match_dup 3)]
13814                    UNSPEC_FSCALE_EXP))]
13815   "TARGET_USE_FANCY_MATH_387
13816    && flag_unsafe_math_optimizations"
13817   "fscale"
13818   [(set_attr "type" "fpspc")
13819    (set_attr "mode" "XF")])
13820
13821 (define_expand "expNcorexf3"
13822   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
13823                                (match_operand:XF 2 "register_operand" "")))
13824    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
13825    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
13826    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
13827    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
13828    (parallel [(set (match_operand:XF 0 "register_operand" "")
13829                    (unspec:XF [(match_dup 8) (match_dup 4)]
13830                               UNSPEC_FSCALE_FRACT))
13831               (set (match_dup 9)
13832                    (unspec:XF [(match_dup 8) (match_dup 4)]
13833                               UNSPEC_FSCALE_EXP))])]
13834   "TARGET_USE_FANCY_MATH_387
13835    && flag_unsafe_math_optimizations"
13836 {
13837   int i;
13838
13839   if (optimize_insn_for_size_p ())
13840     FAIL;
13841
13842   for (i = 3; i < 10; i++)
13843     operands[i] = gen_reg_rtx (XFmode);
13844
13845   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
13846 })
13847
13848 (define_expand "expxf2"
13849   [(use (match_operand:XF 0 "register_operand" ""))
13850    (use (match_operand:XF 1 "register_operand" ""))]
13851   "TARGET_USE_FANCY_MATH_387
13852    && flag_unsafe_math_optimizations"
13853 {
13854   rtx op2;
13855
13856   if (optimize_insn_for_size_p ())
13857     FAIL;
13858
13859   op2 = gen_reg_rtx (XFmode);
13860   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
13861
13862   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
13863   DONE;
13864 })
13865
13866 (define_expand "exp<mode>2"
13867   [(use (match_operand:MODEF 0 "register_operand" ""))
13868    (use (match_operand:MODEF 1 "general_operand" ""))]
13869  "TARGET_USE_FANCY_MATH_387
13870    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13871        || TARGET_MIX_SSE_I387)
13872    && flag_unsafe_math_optimizations"
13873 {
13874   rtx op0, op1;
13875
13876   if (optimize_insn_for_size_p ())
13877     FAIL;
13878
13879   op0 = gen_reg_rtx (XFmode);
13880   op1 = gen_reg_rtx (XFmode);
13881
13882   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13883   emit_insn (gen_expxf2 (op0, op1));
13884   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13885   DONE;
13886 })
13887
13888 (define_expand "exp10xf2"
13889   [(use (match_operand:XF 0 "register_operand" ""))
13890    (use (match_operand:XF 1 "register_operand" ""))]
13891   "TARGET_USE_FANCY_MATH_387
13892    && flag_unsafe_math_optimizations"
13893 {
13894   rtx op2;
13895
13896   if (optimize_insn_for_size_p ())
13897     FAIL;
13898
13899   op2 = gen_reg_rtx (XFmode);
13900   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
13901
13902   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
13903   DONE;
13904 })
13905
13906 (define_expand "exp10<mode>2"
13907   [(use (match_operand:MODEF 0 "register_operand" ""))
13908    (use (match_operand:MODEF 1 "general_operand" ""))]
13909  "TARGET_USE_FANCY_MATH_387
13910    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13911        || TARGET_MIX_SSE_I387)
13912    && flag_unsafe_math_optimizations"
13913 {
13914   rtx op0, op1;
13915
13916   if (optimize_insn_for_size_p ())
13917     FAIL;
13918
13919   op0 = gen_reg_rtx (XFmode);
13920   op1 = gen_reg_rtx (XFmode);
13921
13922   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13923   emit_insn (gen_exp10xf2 (op0, op1));
13924   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13925   DONE;
13926 })
13927
13928 (define_expand "exp2xf2"
13929   [(use (match_operand:XF 0 "register_operand" ""))
13930    (use (match_operand:XF 1 "register_operand" ""))]
13931   "TARGET_USE_FANCY_MATH_387
13932    && flag_unsafe_math_optimizations"
13933 {
13934   rtx op2;
13935
13936   if (optimize_insn_for_size_p ())
13937     FAIL;
13938
13939   op2 = gen_reg_rtx (XFmode);
13940   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
13941
13942   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
13943   DONE;
13944 })
13945
13946 (define_expand "exp2<mode>2"
13947   [(use (match_operand:MODEF 0 "register_operand" ""))
13948    (use (match_operand:MODEF 1 "general_operand" ""))]
13949  "TARGET_USE_FANCY_MATH_387
13950    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13951        || TARGET_MIX_SSE_I387)
13952    && flag_unsafe_math_optimizations"
13953 {
13954   rtx op0, op1;
13955
13956   if (optimize_insn_for_size_p ())
13957     FAIL;
13958
13959   op0 = gen_reg_rtx (XFmode);
13960   op1 = gen_reg_rtx (XFmode);
13961
13962   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13963   emit_insn (gen_exp2xf2 (op0, op1));
13964   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13965   DONE;
13966 })
13967
13968 (define_expand "expm1xf2"
13969   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
13970                                (match_dup 2)))
13971    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
13972    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
13973    (set (match_dup 9) (float_extend:XF (match_dup 13)))
13974    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
13975    (parallel [(set (match_dup 7)
13976                    (unspec:XF [(match_dup 6) (match_dup 4)]
13977                               UNSPEC_FSCALE_FRACT))
13978               (set (match_dup 8)
13979                    (unspec:XF [(match_dup 6) (match_dup 4)]
13980                               UNSPEC_FSCALE_EXP))])
13981    (parallel [(set (match_dup 10)
13982                    (unspec:XF [(match_dup 9) (match_dup 8)]
13983                               UNSPEC_FSCALE_FRACT))
13984               (set (match_dup 11)
13985                    (unspec:XF [(match_dup 9) (match_dup 8)]
13986                               UNSPEC_FSCALE_EXP))])
13987    (set (match_dup 12) (minus:XF (match_dup 10)
13988                                  (float_extend:XF (match_dup 13))))
13989    (set (match_operand:XF 0 "register_operand" "")
13990         (plus:XF (match_dup 12) (match_dup 7)))]
13991   "TARGET_USE_FANCY_MATH_387
13992    && flag_unsafe_math_optimizations"
13993 {
13994   int i;
13995
13996   if (optimize_insn_for_size_p ())
13997     FAIL;
13998
13999   for (i = 2; i < 13; i++)
14000     operands[i] = gen_reg_rtx (XFmode);
14001
14002   operands[13]
14003     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14004
14005   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14006 })
14007
14008 (define_expand "expm1<mode>2"
14009   [(use (match_operand:MODEF 0 "register_operand" ""))
14010    (use (match_operand:MODEF 1 "general_operand" ""))]
14011  "TARGET_USE_FANCY_MATH_387
14012    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14013        || TARGET_MIX_SSE_I387)
14014    && flag_unsafe_math_optimizations"
14015 {
14016   rtx op0, op1;
14017
14018   if (optimize_insn_for_size_p ())
14019     FAIL;
14020
14021   op0 = gen_reg_rtx (XFmode);
14022   op1 = gen_reg_rtx (XFmode);
14023
14024   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14025   emit_insn (gen_expm1xf2 (op0, op1));
14026   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14027   DONE;
14028 })
14029
14030 (define_expand "ldexpxf3"
14031   [(set (match_dup 3)
14032         (float:XF (match_operand:SI 2 "register_operand" "")))
14033    (parallel [(set (match_operand:XF 0 " register_operand" "")
14034                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
14035                                (match_dup 3)]
14036                               UNSPEC_FSCALE_FRACT))
14037               (set (match_dup 4)
14038                    (unspec:XF [(match_dup 1) (match_dup 3)]
14039                               UNSPEC_FSCALE_EXP))])]
14040   "TARGET_USE_FANCY_MATH_387
14041    && flag_unsafe_math_optimizations"
14042 {
14043   if (optimize_insn_for_size_p ())
14044     FAIL;
14045
14046   operands[3] = gen_reg_rtx (XFmode);
14047   operands[4] = gen_reg_rtx (XFmode);
14048 })
14049
14050 (define_expand "ldexp<mode>3"
14051   [(use (match_operand:MODEF 0 "register_operand" ""))
14052    (use (match_operand:MODEF 1 "general_operand" ""))
14053    (use (match_operand:SI 2 "register_operand" ""))]
14054  "TARGET_USE_FANCY_MATH_387
14055    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14056        || TARGET_MIX_SSE_I387)
14057    && flag_unsafe_math_optimizations"
14058 {
14059   rtx op0, op1;
14060
14061   if (optimize_insn_for_size_p ())
14062     FAIL;
14063
14064   op0 = gen_reg_rtx (XFmode);
14065   op1 = gen_reg_rtx (XFmode);
14066
14067   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14068   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14069   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14070   DONE;
14071 })
14072
14073 (define_expand "scalbxf3"
14074   [(parallel [(set (match_operand:XF 0 " register_operand" "")
14075                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
14076                                (match_operand:XF 2 "register_operand" "")]
14077                               UNSPEC_FSCALE_FRACT))
14078               (set (match_dup 3)
14079                    (unspec:XF [(match_dup 1) (match_dup 2)]
14080                               UNSPEC_FSCALE_EXP))])]
14081   "TARGET_USE_FANCY_MATH_387
14082    && flag_unsafe_math_optimizations"
14083 {
14084   if (optimize_insn_for_size_p ())
14085     FAIL;
14086
14087   operands[3] = gen_reg_rtx (XFmode);
14088 })
14089
14090 (define_expand "scalb<mode>3"
14091   [(use (match_operand:MODEF 0 "register_operand" ""))
14092    (use (match_operand:MODEF 1 "general_operand" ""))
14093    (use (match_operand:MODEF 2 "general_operand" ""))]
14094  "TARGET_USE_FANCY_MATH_387
14095    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14096        || TARGET_MIX_SSE_I387)
14097    && flag_unsafe_math_optimizations"
14098 {
14099   rtx op0, op1, op2;
14100
14101   if (optimize_insn_for_size_p ())
14102     FAIL;
14103
14104   op0 = gen_reg_rtx (XFmode);
14105   op1 = gen_reg_rtx (XFmode);
14106   op2 = gen_reg_rtx (XFmode);
14107
14108   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14109   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14110   emit_insn (gen_scalbxf3 (op0, op1, op2));
14111   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14112   DONE;
14113 })
14114
14115 (define_expand "significandxf2"
14116   [(parallel [(set (match_operand:XF 0 "register_operand" "")
14117                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14118                               UNSPEC_XTRACT_FRACT))
14119               (set (match_dup 2)
14120                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14121   "TARGET_USE_FANCY_MATH_387
14122    && flag_unsafe_math_optimizations"
14123 {
14124   operands[2] = gen_reg_rtx (XFmode);
14125 })
14126
14127 (define_expand "significand<mode>2"
14128   [(use (match_operand:MODEF 0 "register_operand" ""))
14129    (use (match_operand:MODEF 1 "register_operand" ""))]
14130   "TARGET_USE_FANCY_MATH_387
14131    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14132        || TARGET_MIX_SSE_I387)
14133    && flag_unsafe_math_optimizations"
14134 {
14135   rtx op0 = gen_reg_rtx (XFmode);
14136   rtx op1 = gen_reg_rtx (XFmode);
14137
14138   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14139   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14140   DONE;
14141 })
14142 \f
14143
14144 (define_insn "sse4_1_round<mode>2"
14145   [(set (match_operand:MODEF 0 "register_operand" "=x")
14146         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14147                        (match_operand:SI 2 "const_0_to_15_operand" "n")]
14148                       UNSPEC_ROUND))]
14149   "TARGET_ROUND"
14150   "%vrounds<ssemodefsuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14151   [(set_attr "type" "ssecvt")
14152    (set_attr "prefix_extra" "1")
14153    (set_attr "prefix" "maybe_vex")
14154    (set_attr "mode" "<MODE>")])
14155
14156 (define_insn "rintxf2"
14157   [(set (match_operand:XF 0 "register_operand" "=f")
14158         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14159                    UNSPEC_FRNDINT))]
14160   "TARGET_USE_FANCY_MATH_387
14161    && flag_unsafe_math_optimizations"
14162   "frndint"
14163   [(set_attr "type" "fpspc")
14164    (set_attr "mode" "XF")])
14165
14166 (define_expand "rint<mode>2"
14167   [(use (match_operand:MODEF 0 "register_operand" ""))
14168    (use (match_operand:MODEF 1 "register_operand" ""))]
14169   "(TARGET_USE_FANCY_MATH_387
14170     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14171         || TARGET_MIX_SSE_I387)
14172     && flag_unsafe_math_optimizations)
14173    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14174        && !flag_trapping_math)"
14175 {
14176   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14177       && !flag_trapping_math)
14178     {
14179       if (!TARGET_ROUND && optimize_insn_for_size_p ())
14180         FAIL;
14181       if (TARGET_ROUND)
14182         emit_insn (gen_sse4_1_round<mode>2
14183                    (operands[0], operands[1], GEN_INT (0x04)));
14184       else
14185         ix86_expand_rint (operand0, operand1);
14186     }
14187   else
14188     {
14189       rtx op0 = gen_reg_rtx (XFmode);
14190       rtx op1 = gen_reg_rtx (XFmode);
14191
14192       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14193       emit_insn (gen_rintxf2 (op0, op1));
14194
14195       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14196     }
14197   DONE;
14198 })
14199
14200 (define_expand "round<mode>2"
14201   [(match_operand:MODEF 0 "register_operand" "")
14202    (match_operand:MODEF 1 "nonimmediate_operand" "")]
14203   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14204    && !flag_trapping_math && !flag_rounding_math"
14205 {
14206   if (optimize_insn_for_size_p ())
14207     FAIL;
14208   if (TARGET_64BIT || (<MODE>mode != DFmode))
14209     ix86_expand_round (operand0, operand1);
14210   else
14211     ix86_expand_rounddf_32 (operand0, operand1);
14212   DONE;
14213 })
14214
14215 (define_insn_and_split "*fistdi2_1"
14216   [(set (match_operand:DI 0 "nonimmediate_operand" "")
14217         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14218                    UNSPEC_FIST))]
14219   "TARGET_USE_FANCY_MATH_387
14220    && can_create_pseudo_p ()"
14221   "#"
14222   "&& 1"
14223   [(const_int 0)]
14224 {
14225   if (memory_operand (operands[0], VOIDmode))
14226     emit_insn (gen_fistdi2 (operands[0], operands[1]));
14227   else
14228     {
14229       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14230       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14231                                          operands[2]));
14232     }
14233   DONE;
14234 }
14235   [(set_attr "type" "fpspc")
14236    (set_attr "mode" "DI")])
14237
14238 (define_insn "fistdi2"
14239   [(set (match_operand:DI 0 "memory_operand" "=m")
14240         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14241                    UNSPEC_FIST))
14242    (clobber (match_scratch:XF 2 "=&1f"))]
14243   "TARGET_USE_FANCY_MATH_387"
14244   "* return output_fix_trunc (insn, operands, 0);"
14245   [(set_attr "type" "fpspc")
14246    (set_attr "mode" "DI")])
14247
14248 (define_insn "fistdi2_with_temp"
14249   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14250         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14251                    UNSPEC_FIST))
14252    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14253    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14254   "TARGET_USE_FANCY_MATH_387"
14255   "#"
14256   [(set_attr "type" "fpspc")
14257    (set_attr "mode" "DI")])
14258
14259 (define_split
14260   [(set (match_operand:DI 0 "register_operand" "")
14261         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14262                    UNSPEC_FIST))
14263    (clobber (match_operand:DI 2 "memory_operand" ""))
14264    (clobber (match_scratch 3 ""))]
14265   "reload_completed"
14266   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14267               (clobber (match_dup 3))])
14268    (set (match_dup 0) (match_dup 2))]
14269   "")
14270
14271 (define_split
14272   [(set (match_operand:DI 0 "memory_operand" "")
14273         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14274                    UNSPEC_FIST))
14275    (clobber (match_operand:DI 2 "memory_operand" ""))
14276    (clobber (match_scratch 3 ""))]
14277   "reload_completed"
14278   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14279               (clobber (match_dup 3))])]
14280   "")
14281
14282 (define_insn_and_split "*fist<mode>2_1"
14283   [(set (match_operand:X87MODEI12 0 "register_operand" "")
14284         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14285                            UNSPEC_FIST))]
14286   "TARGET_USE_FANCY_MATH_387
14287    && can_create_pseudo_p ()"
14288   "#"
14289   "&& 1"
14290   [(const_int 0)]
14291 {
14292   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14293   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14294                                         operands[2]));
14295   DONE;
14296 }
14297   [(set_attr "type" "fpspc")
14298    (set_attr "mode" "<MODE>")])
14299
14300 (define_insn "fist<mode>2"
14301   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14302         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14303                            UNSPEC_FIST))]
14304   "TARGET_USE_FANCY_MATH_387"
14305   "* return output_fix_trunc (insn, operands, 0);"
14306   [(set_attr "type" "fpspc")
14307    (set_attr "mode" "<MODE>")])
14308
14309 (define_insn "fist<mode>2_with_temp"
14310   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
14311         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14312                            UNSPEC_FIST))
14313    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
14314   "TARGET_USE_FANCY_MATH_387"
14315   "#"
14316   [(set_attr "type" "fpspc")
14317    (set_attr "mode" "<MODE>")])
14318
14319 (define_split
14320   [(set (match_operand:X87MODEI12 0 "register_operand" "")
14321         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14322                            UNSPEC_FIST))
14323    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14324   "reload_completed"
14325   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
14326    (set (match_dup 0) (match_dup 2))]
14327   "")
14328
14329 (define_split
14330   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14331         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14332                            UNSPEC_FIST))
14333    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14334   "reload_completed"
14335   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
14336   "")
14337
14338 (define_expand "lrintxf<mode>2"
14339   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14340      (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14341                       UNSPEC_FIST))]
14342   "TARGET_USE_FANCY_MATH_387"
14343   "")
14344
14345 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
14346   [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14347      (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
14348                         UNSPEC_FIX_NOTRUNC))]
14349   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14350    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
14351   "")
14352
14353 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
14354   [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14355    (match_operand:MODEF 1 "register_operand" "")]
14356   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14357    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
14358    && !flag_trapping_math && !flag_rounding_math"
14359 {
14360   if (optimize_insn_for_size_p ())
14361     FAIL;
14362   ix86_expand_lround (operand0, operand1);
14363   DONE;
14364 })
14365
14366 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14367 (define_insn_and_split "frndintxf2_floor"
14368   [(set (match_operand:XF 0 "register_operand" "")
14369         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14370          UNSPEC_FRNDINT_FLOOR))
14371    (clobber (reg:CC FLAGS_REG))]
14372   "TARGET_USE_FANCY_MATH_387
14373    && flag_unsafe_math_optimizations
14374    && can_create_pseudo_p ()"
14375   "#"
14376   "&& 1"
14377   [(const_int 0)]
14378 {
14379   ix86_optimize_mode_switching[I387_FLOOR] = 1;
14380
14381   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14382   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14383
14384   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14385                                         operands[2], operands[3]));
14386   DONE;
14387 }
14388   [(set_attr "type" "frndint")
14389    (set_attr "i387_cw" "floor")
14390    (set_attr "mode" "XF")])
14391
14392 (define_insn "frndintxf2_floor_i387"
14393   [(set (match_operand:XF 0 "register_operand" "=f")
14394         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14395          UNSPEC_FRNDINT_FLOOR))
14396    (use (match_operand:HI 2 "memory_operand" "m"))
14397    (use (match_operand:HI 3 "memory_operand" "m"))]
14398   "TARGET_USE_FANCY_MATH_387
14399    && flag_unsafe_math_optimizations"
14400   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14401   [(set_attr "type" "frndint")
14402    (set_attr "i387_cw" "floor")
14403    (set_attr "mode" "XF")])
14404
14405 (define_expand "floorxf2"
14406   [(use (match_operand:XF 0 "register_operand" ""))
14407    (use (match_operand:XF 1 "register_operand" ""))]
14408   "TARGET_USE_FANCY_MATH_387
14409    && flag_unsafe_math_optimizations"
14410 {
14411   if (optimize_insn_for_size_p ())
14412     FAIL;
14413   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14414   DONE;
14415 })
14416
14417 (define_expand "floor<mode>2"
14418   [(use (match_operand:MODEF 0 "register_operand" ""))
14419    (use (match_operand:MODEF 1 "register_operand" ""))]
14420   "(TARGET_USE_FANCY_MATH_387
14421     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14422         || TARGET_MIX_SSE_I387)
14423     && flag_unsafe_math_optimizations)
14424    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14425        && !flag_trapping_math)"
14426 {
14427   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14428       && !flag_trapping_math
14429       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14430     {
14431       if (!TARGET_ROUND && optimize_insn_for_size_p ())
14432         FAIL;
14433       if (TARGET_ROUND)
14434         emit_insn (gen_sse4_1_round<mode>2
14435                    (operands[0], operands[1], GEN_INT (0x01)));
14436       else if (TARGET_64BIT || (<MODE>mode != DFmode))
14437         ix86_expand_floorceil (operand0, operand1, true);
14438       else
14439         ix86_expand_floorceildf_32 (operand0, operand1, true);
14440     }
14441   else
14442     {
14443       rtx op0, op1;
14444
14445       if (optimize_insn_for_size_p ())
14446         FAIL;
14447
14448       op0 = gen_reg_rtx (XFmode);
14449       op1 = gen_reg_rtx (XFmode);
14450       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14451       emit_insn (gen_frndintxf2_floor (op0, op1));
14452
14453       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14454     }
14455   DONE;
14456 })
14457
14458 (define_insn_and_split "*fist<mode>2_floor_1"
14459   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14460         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14461          UNSPEC_FIST_FLOOR))
14462    (clobber (reg:CC FLAGS_REG))]
14463   "TARGET_USE_FANCY_MATH_387
14464    && flag_unsafe_math_optimizations
14465    && can_create_pseudo_p ()"
14466   "#"
14467   "&& 1"
14468   [(const_int 0)]
14469 {
14470   ix86_optimize_mode_switching[I387_FLOOR] = 1;
14471
14472   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14473   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14474   if (memory_operand (operands[0], VOIDmode))
14475     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14476                                       operands[2], operands[3]));
14477   else
14478     {
14479       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14480       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14481                                                   operands[2], operands[3],
14482                                                   operands[4]));
14483     }
14484   DONE;
14485 }
14486   [(set_attr "type" "fistp")
14487    (set_attr "i387_cw" "floor")
14488    (set_attr "mode" "<MODE>")])
14489
14490 (define_insn "fistdi2_floor"
14491   [(set (match_operand:DI 0 "memory_operand" "=m")
14492         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14493          UNSPEC_FIST_FLOOR))
14494    (use (match_operand:HI 2 "memory_operand" "m"))
14495    (use (match_operand:HI 3 "memory_operand" "m"))
14496    (clobber (match_scratch:XF 4 "=&1f"))]
14497   "TARGET_USE_FANCY_MATH_387
14498    && flag_unsafe_math_optimizations"
14499   "* return output_fix_trunc (insn, operands, 0);"
14500   [(set_attr "type" "fistp")
14501    (set_attr "i387_cw" "floor")
14502    (set_attr "mode" "DI")])
14503
14504 (define_insn "fistdi2_floor_with_temp"
14505   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14506         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14507          UNSPEC_FIST_FLOOR))
14508    (use (match_operand:HI 2 "memory_operand" "m,m"))
14509    (use (match_operand:HI 3 "memory_operand" "m,m"))
14510    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14511    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14512   "TARGET_USE_FANCY_MATH_387
14513    && flag_unsafe_math_optimizations"
14514   "#"
14515   [(set_attr "type" "fistp")
14516    (set_attr "i387_cw" "floor")
14517    (set_attr "mode" "DI")])
14518
14519 (define_split
14520   [(set (match_operand:DI 0 "register_operand" "")
14521         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14522          UNSPEC_FIST_FLOOR))
14523    (use (match_operand:HI 2 "memory_operand" ""))
14524    (use (match_operand:HI 3 "memory_operand" ""))
14525    (clobber (match_operand:DI 4 "memory_operand" ""))
14526    (clobber (match_scratch 5 ""))]
14527   "reload_completed"
14528   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14529               (use (match_dup 2))
14530               (use (match_dup 3))
14531               (clobber (match_dup 5))])
14532    (set (match_dup 0) (match_dup 4))]
14533   "")
14534
14535 (define_split
14536   [(set (match_operand:DI 0 "memory_operand" "")
14537         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14538          UNSPEC_FIST_FLOOR))
14539    (use (match_operand:HI 2 "memory_operand" ""))
14540    (use (match_operand:HI 3 "memory_operand" ""))
14541    (clobber (match_operand:DI 4 "memory_operand" ""))
14542    (clobber (match_scratch 5 ""))]
14543   "reload_completed"
14544   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14545               (use (match_dup 2))
14546               (use (match_dup 3))
14547               (clobber (match_dup 5))])]
14548   "")
14549
14550 (define_insn "fist<mode>2_floor"
14551   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14552         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14553          UNSPEC_FIST_FLOOR))
14554    (use (match_operand:HI 2 "memory_operand" "m"))
14555    (use (match_operand:HI 3 "memory_operand" "m"))]
14556   "TARGET_USE_FANCY_MATH_387
14557    && flag_unsafe_math_optimizations"
14558   "* return output_fix_trunc (insn, operands, 0);"
14559   [(set_attr "type" "fistp")
14560    (set_attr "i387_cw" "floor")
14561    (set_attr "mode" "<MODE>")])
14562
14563 (define_insn "fist<mode>2_floor_with_temp"
14564   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
14565         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
14566          UNSPEC_FIST_FLOOR))
14567    (use (match_operand:HI 2 "memory_operand" "m,m"))
14568    (use (match_operand:HI 3 "memory_operand" "m,m"))
14569    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
14570   "TARGET_USE_FANCY_MATH_387
14571    && flag_unsafe_math_optimizations"
14572   "#"
14573   [(set_attr "type" "fistp")
14574    (set_attr "i387_cw" "floor")
14575    (set_attr "mode" "<MODE>")])
14576
14577 (define_split
14578   [(set (match_operand:X87MODEI12 0 "register_operand" "")
14579         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14580          UNSPEC_FIST_FLOOR))
14581    (use (match_operand:HI 2 "memory_operand" ""))
14582    (use (match_operand:HI 3 "memory_operand" ""))
14583    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14584   "reload_completed"
14585   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
14586                                   UNSPEC_FIST_FLOOR))
14587               (use (match_dup 2))
14588               (use (match_dup 3))])
14589    (set (match_dup 0) (match_dup 4))]
14590   "")
14591
14592 (define_split
14593   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14594         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14595          UNSPEC_FIST_FLOOR))
14596    (use (match_operand:HI 2 "memory_operand" ""))
14597    (use (match_operand:HI 3 "memory_operand" ""))
14598    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14599   "reload_completed"
14600   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
14601                                   UNSPEC_FIST_FLOOR))
14602               (use (match_dup 2))
14603               (use (match_dup 3))])]
14604   "")
14605
14606 (define_expand "lfloorxf<mode>2"
14607   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14608                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14609                     UNSPEC_FIST_FLOOR))
14610               (clobber (reg:CC FLAGS_REG))])]
14611   "TARGET_USE_FANCY_MATH_387
14612    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14613    && flag_unsafe_math_optimizations"
14614   "")
14615
14616 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
14617   [(match_operand:SWI48 0 "nonimmediate_operand" "")
14618    (match_operand:MODEF 1 "register_operand" "")]
14619   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14620    && !flag_trapping_math"
14621 {
14622   if (TARGET_64BIT && optimize_insn_for_size_p ())
14623     FAIL;
14624   ix86_expand_lfloorceil (operand0, operand1, true);
14625   DONE;
14626 })
14627
14628 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14629 (define_insn_and_split "frndintxf2_ceil"
14630   [(set (match_operand:XF 0 "register_operand" "")
14631         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14632          UNSPEC_FRNDINT_CEIL))
14633    (clobber (reg:CC FLAGS_REG))]
14634   "TARGET_USE_FANCY_MATH_387
14635    && flag_unsafe_math_optimizations
14636    && can_create_pseudo_p ()"
14637   "#"
14638   "&& 1"
14639   [(const_int 0)]
14640 {
14641   ix86_optimize_mode_switching[I387_CEIL] = 1;
14642
14643   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14644   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14645
14646   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
14647                                        operands[2], operands[3]));
14648   DONE;
14649 }
14650   [(set_attr "type" "frndint")
14651    (set_attr "i387_cw" "ceil")
14652    (set_attr "mode" "XF")])
14653
14654 (define_insn "frndintxf2_ceil_i387"
14655   [(set (match_operand:XF 0 "register_operand" "=f")
14656         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14657          UNSPEC_FRNDINT_CEIL))
14658    (use (match_operand:HI 2 "memory_operand" "m"))
14659    (use (match_operand:HI 3 "memory_operand" "m"))]
14660   "TARGET_USE_FANCY_MATH_387
14661    && flag_unsafe_math_optimizations"
14662   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14663   [(set_attr "type" "frndint")
14664    (set_attr "i387_cw" "ceil")
14665    (set_attr "mode" "XF")])
14666
14667 (define_expand "ceilxf2"
14668   [(use (match_operand:XF 0 "register_operand" ""))
14669    (use (match_operand:XF 1 "register_operand" ""))]
14670   "TARGET_USE_FANCY_MATH_387
14671    && flag_unsafe_math_optimizations"
14672 {
14673   if (optimize_insn_for_size_p ())
14674     FAIL;
14675   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
14676   DONE;
14677 })
14678
14679 (define_expand "ceil<mode>2"
14680   [(use (match_operand:MODEF 0 "register_operand" ""))
14681    (use (match_operand:MODEF 1 "register_operand" ""))]
14682   "(TARGET_USE_FANCY_MATH_387
14683     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14684         || TARGET_MIX_SSE_I387)
14685     && flag_unsafe_math_optimizations)
14686    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14687        && !flag_trapping_math)"
14688 {
14689   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14690       && !flag_trapping_math
14691       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14692     {
14693       if (TARGET_ROUND)
14694         emit_insn (gen_sse4_1_round<mode>2
14695                    (operands[0], operands[1], GEN_INT (0x02)));
14696       else if (optimize_insn_for_size_p ())
14697         FAIL;
14698       else if (TARGET_64BIT || (<MODE>mode != DFmode))
14699         ix86_expand_floorceil (operand0, operand1, false);
14700       else
14701         ix86_expand_floorceildf_32 (operand0, operand1, false);
14702     }
14703   else
14704     {
14705       rtx op0, op1;
14706
14707       if (optimize_insn_for_size_p ())
14708         FAIL;
14709
14710       op0 = gen_reg_rtx (XFmode);
14711       op1 = gen_reg_rtx (XFmode);
14712       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14713       emit_insn (gen_frndintxf2_ceil (op0, op1));
14714
14715       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14716     }
14717   DONE;
14718 })
14719
14720 (define_insn_and_split "*fist<mode>2_ceil_1"
14721   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14722         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14723          UNSPEC_FIST_CEIL))
14724    (clobber (reg:CC FLAGS_REG))]
14725   "TARGET_USE_FANCY_MATH_387
14726    && flag_unsafe_math_optimizations
14727    && can_create_pseudo_p ()"
14728   "#"
14729   "&& 1"
14730   [(const_int 0)]
14731 {
14732   ix86_optimize_mode_switching[I387_CEIL] = 1;
14733
14734   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14735   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14736   if (memory_operand (operands[0], VOIDmode))
14737     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
14738                                      operands[2], operands[3]));
14739   else
14740     {
14741       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14742       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
14743                                                  operands[2], operands[3],
14744                                                  operands[4]));
14745     }
14746   DONE;
14747 }
14748   [(set_attr "type" "fistp")
14749    (set_attr "i387_cw" "ceil")
14750    (set_attr "mode" "<MODE>")])
14751
14752 (define_insn "fistdi2_ceil"
14753   [(set (match_operand:DI 0 "memory_operand" "=m")
14754         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14755          UNSPEC_FIST_CEIL))
14756    (use (match_operand:HI 2 "memory_operand" "m"))
14757    (use (match_operand:HI 3 "memory_operand" "m"))
14758    (clobber (match_scratch:XF 4 "=&1f"))]
14759   "TARGET_USE_FANCY_MATH_387
14760    && flag_unsafe_math_optimizations"
14761   "* return output_fix_trunc (insn, operands, 0);"
14762   [(set_attr "type" "fistp")
14763    (set_attr "i387_cw" "ceil")
14764    (set_attr "mode" "DI")])
14765
14766 (define_insn "fistdi2_ceil_with_temp"
14767   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14768         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14769          UNSPEC_FIST_CEIL))
14770    (use (match_operand:HI 2 "memory_operand" "m,m"))
14771    (use (match_operand:HI 3 "memory_operand" "m,m"))
14772    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14773    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14774   "TARGET_USE_FANCY_MATH_387
14775    && flag_unsafe_math_optimizations"
14776   "#"
14777   [(set_attr "type" "fistp")
14778    (set_attr "i387_cw" "ceil")
14779    (set_attr "mode" "DI")])
14780
14781 (define_split
14782   [(set (match_operand:DI 0 "register_operand" "")
14783         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14784          UNSPEC_FIST_CEIL))
14785    (use (match_operand:HI 2 "memory_operand" ""))
14786    (use (match_operand:HI 3 "memory_operand" ""))
14787    (clobber (match_operand:DI 4 "memory_operand" ""))
14788    (clobber (match_scratch 5 ""))]
14789   "reload_completed"
14790   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
14791               (use (match_dup 2))
14792               (use (match_dup 3))
14793               (clobber (match_dup 5))])
14794    (set (match_dup 0) (match_dup 4))]
14795   "")
14796
14797 (define_split
14798   [(set (match_operand:DI 0 "memory_operand" "")
14799         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14800          UNSPEC_FIST_CEIL))
14801    (use (match_operand:HI 2 "memory_operand" ""))
14802    (use (match_operand:HI 3 "memory_operand" ""))
14803    (clobber (match_operand:DI 4 "memory_operand" ""))
14804    (clobber (match_scratch 5 ""))]
14805   "reload_completed"
14806   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
14807               (use (match_dup 2))
14808               (use (match_dup 3))
14809               (clobber (match_dup 5))])]
14810   "")
14811
14812 (define_insn "fist<mode>2_ceil"
14813   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14814         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14815          UNSPEC_FIST_CEIL))
14816    (use (match_operand:HI 2 "memory_operand" "m"))
14817    (use (match_operand:HI 3 "memory_operand" "m"))]
14818   "TARGET_USE_FANCY_MATH_387
14819    && flag_unsafe_math_optimizations"
14820   "* return output_fix_trunc (insn, operands, 0);"
14821   [(set_attr "type" "fistp")
14822    (set_attr "i387_cw" "ceil")
14823    (set_attr "mode" "<MODE>")])
14824
14825 (define_insn "fist<mode>2_ceil_with_temp"
14826   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
14827         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
14828          UNSPEC_FIST_CEIL))
14829    (use (match_operand:HI 2 "memory_operand" "m,m"))
14830    (use (match_operand:HI 3 "memory_operand" "m,m"))
14831    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
14832   "TARGET_USE_FANCY_MATH_387
14833    && flag_unsafe_math_optimizations"
14834   "#"
14835   [(set_attr "type" "fistp")
14836    (set_attr "i387_cw" "ceil")
14837    (set_attr "mode" "<MODE>")])
14838
14839 (define_split
14840   [(set (match_operand:X87MODEI12 0 "register_operand" "")
14841         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14842          UNSPEC_FIST_CEIL))
14843    (use (match_operand:HI 2 "memory_operand" ""))
14844    (use (match_operand:HI 3 "memory_operand" ""))
14845    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14846   "reload_completed"
14847   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
14848                                   UNSPEC_FIST_CEIL))
14849               (use (match_dup 2))
14850               (use (match_dup 3))])
14851    (set (match_dup 0) (match_dup 4))]
14852   "")
14853
14854 (define_split
14855   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14856         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14857          UNSPEC_FIST_CEIL))
14858    (use (match_operand:HI 2 "memory_operand" ""))
14859    (use (match_operand:HI 3 "memory_operand" ""))
14860    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14861   "reload_completed"
14862   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
14863                                   UNSPEC_FIST_CEIL))
14864               (use (match_dup 2))
14865               (use (match_dup 3))])]
14866   "")
14867
14868 (define_expand "lceilxf<mode>2"
14869   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14870                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14871                     UNSPEC_FIST_CEIL))
14872               (clobber (reg:CC FLAGS_REG))])]
14873   "TARGET_USE_FANCY_MATH_387
14874    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14875    && flag_unsafe_math_optimizations"
14876   "")
14877
14878 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
14879   [(match_operand:SWI48 0 "nonimmediate_operand" "")
14880    (match_operand:MODEF 1 "register_operand" "")]
14881   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14882    && !flag_trapping_math"
14883 {
14884   ix86_expand_lfloorceil (operand0, operand1, false);
14885   DONE;
14886 })
14887
14888 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14889 (define_insn_and_split "frndintxf2_trunc"
14890   [(set (match_operand:XF 0 "register_operand" "")
14891         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14892          UNSPEC_FRNDINT_TRUNC))
14893    (clobber (reg:CC FLAGS_REG))]
14894   "TARGET_USE_FANCY_MATH_387
14895    && flag_unsafe_math_optimizations
14896    && can_create_pseudo_p ()"
14897   "#"
14898   "&& 1"
14899   [(const_int 0)]
14900 {
14901   ix86_optimize_mode_switching[I387_TRUNC] = 1;
14902
14903   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14904   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
14905
14906   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
14907                                         operands[2], operands[3]));
14908   DONE;
14909 }
14910   [(set_attr "type" "frndint")
14911    (set_attr "i387_cw" "trunc")
14912    (set_attr "mode" "XF")])
14913
14914 (define_insn "frndintxf2_trunc_i387"
14915   [(set (match_operand:XF 0 "register_operand" "=f")
14916         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14917          UNSPEC_FRNDINT_TRUNC))
14918    (use (match_operand:HI 2 "memory_operand" "m"))
14919    (use (match_operand:HI 3 "memory_operand" "m"))]
14920   "TARGET_USE_FANCY_MATH_387
14921    && flag_unsafe_math_optimizations"
14922   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14923   [(set_attr "type" "frndint")
14924    (set_attr "i387_cw" "trunc")
14925    (set_attr "mode" "XF")])
14926
14927 (define_expand "btruncxf2"
14928   [(use (match_operand:XF 0 "register_operand" ""))
14929    (use (match_operand:XF 1 "register_operand" ""))]
14930   "TARGET_USE_FANCY_MATH_387
14931    && flag_unsafe_math_optimizations"
14932 {
14933   if (optimize_insn_for_size_p ())
14934     FAIL;
14935   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
14936   DONE;
14937 })
14938
14939 (define_expand "btrunc<mode>2"
14940   [(use (match_operand:MODEF 0 "register_operand" ""))
14941    (use (match_operand:MODEF 1 "register_operand" ""))]
14942   "(TARGET_USE_FANCY_MATH_387
14943     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14944         || TARGET_MIX_SSE_I387)
14945     && flag_unsafe_math_optimizations)
14946    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14947        && !flag_trapping_math)"
14948 {
14949   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14950       && !flag_trapping_math
14951       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14952     {
14953       if (TARGET_ROUND)
14954         emit_insn (gen_sse4_1_round<mode>2
14955                    (operands[0], operands[1], GEN_INT (0x03)));
14956       else if (optimize_insn_for_size_p ())
14957         FAIL;
14958       else if (TARGET_64BIT || (<MODE>mode != DFmode))
14959         ix86_expand_trunc (operand0, operand1);
14960       else
14961         ix86_expand_truncdf_32 (operand0, operand1);
14962     }
14963   else
14964     {
14965       rtx op0, op1;
14966
14967       if (optimize_insn_for_size_p ())
14968         FAIL;
14969
14970       op0 = gen_reg_rtx (XFmode);
14971       op1 = gen_reg_rtx (XFmode);
14972       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14973       emit_insn (gen_frndintxf2_trunc (op0, op1));
14974
14975       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14976     }
14977   DONE;
14978 })
14979
14980 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14981 (define_insn_and_split "frndintxf2_mask_pm"
14982   [(set (match_operand:XF 0 "register_operand" "")
14983         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14984          UNSPEC_FRNDINT_MASK_PM))
14985    (clobber (reg:CC FLAGS_REG))]
14986   "TARGET_USE_FANCY_MATH_387
14987    && flag_unsafe_math_optimizations
14988    && can_create_pseudo_p ()"
14989   "#"
14990   "&& 1"
14991   [(const_int 0)]
14992 {
14993   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
14994
14995   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14996   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
14997
14998   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
14999                                           operands[2], operands[3]));
15000   DONE;
15001 }
15002   [(set_attr "type" "frndint")
15003    (set_attr "i387_cw" "mask_pm")
15004    (set_attr "mode" "XF")])
15005
15006 (define_insn "frndintxf2_mask_pm_i387"
15007   [(set (match_operand:XF 0 "register_operand" "=f")
15008         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15009          UNSPEC_FRNDINT_MASK_PM))
15010    (use (match_operand:HI 2 "memory_operand" "m"))
15011    (use (match_operand:HI 3 "memory_operand" "m"))]
15012   "TARGET_USE_FANCY_MATH_387
15013    && flag_unsafe_math_optimizations"
15014   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15015   [(set_attr "type" "frndint")
15016    (set_attr "i387_cw" "mask_pm")
15017    (set_attr "mode" "XF")])
15018
15019 (define_expand "nearbyintxf2"
15020   [(use (match_operand:XF 0 "register_operand" ""))
15021    (use (match_operand:XF 1 "register_operand" ""))]
15022   "TARGET_USE_FANCY_MATH_387
15023    && flag_unsafe_math_optimizations"
15024 {
15025   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15026
15027   DONE;
15028 })
15029
15030 (define_expand "nearbyint<mode>2"
15031   [(use (match_operand:MODEF 0 "register_operand" ""))
15032    (use (match_operand:MODEF 1 "register_operand" ""))]
15033   "TARGET_USE_FANCY_MATH_387
15034    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15035        || TARGET_MIX_SSE_I387)
15036    && flag_unsafe_math_optimizations"
15037 {
15038   rtx op0 = gen_reg_rtx (XFmode);
15039   rtx op1 = gen_reg_rtx (XFmode);
15040
15041   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15042   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15043
15044   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15045   DONE;
15046 })
15047
15048 (define_insn "fxam<mode>2_i387"
15049   [(set (match_operand:HI 0 "register_operand" "=a")
15050         (unspec:HI
15051           [(match_operand:X87MODEF 1 "register_operand" "f")]
15052           UNSPEC_FXAM))]
15053   "TARGET_USE_FANCY_MATH_387"
15054   "fxam\n\tfnstsw\t%0"
15055   [(set_attr "type" "multi")
15056    (set_attr "length" "4")
15057    (set_attr "unit" "i387")
15058    (set_attr "mode" "<MODE>")])
15059
15060 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15061   [(set (match_operand:HI 0 "register_operand" "")
15062         (unspec:HI
15063           [(match_operand:MODEF 1 "memory_operand" "")]
15064           UNSPEC_FXAM_MEM))]
15065   "TARGET_USE_FANCY_MATH_387
15066    && can_create_pseudo_p ()"
15067   "#"
15068   "&& 1"
15069   [(set (match_dup 2)(match_dup 1))
15070    (set (match_dup 0)
15071         (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15072 {
15073   operands[2] = gen_reg_rtx (<MODE>mode);
15074
15075   MEM_VOLATILE_P (operands[1]) = 1;
15076 }
15077   [(set_attr "type" "multi")
15078    (set_attr "unit" "i387")
15079    (set_attr "mode" "<MODE>")])
15080
15081 (define_expand "isinfxf2"
15082   [(use (match_operand:SI 0 "register_operand" ""))
15083    (use (match_operand:XF 1 "register_operand" ""))]
15084   "TARGET_USE_FANCY_MATH_387
15085    && TARGET_C99_FUNCTIONS"
15086 {
15087   rtx mask = GEN_INT (0x45);
15088   rtx val = GEN_INT (0x05);
15089
15090   rtx cond;
15091
15092   rtx scratch = gen_reg_rtx (HImode);
15093   rtx res = gen_reg_rtx (QImode);
15094
15095   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15096
15097   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15098   emit_insn (gen_cmpqi_ext_3 (scratch, val));
15099   cond = gen_rtx_fmt_ee (EQ, QImode,
15100                          gen_rtx_REG (CCmode, FLAGS_REG),
15101                          const0_rtx);
15102   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15103   emit_insn (gen_zero_extendqisi2 (operands[0], res));
15104   DONE;
15105 })
15106
15107 (define_expand "isinf<mode>2"
15108   [(use (match_operand:SI 0 "register_operand" ""))
15109    (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15110   "TARGET_USE_FANCY_MATH_387
15111    && TARGET_C99_FUNCTIONS
15112    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15113 {
15114   rtx mask = GEN_INT (0x45);
15115   rtx val = GEN_INT (0x05);
15116
15117   rtx cond;
15118
15119   rtx scratch = gen_reg_rtx (HImode);
15120   rtx res = gen_reg_rtx (QImode);
15121
15122   /* Remove excess precision by forcing value through memory. */
15123   if (memory_operand (operands[1], VOIDmode))
15124     emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15125   else
15126     {
15127       enum ix86_stack_slot slot = (virtuals_instantiated
15128                                    ? SLOT_TEMP
15129                                    : SLOT_VIRTUAL);
15130       rtx temp = assign_386_stack_local (<MODE>mode, slot);
15131
15132       emit_move_insn (temp, operands[1]);
15133       emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15134     }
15135
15136   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15137   emit_insn (gen_cmpqi_ext_3 (scratch, val));
15138   cond = gen_rtx_fmt_ee (EQ, QImode,
15139                          gen_rtx_REG (CCmode, FLAGS_REG),
15140                          const0_rtx);
15141   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15142   emit_insn (gen_zero_extendqisi2 (operands[0], res));
15143   DONE;
15144 })
15145
15146 (define_expand "signbit<mode>2"
15147   [(use (match_operand:SI 0 "register_operand" ""))
15148    (use (match_operand:X87MODEF 1 "register_operand" ""))]
15149   "TARGET_USE_FANCY_MATH_387
15150    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15151 {
15152   rtx mask = GEN_INT (0x0200);
15153
15154   rtx scratch = gen_reg_rtx (HImode);
15155
15156   emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
15157   emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
15158   DONE;
15159 })
15160 \f
15161 ;; Block operation instructions
15162
15163 (define_insn "cld"
15164   [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15165   ""
15166   "cld"
15167   [(set_attr "length" "1")
15168    (set_attr "length_immediate" "0")
15169    (set_attr "modrm" "0")])
15170
15171 (define_expand "movmemsi"
15172   [(use (match_operand:BLK 0 "memory_operand" ""))
15173    (use (match_operand:BLK 1 "memory_operand" ""))
15174    (use (match_operand:SI 2 "nonmemory_operand" ""))
15175    (use (match_operand:SI 3 "const_int_operand" ""))
15176    (use (match_operand:SI 4 "const_int_operand" ""))
15177    (use (match_operand:SI 5 "const_int_operand" ""))]
15178   ""
15179 {
15180  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15181                          operands[4], operands[5]))
15182    DONE;
15183  else
15184    FAIL;
15185 })
15186
15187 (define_expand "movmemdi"
15188   [(use (match_operand:BLK 0 "memory_operand" ""))
15189    (use (match_operand:BLK 1 "memory_operand" ""))
15190    (use (match_operand:DI 2 "nonmemory_operand" ""))
15191    (use (match_operand:DI 3 "const_int_operand" ""))
15192    (use (match_operand:SI 4 "const_int_operand" ""))
15193    (use (match_operand:SI 5 "const_int_operand" ""))]
15194   "TARGET_64BIT"
15195 {
15196  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15197                          operands[4], operands[5]))
15198    DONE;
15199  else
15200    FAIL;
15201 })
15202
15203 ;; Most CPUs don't like single string operations
15204 ;; Handle this case here to simplify previous expander.
15205
15206 (define_expand "strmov"
15207   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15208    (set (match_operand 1 "memory_operand" "") (match_dup 4))
15209    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15210               (clobber (reg:CC FLAGS_REG))])
15211    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15212               (clobber (reg:CC FLAGS_REG))])]
15213   ""
15214 {
15215   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15216
15217   /* If .md ever supports :P for Pmode, these can be directly
15218      in the pattern above.  */
15219   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15220   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15221
15222   /* Can't use this if the user has appropriated esi or edi.  */
15223   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15224       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15225     {
15226       emit_insn (gen_strmov_singleop (operands[0], operands[1],
15227                                       operands[2], operands[3],
15228                                       operands[5], operands[6]));
15229       DONE;
15230     }
15231
15232   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15233 })
15234
15235 (define_expand "strmov_singleop"
15236   [(parallel [(set (match_operand 1 "memory_operand" "")
15237                    (match_operand 3 "memory_operand" ""))
15238               (set (match_operand 0 "register_operand" "")
15239                    (match_operand 4 "" ""))
15240               (set (match_operand 2 "register_operand" "")
15241                    (match_operand 5 "" ""))])]
15242   ""
15243   "ix86_current_function_needs_cld = 1;")
15244
15245 (define_insn "*strmovdi_rex_1"
15246   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15247         (mem:DI (match_operand:DI 3 "register_operand" "1")))
15248    (set (match_operand:DI 0 "register_operand" "=D")
15249         (plus:DI (match_dup 2)
15250                  (const_int 8)))
15251    (set (match_operand:DI 1 "register_operand" "=S")
15252         (plus:DI (match_dup 3)
15253                  (const_int 8)))]
15254   "TARGET_64BIT"
15255   "movsq"
15256   [(set_attr "type" "str")
15257    (set_attr "mode" "DI")
15258    (set_attr "memory" "both")])
15259
15260 (define_insn "*strmovsi_1"
15261   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
15262         (mem:SI (match_operand:SI 3 "register_operand" "1")))
15263    (set (match_operand:SI 0 "register_operand" "=D")
15264         (plus:SI (match_dup 2)
15265                  (const_int 4)))
15266    (set (match_operand:SI 1 "register_operand" "=S")
15267         (plus:SI (match_dup 3)
15268                  (const_int 4)))]
15269   "!TARGET_64BIT"
15270   "movs{l|d}"
15271   [(set_attr "type" "str")
15272    (set_attr "mode" "SI")
15273    (set_attr "memory" "both")])
15274
15275 (define_insn "*strmovsi_rex_1"
15276   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
15277         (mem:SI (match_operand:DI 3 "register_operand" "1")))
15278    (set (match_operand:DI 0 "register_operand" "=D")
15279         (plus:DI (match_dup 2)
15280                  (const_int 4)))
15281    (set (match_operand:DI 1 "register_operand" "=S")
15282         (plus:DI (match_dup 3)
15283                  (const_int 4)))]
15284   "TARGET_64BIT"
15285   "movs{l|d}"
15286   [(set_attr "type" "str")
15287    (set_attr "mode" "SI")
15288    (set_attr "memory" "both")])
15289
15290 (define_insn "*strmovhi_1"
15291   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
15292         (mem:HI (match_operand:SI 3 "register_operand" "1")))
15293    (set (match_operand:SI 0 "register_operand" "=D")
15294         (plus:SI (match_dup 2)
15295                  (const_int 2)))
15296    (set (match_operand:SI 1 "register_operand" "=S")
15297         (plus:SI (match_dup 3)
15298                  (const_int 2)))]
15299   "!TARGET_64BIT"
15300   "movsw"
15301   [(set_attr "type" "str")
15302    (set_attr "memory" "both")
15303    (set_attr "mode" "HI")])
15304
15305 (define_insn "*strmovhi_rex_1"
15306   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
15307         (mem:HI (match_operand:DI 3 "register_operand" "1")))
15308    (set (match_operand:DI 0 "register_operand" "=D")
15309         (plus:DI (match_dup 2)
15310                  (const_int 2)))
15311    (set (match_operand:DI 1 "register_operand" "=S")
15312         (plus:DI (match_dup 3)
15313                  (const_int 2)))]
15314   "TARGET_64BIT"
15315   "movsw"
15316   [(set_attr "type" "str")
15317    (set_attr "memory" "both")
15318    (set_attr "mode" "HI")])
15319
15320 (define_insn "*strmovqi_1"
15321   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
15322         (mem:QI (match_operand:SI 3 "register_operand" "1")))
15323    (set (match_operand:SI 0 "register_operand" "=D")
15324         (plus:SI (match_dup 2)
15325                  (const_int 1)))
15326    (set (match_operand:SI 1 "register_operand" "=S")
15327         (plus:SI (match_dup 3)
15328                  (const_int 1)))]
15329   "!TARGET_64BIT"
15330   "movsb"
15331   [(set_attr "type" "str")
15332    (set_attr "memory" "both")
15333    (set_attr "mode" "QI")])
15334
15335 (define_insn "*strmovqi_rex_1"
15336   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
15337         (mem:QI (match_operand:DI 3 "register_operand" "1")))
15338    (set (match_operand:DI 0 "register_operand" "=D")
15339         (plus:DI (match_dup 2)
15340                  (const_int 1)))
15341    (set (match_operand:DI 1 "register_operand" "=S")
15342         (plus:DI (match_dup 3)
15343                  (const_int 1)))]
15344   "TARGET_64BIT"
15345   "movsb"
15346   [(set_attr "type" "str")
15347    (set_attr "memory" "both")
15348    (set_attr "prefix_rex" "0")
15349    (set_attr "mode" "QI")])
15350
15351 (define_expand "rep_mov"
15352   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15353               (set (match_operand 0 "register_operand" "")
15354                    (match_operand 5 "" ""))
15355               (set (match_operand 2 "register_operand" "")
15356                    (match_operand 6 "" ""))
15357               (set (match_operand 1 "memory_operand" "")
15358                    (match_operand 3 "memory_operand" ""))
15359               (use (match_dup 4))])]
15360   ""
15361   "ix86_current_function_needs_cld = 1;")
15362
15363 (define_insn "*rep_movdi_rex64"
15364   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15365    (set (match_operand:DI 0 "register_operand" "=D")
15366         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15367                             (const_int 3))
15368                  (match_operand:DI 3 "register_operand" "0")))
15369    (set (match_operand:DI 1 "register_operand" "=S")
15370         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15371                  (match_operand:DI 4 "register_operand" "1")))
15372    (set (mem:BLK (match_dup 3))
15373         (mem:BLK (match_dup 4)))
15374    (use (match_dup 5))]
15375   "TARGET_64BIT"
15376   "rep{%;} movsq"
15377   [(set_attr "type" "str")
15378    (set_attr "prefix_rep" "1")
15379    (set_attr "memory" "both")
15380    (set_attr "mode" "DI")])
15381
15382 (define_insn "*rep_movsi"
15383   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
15384    (set (match_operand:SI 0 "register_operand" "=D")
15385         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
15386                             (const_int 2))
15387                  (match_operand:SI 3 "register_operand" "0")))
15388    (set (match_operand:SI 1 "register_operand" "=S")
15389         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
15390                  (match_operand:SI 4 "register_operand" "1")))
15391    (set (mem:BLK (match_dup 3))
15392         (mem:BLK (match_dup 4)))
15393    (use (match_dup 5))]
15394   "!TARGET_64BIT"
15395   "rep{%;} movs{l|d}"
15396   [(set_attr "type" "str")
15397    (set_attr "prefix_rep" "1")
15398    (set_attr "memory" "both")
15399    (set_attr "mode" "SI")])
15400
15401 (define_insn "*rep_movsi_rex64"
15402   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15403    (set (match_operand:DI 0 "register_operand" "=D")
15404         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15405                             (const_int 2))
15406                  (match_operand:DI 3 "register_operand" "0")))
15407    (set (match_operand:DI 1 "register_operand" "=S")
15408         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
15409                  (match_operand:DI 4 "register_operand" "1")))
15410    (set (mem:BLK (match_dup 3))
15411         (mem:BLK (match_dup 4)))
15412    (use (match_dup 5))]
15413   "TARGET_64BIT"
15414   "rep{%;} movs{l|d}"
15415   [(set_attr "type" "str")
15416    (set_attr "prefix_rep" "1")
15417    (set_attr "memory" "both")
15418    (set_attr "mode" "SI")])
15419
15420 (define_insn "*rep_movqi"
15421   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
15422    (set (match_operand:SI 0 "register_operand" "=D")
15423         (plus:SI (match_operand:SI 3 "register_operand" "0")
15424                  (match_operand:SI 5 "register_operand" "2")))
15425    (set (match_operand:SI 1 "register_operand" "=S")
15426         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
15427    (set (mem:BLK (match_dup 3))
15428         (mem:BLK (match_dup 4)))
15429    (use (match_dup 5))]
15430   "!TARGET_64BIT"
15431   "rep{%;} movsb"
15432   [(set_attr "type" "str")
15433    (set_attr "prefix_rep" "1")
15434    (set_attr "memory" "both")
15435    (set_attr "mode" "SI")])
15436
15437 (define_insn "*rep_movqi_rex64"
15438   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15439    (set (match_operand:DI 0 "register_operand" "=D")
15440         (plus:DI (match_operand:DI 3 "register_operand" "0")
15441                  (match_operand:DI 5 "register_operand" "2")))
15442    (set (match_operand:DI 1 "register_operand" "=S")
15443         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
15444    (set (mem:BLK (match_dup 3))
15445         (mem:BLK (match_dup 4)))
15446    (use (match_dup 5))]
15447   "TARGET_64BIT"
15448   "rep{%;} movsb"
15449   [(set_attr "type" "str")
15450    (set_attr "prefix_rep" "1")
15451    (set_attr "memory" "both")
15452    (set_attr "mode" "SI")])
15453
15454 (define_expand "setmemsi"
15455    [(use (match_operand:BLK 0 "memory_operand" ""))
15456     (use (match_operand:SI 1 "nonmemory_operand" ""))
15457     (use (match_operand 2 "const_int_operand" ""))
15458     (use (match_operand 3 "const_int_operand" ""))
15459     (use (match_operand:SI 4 "const_int_operand" ""))
15460     (use (match_operand:SI 5 "const_int_operand" ""))]
15461   ""
15462 {
15463  if (ix86_expand_setmem (operands[0], operands[1],
15464                          operands[2], operands[3],
15465                          operands[4], operands[5]))
15466    DONE;
15467  else
15468    FAIL;
15469 })
15470
15471 (define_expand "setmemdi"
15472    [(use (match_operand:BLK 0 "memory_operand" ""))
15473     (use (match_operand:DI 1 "nonmemory_operand" ""))
15474     (use (match_operand 2 "const_int_operand" ""))
15475     (use (match_operand 3 "const_int_operand" ""))
15476     (use (match_operand 4 "const_int_operand" ""))
15477     (use (match_operand 5 "const_int_operand" ""))]
15478   "TARGET_64BIT"
15479 {
15480  if (ix86_expand_setmem (operands[0], operands[1],
15481                          operands[2], operands[3],
15482                          operands[4], operands[5]))
15483    DONE;
15484  else
15485    FAIL;
15486 })
15487
15488 ;; Most CPUs don't like single string operations
15489 ;; Handle this case here to simplify previous expander.
15490
15491 (define_expand "strset"
15492   [(set (match_operand 1 "memory_operand" "")
15493         (match_operand 2 "register_operand" ""))
15494    (parallel [(set (match_operand 0 "register_operand" "")
15495                    (match_dup 3))
15496               (clobber (reg:CC FLAGS_REG))])]
15497   ""
15498 {
15499   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15500     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15501
15502   /* If .md ever supports :P for Pmode, this can be directly
15503      in the pattern above.  */
15504   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15505                               GEN_INT (GET_MODE_SIZE (GET_MODE
15506                                                       (operands[2]))));
15507   if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15508     {
15509       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15510                                       operands[3]));
15511       DONE;
15512     }
15513 })
15514
15515 (define_expand "strset_singleop"
15516   [(parallel [(set (match_operand 1 "memory_operand" "")
15517                    (match_operand 2 "register_operand" ""))
15518               (set (match_operand 0 "register_operand" "")
15519                    (match_operand 3 "" ""))])]
15520   ""
15521   "ix86_current_function_needs_cld = 1;")
15522
15523 (define_insn "*strsetdi_rex_1"
15524   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
15525         (match_operand:DI 2 "register_operand" "a"))
15526    (set (match_operand:DI 0 "register_operand" "=D")
15527         (plus:DI (match_dup 1)
15528                  (const_int 8)))]
15529   "TARGET_64BIT"
15530   "stosq"
15531   [(set_attr "type" "str")
15532    (set_attr "memory" "store")
15533    (set_attr "mode" "DI")])
15534
15535 (define_insn "*strsetsi_1"
15536   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
15537         (match_operand:SI 2 "register_operand" "a"))
15538    (set (match_operand:SI 0 "register_operand" "=D")
15539         (plus:SI (match_dup 1)
15540                  (const_int 4)))]
15541   "!TARGET_64BIT"
15542   "stos{l|d}"
15543   [(set_attr "type" "str")
15544    (set_attr "memory" "store")
15545    (set_attr "mode" "SI")])
15546
15547 (define_insn "*strsetsi_rex_1"
15548   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
15549         (match_operand:SI 2 "register_operand" "a"))
15550    (set (match_operand:DI 0 "register_operand" "=D")
15551         (plus:DI (match_dup 1)
15552                  (const_int 4)))]
15553   "TARGET_64BIT"
15554   "stos{l|d}"
15555   [(set_attr "type" "str")
15556    (set_attr "memory" "store")
15557    (set_attr "mode" "SI")])
15558
15559 (define_insn "*strsethi_1"
15560   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
15561         (match_operand:HI 2 "register_operand" "a"))
15562    (set (match_operand:SI 0 "register_operand" "=D")
15563         (plus:SI (match_dup 1)
15564                  (const_int 2)))]
15565   "!TARGET_64BIT"
15566   "stosw"
15567   [(set_attr "type" "str")
15568    (set_attr "memory" "store")
15569    (set_attr "mode" "HI")])
15570
15571 (define_insn "*strsethi_rex_1"
15572   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
15573         (match_operand:HI 2 "register_operand" "a"))
15574    (set (match_operand:DI 0 "register_operand" "=D")
15575         (plus:DI (match_dup 1)
15576                  (const_int 2)))]
15577   "TARGET_64BIT"
15578   "stosw"
15579   [(set_attr "type" "str")
15580    (set_attr "memory" "store")
15581    (set_attr "mode" "HI")])
15582
15583 (define_insn "*strsetqi_1"
15584   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
15585         (match_operand:QI 2 "register_operand" "a"))
15586    (set (match_operand:SI 0 "register_operand" "=D")
15587         (plus:SI (match_dup 1)
15588                  (const_int 1)))]
15589   "!TARGET_64BIT"
15590   "stosb"
15591   [(set_attr "type" "str")
15592    (set_attr "memory" "store")
15593    (set_attr "mode" "QI")])
15594
15595 (define_insn "*strsetqi_rex_1"
15596   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
15597         (match_operand:QI 2 "register_operand" "a"))
15598    (set (match_operand:DI 0 "register_operand" "=D")
15599         (plus:DI (match_dup 1)
15600                  (const_int 1)))]
15601   "TARGET_64BIT"
15602   "stosb"
15603   [(set_attr "type" "str")
15604    (set_attr "memory" "store")
15605    (set_attr "prefix_rex" "0")
15606    (set_attr "mode" "QI")])
15607
15608 (define_expand "rep_stos"
15609   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15610               (set (match_operand 0 "register_operand" "")
15611                    (match_operand 4 "" ""))
15612               (set (match_operand 2 "memory_operand" "") (const_int 0))
15613               (use (match_operand 3 "register_operand" ""))
15614               (use (match_dup 1))])]
15615   ""
15616   "ix86_current_function_needs_cld = 1;")
15617
15618 (define_insn "*rep_stosdi_rex64"
15619   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15620    (set (match_operand:DI 0 "register_operand" "=D")
15621         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15622                             (const_int 3))
15623                  (match_operand:DI 3 "register_operand" "0")))
15624    (set (mem:BLK (match_dup 3))
15625         (const_int 0))
15626    (use (match_operand:DI 2 "register_operand" "a"))
15627    (use (match_dup 4))]
15628   "TARGET_64BIT"
15629   "rep{%;} stosq"
15630   [(set_attr "type" "str")
15631    (set_attr "prefix_rep" "1")
15632    (set_attr "memory" "store")
15633    (set_attr "mode" "DI")])
15634
15635 (define_insn "*rep_stossi"
15636   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
15637    (set (match_operand:SI 0 "register_operand" "=D")
15638         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
15639                             (const_int 2))
15640                  (match_operand:SI 3 "register_operand" "0")))
15641    (set (mem:BLK (match_dup 3))
15642         (const_int 0))
15643    (use (match_operand:SI 2 "register_operand" "a"))
15644    (use (match_dup 4))]
15645   "!TARGET_64BIT"
15646   "rep{%;} stos{l|d}"
15647   [(set_attr "type" "str")
15648    (set_attr "prefix_rep" "1")
15649    (set_attr "memory" "store")
15650    (set_attr "mode" "SI")])
15651
15652 (define_insn "*rep_stossi_rex64"
15653   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15654    (set (match_operand:DI 0 "register_operand" "=D")
15655         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15656                             (const_int 2))
15657                  (match_operand:DI 3 "register_operand" "0")))
15658    (set (mem:BLK (match_dup 3))
15659         (const_int 0))
15660    (use (match_operand:SI 2 "register_operand" "a"))
15661    (use (match_dup 4))]
15662   "TARGET_64BIT"
15663   "rep{%;} stos{l|d}"
15664   [(set_attr "type" "str")
15665    (set_attr "prefix_rep" "1")
15666    (set_attr "memory" "store")
15667    (set_attr "mode" "SI")])
15668
15669 (define_insn "*rep_stosqi"
15670   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
15671    (set (match_operand:SI 0 "register_operand" "=D")
15672         (plus:SI (match_operand:SI 3 "register_operand" "0")
15673                  (match_operand:SI 4 "register_operand" "1")))
15674    (set (mem:BLK (match_dup 3))
15675         (const_int 0))
15676    (use (match_operand:QI 2 "register_operand" "a"))
15677    (use (match_dup 4))]
15678   "!TARGET_64BIT"
15679   "rep{%;} stosb"
15680   [(set_attr "type" "str")
15681    (set_attr "prefix_rep" "1")
15682    (set_attr "memory" "store")
15683    (set_attr "mode" "QI")])
15684
15685 (define_insn "*rep_stosqi_rex64"
15686   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15687    (set (match_operand:DI 0 "register_operand" "=D")
15688         (plus:DI (match_operand:DI 3 "register_operand" "0")
15689                  (match_operand:DI 4 "register_operand" "1")))
15690    (set (mem:BLK (match_dup 3))
15691         (const_int 0))
15692    (use (match_operand:QI 2 "register_operand" "a"))
15693    (use (match_dup 4))]
15694   "TARGET_64BIT"
15695   "rep{%;} stosb"
15696   [(set_attr "type" "str")
15697    (set_attr "prefix_rep" "1")
15698    (set_attr "memory" "store")
15699    (set_attr "prefix_rex" "0")
15700    (set_attr "mode" "QI")])
15701
15702 (define_expand "cmpstrnsi"
15703   [(set (match_operand:SI 0 "register_operand" "")
15704         (compare:SI (match_operand:BLK 1 "general_operand" "")
15705                     (match_operand:BLK 2 "general_operand" "")))
15706    (use (match_operand 3 "general_operand" ""))
15707    (use (match_operand 4 "immediate_operand" ""))]
15708   ""
15709 {
15710   rtx addr1, addr2, out, outlow, count, countreg, align;
15711
15712   if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
15713     FAIL;
15714
15715   /* Can't use this if the user has appropriated esi or edi.  */
15716   if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
15717     FAIL;
15718
15719   out = operands[0];
15720   if (!REG_P (out))
15721     out = gen_reg_rtx (SImode);
15722
15723   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
15724   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
15725   if (addr1 != XEXP (operands[1], 0))
15726     operands[1] = replace_equiv_address_nv (operands[1], addr1);
15727   if (addr2 != XEXP (operands[2], 0))
15728     operands[2] = replace_equiv_address_nv (operands[2], addr2);
15729
15730   count = operands[3];
15731   countreg = ix86_zero_extend_to_Pmode (count);
15732
15733   /* %%% Iff we are testing strict equality, we can use known alignment
15734      to good advantage.  This may be possible with combine, particularly
15735      once cc0 is dead.  */
15736   align = operands[4];
15737
15738   if (CONST_INT_P (count))
15739     {
15740       if (INTVAL (count) == 0)
15741         {
15742           emit_move_insn (operands[0], const0_rtx);
15743           DONE;
15744         }
15745       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
15746                                      operands[1], operands[2]));
15747     }
15748   else
15749     {
15750       rtx (*gen_cmp) (rtx, rtx);
15751
15752       gen_cmp = (TARGET_64BIT
15753                  ? gen_cmpdi_1 : gen_cmpsi_1);
15754
15755       emit_insn (gen_cmp (countreg, countreg));
15756       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
15757                                   operands[1], operands[2]));
15758     }
15759
15760   outlow = gen_lowpart (QImode, out);
15761   emit_insn (gen_cmpintqi (outlow));
15762   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
15763
15764   if (operands[0] != out)
15765     emit_move_insn (operands[0], out);
15766
15767   DONE;
15768 })
15769
15770 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
15771
15772 (define_expand "cmpintqi"
15773   [(set (match_dup 1)
15774         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15775    (set (match_dup 2)
15776         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15777    (parallel [(set (match_operand:QI 0 "register_operand" "")
15778                    (minus:QI (match_dup 1)
15779                              (match_dup 2)))
15780               (clobber (reg:CC FLAGS_REG))])]
15781   ""
15782   "operands[1] = gen_reg_rtx (QImode);
15783    operands[2] = gen_reg_rtx (QImode);")
15784
15785 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
15786 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
15787
15788 (define_expand "cmpstrnqi_nz_1"
15789   [(parallel [(set (reg:CC FLAGS_REG)
15790                    (compare:CC (match_operand 4 "memory_operand" "")
15791                                (match_operand 5 "memory_operand" "")))
15792               (use (match_operand 2 "register_operand" ""))
15793               (use (match_operand:SI 3 "immediate_operand" ""))
15794               (clobber (match_operand 0 "register_operand" ""))
15795               (clobber (match_operand 1 "register_operand" ""))
15796               (clobber (match_dup 2))])]
15797   ""
15798   "ix86_current_function_needs_cld = 1;")
15799
15800 (define_insn "*cmpstrnqi_nz_1"
15801   [(set (reg:CC FLAGS_REG)
15802         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
15803                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
15804    (use (match_operand:SI 6 "register_operand" "2"))
15805    (use (match_operand:SI 3 "immediate_operand" "i"))
15806    (clobber (match_operand:SI 0 "register_operand" "=S"))
15807    (clobber (match_operand:SI 1 "register_operand" "=D"))
15808    (clobber (match_operand:SI 2 "register_operand" "=c"))]
15809   "!TARGET_64BIT"
15810   "repz{%;} cmpsb"
15811   [(set_attr "type" "str")
15812    (set_attr "mode" "QI")
15813    (set_attr "prefix_rep" "1")])
15814
15815 (define_insn "*cmpstrnqi_nz_rex_1"
15816   [(set (reg:CC FLAGS_REG)
15817         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
15818                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
15819    (use (match_operand:DI 6 "register_operand" "2"))
15820    (use (match_operand:SI 3 "immediate_operand" "i"))
15821    (clobber (match_operand:DI 0 "register_operand" "=S"))
15822    (clobber (match_operand:DI 1 "register_operand" "=D"))
15823    (clobber (match_operand:DI 2 "register_operand" "=c"))]
15824   "TARGET_64BIT"
15825   "repz{%;} cmpsb"
15826   [(set_attr "type" "str")
15827    (set_attr "mode" "QI")
15828    (set_attr "prefix_rex" "0")
15829    (set_attr "prefix_rep" "1")])
15830
15831 ;; The same, but the count is not known to not be zero.
15832
15833 (define_expand "cmpstrnqi_1"
15834   [(parallel [(set (reg:CC FLAGS_REG)
15835                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
15836                                      (const_int 0))
15837                   (compare:CC (match_operand 4 "memory_operand" "")
15838                               (match_operand 5 "memory_operand" ""))
15839                   (const_int 0)))
15840               (use (match_operand:SI 3 "immediate_operand" ""))
15841               (use (reg:CC FLAGS_REG))
15842               (clobber (match_operand 0 "register_operand" ""))
15843               (clobber (match_operand 1 "register_operand" ""))
15844               (clobber (match_dup 2))])]
15845   ""
15846   "ix86_current_function_needs_cld = 1;")
15847
15848 (define_insn "*cmpstrnqi_1"
15849   [(set (reg:CC FLAGS_REG)
15850         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
15851                              (const_int 0))
15852           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
15853                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
15854           (const_int 0)))
15855    (use (match_operand:SI 3 "immediate_operand" "i"))
15856    (use (reg:CC FLAGS_REG))
15857    (clobber (match_operand:SI 0 "register_operand" "=S"))
15858    (clobber (match_operand:SI 1 "register_operand" "=D"))
15859    (clobber (match_operand:SI 2 "register_operand" "=c"))]
15860   "!TARGET_64BIT"
15861   "repz{%;} cmpsb"
15862   [(set_attr "type" "str")
15863    (set_attr "mode" "QI")
15864    (set_attr "prefix_rep" "1")])
15865
15866 (define_insn "*cmpstrnqi_rex_1"
15867   [(set (reg:CC FLAGS_REG)
15868         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
15869                              (const_int 0))
15870           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
15871                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
15872           (const_int 0)))
15873    (use (match_operand:SI 3 "immediate_operand" "i"))
15874    (use (reg:CC FLAGS_REG))
15875    (clobber (match_operand:DI 0 "register_operand" "=S"))
15876    (clobber (match_operand:DI 1 "register_operand" "=D"))
15877    (clobber (match_operand:DI 2 "register_operand" "=c"))]
15878   "TARGET_64BIT"
15879   "repz{%;} cmpsb"
15880   [(set_attr "type" "str")
15881    (set_attr "mode" "QI")
15882    (set_attr "prefix_rex" "0")
15883    (set_attr "prefix_rep" "1")])
15884
15885 (define_expand "strlensi"
15886   [(set (match_operand:SI 0 "register_operand" "")
15887         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
15888                     (match_operand:QI 2 "immediate_operand" "")
15889                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
15890   ""
15891 {
15892  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
15893    DONE;
15894  else
15895    FAIL;
15896 })
15897
15898 (define_expand "strlendi"
15899   [(set (match_operand:DI 0 "register_operand" "")
15900         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
15901                     (match_operand:QI 2 "immediate_operand" "")
15902                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
15903   ""
15904 {
15905  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
15906    DONE;
15907  else
15908    FAIL;
15909 })
15910
15911 (define_expand "strlenqi_1"
15912   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
15913               (clobber (match_operand 1 "register_operand" ""))
15914               (clobber (reg:CC FLAGS_REG))])]
15915   ""
15916   "ix86_current_function_needs_cld = 1;")
15917
15918 (define_insn "*strlenqi_1"
15919   [(set (match_operand:SI 0 "register_operand" "=&c")
15920         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
15921                     (match_operand:QI 2 "register_operand" "a")
15922                     (match_operand:SI 3 "immediate_operand" "i")
15923                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
15924    (clobber (match_operand:SI 1 "register_operand" "=D"))
15925    (clobber (reg:CC FLAGS_REG))]
15926   "!TARGET_64BIT"
15927   "repnz{%;} scasb"
15928   [(set_attr "type" "str")
15929    (set_attr "mode" "QI")
15930    (set_attr "prefix_rep" "1")])
15931
15932 (define_insn "*strlenqi_rex_1"
15933   [(set (match_operand:DI 0 "register_operand" "=&c")
15934         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
15935                     (match_operand:QI 2 "register_operand" "a")
15936                     (match_operand:DI 3 "immediate_operand" "i")
15937                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
15938    (clobber (match_operand:DI 1 "register_operand" "=D"))
15939    (clobber (reg:CC FLAGS_REG))]
15940   "TARGET_64BIT"
15941   "repnz{%;} scasb"
15942   [(set_attr "type" "str")
15943    (set_attr "mode" "QI")
15944    (set_attr "prefix_rex" "0")
15945    (set_attr "prefix_rep" "1")])
15946
15947 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
15948 ;; handled in combine, but it is not currently up to the task.
15949 ;; When used for their truth value, the cmpstrn* expanders generate
15950 ;; code like this:
15951 ;;
15952 ;;   repz cmpsb
15953 ;;   seta       %al
15954 ;;   setb       %dl
15955 ;;   cmpb       %al, %dl
15956 ;;   jcc        label
15957 ;;
15958 ;; The intermediate three instructions are unnecessary.
15959
15960 ;; This one handles cmpstrn*_nz_1...
15961 (define_peephole2
15962   [(parallel[
15963      (set (reg:CC FLAGS_REG)
15964           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15965                       (mem:BLK (match_operand 5 "register_operand" ""))))
15966      (use (match_operand 6 "register_operand" ""))
15967      (use (match_operand:SI 3 "immediate_operand" ""))
15968      (clobber (match_operand 0 "register_operand" ""))
15969      (clobber (match_operand 1 "register_operand" ""))
15970      (clobber (match_operand 2 "register_operand" ""))])
15971    (set (match_operand:QI 7 "register_operand" "")
15972         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15973    (set (match_operand:QI 8 "register_operand" "")
15974         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15975    (set (reg FLAGS_REG)
15976         (compare (match_dup 7) (match_dup 8)))
15977   ]
15978   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15979   [(parallel[
15980      (set (reg:CC FLAGS_REG)
15981           (compare:CC (mem:BLK (match_dup 4))
15982                       (mem:BLK (match_dup 5))))
15983      (use (match_dup 6))
15984      (use (match_dup 3))
15985      (clobber (match_dup 0))
15986      (clobber (match_dup 1))
15987      (clobber (match_dup 2))])]
15988   "")
15989
15990 ;; ...and this one handles cmpstrn*_1.
15991 (define_peephole2
15992   [(parallel[
15993      (set (reg:CC FLAGS_REG)
15994           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
15995                                (const_int 0))
15996             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15997                         (mem:BLK (match_operand 5 "register_operand" "")))
15998             (const_int 0)))
15999      (use (match_operand:SI 3 "immediate_operand" ""))
16000      (use (reg:CC FLAGS_REG))
16001      (clobber (match_operand 0 "register_operand" ""))
16002      (clobber (match_operand 1 "register_operand" ""))
16003      (clobber (match_operand 2 "register_operand" ""))])
16004    (set (match_operand:QI 7 "register_operand" "")
16005         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16006    (set (match_operand:QI 8 "register_operand" "")
16007         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16008    (set (reg FLAGS_REG)
16009         (compare (match_dup 7) (match_dup 8)))
16010   ]
16011   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16012   [(parallel[
16013      (set (reg:CC FLAGS_REG)
16014           (if_then_else:CC (ne (match_dup 6)
16015                                (const_int 0))
16016             (compare:CC (mem:BLK (match_dup 4))
16017                         (mem:BLK (match_dup 5)))
16018             (const_int 0)))
16019      (use (match_dup 3))
16020      (use (reg:CC FLAGS_REG))
16021      (clobber (match_dup 0))
16022      (clobber (match_dup 1))
16023      (clobber (match_dup 2))])]
16024   "")
16025
16026
16027 \f
16028 ;; Conditional move instructions.
16029
16030 (define_expand "mov<mode>cc"
16031   [(set (match_operand:SWIM 0 "register_operand" "")
16032         (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator" "")
16033                            (match_operand:SWIM 2 "general_operand" "")
16034                            (match_operand:SWIM 3 "general_operand" "")))]
16035   ""
16036   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16037
16038 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16039 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16040 ;; So just document what we're doing explicitly.
16041
16042 (define_expand "x86_mov<mode>cc_0_m1"
16043   [(parallel
16044     [(set (match_operand:SWI48 0 "register_operand" "")
16045           (if_then_else:SWI48
16046             (match_operator:SWI48 2 "ix86_carry_flag_operator"
16047              [(match_operand 1 "flags_reg_operand" "")
16048               (const_int 0)])
16049             (const_int -1)
16050             (const_int 0)))
16051      (clobber (reg:CC FLAGS_REG))])]
16052   ""
16053   "")
16054
16055 (define_insn "*x86_mov<mode>cc_0_m1"
16056   [(set (match_operand:SWI48 0 "register_operand" "=r")
16057         (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16058                              [(reg FLAGS_REG) (const_int 0)])
16059           (const_int -1)
16060           (const_int 0)))
16061    (clobber (reg:CC FLAGS_REG))]
16062   ""
16063   "sbb{<imodesuffix>}\t%0, %0"
16064   ; Since we don't have the proper number of operands for an alu insn,
16065   ; fill in all the blanks.
16066   [(set_attr "type" "alu")
16067    (set_attr "use_carry" "1")
16068    (set_attr "pent_pair" "pu")
16069    (set_attr "memory" "none")
16070    (set_attr "imm_disp" "false")
16071    (set_attr "mode" "<MODE>")
16072    (set_attr "length_immediate" "0")])
16073
16074 (define_insn "*x86_mov<mode>cc_0_m1_se"
16075   [(set (match_operand:SWI48 0 "register_operand" "=r")
16076         (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16077                              [(reg FLAGS_REG) (const_int 0)])
16078                             (const_int 1)
16079                             (const_int 0)))
16080    (clobber (reg:CC FLAGS_REG))]
16081   ""
16082   "sbb{<imodesuffix>}\t%0, %0"
16083   [(set_attr "type" "alu")
16084    (set_attr "use_carry" "1")
16085    (set_attr "pent_pair" "pu")
16086    (set_attr "memory" "none")
16087    (set_attr "imm_disp" "false")
16088    (set_attr "mode" "<MODE>")
16089    (set_attr "length_immediate" "0")])
16090
16091 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16092   [(set (match_operand:SWI48 0 "register_operand" "=r")
16093         (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16094                     [(reg FLAGS_REG) (const_int 0)])))]
16095   ""
16096   "sbb{<imodesuffix>}\t%0, %0"
16097   [(set_attr "type" "alu")
16098    (set_attr "use_carry" "1")
16099    (set_attr "pent_pair" "pu")
16100    (set_attr "memory" "none")
16101    (set_attr "imm_disp" "false")
16102    (set_attr "mode" "<MODE>")
16103    (set_attr "length_immediate" "0")])
16104
16105 (define_insn "*mov<mode>cc_noc"
16106   [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16107         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16108                                [(reg FLAGS_REG) (const_int 0)])
16109           (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16110           (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16111   "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16112   "@
16113    cmov%O2%C1\t{%2, %0|%0, %2}
16114    cmov%O2%c1\t{%3, %0|%0, %3}"
16115   [(set_attr "type" "icmov")
16116    (set_attr "mode" "<MODE>")])
16117
16118 (define_insn_and_split "*movqicc_noc"
16119   [(set (match_operand:QI 0 "register_operand" "=r,r")
16120         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16121                            [(match_operand 4 "flags_reg_operand" "")
16122                             (const_int 0)])
16123                       (match_operand:QI 2 "register_operand" "r,0")
16124                       (match_operand:QI 3 "register_operand" "0,r")))]
16125   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16126   "#"
16127   "&& reload_completed"
16128   [(set (match_dup 0)
16129         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16130                       (match_dup 2)
16131                       (match_dup 3)))]
16132   "operands[0] = gen_lowpart (SImode, operands[0]);
16133    operands[2] = gen_lowpart (SImode, operands[2]);
16134    operands[3] = gen_lowpart (SImode, operands[3]);"
16135   [(set_attr "type" "icmov")
16136    (set_attr "mode" "SI")])
16137
16138 (define_expand "mov<mode>cc"
16139   [(set (match_operand:X87MODEF 0 "register_operand" "")
16140         (if_then_else:X87MODEF
16141           (match_operand 1 "ix86_fp_comparison_operator" "")
16142           (match_operand:X87MODEF 2 "register_operand" "")
16143           (match_operand:X87MODEF 3 "register_operand" "")))]
16144   "(TARGET_80387 && TARGET_CMOVE)
16145    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16146   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16147
16148 (define_insn "*movsfcc_1_387"
16149   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16150         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16151                                 [(reg FLAGS_REG) (const_int 0)])
16152                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16153                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16154   "TARGET_80387 && TARGET_CMOVE
16155    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16156   "@
16157    fcmov%F1\t{%2, %0|%0, %2}
16158    fcmov%f1\t{%3, %0|%0, %3}
16159    cmov%O2%C1\t{%2, %0|%0, %2}
16160    cmov%O2%c1\t{%3, %0|%0, %3}"
16161   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16162    (set_attr "mode" "SF,SF,SI,SI")])
16163
16164 (define_insn "*movdfcc_1"
16165   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16166         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16167                                 [(reg FLAGS_REG) (const_int 0)])
16168                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16169                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16170   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16171    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16172   "@
16173    fcmov%F1\t{%2, %0|%0, %2}
16174    fcmov%f1\t{%3, %0|%0, %3}
16175    #
16176    #"
16177   [(set_attr "type" "fcmov,fcmov,multi,multi")
16178    (set_attr "mode" "DF")])
16179
16180 (define_insn "*movdfcc_1_rex64"
16181   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16182         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16183                                 [(reg FLAGS_REG) (const_int 0)])
16184                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16185                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16186   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16187    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16188   "@
16189    fcmov%F1\t{%2, %0|%0, %2}
16190    fcmov%f1\t{%3, %0|%0, %3}
16191    cmov%O2%C1\t{%2, %0|%0, %2}
16192    cmov%O2%c1\t{%3, %0|%0, %3}"
16193   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16194    (set_attr "mode" "DF")])
16195
16196 (define_split
16197   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16198         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16199                                 [(match_operand 4 "flags_reg_operand" "")
16200                                  (const_int 0)])
16201                       (match_operand:DF 2 "nonimmediate_operand" "")
16202                       (match_operand:DF 3 "nonimmediate_operand" "")))]
16203   "!TARGET_64BIT && reload_completed"
16204   [(set (match_dup 2)
16205         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16206                       (match_dup 5)
16207                       (match_dup 6)))
16208    (set (match_dup 3)
16209         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16210                       (match_dup 7)
16211                       (match_dup 8)))]
16212 {
16213   split_di (&operands[2], 2, &operands[5], &operands[7]);
16214   split_di (&operands[0], 1, &operands[2], &operands[3]);
16215 })
16216
16217 (define_insn "*movxfcc_1"
16218   [(set (match_operand:XF 0 "register_operand" "=f,f")
16219         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16220                                 [(reg FLAGS_REG) (const_int 0)])
16221                       (match_operand:XF 2 "register_operand" "f,0")
16222                       (match_operand:XF 3 "register_operand" "0,f")))]
16223   "TARGET_80387 && TARGET_CMOVE"
16224   "@
16225    fcmov%F1\t{%2, %0|%0, %2}
16226    fcmov%f1\t{%3, %0|%0, %3}"
16227   [(set_attr "type" "fcmov")
16228    (set_attr "mode" "XF")])
16229
16230 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16231 ;; the scalar versions to have only XMM registers as operands.
16232
16233 ;; XOP conditional move
16234 (define_insn "*xop_pcmov_<mode>"
16235   [(set (match_operand:MODEF 0 "register_operand" "=x")
16236         (if_then_else:MODEF
16237           (match_operand:MODEF 1 "register_operand" "x")
16238           (match_operand:MODEF 2 "register_operand" "x")
16239           (match_operand:MODEF 3 "register_operand" "x")))]
16240   "TARGET_XOP"
16241   "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16242   [(set_attr "type" "sse4arg")])
16243
16244 ;; These versions of the min/max patterns are intentionally ignorant of
16245 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16246 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16247 ;; are undefined in this condition, we're certain this is correct.
16248
16249 (define_insn "*avx_<code><mode>3"
16250   [(set (match_operand:MODEF 0 "register_operand" "=x")
16251         (smaxmin:MODEF
16252           (match_operand:MODEF 1 "nonimmediate_operand" "%x")
16253           (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
16254   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16255   "v<maxmin_float>s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16256   [(set_attr "type" "sseadd")
16257    (set_attr "prefix" "vex")
16258    (set_attr "mode" "<MODE>")])
16259
16260 (define_insn "<code><mode>3"
16261   [(set (match_operand:MODEF 0 "register_operand" "=x")
16262         (smaxmin:MODEF
16263           (match_operand:MODEF 1 "nonimmediate_operand" "%0")
16264           (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
16265   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16266   "<maxmin_float>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
16267   [(set_attr "type" "sseadd")
16268    (set_attr "mode" "<MODE>")])
16269
16270 ;; These versions of the min/max patterns implement exactly the operations
16271 ;;   min = (op1 < op2 ? op1 : op2)
16272 ;;   max = (!(op1 < op2) ? op1 : op2)
16273 ;; Their operands are not commutative, and thus they may be used in the
16274 ;; presence of -0.0 and NaN.
16275
16276 (define_insn "*avx_ieee_smin<mode>3"
16277   [(set (match_operand:MODEF 0 "register_operand" "=x")
16278         (unspec:MODEF
16279           [(match_operand:MODEF 1 "register_operand" "x")
16280            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16281          UNSPEC_IEEE_MIN))]
16282   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16283   "vmins<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16284   [(set_attr "type" "sseadd")
16285    (set_attr "prefix" "vex")
16286    (set_attr "mode" "<MODE>")])
16287
16288 (define_insn "*ieee_smin<mode>3"
16289   [(set (match_operand:MODEF 0 "register_operand" "=x")
16290         (unspec:MODEF
16291           [(match_operand:MODEF 1 "register_operand" "0")
16292            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16293          UNSPEC_IEEE_MIN))]
16294   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16295   "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
16296   [(set_attr "type" "sseadd")
16297    (set_attr "mode" "<MODE>")])
16298
16299 (define_insn "*avx_ieee_smax<mode>3"
16300   [(set (match_operand:MODEF 0 "register_operand" "=x")
16301         (unspec:MODEF
16302           [(match_operand:MODEF 1 "register_operand" "0")
16303            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16304          UNSPEC_IEEE_MAX))]
16305   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16306   "vmaxs<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16307   [(set_attr "type" "sseadd")
16308    (set_attr "prefix" "vex")
16309    (set_attr "mode" "<MODE>")])
16310
16311 (define_insn "*ieee_smax<mode>3"
16312   [(set (match_operand:MODEF 0 "register_operand" "=x")
16313         (unspec:MODEF
16314           [(match_operand:MODEF 1 "register_operand" "0")
16315            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16316          UNSPEC_IEEE_MAX))]
16317   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16318   "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
16319   [(set_attr "type" "sseadd")
16320    (set_attr "mode" "<MODE>")])
16321
16322 ;; Make two stack loads independent:
16323 ;;   fld aa              fld aa
16324 ;;   fld %st(0)     ->   fld bb
16325 ;;   fmul bb             fmul %st(1), %st
16326 ;;
16327 ;; Actually we only match the last two instructions for simplicity.
16328 (define_peephole2
16329   [(set (match_operand 0 "fp_register_operand" "")
16330         (match_operand 1 "fp_register_operand" ""))
16331    (set (match_dup 0)
16332         (match_operator 2 "binary_fp_operator"
16333            [(match_dup 0)
16334             (match_operand 3 "memory_operand" "")]))]
16335   "REGNO (operands[0]) != REGNO (operands[1])"
16336   [(set (match_dup 0) (match_dup 3))
16337    (set (match_dup 0) (match_dup 4))]
16338
16339   ;; The % modifier is not operational anymore in peephole2's, so we have to
16340   ;; swap the operands manually in the case of addition and multiplication.
16341   "if (COMMUTATIVE_ARITH_P (operands[2]))
16342      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
16343                                  operands[0], operands[1]);
16344    else
16345      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
16346                                  operands[1], operands[0]);")
16347
16348 ;; Conditional addition patterns
16349 (define_expand "add<mode>cc"
16350   [(match_operand:SWI 0 "register_operand" "")
16351    (match_operand 1 "ordered_comparison_operator" "")
16352    (match_operand:SWI 2 "register_operand" "")
16353    (match_operand:SWI 3 "const_int_operand" "")]
16354   ""
16355   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16356
16357 \f
16358 ;; Misc patterns (?)
16359
16360 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16361 ;; Otherwise there will be nothing to keep
16362 ;;
16363 ;; [(set (reg ebp) (reg esp))]
16364 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16365 ;;  (clobber (eflags)]
16366 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16367 ;;
16368 ;; in proper program order.
16369
16370 (define_insn "pro_epilogue_adjust_stack_<mode>_1"
16371   [(set (match_operand:P 0 "register_operand" "=r,r")
16372         (plus:P (match_operand:P 1 "register_operand" "0,r")
16373                 (match_operand:P 2 "<immediate_operand>" "<i>,<i>")))
16374    (clobber (reg:CC FLAGS_REG))
16375    (clobber (mem:BLK (scratch)))]
16376   ""
16377 {
16378   switch (get_attr_type (insn))
16379     {
16380     case TYPE_IMOV:
16381       return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16382
16383     case TYPE_ALU:
16384       gcc_assert (rtx_equal_p (operands[0], operands[1]));
16385       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16386         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16387
16388       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16389
16390     default:
16391       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16392       return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
16393     }
16394 }
16395   [(set (attr "type")
16396         (cond [(and (eq_attr "alternative" "0")
16397                     (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
16398                  (const_string "alu")
16399                (match_operand:<MODE> 2 "const0_operand" "")
16400                  (const_string "imov")
16401               ]
16402               (const_string "lea")))
16403    (set (attr "length_immediate")
16404         (cond [(eq_attr "type" "imov")
16405                  (const_string "0")
16406                (and (eq_attr "type" "alu")
16407                     (match_operand 2 "const128_operand" ""))
16408                  (const_string "1")
16409               ]
16410               (const_string "*")))
16411    (set_attr "mode" "<MODE>")])
16412
16413 (define_insn "pro_epilogue_adjust_stack_di_2"
16414   [(set (match_operand:DI 0 "register_operand" "=r,r")
16415         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
16416                  (match_operand:DI 3 "immediate_operand" "i,i")))
16417    (use (match_operand:DI 2 "register_operand" "r,r"))
16418    (clobber (reg:CC FLAGS_REG))
16419    (clobber (mem:BLK (scratch)))]
16420   "TARGET_64BIT"
16421 {
16422   switch (get_attr_type (insn))
16423     {
16424     case TYPE_ALU:
16425       return "add{q}\t{%2, %0|%0, %2}";
16426
16427     case TYPE_LEA:
16428       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
16429       return "lea{q}\t{%a2, %0|%0, %a2}";
16430
16431     default:
16432       gcc_unreachable ();
16433     }
16434 }
16435   [(set_attr "type" "alu,lea")
16436    (set_attr "mode" "DI")])
16437
16438 (define_insn "allocate_stack_worker_32"
16439   [(set (match_operand:SI 0 "register_operand" "=a")
16440         (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")]
16441                             UNSPECV_STACK_PROBE))
16442    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 1)))
16443    (clobber (reg:CC FLAGS_REG))]
16444   "!TARGET_64BIT && ix86_target_stack_probe ()"
16445   "call\t___chkstk"
16446   [(set_attr "type" "multi")
16447    (set_attr "length" "5")])
16448
16449 (define_insn "allocate_stack_worker_64"
16450   [(set (match_operand:DI 0 "register_operand" "=a")
16451         (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "0")]
16452                             UNSPECV_STACK_PROBE))
16453    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 1)))
16454    (clobber (reg:DI R10_REG))
16455    (clobber (reg:DI R11_REG))
16456    (clobber (reg:CC FLAGS_REG))]
16457   "TARGET_64BIT && ix86_target_stack_probe ()"
16458   "call\t___chkstk"
16459   [(set_attr "type" "multi")
16460    (set_attr "length" "5")])
16461
16462 (define_expand "allocate_stack"
16463   [(match_operand 0 "register_operand" "")
16464    (match_operand 1 "general_operand" "")]
16465   "ix86_target_stack_probe ()"
16466 {
16467   rtx x;
16468
16469 #ifndef CHECK_STACK_LIMIT
16470 #define CHECK_STACK_LIMIT 0
16471 #endif
16472
16473   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16474       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16475     {
16476       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16477                                stack_pointer_rtx, 0, OPTAB_DIRECT);
16478       if (x != stack_pointer_rtx)
16479         emit_move_insn (stack_pointer_rtx, x);
16480     }
16481   else
16482     {
16483       rtx (*gen_allocate_stack_worker) (rtx, rtx);
16484
16485       if (TARGET_64BIT)
16486         gen_allocate_stack_worker = gen_allocate_stack_worker_64;
16487       else
16488         gen_allocate_stack_worker = gen_allocate_stack_worker_32;
16489
16490       x = copy_to_mode_reg (Pmode, operands[1]);
16491       emit_insn (gen_allocate_stack_worker (x, x));
16492     }
16493
16494   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16495   DONE;
16496 })
16497
16498 ;; Use IOR for stack probes, this is shorter.
16499 (define_expand "probe_stack"
16500   [(match_operand 0 "memory_operand" "")]
16501   ""
16502 {
16503   rtx (*gen_ior3) (rtx, rtx, rtx);
16504
16505   gen_ior3 = (GET_MODE (operands[0]) == DImode
16506               ? gen_iordi3 : gen_iorsi3);
16507
16508   emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16509   DONE;
16510 })
16511
16512 (define_insn "adjust_stack_and_probe<mode>"
16513   [(set (match_operand:P 0 "register_operand" "=r")
16514         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16515                             UNSPECV_PROBE_STACK_RANGE))
16516    (set (reg:P SP_REG)
16517         (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16518    (clobber (reg:CC FLAGS_REG))
16519    (clobber (mem:BLK (scratch)))]
16520   ""
16521   "* return output_adjust_stack_and_probe (operands[0]);"
16522   [(set_attr "type" "multi")])
16523
16524 (define_insn "probe_stack_range<mode>"
16525   [(set (match_operand:P 0 "register_operand" "=r")
16526         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16527                             (match_operand:P 2 "const_int_operand" "n")]
16528                             UNSPECV_PROBE_STACK_RANGE))
16529    (clobber (reg:CC FLAGS_REG))]
16530   ""
16531   "* return output_probe_stack_range (operands[0], operands[2]);"
16532   [(set_attr "type" "multi")])
16533
16534 (define_expand "builtin_setjmp_receiver"
16535   [(label_ref (match_operand 0 "" ""))]
16536   "!TARGET_64BIT && flag_pic"
16537 {
16538 #if TARGET_MACHO
16539   if (TARGET_MACHO)
16540     {
16541       rtx xops[3];
16542       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16543       rtx label_rtx = gen_label_rtx ();
16544       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16545       xops[0] = xops[1] = picreg;
16546       xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16547       ix86_expand_binary_operator (MINUS, SImode, xops);
16548     }
16549   else
16550 #endif
16551     emit_insn (gen_set_got (pic_offset_table_rtx));
16552   DONE;
16553 })
16554 \f
16555 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16556
16557 (define_split
16558   [(set (match_operand 0 "register_operand" "")
16559         (match_operator 3 "promotable_binary_operator"
16560            [(match_operand 1 "register_operand" "")
16561             (match_operand 2 "aligned_operand" "")]))
16562    (clobber (reg:CC FLAGS_REG))]
16563   "! TARGET_PARTIAL_REG_STALL && reload_completed
16564    && ((GET_MODE (operands[0]) == HImode
16565         && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16566             /* ??? next two lines just !satisfies_constraint_K (...) */
16567             || !CONST_INT_P (operands[2])
16568             || satisfies_constraint_K (operands[2])))
16569        || (GET_MODE (operands[0]) == QImode
16570            && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16571   [(parallel [(set (match_dup 0)
16572                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16573               (clobber (reg:CC FLAGS_REG))])]
16574   "operands[0] = gen_lowpart (SImode, operands[0]);
16575    operands[1] = gen_lowpart (SImode, operands[1]);
16576    if (GET_CODE (operands[3]) != ASHIFT)
16577      operands[2] = gen_lowpart (SImode, operands[2]);
16578    PUT_MODE (operands[3], SImode);")
16579
16580 ; Promote the QImode tests, as i386 has encoding of the AND
16581 ; instruction with 32-bit sign-extended immediate and thus the
16582 ; instruction size is unchanged, except in the %eax case for
16583 ; which it is increased by one byte, hence the ! optimize_size.
16584 (define_split
16585   [(set (match_operand 0 "flags_reg_operand" "")
16586         (match_operator 2 "compare_operator"
16587           [(and (match_operand 3 "aligned_operand" "")
16588                 (match_operand 4 "const_int_operand" ""))
16589            (const_int 0)]))
16590    (set (match_operand 1 "register_operand" "")
16591         (and (match_dup 3) (match_dup 4)))]
16592   "! TARGET_PARTIAL_REG_STALL && reload_completed
16593    && optimize_insn_for_speed_p ()
16594    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16595        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16596    /* Ensure that the operand will remain sign-extended immediate.  */
16597    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16598   [(parallel [(set (match_dup 0)
16599                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16600                                     (const_int 0)]))
16601               (set (match_dup 1)
16602                    (and:SI (match_dup 3) (match_dup 4)))])]
16603 {
16604   operands[4]
16605     = gen_int_mode (INTVAL (operands[4])
16606                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16607   operands[1] = gen_lowpart (SImode, operands[1]);
16608   operands[3] = gen_lowpart (SImode, operands[3]);
16609 })
16610
16611 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16612 ; the TEST instruction with 32-bit sign-extended immediate and thus
16613 ; the instruction size would at least double, which is not what we
16614 ; want even with ! optimize_size.
16615 (define_split
16616   [(set (match_operand 0 "flags_reg_operand" "")
16617         (match_operator 1 "compare_operator"
16618           [(and (match_operand:HI 2 "aligned_operand" "")
16619                 (match_operand:HI 3 "const_int_operand" ""))
16620            (const_int 0)]))]
16621   "! TARGET_PARTIAL_REG_STALL && reload_completed
16622    && ! TARGET_FAST_PREFIX
16623    && optimize_insn_for_speed_p ()
16624    /* Ensure that the operand will remain sign-extended immediate.  */
16625    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16626   [(set (match_dup 0)
16627         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16628                          (const_int 0)]))]
16629 {
16630   operands[3]
16631     = gen_int_mode (INTVAL (operands[3])
16632                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16633   operands[2] = gen_lowpart (SImode, operands[2]);
16634 })
16635
16636 (define_split
16637   [(set (match_operand 0 "register_operand" "")
16638         (neg (match_operand 1 "register_operand" "")))
16639    (clobber (reg:CC FLAGS_REG))]
16640   "! TARGET_PARTIAL_REG_STALL && reload_completed
16641    && (GET_MODE (operands[0]) == HImode
16642        || (GET_MODE (operands[0]) == QImode
16643            && (TARGET_PROMOTE_QImode
16644                || optimize_insn_for_size_p ())))"
16645   [(parallel [(set (match_dup 0)
16646                    (neg:SI (match_dup 1)))
16647               (clobber (reg:CC FLAGS_REG))])]
16648   "operands[0] = gen_lowpart (SImode, operands[0]);
16649    operands[1] = gen_lowpart (SImode, operands[1]);")
16650
16651 (define_split
16652   [(set (match_operand 0 "register_operand" "")
16653         (not (match_operand 1 "register_operand" "")))]
16654   "! TARGET_PARTIAL_REG_STALL && reload_completed
16655    && (GET_MODE (operands[0]) == HImode
16656        || (GET_MODE (operands[0]) == QImode
16657            && (TARGET_PROMOTE_QImode
16658                || optimize_insn_for_size_p ())))"
16659   [(set (match_dup 0)
16660         (not:SI (match_dup 1)))]
16661   "operands[0] = gen_lowpart (SImode, operands[0]);
16662    operands[1] = gen_lowpart (SImode, operands[1]);")
16663
16664 (define_split
16665   [(set (match_operand 0 "register_operand" "")
16666         (if_then_else (match_operator 1 "ordered_comparison_operator"
16667                                 [(reg FLAGS_REG) (const_int 0)])
16668                       (match_operand 2 "register_operand" "")
16669                       (match_operand 3 "register_operand" "")))]
16670   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
16671    && (GET_MODE (operands[0]) == HImode
16672        || (GET_MODE (operands[0]) == QImode
16673            && (TARGET_PROMOTE_QImode
16674                || optimize_insn_for_size_p ())))"
16675   [(set (match_dup 0)
16676         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16677   "operands[0] = gen_lowpart (SImode, operands[0]);
16678    operands[2] = gen_lowpart (SImode, operands[2]);
16679    operands[3] = gen_lowpart (SImode, operands[3]);")
16680
16681 \f
16682 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
16683 ;; transform a complex memory operation into two memory to register operations.
16684
16685 ;; Don't push memory operands
16686 (define_peephole2
16687   [(set (match_operand:SI 0 "push_operand" "")
16688         (match_operand:SI 1 "memory_operand" ""))
16689    (match_scratch:SI 2 "r")]
16690   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16691    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16692   [(set (match_dup 2) (match_dup 1))
16693    (set (match_dup 0) (match_dup 2))]
16694   "")
16695
16696 (define_peephole2
16697   [(set (match_operand:DI 0 "push_operand" "")
16698         (match_operand:DI 1 "memory_operand" ""))
16699    (match_scratch:DI 2 "r")]
16700   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16701    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16702   [(set (match_dup 2) (match_dup 1))
16703    (set (match_dup 0) (match_dup 2))]
16704   "")
16705
16706 ;; We need to handle SFmode only, because DFmode and XFmode is split to
16707 ;; SImode pushes.
16708 (define_peephole2
16709   [(set (match_operand:SF 0 "push_operand" "")
16710         (match_operand:SF 1 "memory_operand" ""))
16711    (match_scratch:SF 2 "r")]
16712   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16713    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16714   [(set (match_dup 2) (match_dup 1))
16715    (set (match_dup 0) (match_dup 2))]
16716   "")
16717
16718 (define_peephole2
16719   [(set (match_operand:HI 0 "push_operand" "")
16720         (match_operand:HI 1 "memory_operand" ""))
16721    (match_scratch:HI 2 "r")]
16722   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16723    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16724   [(set (match_dup 2) (match_dup 1))
16725    (set (match_dup 0) (match_dup 2))]
16726   "")
16727
16728 (define_peephole2
16729   [(set (match_operand:QI 0 "push_operand" "")
16730         (match_operand:QI 1 "memory_operand" ""))
16731    (match_scratch:QI 2 "q")]
16732   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16733    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16734   [(set (match_dup 2) (match_dup 1))
16735    (set (match_dup 0) (match_dup 2))]
16736   "")
16737
16738 ;; Don't move an immediate directly to memory when the instruction
16739 ;; gets too big.
16740 (define_peephole2
16741   [(match_scratch:SI 1 "r")
16742    (set (match_operand:SI 0 "memory_operand" "")
16743         (const_int 0))]
16744   "optimize_insn_for_speed_p ()
16745    && ! TARGET_USE_MOV0
16746    && TARGET_SPLIT_LONG_MOVES
16747    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16748    && peep2_regno_dead_p (0, FLAGS_REG)"
16749   [(parallel [(set (match_dup 1) (const_int 0))
16750               (clobber (reg:CC FLAGS_REG))])
16751    (set (match_dup 0) (match_dup 1))]
16752   "")
16753
16754 (define_peephole2
16755   [(match_scratch:HI 1 "r")
16756    (set (match_operand:HI 0 "memory_operand" "")
16757         (const_int 0))]
16758   "optimize_insn_for_speed_p ()
16759    && ! TARGET_USE_MOV0
16760    && TARGET_SPLIT_LONG_MOVES
16761    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16762    && peep2_regno_dead_p (0, FLAGS_REG)"
16763   [(parallel [(set (match_dup 2) (const_int 0))
16764               (clobber (reg:CC FLAGS_REG))])
16765    (set (match_dup 0) (match_dup 1))]
16766   "operands[2] = gen_lowpart (SImode, operands[1]);")
16767
16768 (define_peephole2
16769   [(match_scratch:QI 1 "q")
16770    (set (match_operand:QI 0 "memory_operand" "")
16771         (const_int 0))]
16772   "optimize_insn_for_speed_p ()
16773    && ! TARGET_USE_MOV0
16774    && TARGET_SPLIT_LONG_MOVES
16775    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16776    && peep2_regno_dead_p (0, FLAGS_REG)"
16777   [(parallel [(set (match_dup 2) (const_int 0))
16778               (clobber (reg:CC FLAGS_REG))])
16779    (set (match_dup 0) (match_dup 1))]
16780   "operands[2] = gen_lowpart (SImode, operands[1]);")
16781
16782 (define_peephole2
16783   [(match_scratch:SI 2 "r")
16784    (set (match_operand:SI 0 "memory_operand" "")
16785         (match_operand:SI 1 "immediate_operand" ""))]
16786   "optimize_insn_for_speed_p ()
16787    && TARGET_SPLIT_LONG_MOVES
16788    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16789   [(set (match_dup 2) (match_dup 1))
16790    (set (match_dup 0) (match_dup 2))]
16791   "")
16792
16793 (define_peephole2
16794   [(match_scratch:HI 2 "r")
16795    (set (match_operand:HI 0 "memory_operand" "")
16796         (match_operand:HI 1 "immediate_operand" ""))]
16797   "optimize_insn_for_speed_p ()
16798    && TARGET_SPLIT_LONG_MOVES
16799    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16800   [(set (match_dup 2) (match_dup 1))
16801    (set (match_dup 0) (match_dup 2))]
16802   "")
16803
16804 (define_peephole2
16805   [(match_scratch:QI 2 "q")
16806    (set (match_operand:QI 0 "memory_operand" "")
16807         (match_operand:QI 1 "immediate_operand" ""))]
16808   "optimize_insn_for_speed_p ()
16809    && TARGET_SPLIT_LONG_MOVES
16810    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16811   [(set (match_dup 2) (match_dup 1))
16812    (set (match_dup 0) (match_dup 2))]
16813   "")
16814
16815 ;; Don't compare memory with zero, load and use a test instead.
16816 (define_peephole2
16817   [(set (match_operand 0 "flags_reg_operand" "")
16818         (match_operator 1 "compare_operator"
16819           [(match_operand:SI 2 "memory_operand" "")
16820            (const_int 0)]))
16821    (match_scratch:SI 3 "r")]
16822   "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16823   [(set (match_dup 3) (match_dup 2))
16824    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
16825   "")
16826
16827 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16828 ;; Don't split NOTs with a displacement operand, because resulting XOR
16829 ;; will not be pairable anyway.
16830 ;;
16831 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16832 ;; represented using a modRM byte.  The XOR replacement is long decoded,
16833 ;; so this split helps here as well.
16834 ;;
16835 ;; Note: Can't do this as a regular split because we can't get proper
16836 ;; lifetime information then.
16837
16838 (define_peephole2
16839   [(set (match_operand:SI 0 "nonimmediate_operand" "")
16840         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
16841   "optimize_insn_for_speed_p ()
16842    && ((TARGET_NOT_UNPAIRABLE
16843         && (!MEM_P (operands[0])
16844             || !memory_displacement_operand (operands[0], SImode)))
16845        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
16846    && peep2_regno_dead_p (0, FLAGS_REG)"
16847   [(parallel [(set (match_dup 0)
16848                    (xor:SI (match_dup 1) (const_int -1)))
16849               (clobber (reg:CC FLAGS_REG))])]
16850   "")
16851
16852 (define_peephole2
16853   [(set (match_operand:HI 0 "nonimmediate_operand" "")
16854         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
16855   "optimize_insn_for_speed_p ()
16856    && ((TARGET_NOT_UNPAIRABLE
16857         && (!MEM_P (operands[0])
16858             || !memory_displacement_operand (operands[0], HImode)))
16859        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
16860    && peep2_regno_dead_p (0, FLAGS_REG)"
16861   [(parallel [(set (match_dup 0)
16862                    (xor:HI (match_dup 1) (const_int -1)))
16863               (clobber (reg:CC FLAGS_REG))])]
16864   "")
16865
16866 (define_peephole2
16867   [(set (match_operand:QI 0 "nonimmediate_operand" "")
16868         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
16869   "optimize_insn_for_speed_p ()
16870    && ((TARGET_NOT_UNPAIRABLE
16871         && (!MEM_P (operands[0])
16872             || !memory_displacement_operand (operands[0], QImode)))
16873        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
16874    && peep2_regno_dead_p (0, FLAGS_REG)"
16875   [(parallel [(set (match_dup 0)
16876                    (xor:QI (match_dup 1) (const_int -1)))
16877               (clobber (reg:CC FLAGS_REG))])]
16878   "")
16879
16880 ;; Non pairable "test imm, reg" instructions can be translated to
16881 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
16882 ;; byte opcode instead of two, have a short form for byte operands),
16883 ;; so do it for other CPUs as well.  Given that the value was dead,
16884 ;; this should not create any new dependencies.  Pass on the sub-word
16885 ;; versions if we're concerned about partial register stalls.
16886
16887 (define_peephole2
16888   [(set (match_operand 0 "flags_reg_operand" "")
16889         (match_operator 1 "compare_operator"
16890           [(and:SI (match_operand:SI 2 "register_operand" "")
16891                    (match_operand:SI 3 "immediate_operand" ""))
16892            (const_int 0)]))]
16893   "ix86_match_ccmode (insn, CCNOmode)
16894    && (true_regnum (operands[2]) != AX_REG
16895        || satisfies_constraint_K (operands[3]))
16896    && peep2_reg_dead_p (1, operands[2])"
16897   [(parallel
16898      [(set (match_dup 0)
16899            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16900                             (const_int 0)]))
16901       (set (match_dup 2)
16902            (and:SI (match_dup 2) (match_dup 3)))])]
16903   "")
16904
16905 ;; We don't need to handle HImode case, because it will be promoted to SImode
16906 ;; on ! TARGET_PARTIAL_REG_STALL
16907
16908 (define_peephole2
16909   [(set (match_operand 0 "flags_reg_operand" "")
16910         (match_operator 1 "compare_operator"
16911           [(and:QI (match_operand:QI 2 "register_operand" "")
16912                    (match_operand:QI 3 "immediate_operand" ""))
16913            (const_int 0)]))]
16914   "! TARGET_PARTIAL_REG_STALL
16915    && ix86_match_ccmode (insn, CCNOmode)
16916    && true_regnum (operands[2]) != AX_REG
16917    && peep2_reg_dead_p (1, operands[2])"
16918   [(parallel
16919      [(set (match_dup 0)
16920            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
16921                             (const_int 0)]))
16922       (set (match_dup 2)
16923            (and:QI (match_dup 2) (match_dup 3)))])]
16924   "")
16925
16926 (define_peephole2
16927   [(set (match_operand 0 "flags_reg_operand" "")
16928         (match_operator 1 "compare_operator"
16929           [(and:SI
16930              (zero_extract:SI
16931                (match_operand 2 "ext_register_operand" "")
16932                (const_int 8)
16933                (const_int 8))
16934              (match_operand 3 "const_int_operand" ""))
16935            (const_int 0)]))]
16936   "! TARGET_PARTIAL_REG_STALL
16937    && ix86_match_ccmode (insn, CCNOmode)
16938    && true_regnum (operands[2]) != AX_REG
16939    && peep2_reg_dead_p (1, operands[2])"
16940   [(parallel [(set (match_dup 0)
16941                    (match_op_dup 1
16942                      [(and:SI
16943                         (zero_extract:SI
16944                           (match_dup 2)
16945                           (const_int 8)
16946                           (const_int 8))
16947                         (match_dup 3))
16948                       (const_int 0)]))
16949               (set (zero_extract:SI (match_dup 2)
16950                                     (const_int 8)
16951                                     (const_int 8))
16952                    (and:SI
16953                      (zero_extract:SI
16954                        (match_dup 2)
16955                        (const_int 8)
16956                        (const_int 8))
16957                      (match_dup 3)))])]
16958   "")
16959
16960 ;; Don't do logical operations with memory inputs.
16961 (define_peephole2
16962   [(match_scratch:SI 2 "r")
16963    (parallel [(set (match_operand:SI 0 "register_operand" "")
16964                    (match_operator:SI 3 "arith_or_logical_operator"
16965                      [(match_dup 0)
16966                       (match_operand:SI 1 "memory_operand" "")]))
16967               (clobber (reg:CC FLAGS_REG))])]
16968   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
16969   [(set (match_dup 2) (match_dup 1))
16970    (parallel [(set (match_dup 0)
16971                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
16972               (clobber (reg:CC FLAGS_REG))])]
16973   "")
16974
16975 (define_peephole2
16976   [(match_scratch:SI 2 "r")
16977    (parallel [(set (match_operand:SI 0 "register_operand" "")
16978                    (match_operator:SI 3 "arith_or_logical_operator"
16979                      [(match_operand:SI 1 "memory_operand" "")
16980                       (match_dup 0)]))
16981               (clobber (reg:CC FLAGS_REG))])]
16982   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
16983   [(set (match_dup 2) (match_dup 1))
16984    (parallel [(set (match_dup 0)
16985                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
16986               (clobber (reg:CC FLAGS_REG))])]
16987   "")
16988
16989 ;; Prefer Load+RegOp to Mov+MemOp.  Watch out for cases when the memory address
16990 ;; refers to the destination of the load!
16991
16992 (define_peephole2
16993   [(set (match_operand:SI 0 "register_operand" "")
16994         (match_operand:SI 1 "register_operand" ""))
16995    (parallel [(set (match_dup 0)
16996                    (match_operator:SI 3 "commutative_operator"
16997                      [(match_dup 0)
16998                       (match_operand:SI 2 "memory_operand" "")]))
16999               (clobber (reg:CC FLAGS_REG))])]
17000   "REGNO (operands[0]) != REGNO (operands[1])
17001    && GENERAL_REGNO_P (REGNO (operands[0]))
17002    && GENERAL_REGNO_P (REGNO (operands[1]))"
17003   [(set (match_dup 0) (match_dup 4))
17004    (parallel [(set (match_dup 0)
17005                    (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17006               (clobber (reg:CC FLAGS_REG))])]
17007   "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17008
17009 (define_peephole2
17010   [(set (match_operand 0 "register_operand" "")
17011         (match_operand 1 "register_operand" ""))
17012    (set (match_dup 0)
17013                    (match_operator 3 "commutative_operator"
17014                      [(match_dup 0)
17015                       (match_operand 2 "memory_operand" "")]))]
17016   "REGNO (operands[0]) != REGNO (operands[1])
17017    && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1])) 
17018        || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17019   [(set (match_dup 0) (match_dup 2))
17020    (set (match_dup 0)
17021         (match_op_dup 3 [(match_dup 0) (match_dup 1)]))]
17022   "")
17023
17024 ; Don't do logical operations with memory outputs
17025 ;
17026 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17027 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
17028 ; the same decoder scheduling characteristics as the original.
17029
17030 (define_peephole2
17031   [(match_scratch:SI 2 "r")
17032    (parallel [(set (match_operand:SI 0 "memory_operand" "")
17033                    (match_operator:SI 3 "arith_or_logical_operator"
17034                      [(match_dup 0)
17035                       (match_operand:SI 1 "nonmemory_operand" "")]))
17036               (clobber (reg:CC FLAGS_REG))])]
17037   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
17038    /* Do not split stack checking probes.  */
17039    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17040   [(set (match_dup 2) (match_dup 0))
17041    (parallel [(set (match_dup 2)
17042                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17043               (clobber (reg:CC FLAGS_REG))])
17044    (set (match_dup 0) (match_dup 2))]
17045   "")
17046
17047 (define_peephole2
17048   [(match_scratch:SI 2 "r")
17049    (parallel [(set (match_operand:SI 0 "memory_operand" "")
17050                    (match_operator:SI 3 "arith_or_logical_operator"
17051                      [(match_operand:SI 1 "nonmemory_operand" "")
17052                       (match_dup 0)]))
17053               (clobber (reg:CC FLAGS_REG))])]
17054   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
17055    /* Do not split stack checking probes.  */
17056    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17057   [(set (match_dup 2) (match_dup 0))
17058    (parallel [(set (match_dup 2)
17059                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17060               (clobber (reg:CC FLAGS_REG))])
17061    (set (match_dup 0) (match_dup 2))]
17062   "")
17063
17064 ;; Attempt to always use XOR for zeroing registers.
17065 (define_peephole2
17066   [(set (match_operand 0 "register_operand" "")
17067         (match_operand 1 "const0_operand" ""))]
17068   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17069    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17070    && GENERAL_REG_P (operands[0])
17071    && peep2_regno_dead_p (0, FLAGS_REG)"
17072   [(parallel [(set (match_dup 0) (const_int 0))
17073               (clobber (reg:CC FLAGS_REG))])]
17074 {
17075   operands[0] = gen_lowpart (word_mode, operands[0]);
17076 })
17077
17078 (define_peephole2
17079   [(set (strict_low_part (match_operand 0 "register_operand" ""))
17080         (const_int 0))]
17081   "(GET_MODE (operands[0]) == QImode
17082     || GET_MODE (operands[0]) == HImode)
17083    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17084    && peep2_regno_dead_p (0, FLAGS_REG)"
17085   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17086               (clobber (reg:CC FLAGS_REG))])])
17087
17088 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
17089 (define_peephole2
17090   [(set (match_operand 0 "register_operand" "")
17091         (const_int -1))]
17092   "(GET_MODE (operands[0]) == HImode
17093     || GET_MODE (operands[0]) == SImode
17094     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
17095    && (optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17096    && peep2_regno_dead_p (0, FLAGS_REG)"
17097   [(parallel [(set (match_dup 0) (const_int -1))
17098               (clobber (reg:CC FLAGS_REG))])]
17099   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
17100                               operands[0]);")
17101
17102 ;; Attempt to convert simple leas to adds. These can be created by
17103 ;; move expanders.
17104 (define_peephole2
17105   [(set (match_operand:SI 0 "register_operand" "")
17106         (plus:SI (match_dup 0)
17107                  (match_operand:SI 1 "nonmemory_operand" "")))]
17108   "peep2_regno_dead_p (0, FLAGS_REG)"
17109   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
17110               (clobber (reg:CC FLAGS_REG))])]
17111   "")
17112
17113 (define_peephole2
17114   [(set (match_operand:SI 0 "register_operand" "")
17115         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
17116                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
17117   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
17118   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17119               (clobber (reg:CC FLAGS_REG))])]
17120   "operands[2] = gen_lowpart (SImode, operands[2]);")
17121
17122 (define_peephole2
17123   [(set (match_operand:DI 0 "register_operand" "")
17124         (plus:DI (match_dup 0)
17125                  (match_operand:DI 1 "x86_64_general_operand" "")))]
17126   "peep2_regno_dead_p (0, FLAGS_REG)"
17127   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
17128               (clobber (reg:CC FLAGS_REG))])]
17129   "")
17130
17131 (define_peephole2
17132   [(set (match_operand:SI 0 "register_operand" "")
17133         (mult:SI (match_dup 0)
17134                  (match_operand:SI 1 "const_int_operand" "")))]
17135   "exact_log2 (INTVAL (operands[1])) >= 0
17136    && peep2_regno_dead_p (0, FLAGS_REG)"
17137   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17138               (clobber (reg:CC FLAGS_REG))])]
17139   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17140
17141 (define_peephole2
17142   [(set (match_operand:DI 0 "register_operand" "")
17143         (mult:DI (match_dup 0)
17144                  (match_operand:DI 1 "const_int_operand" "")))]
17145   "exact_log2 (INTVAL (operands[1])) >= 0
17146    && peep2_regno_dead_p (0, FLAGS_REG)"
17147   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
17148               (clobber (reg:CC FLAGS_REG))])]
17149   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17150
17151 (define_peephole2
17152   [(set (match_operand:SI 0 "register_operand" "")
17153         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
17154                    (match_operand:DI 2 "const_int_operand" "")) 0))]
17155   "exact_log2 (INTVAL (operands[2])) >= 0
17156    && REGNO (operands[0]) == REGNO (operands[1])
17157    && peep2_regno_dead_p (0, FLAGS_REG)"
17158   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17159               (clobber (reg:CC FLAGS_REG))])]
17160   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17161
17162 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
17163 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
17164 ;; many CPUs it is also faster, since special hardware to avoid esp
17165 ;; dependencies is present.
17166
17167 ;; While some of these conversions may be done using splitters, we use peepholes
17168 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
17169
17170 ;; Convert prologue esp subtractions to push.
17171 ;; We need register to push.  In order to keep verify_flow_info happy we have
17172 ;; two choices
17173 ;; - use scratch and clobber it in order to avoid dependencies
17174 ;; - use already live register
17175 ;; We can't use the second way right now, since there is no reliable way how to
17176 ;; verify that given register is live.  First choice will also most likely in
17177 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
17178 ;; call clobbered registers are dead.  We may want to use base pointer as an
17179 ;; alternative when no register is available later.
17180
17181 (define_peephole2
17182   [(match_scratch:SI 0 "r")
17183    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
17184               (clobber (reg:CC FLAGS_REG))
17185               (clobber (mem:BLK (scratch)))])]
17186   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
17187   [(clobber (match_dup 0))
17188    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
17189               (clobber (mem:BLK (scratch)))])])
17190
17191 (define_peephole2
17192   [(match_scratch:SI 0 "r")
17193    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
17194               (clobber (reg:CC FLAGS_REG))
17195               (clobber (mem:BLK (scratch)))])]
17196   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
17197   [(clobber (match_dup 0))
17198    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
17199    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
17200               (clobber (mem:BLK (scratch)))])])
17201
17202 ;; Convert esp subtractions to push.
17203 (define_peephole2
17204   [(match_scratch:SI 0 "r")
17205    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
17206               (clobber (reg:CC FLAGS_REG))])]
17207   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
17208   [(clobber (match_dup 0))
17209    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
17210
17211 (define_peephole2
17212   [(match_scratch:SI 0 "r")
17213    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
17214               (clobber (reg:CC FLAGS_REG))])]
17215   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
17216   [(clobber (match_dup 0))
17217    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
17218    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
17219
17220 ;; Convert epilogue deallocator to pop.
17221 (define_peephole2
17222   [(match_scratch:SI 0 "r")
17223    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
17224               (clobber (reg:CC FLAGS_REG))
17225               (clobber (mem:BLK (scratch)))])]
17226   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
17227   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17228               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
17229               (clobber (mem:BLK (scratch)))])]
17230   "")
17231
17232 ;; Two pops case is tricky, since pop causes dependency on destination register.
17233 ;; We use two registers if available.
17234 (define_peephole2
17235   [(match_scratch:SI 0 "r")
17236    (match_scratch:SI 1 "r")
17237    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
17238               (clobber (reg:CC FLAGS_REG))
17239               (clobber (mem:BLK (scratch)))])]
17240   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
17241   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17242               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
17243               (clobber (mem:BLK (scratch)))])
17244    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
17245               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
17246   "")
17247
17248 (define_peephole2
17249   [(match_scratch:SI 0 "r")
17250    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
17251               (clobber (reg:CC FLAGS_REG))
17252               (clobber (mem:BLK (scratch)))])]
17253   "optimize_insn_for_size_p ()"
17254   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17255               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
17256               (clobber (mem:BLK (scratch)))])
17257    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17258               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
17259   "")
17260
17261 ;; Convert esp additions to pop.
17262 (define_peephole2
17263   [(match_scratch:SI 0 "r")
17264    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
17265               (clobber (reg:CC FLAGS_REG))])]
17266   ""
17267   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17268               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
17269   "")
17270
17271 ;; Two pops case is tricky, since pop causes dependency on destination register.
17272 ;; We use two registers if available.
17273 (define_peephole2
17274   [(match_scratch:SI 0 "r")
17275    (match_scratch:SI 1 "r")
17276    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
17277               (clobber (reg:CC FLAGS_REG))])]
17278   ""
17279   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17280               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
17281    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
17282               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
17283   "")
17284
17285 (define_peephole2
17286   [(match_scratch:SI 0 "r")
17287    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
17288               (clobber (reg:CC FLAGS_REG))])]
17289   "optimize_insn_for_size_p ()"
17290   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17291               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
17292    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17293               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
17294   "")
17295 \f
17296 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17297 ;; required and register dies.  Similarly for 128 to -128.
17298 (define_peephole2
17299   [(set (match_operand 0 "flags_reg_operand" "")
17300         (match_operator 1 "compare_operator"
17301           [(match_operand 2 "register_operand" "")
17302            (match_operand 3 "const_int_operand" "")]))]
17303   "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17304      && incdec_operand (operands[3], GET_MODE (operands[3])))
17305     || (!TARGET_FUSE_CMP_AND_BRANCH
17306         && INTVAL (operands[3]) == 128))
17307    && ix86_match_ccmode (insn, CCGCmode)
17308    && peep2_reg_dead_p (1, operands[2])"
17309   [(parallel [(set (match_dup 0)
17310                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17311               (clobber (match_dup 2))])]
17312   "")
17313 \f
17314 (define_peephole2
17315   [(match_scratch:DI 0 "r")
17316    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
17317               (clobber (reg:CC FLAGS_REG))
17318               (clobber (mem:BLK (scratch)))])]
17319   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
17320   [(clobber (match_dup 0))
17321    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
17322               (clobber (mem:BLK (scratch)))])])
17323
17324 (define_peephole2
17325   [(match_scratch:DI 0 "r")
17326    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
17327               (clobber (reg:CC FLAGS_REG))
17328               (clobber (mem:BLK (scratch)))])]
17329   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
17330   [(clobber (match_dup 0))
17331    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
17332    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
17333               (clobber (mem:BLK (scratch)))])])
17334
17335 ;; Convert esp subtractions to push.
17336 (define_peephole2
17337   [(match_scratch:DI 0 "r")
17338    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
17339               (clobber (reg:CC FLAGS_REG))])]
17340   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
17341   [(clobber (match_dup 0))
17342    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
17343
17344 (define_peephole2
17345   [(match_scratch:DI 0 "r")
17346    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
17347               (clobber (reg:CC FLAGS_REG))])]
17348   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
17349   [(clobber (match_dup 0))
17350    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
17351    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
17352
17353 ;; Convert epilogue deallocator to pop.
17354 (define_peephole2
17355   [(match_scratch:DI 0 "r")
17356    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
17357               (clobber (reg:CC FLAGS_REG))
17358               (clobber (mem:BLK (scratch)))])]
17359   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
17360   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17361               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
17362               (clobber (mem:BLK (scratch)))])]
17363   "")
17364
17365 ;; Two pops case is tricky, since pop causes dependency on destination register.
17366 ;; We use two registers if available.
17367 (define_peephole2
17368   [(match_scratch:DI 0 "r")
17369    (match_scratch:DI 1 "r")
17370    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
17371               (clobber (reg:CC FLAGS_REG))
17372               (clobber (mem:BLK (scratch)))])]
17373   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
17374   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17375               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
17376               (clobber (mem:BLK (scratch)))])
17377    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
17378               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
17379   "")
17380
17381 (define_peephole2
17382   [(match_scratch:DI 0 "r")
17383    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
17384               (clobber (reg:CC FLAGS_REG))
17385               (clobber (mem:BLK (scratch)))])]
17386   "optimize_insn_for_size_p ()"
17387   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17388               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
17389               (clobber (mem:BLK (scratch)))])
17390    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17391               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
17392   "")
17393
17394 ;; Convert esp additions to pop.
17395 (define_peephole2
17396   [(match_scratch:DI 0 "r")
17397    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
17398               (clobber (reg:CC FLAGS_REG))])]
17399   ""
17400   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17401               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
17402   "")
17403
17404 ;; Two pops case is tricky, since pop causes dependency on destination register.
17405 ;; We use two registers if available.
17406 (define_peephole2
17407   [(match_scratch:DI 0 "r")
17408    (match_scratch:DI 1 "r")
17409    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
17410               (clobber (reg:CC FLAGS_REG))])]
17411   ""
17412   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17413               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
17414    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
17415               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
17416   "")
17417
17418 (define_peephole2
17419   [(match_scratch:DI 0 "r")
17420    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
17421               (clobber (reg:CC FLAGS_REG))])]
17422   "optimize_insn_for_size_p ()"
17423   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17424               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
17425    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17426               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
17427   "")
17428 \f
17429 ;; Convert imul by three, five and nine into lea
17430 (define_peephole2
17431   [(parallel
17432     [(set (match_operand:SI 0 "register_operand" "")
17433           (mult:SI (match_operand:SI 1 "register_operand" "")
17434                    (match_operand:SI 2 "const_int_operand" "")))
17435      (clobber (reg:CC FLAGS_REG))])]
17436   "INTVAL (operands[2]) == 3
17437    || INTVAL (operands[2]) == 5
17438    || INTVAL (operands[2]) == 9"
17439   [(set (match_dup 0)
17440         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
17441                  (match_dup 1)))]
17442   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17443
17444 (define_peephole2
17445   [(parallel
17446     [(set (match_operand:SI 0 "register_operand" "")
17447           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
17448                    (match_operand:SI 2 "const_int_operand" "")))
17449      (clobber (reg:CC FLAGS_REG))])]
17450   "optimize_insn_for_speed_p ()
17451    && (INTVAL (operands[2]) == 3
17452        || INTVAL (operands[2]) == 5
17453        || INTVAL (operands[2]) == 9)"
17454   [(set (match_dup 0) (match_dup 1))
17455    (set (match_dup 0)
17456         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
17457                  (match_dup 0)))]
17458   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17459
17460 (define_peephole2
17461   [(parallel
17462     [(set (match_operand:DI 0 "register_operand" "")
17463           (mult:DI (match_operand:DI 1 "register_operand" "")
17464                    (match_operand:DI 2 "const_int_operand" "")))
17465      (clobber (reg:CC FLAGS_REG))])]
17466   "TARGET_64BIT
17467    && (INTVAL (operands[2]) == 3
17468        || INTVAL (operands[2]) == 5
17469        || INTVAL (operands[2]) == 9)"
17470   [(set (match_dup 0)
17471         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
17472                  (match_dup 1)))]
17473   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17474
17475 (define_peephole2
17476   [(parallel
17477     [(set (match_operand:DI 0 "register_operand" "")
17478           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
17479                    (match_operand:DI 2 "const_int_operand" "")))
17480      (clobber (reg:CC FLAGS_REG))])]
17481   "TARGET_64BIT
17482    && optimize_insn_for_speed_p ()
17483    && (INTVAL (operands[2]) == 3
17484        || INTVAL (operands[2]) == 5
17485        || INTVAL (operands[2]) == 9)"
17486   [(set (match_dup 0) (match_dup 1))
17487    (set (match_dup 0)
17488         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
17489                  (match_dup 0)))]
17490   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17491
17492 ;; Imul $32bit_imm, mem, reg is vector decoded, while
17493 ;; imul $32bit_imm, reg, reg is direct decoded.
17494 (define_peephole2
17495   [(match_scratch:DI 3 "r")
17496    (parallel [(set (match_operand:DI 0 "register_operand" "")
17497                    (mult:DI (match_operand:DI 1 "memory_operand" "")
17498                             (match_operand:DI 2 "immediate_operand" "")))
17499               (clobber (reg:CC FLAGS_REG))])]
17500   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17501    && !satisfies_constraint_K (operands[2])"
17502   [(set (match_dup 3) (match_dup 1))
17503    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
17504               (clobber (reg:CC FLAGS_REG))])]
17505   "")
17506
17507 (define_peephole2
17508   [(match_scratch:SI 3 "r")
17509    (parallel [(set (match_operand:SI 0 "register_operand" "")
17510                    (mult:SI (match_operand:SI 1 "memory_operand" "")
17511                             (match_operand:SI 2 "immediate_operand" "")))
17512               (clobber (reg:CC FLAGS_REG))])]
17513   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17514    && !satisfies_constraint_K (operands[2])"
17515   [(set (match_dup 3) (match_dup 1))
17516    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
17517               (clobber (reg:CC FLAGS_REG))])]
17518   "")
17519
17520 (define_peephole2
17521   [(match_scratch:SI 3 "r")
17522    (parallel [(set (match_operand:DI 0 "register_operand" "")
17523                    (zero_extend:DI
17524                      (mult:SI (match_operand:SI 1 "memory_operand" "")
17525                               (match_operand:SI 2 "immediate_operand" ""))))
17526               (clobber (reg:CC FLAGS_REG))])]
17527   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17528    && !satisfies_constraint_K (operands[2])"
17529   [(set (match_dup 3) (match_dup 1))
17530    (parallel [(set (match_dup 0)
17531                    (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17532               (clobber (reg:CC FLAGS_REG))])]
17533   "")
17534
17535 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17536 ;; Convert it into imul reg, reg
17537 ;; It would be better to force assembler to encode instruction using long
17538 ;; immediate, but there is apparently no way to do so.
17539 (define_peephole2
17540   [(parallel [(set (match_operand:DI 0 "register_operand" "")
17541                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
17542                             (match_operand:DI 2 "const_int_operand" "")))
17543               (clobber (reg:CC FLAGS_REG))])
17544    (match_scratch:DI 3 "r")]
17545   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17546    && satisfies_constraint_K (operands[2])"
17547   [(set (match_dup 3) (match_dup 2))
17548    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
17549               (clobber (reg:CC FLAGS_REG))])]
17550 {
17551   if (!rtx_equal_p (operands[0], operands[1]))
17552     emit_move_insn (operands[0], operands[1]);
17553 })
17554
17555 (define_peephole2
17556   [(parallel [(set (match_operand:SI 0 "register_operand" "")
17557                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
17558                             (match_operand:SI 2 "const_int_operand" "")))
17559               (clobber (reg:CC FLAGS_REG))])
17560    (match_scratch:SI 3 "r")]
17561   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17562    && satisfies_constraint_K (operands[2])"
17563   [(set (match_dup 3) (match_dup 2))
17564    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
17565               (clobber (reg:CC FLAGS_REG))])]
17566 {
17567   if (!rtx_equal_p (operands[0], operands[1]))
17568     emit_move_insn (operands[0], operands[1]);
17569 })
17570
17571 (define_peephole2
17572   [(parallel [(set (match_operand:HI 0 "register_operand" "")
17573                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
17574                             (match_operand:HI 2 "immediate_operand" "")))
17575               (clobber (reg:CC FLAGS_REG))])
17576    (match_scratch:HI 3 "r")]
17577   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()"
17578   [(set (match_dup 3) (match_dup 2))
17579    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
17580               (clobber (reg:CC FLAGS_REG))])]
17581 {
17582   if (!rtx_equal_p (operands[0], operands[1]))
17583     emit_move_insn (operands[0], operands[1]);
17584 })
17585
17586 ;; After splitting up read-modify operations, array accesses with memory
17587 ;; operands might end up in form:
17588 ;;  sall    $2, %eax
17589 ;;  movl    4(%esp), %edx
17590 ;;  addl    %edx, %eax
17591 ;; instead of pre-splitting:
17592 ;;  sall    $2, %eax
17593 ;;  addl    4(%esp), %eax
17594 ;; Turn it into:
17595 ;;  movl    4(%esp), %edx
17596 ;;  leal    (%edx,%eax,4), %eax
17597
17598 (define_peephole2
17599   [(match_scratch:P 5 "r")
17600    (parallel [(set (match_operand 0 "register_operand" "")
17601                    (ashift (match_operand 1 "register_operand" "")
17602                            (match_operand 2 "const_int_operand" "")))
17603                (clobber (reg:CC FLAGS_REG))])
17604    (parallel [(set (match_operand 3 "register_operand" "")
17605                    (plus (match_dup 0)
17606                          (match_operand 4 "x86_64_general_operand" "")))
17607                    (clobber (reg:CC FLAGS_REG))])]
17608   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
17609    /* Validate MODE for lea.  */
17610    && ((!TARGET_PARTIAL_REG_STALL
17611         && (GET_MODE (operands[0]) == QImode
17612             || GET_MODE (operands[0]) == HImode))
17613        || GET_MODE (operands[0]) == SImode
17614        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17615    && (rtx_equal_p (operands[0], operands[3])
17616        || peep2_reg_dead_p (2, operands[0]))
17617    /* We reorder load and the shift.  */
17618    && !reg_overlap_mentioned_p (operands[0], operands[4])"
17619   [(set (match_dup 5) (match_dup 4))
17620    (set (match_dup 0) (match_dup 1))]
17621 {
17622   enum machine_mode mode = GET_MODE (operands[1]) == DImode ? DImode : SImode;
17623   int scale = 1 << INTVAL (operands[2]);
17624   rtx index = gen_lowpart (Pmode, operands[1]);
17625   rtx base = gen_lowpart (Pmode, operands[5]);
17626   rtx dest = gen_lowpart (mode, operands[3]);
17627
17628   operands[1] = gen_rtx_PLUS (Pmode, base,
17629                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
17630   operands[5] = base;
17631   if (mode != Pmode)
17632     {
17633       operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17634       operands[5] = gen_rtx_SUBREG (mode, operands[5], 0);
17635     }
17636   operands[0] = dest;
17637 })
17638 \f
17639 ;; Call-value patterns last so that the wildcard operand does not
17640 ;; disrupt insn-recog's switch tables.
17641
17642 (define_insn "*call_value_pop_0"
17643   [(set (match_operand 0 "" "")
17644         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17645               (match_operand:SI 2 "" "")))
17646    (set (reg:SI SP_REG)
17647         (plus:SI (reg:SI SP_REG)
17648                  (match_operand:SI 3 "immediate_operand" "")))]
17649   "!TARGET_64BIT"
17650 {
17651   if (SIBLING_CALL_P (insn))
17652     return "jmp\t%P1";
17653   else
17654     return "call\t%P1";
17655 }
17656   [(set_attr "type" "callv")])
17657
17658 (define_insn "*call_value_pop_1"
17659   [(set (match_operand 0 "" "")
17660         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17661               (match_operand:SI 2 "" "")))
17662    (set (reg:SI SP_REG)
17663         (plus:SI (reg:SI SP_REG)
17664                  (match_operand:SI 3 "immediate_operand" "i")))]
17665   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17666 {
17667   if (constant_call_address_operand (operands[1], Pmode))
17668     return "call\t%P1";
17669   return "call\t%A1";
17670 }
17671   [(set_attr "type" "callv")])
17672
17673 (define_insn "*sibcall_value_pop_1"
17674   [(set (match_operand 0 "" "")
17675         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17676               (match_operand:SI 2 "" "")))
17677    (set (reg:SI SP_REG)
17678         (plus:SI (reg:SI SP_REG)
17679                  (match_operand:SI 3 "immediate_operand" "i,i")))]
17680   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17681   "@
17682    jmp\t%P1
17683    jmp\t%A1"
17684   [(set_attr "type" "callv")])
17685
17686 (define_insn "*call_value_0"
17687   [(set (match_operand 0 "" "")
17688         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17689               (match_operand:SI 2 "" "")))]
17690   "!TARGET_64BIT"
17691 {
17692   if (SIBLING_CALL_P (insn))
17693     return "jmp\t%P1";
17694   else
17695     return "call\t%P1";
17696 }
17697   [(set_attr "type" "callv")])
17698
17699 (define_insn "*call_value_0_rex64"
17700   [(set (match_operand 0 "" "")
17701         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17702               (match_operand:DI 2 "const_int_operand" "")))]
17703   "TARGET_64BIT"
17704 {
17705   if (SIBLING_CALL_P (insn))
17706     return "jmp\t%P1";
17707   else
17708     return "call\t%P1";
17709 }
17710   [(set_attr "type" "callv")])
17711
17712 (define_insn "*call_value_0_rex64_ms_sysv"
17713   [(set (match_operand 0 "" "")
17714         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17715               (match_operand:DI 2 "const_int_operand" "")))
17716    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17717    (clobber (reg:TI XMM6_REG))
17718    (clobber (reg:TI XMM7_REG))
17719    (clobber (reg:TI XMM8_REG))
17720    (clobber (reg:TI XMM9_REG))
17721    (clobber (reg:TI XMM10_REG))
17722    (clobber (reg:TI XMM11_REG))
17723    (clobber (reg:TI XMM12_REG))
17724    (clobber (reg:TI XMM13_REG))
17725    (clobber (reg:TI XMM14_REG))
17726    (clobber (reg:TI XMM15_REG))
17727    (clobber (reg:DI SI_REG))
17728    (clobber (reg:DI DI_REG))]
17729   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17730 {
17731   if (SIBLING_CALL_P (insn))
17732     return "jmp\t%P1";
17733   else
17734     return "call\t%P1";
17735 }
17736   [(set_attr "type" "callv")])
17737
17738 (define_insn "*call_value_1"
17739   [(set (match_operand 0 "" "")
17740         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17741               (match_operand:SI 2 "" "")))]
17742   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17743 {
17744   if (constant_call_address_operand (operands[1], Pmode))
17745     return "call\t%P1";
17746   return "call\t%A1";
17747 }
17748   [(set_attr "type" "callv")])
17749
17750 (define_insn "*sibcall_value_1"
17751   [(set (match_operand 0 "" "")
17752         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17753               (match_operand:SI 2 "" "")))]
17754   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17755   "@
17756    jmp\t%P1
17757    jmp\t%A1"
17758   [(set_attr "type" "callv")])
17759
17760 (define_insn "*call_value_1_rex64"
17761   [(set (match_operand 0 "" "")
17762         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17763               (match_operand:DI 2 "" "")))]
17764   "TARGET_64BIT && !SIBLING_CALL_P (insn)
17765    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
17766 {
17767   if (constant_call_address_operand (operands[1], Pmode))
17768     return "call\t%P1";
17769   return "call\t%A1";
17770 }
17771   [(set_attr "type" "callv")])
17772
17773 (define_insn "*call_value_1_rex64_ms_sysv"
17774   [(set (match_operand 0 "" "")
17775         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17776               (match_operand:DI 2 "" "")))
17777    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17778    (clobber (reg:TI XMM6_REG))
17779    (clobber (reg:TI XMM7_REG))
17780    (clobber (reg:TI XMM8_REG))
17781    (clobber (reg:TI XMM9_REG))
17782    (clobber (reg:TI XMM10_REG))
17783    (clobber (reg:TI XMM11_REG))
17784    (clobber (reg:TI XMM12_REG))
17785    (clobber (reg:TI XMM13_REG))
17786    (clobber (reg:TI XMM14_REG))
17787    (clobber (reg:TI XMM15_REG))
17788    (clobber (reg:DI SI_REG))
17789    (clobber (reg:DI DI_REG))]
17790   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17791 {
17792   if (constant_call_address_operand (operands[1], Pmode))
17793     return "call\t%P1";
17794   return "call\t%A1";
17795 }
17796   [(set_attr "type" "callv")])
17797
17798 (define_insn "*call_value_1_rex64_large"
17799   [(set (match_operand 0 "" "")
17800         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
17801               (match_operand:DI 2 "" "")))]
17802   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17803   "call\t%A1"
17804   [(set_attr "type" "callv")])
17805
17806 (define_insn "*sibcall_value_1_rex64"
17807   [(set (match_operand 0 "" "")
17808         (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
17809               (match_operand:DI 2 "" "")))]
17810   "TARGET_64BIT && SIBLING_CALL_P (insn)"
17811   "@
17812    jmp\t%P1
17813    jmp\t%A1"
17814   [(set_attr "type" "callv")])
17815 \f
17816 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17817 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17818 ;; caught for use by garbage collectors and the like.  Using an insn that
17819 ;; maps to SIGILL makes it more likely the program will rightfully die.
17820 ;; Keeping with tradition, "6" is in honor of #UD.
17821 (define_insn "trap"
17822   [(trap_if (const_int 1) (const_int 6))]
17823   ""
17824   { return ASM_SHORT "0x0b0f"; }
17825   [(set_attr "length" "2")])
17826
17827 (define_expand "prefetch"
17828   [(prefetch (match_operand 0 "address_operand" "")
17829              (match_operand:SI 1 "const_int_operand" "")
17830              (match_operand:SI 2 "const_int_operand" ""))]
17831   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17832 {
17833   int rw = INTVAL (operands[1]);
17834   int locality = INTVAL (operands[2]);
17835
17836   gcc_assert (rw == 0 || rw == 1);
17837   gcc_assert (locality >= 0 && locality <= 3);
17838   gcc_assert (GET_MODE (operands[0]) == Pmode
17839               || GET_MODE (operands[0]) == VOIDmode);
17840
17841   /* Use 3dNOW prefetch in case we are asking for write prefetch not
17842      supported by SSE counterpart or the SSE prefetch is not available
17843      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
17844      of locality.  */
17845   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17846     operands[2] = GEN_INT (3);
17847   else
17848     operands[1] = const0_rtx;
17849 })
17850
17851 (define_insn "*prefetch_sse_<mode>"
17852   [(prefetch (match_operand:P 0 "address_operand" "p")
17853              (const_int 0)
17854              (match_operand:SI 1 "const_int_operand" ""))]
17855   "TARGET_PREFETCH_SSE"
17856 {
17857   static const char * const patterns[4] = {
17858    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17859   };
17860
17861   int locality = INTVAL (operands[1]);
17862   gcc_assert (locality >= 0 && locality <= 3);
17863
17864   return patterns[locality];
17865 }
17866   [(set_attr "type" "sse")
17867    (set_attr "atom_sse_attr" "prefetch")
17868    (set (attr "length_address")
17869         (symbol_ref "memory_address_length (operands[0])"))
17870    (set_attr "memory" "none")])
17871
17872 (define_insn "*prefetch_3dnow_<mode>"
17873   [(prefetch (match_operand:P 0 "address_operand" "p")
17874              (match_operand:SI 1 "const_int_operand" "n")
17875              (const_int 3))]
17876   "TARGET_3DNOW"
17877 {
17878   if (INTVAL (operands[1]) == 0)
17879     return "prefetch\t%a0";
17880   else
17881     return "prefetchw\t%a0";
17882 }
17883   [(set_attr "type" "mmx")
17884    (set (attr "length_address")
17885         (symbol_ref "memory_address_length (operands[0])"))
17886    (set_attr "memory" "none")])
17887
17888 (define_expand "stack_protect_set"
17889   [(match_operand 0 "memory_operand" "")
17890    (match_operand 1 "memory_operand" "")]
17891   ""
17892 {
17893 #ifdef TARGET_THREAD_SSP_OFFSET
17894   if (TARGET_64BIT)
17895     emit_insn (gen_stack_tls_protect_set_di (operands[0],
17896                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
17897   else
17898     emit_insn (gen_stack_tls_protect_set_si (operands[0],
17899                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
17900 #else
17901   if (TARGET_64BIT)
17902     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
17903   else
17904     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
17905 #endif
17906   DONE;
17907 })
17908
17909 (define_insn "stack_protect_set_si"
17910   [(set (match_operand:SI 0 "memory_operand" "=m")
17911         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
17912    (set (match_scratch:SI 2 "=&r") (const_int 0))
17913    (clobber (reg:CC FLAGS_REG))]
17914   ""
17915   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
17916   [(set_attr "type" "multi")])
17917
17918 (define_insn "stack_protect_set_di"
17919   [(set (match_operand:DI 0 "memory_operand" "=m")
17920         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
17921    (set (match_scratch:DI 2 "=&r") (const_int 0))
17922    (clobber (reg:CC FLAGS_REG))]
17923   "TARGET_64BIT"
17924   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17925   [(set_attr "type" "multi")])
17926
17927 (define_insn "stack_tls_protect_set_si"
17928   [(set (match_operand:SI 0 "memory_operand" "=m")
17929         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")]
17930                    UNSPEC_SP_TLS_SET))
17931    (set (match_scratch:SI 2 "=&r") (const_int 0))
17932    (clobber (reg:CC FLAGS_REG))]
17933   ""
17934   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
17935   [(set_attr "type" "multi")])
17936
17937 (define_insn "stack_tls_protect_set_di"
17938   [(set (match_operand:DI 0 "memory_operand" "=m")
17939         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")]
17940                    UNSPEC_SP_TLS_SET))
17941    (set (match_scratch:DI 2 "=&r") (const_int 0))
17942    (clobber (reg:CC FLAGS_REG))]
17943   "TARGET_64BIT"
17944   {
17945      /* The kernel uses a different segment register for performance reasons; a
17946         system call would not have to trash the userspace segment register,
17947         which would be expensive */
17948      if (ix86_cmodel != CM_KERNEL)
17949         return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
17950      else
17951         return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
17952   }
17953   [(set_attr "type" "multi")])
17954
17955 (define_expand "stack_protect_test"
17956   [(match_operand 0 "memory_operand" "")
17957    (match_operand 1 "memory_operand" "")
17958    (match_operand 2 "" "")]
17959   ""
17960 {
17961   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17962
17963 #ifdef TARGET_THREAD_SSP_OFFSET
17964   if (TARGET_64BIT)
17965     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
17966                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
17967   else
17968     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
17969                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
17970 #else
17971   if (TARGET_64BIT)
17972     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
17973   else
17974     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
17975 #endif
17976
17977   emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17978                                   flags, const0_rtx, operands[2]));
17979   DONE;
17980 })
17981
17982 (define_insn "stack_protect_test_si"
17983   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17984         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
17985                      (match_operand:SI 2 "memory_operand" "m")]
17986                     UNSPEC_SP_TEST))
17987    (clobber (match_scratch:SI 3 "=&r"))]
17988   ""
17989   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
17990   [(set_attr "type" "multi")])
17991
17992 (define_insn "stack_protect_test_di"
17993   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17994         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
17995                      (match_operand:DI 2 "memory_operand" "m")]
17996                     UNSPEC_SP_TEST))
17997    (clobber (match_scratch:DI 3 "=&r"))]
17998   "TARGET_64BIT"
17999   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
18000   [(set_attr "type" "multi")])
18001
18002 (define_insn "stack_tls_protect_test_si"
18003   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
18004         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
18005                      (match_operand:SI 2 "const_int_operand" "i")]
18006                     UNSPEC_SP_TLS_TEST))
18007    (clobber (match_scratch:SI 3 "=r"))]
18008   ""
18009   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
18010   [(set_attr "type" "multi")])
18011
18012 (define_insn "stack_tls_protect_test_di"
18013   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
18014         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
18015                      (match_operand:DI 2 "const_int_operand" "i")]
18016                     UNSPEC_SP_TLS_TEST))
18017    (clobber (match_scratch:DI 3 "=r"))]
18018   "TARGET_64BIT"
18019   {
18020      /* The kernel uses a different segment register for performance reasons; a
18021         system call would not have to trash the userspace segment register,
18022         which would be expensive */
18023      if (ix86_cmodel != CM_KERNEL)
18024         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
18025      else
18026         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
18027   }
18028   [(set_attr "type" "multi")])
18029
18030 (define_insn "sse4_2_crc32<mode>"
18031   [(set (match_operand:SI 0 "register_operand" "=r")
18032         (unspec:SI
18033           [(match_operand:SI 1 "register_operand" "0")
18034            (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
18035           UNSPEC_CRC32))]
18036   "TARGET_SSE4_2 || TARGET_CRC32"
18037   "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
18038   [(set_attr "type" "sselog1")
18039    (set_attr "prefix_rep" "1")
18040    (set_attr "prefix_extra" "1")
18041    (set (attr "prefix_data16")
18042      (if_then_else (match_operand:HI 2 "" "")
18043        (const_string "1")
18044        (const_string "*")))
18045    (set (attr "prefix_rex")
18046      (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
18047        (const_string "1")
18048        (const_string "*")))
18049    (set_attr "mode" "SI")])
18050
18051 (define_insn "sse4_2_crc32di"
18052   [(set (match_operand:DI 0 "register_operand" "=r")
18053         (unspec:DI
18054           [(match_operand:DI 1 "register_operand" "0")
18055            (match_operand:DI 2 "nonimmediate_operand" "rm")]
18056           UNSPEC_CRC32))]
18057   "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
18058   "crc32{q}\t{%2, %0|%0, %2}"
18059   [(set_attr "type" "sselog1")
18060    (set_attr "prefix_rep" "1")
18061    (set_attr "prefix_extra" "1")
18062    (set_attr "mode" "DI")])
18063
18064 (define_expand "rdpmc"
18065   [(match_operand:DI 0 "register_operand" "")
18066    (match_operand:SI 1 "register_operand" "")]
18067   ""
18068 {
18069   rtx reg = gen_reg_rtx (DImode);
18070   rtx si;
18071
18072   /* Force operand 1 into ECX.  */
18073   rtx ecx = gen_rtx_REG (SImode, CX_REG);
18074   emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
18075   si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
18076                                 UNSPECV_RDPMC);
18077
18078   if (TARGET_64BIT)
18079     {
18080       rtvec vec = rtvec_alloc (2);
18081       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18082       rtx upper = gen_reg_rtx (DImode);
18083       rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
18084                                         gen_rtvec (1, const0_rtx),
18085                                         UNSPECV_RDPMC);
18086       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
18087       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
18088       emit_insn (load);
18089       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18090                                    NULL, 1, OPTAB_DIRECT);
18091       reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
18092                                  OPTAB_DIRECT);
18093     }
18094   else
18095     emit_insn (gen_rtx_SET (VOIDmode, reg, si));
18096   emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
18097   DONE;
18098 })
18099
18100 (define_insn "*rdpmc"
18101   [(set (match_operand:DI 0 "register_operand" "=A")
18102         (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
18103                             UNSPECV_RDPMC))]
18104   "!TARGET_64BIT"
18105   "rdpmc"
18106   [(set_attr "type" "other")
18107    (set_attr "length" "2")])
18108
18109 (define_insn "*rdpmc_rex64"
18110   [(set (match_operand:DI 0 "register_operand" "=a")
18111         (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
18112                             UNSPECV_RDPMC))
18113   (set (match_operand:DI 1 "register_operand" "=d")
18114        (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
18115   "TARGET_64BIT"
18116   "rdpmc"
18117   [(set_attr "type" "other")
18118    (set_attr "length" "2")])
18119
18120 (define_expand "rdtsc"
18121   [(set (match_operand:DI 0 "register_operand" "")
18122         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18123   ""
18124 {
18125   if (TARGET_64BIT)
18126     {
18127       rtvec vec = rtvec_alloc (2);
18128       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18129       rtx upper = gen_reg_rtx (DImode);
18130       rtx lower = gen_reg_rtx (DImode);
18131       rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
18132                                          gen_rtvec (1, const0_rtx),
18133                                          UNSPECV_RDTSC);
18134       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
18135       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
18136       emit_insn (load);
18137       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18138                                    NULL, 1, OPTAB_DIRECT);
18139       lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
18140                                    OPTAB_DIRECT);
18141       emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
18142       DONE;
18143     }
18144 })
18145
18146 (define_insn "*rdtsc"
18147   [(set (match_operand:DI 0 "register_operand" "=A")
18148         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18149   "!TARGET_64BIT"
18150   "rdtsc"
18151   [(set_attr "type" "other")
18152    (set_attr "length" "2")])
18153
18154 (define_insn "*rdtsc_rex64"
18155   [(set (match_operand:DI 0 "register_operand" "=a")
18156         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
18157    (set (match_operand:DI 1 "register_operand" "=d")
18158         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18159   "TARGET_64BIT"
18160   "rdtsc"
18161   [(set_attr "type" "other")
18162    (set_attr "length" "2")])
18163
18164 (define_expand "rdtscp"
18165   [(match_operand:DI 0 "register_operand" "")
18166    (match_operand:SI 1 "memory_operand" "")]
18167   ""
18168 {
18169   rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
18170                                     gen_rtvec (1, const0_rtx),
18171                                     UNSPECV_RDTSCP);
18172   rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
18173                                     gen_rtvec (1, const0_rtx),
18174                                     UNSPECV_RDTSCP);
18175   rtx reg = gen_reg_rtx (DImode);
18176   rtx tmp = gen_reg_rtx (SImode);
18177
18178   if (TARGET_64BIT)
18179     {
18180       rtvec vec = rtvec_alloc (3);
18181       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18182       rtx upper = gen_reg_rtx (DImode);
18183       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
18184       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
18185       RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
18186       emit_insn (load);
18187       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18188                                    NULL, 1, OPTAB_DIRECT);
18189       reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
18190                                  OPTAB_DIRECT);
18191     }
18192   else
18193     {
18194       rtvec vec = rtvec_alloc (2);
18195       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18196       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
18197       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
18198       emit_insn (load);
18199     }
18200   emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
18201   emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
18202   DONE;
18203 })
18204
18205 (define_insn "*rdtscp"
18206   [(set (match_operand:DI 0 "register_operand" "=A")
18207         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18208    (set (match_operand:SI 1 "register_operand" "=c")
18209         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18210   "!TARGET_64BIT"
18211   "rdtscp"
18212   [(set_attr "type" "other")
18213    (set_attr "length" "3")])
18214
18215 (define_insn "*rdtscp_rex64"
18216   [(set (match_operand:DI 0 "register_operand" "=a")
18217         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18218    (set (match_operand:DI 1 "register_operand" "=d")
18219         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18220    (set (match_operand:SI 2 "register_operand" "=c")
18221         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18222   "TARGET_64BIT"
18223   "rdtscp"
18224   [(set_attr "type" "other")
18225    (set_attr "length" "3")])
18226
18227 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18228 ;;
18229 ;; LWP instructions
18230 ;;
18231 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18232
18233 (define_expand "lwp_llwpcb"
18234   [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18235                     UNSPECV_LLWP_INTRINSIC)]
18236   "TARGET_LWP"
18237   "")
18238
18239 (define_insn "*lwp_llwpcb<mode>1"
18240   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18241                     UNSPECV_LLWP_INTRINSIC)]
18242   "TARGET_LWP"
18243   "llwpcb\t%0"
18244   [(set_attr "type" "lwp")
18245    (set_attr "mode" "<MODE>")
18246    (set_attr "length" "5")])
18247
18248 (define_expand "lwp_slwpcb"
18249   [(set (match_operand 0 "register_operand" "=r")
18250         (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18251   "TARGET_LWP"
18252   {
18253     if (TARGET_64BIT)
18254       emit_insn (gen_lwp_slwpcbdi (operands[0]));
18255     else
18256       emit_insn (gen_lwp_slwpcbsi (operands[0]));
18257     DONE;
18258   })
18259
18260 (define_insn "lwp_slwpcb<mode>"
18261   [(set (match_operand:P 0 "register_operand" "=r")
18262         (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18263   "TARGET_LWP"
18264   "slwpcb\t%0"
18265   [(set_attr "type" "lwp")
18266    (set_attr "mode" "<MODE>")
18267    (set_attr "length" "5")])
18268
18269 (define_expand "lwp_lwpval<mode>3"
18270   [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18271                      (match_operand:SI 2 "nonimmediate_operand" "rm")
18272                      (match_operand:SI 3 "const_int_operand" "i")]
18273                     UNSPECV_LWPVAL_INTRINSIC)]
18274   "TARGET_LWP"
18275   "/* Avoid unused variable warning.  */
18276    (void) operand0;")
18277
18278 (define_insn "*lwp_lwpval<mode>3_1"
18279   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18280                      (match_operand:SI 1 "nonimmediate_operand" "rm")
18281                      (match_operand:SI 2 "const_int_operand" "i")]
18282                     UNSPECV_LWPVAL_INTRINSIC)]
18283   "TARGET_LWP"
18284   "lwpval\t{%2, %1, %0|%0, %1, %2}"
18285   [(set_attr "type" "lwp")
18286    (set_attr "mode" "<MODE>")
18287    (set (attr "length")
18288         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18289
18290 (define_expand "lwp_lwpins<mode>3"
18291   [(set (reg:CCC FLAGS_REG)
18292         (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18293                               (match_operand:SI 2 "nonimmediate_operand" "rm")
18294                               (match_operand:SI 3 "const_int_operand" "i")]
18295                              UNSPECV_LWPINS_INTRINSIC))
18296    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18297         (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18298   "TARGET_LWP"
18299   "")
18300
18301 (define_insn "*lwp_lwpins<mode>3_1"
18302   [(set (reg:CCC FLAGS_REG)
18303         (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18304                               (match_operand:SI 1 "nonimmediate_operand" "rm")
18305                               (match_operand:SI 2 "const_int_operand" "i")]
18306                              UNSPECV_LWPINS_INTRINSIC))]
18307   "TARGET_LWP"
18308   "lwpins\t{%2, %1, %0|%0, %1, %2}"
18309   [(set_attr "type" "lwp")
18310    (set_attr "mode" "<MODE>")
18311    (set (attr "length")
18312         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18313
18314 (define_insn "rdfsbase<mode>"
18315   [(set (match_operand:SWI48 0 "register_operand" "=r")
18316         (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDFSBASE))]
18317   "TARGET_64BIT && TARGET_FSGSBASE"
18318   "rdfsbase %0"
18319   [(set_attr "type" "other")
18320    (set_attr "prefix_extra" "2")])
18321
18322 (define_insn "rdgsbase<mode>"
18323   [(set (match_operand:SWI48 0 "register_operand" "=r")
18324         (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDGSBASE))]
18325   "TARGET_64BIT && TARGET_FSGSBASE"
18326   "rdgsbase %0"
18327   [(set_attr "type" "other")
18328    (set_attr "prefix_extra" "2")])
18329
18330 (define_insn "wrfsbase<mode>"
18331   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18332                     UNSPECV_WRFSBASE)]
18333   "TARGET_64BIT && TARGET_FSGSBASE"
18334   "wrfsbase %0"
18335   [(set_attr "type" "other")
18336    (set_attr "prefix_extra" "2")])
18337
18338 (define_insn "wrgsbase<mode>"
18339   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18340                     UNSPECV_WRGSBASE)]
18341   "TARGET_64BIT && TARGET_FSGSBASE"
18342   "wrgsbase %0"
18343   [(set_attr "type" "other")
18344    (set_attr "prefix_extra" "2")])
18345
18346 (define_expand "rdrand<mode>"
18347   [(set (match_operand:SWI248 0 "register_operand" "=r")
18348         (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))]
18349   "TARGET_RDRND"
18350 {
18351   rtx retry_label, insn, ccc;
18352
18353   retry_label = gen_label_rtx ();
18354
18355   emit_label (retry_label);
18356
18357   /* Generate rdrand.  */
18358   emit_insn (gen_rdrand<mode>_1 (operands[0]));
18359
18360   /* Retry if the carry flag isn't valid.  */
18361   ccc = gen_rtx_REG (CCCmode, FLAGS_REG);
18362   ccc = gen_rtx_EQ (VOIDmode, ccc, const0_rtx);
18363   ccc = gen_rtx_IF_THEN_ELSE (VOIDmode, ccc, pc_rtx,
18364                               gen_rtx_LABEL_REF (VOIDmode, retry_label));
18365   insn = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, ccc));
18366   JUMP_LABEL (insn) = retry_label;
18367
18368   DONE;
18369 })
18370
18371 (define_insn "rdrand<mode>_1"
18372   [(set (match_operand:SWI248 0 "register_operand" "=r")
18373         (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))]
18374   "TARGET_RDRND"
18375   "rdrand %0"
18376   [(set_attr "type" "other")
18377    (set_attr "prefix_extra" "1")])
18378
18379 (include "mmx.md")
18380 (include "sse.md")
18381 (include "sync.md")