OSDN Git Service

* config/i386/predicates.md (sse_reg_operand): New predicate.
[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 ;; Nonmemory operand predicate for integer modes.
862 (define_mode_attr nonmemory_operand
863         [(QI "nonmemory_operand")
864          (HI "nonmemory_operand")
865          (SI "nonmemory_operand")
866          (DI "x86_64_nonmemory_operand")])
867
868 ;; Operand predicate for shifts.
869 (define_mode_attr shift_operand
870         [(QI "nonimmediate_operand")
871          (HI "nonimmediate_operand")
872          (SI "nonimmediate_operand")
873          (DI "shiftdi_operand")
874          (TI "register_operand")])
875
876 ;; Operand predicate for shift argument.
877 (define_mode_attr shift_immediate_operand
878         [(QI "const_1_to_31_operand")
879          (HI "const_1_to_31_operand")
880          (SI "const_1_to_31_operand")
881          (DI "const_1_to_63_operand")])
882
883 ;; Input operand predicate for arithmetic left shifts.
884 (define_mode_attr ashl_input_operand
885         [(QI "nonimmediate_operand")
886          (HI "nonimmediate_operand")
887          (SI "nonimmediate_operand")
888          (DI "ashldi_input_operand")
889          (TI "reg_or_pm1_operand")])
890
891 ;; SSE and x87 SFmode and DFmode floating point modes
892 (define_mode_iterator MODEF [SF DF])
893
894 ;; All x87 floating point modes
895 (define_mode_iterator X87MODEF [SF DF XF])
896
897 ;; All integer modes handled by x87 fisttp operator.
898 (define_mode_iterator X87MODEI [HI SI DI])
899
900 ;; All integer modes handled by integer x87 operators.
901 (define_mode_iterator X87MODEI12 [HI SI])
902
903 ;; All integer modes handled by SSE cvtts?2si* operators.
904 (define_mode_iterator SSEMODEI24 [SI DI])
905
906 ;; SSE asm suffix for floating point modes
907 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
908
909 ;; SSE vector mode corresponding to a scalar mode
910 (define_mode_attr ssevecmode
911   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
912
913 ;; Instruction suffix for REX 64bit operators.
914 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
915
916 ;; This mode iterator allows :P to be used for patterns that operate on
917 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
918 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
919 \f
920 ;; Scheduling descriptions
921
922 (include "pentium.md")
923 (include "ppro.md")
924 (include "k6.md")
925 (include "athlon.md")
926 (include "geode.md")
927 (include "atom.md")
928
929 \f
930 ;; Operand and operator predicates and constraints
931
932 (include "predicates.md")
933 (include "constraints.md")
934
935 \f
936 ;; Compare and branch/compare and store instructions.
937
938 (define_expand "cbranch<mode>4"
939   [(set (reg:CC FLAGS_REG)
940         (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
941                     (match_operand:SDWIM 2 "<general_operand>" "")))
942    (set (pc) (if_then_else
943                (match_operator 0 "ordered_comparison_operator"
944                 [(reg:CC FLAGS_REG) (const_int 0)])
945                (label_ref (match_operand 3 "" ""))
946                (pc)))]
947   ""
948 {
949   if (MEM_P (operands[1]) && MEM_P (operands[2]))
950     operands[1] = force_reg (<MODE>mode, operands[1]);
951   ix86_expand_branch (GET_CODE (operands[0]),
952                       operands[1], operands[2], operands[3]);
953   DONE;
954 })
955
956 (define_expand "cstore<mode>4"
957   [(set (reg:CC FLAGS_REG)
958         (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
959                     (match_operand:SWIM 3 "<general_operand>" "")))
960    (set (match_operand:QI 0 "register_operand" "")
961         (match_operator 1 "ordered_comparison_operator"
962           [(reg:CC FLAGS_REG) (const_int 0)]))]
963   ""
964 {
965   if (MEM_P (operands[2]) && MEM_P (operands[3]))
966     operands[2] = force_reg (<MODE>mode, operands[2]);
967   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
968                      operands[2], operands[3]);
969   DONE;
970 })
971
972 (define_expand "cmp<mode>_1"
973   [(set (reg:CC FLAGS_REG)
974         (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
975                     (match_operand:SWI48 1 "<general_operand>" "")))]
976   ""
977   "")
978
979 (define_insn "*cmp<mode>_ccno_1"
980   [(set (reg FLAGS_REG)
981         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
982                  (match_operand:SWI 1 "const0_operand" "")))]
983   "ix86_match_ccmode (insn, CCNOmode)"
984   "@
985    test{<imodesuffix>}\t%0, %0
986    cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
987   [(set_attr "type" "test,icmp")
988    (set_attr "length_immediate" "0,1")
989    (set_attr "mode" "<MODE>")])
990
991 (define_insn "*cmp<mode>_1"
992   [(set (reg FLAGS_REG)
993         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
994                  (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
995   "ix86_match_ccmode (insn, CCmode)"
996   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
997   [(set_attr "type" "icmp")
998    (set_attr "mode" "<MODE>")])
999
1000 (define_insn "*cmp<mode>_minus_1"
1001   [(set (reg FLAGS_REG)
1002         (compare
1003           (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1004                      (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1005           (const_int 0)))]
1006   "ix86_match_ccmode (insn, CCGOCmode)"
1007   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1008   [(set_attr "type" "icmp")
1009    (set_attr "mode" "<MODE>")])
1010
1011 (define_insn "*cmpqi_ext_1"
1012   [(set (reg FLAGS_REG)
1013         (compare
1014           (match_operand:QI 0 "general_operand" "Qm")
1015           (subreg:QI
1016             (zero_extract:SI
1017               (match_operand 1 "ext_register_operand" "Q")
1018               (const_int 8)
1019               (const_int 8)) 0)))]
1020   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1021   "cmp{b}\t{%h1, %0|%0, %h1}"
1022   [(set_attr "type" "icmp")
1023    (set_attr "mode" "QI")])
1024
1025 (define_insn "*cmpqi_ext_1_rex64"
1026   [(set (reg FLAGS_REG)
1027         (compare
1028           (match_operand:QI 0 "register_operand" "Q")
1029           (subreg:QI
1030             (zero_extract:SI
1031               (match_operand 1 "ext_register_operand" "Q")
1032               (const_int 8)
1033               (const_int 8)) 0)))]
1034   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1035   "cmp{b}\t{%h1, %0|%0, %h1}"
1036   [(set_attr "type" "icmp")
1037    (set_attr "mode" "QI")])
1038
1039 (define_insn "*cmpqi_ext_2"
1040   [(set (reg FLAGS_REG)
1041         (compare
1042           (subreg:QI
1043             (zero_extract:SI
1044               (match_operand 0 "ext_register_operand" "Q")
1045               (const_int 8)
1046               (const_int 8)) 0)
1047           (match_operand:QI 1 "const0_operand" "")))]
1048   "ix86_match_ccmode (insn, CCNOmode)"
1049   "test{b}\t%h0, %h0"
1050   [(set_attr "type" "test")
1051    (set_attr "length_immediate" "0")
1052    (set_attr "mode" "QI")])
1053
1054 (define_expand "cmpqi_ext_3"
1055   [(set (reg:CC FLAGS_REG)
1056         (compare:CC
1057           (subreg:QI
1058             (zero_extract:SI
1059               (match_operand 0 "ext_register_operand" "")
1060               (const_int 8)
1061               (const_int 8)) 0)
1062           (match_operand:QI 1 "immediate_operand" "")))]
1063   ""
1064   "")
1065
1066 (define_insn "*cmpqi_ext_3_insn"
1067   [(set (reg FLAGS_REG)
1068         (compare
1069           (subreg:QI
1070             (zero_extract:SI
1071               (match_operand 0 "ext_register_operand" "Q")
1072               (const_int 8)
1073               (const_int 8)) 0)
1074           (match_operand:QI 1 "general_operand" "Qmn")))]
1075   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1076   "cmp{b}\t{%1, %h0|%h0, %1}"
1077   [(set_attr "type" "icmp")
1078    (set_attr "modrm" "1")
1079    (set_attr "mode" "QI")])
1080
1081 (define_insn "*cmpqi_ext_3_insn_rex64"
1082   [(set (reg FLAGS_REG)
1083         (compare
1084           (subreg:QI
1085             (zero_extract:SI
1086               (match_operand 0 "ext_register_operand" "Q")
1087               (const_int 8)
1088               (const_int 8)) 0)
1089           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1090   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1091   "cmp{b}\t{%1, %h0|%h0, %1}"
1092   [(set_attr "type" "icmp")
1093    (set_attr "modrm" "1")
1094    (set_attr "mode" "QI")])
1095
1096 (define_insn "*cmpqi_ext_4"
1097   [(set (reg FLAGS_REG)
1098         (compare
1099           (subreg:QI
1100             (zero_extract:SI
1101               (match_operand 0 "ext_register_operand" "Q")
1102               (const_int 8)
1103               (const_int 8)) 0)
1104           (subreg:QI
1105             (zero_extract:SI
1106               (match_operand 1 "ext_register_operand" "Q")
1107               (const_int 8)
1108               (const_int 8)) 0)))]
1109   "ix86_match_ccmode (insn, CCmode)"
1110   "cmp{b}\t{%h1, %h0|%h0, %h1}"
1111   [(set_attr "type" "icmp")
1112    (set_attr "mode" "QI")])
1113
1114 ;; These implement float point compares.
1115 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1116 ;; which would allow mix and match FP modes on the compares.  Which is what
1117 ;; the old patterns did, but with many more of them.
1118
1119 (define_expand "cbranchxf4"
1120   [(set (reg:CC FLAGS_REG)
1121         (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1122                     (match_operand:XF 2 "nonmemory_operand" "")))
1123    (set (pc) (if_then_else
1124               (match_operator 0 "ix86_fp_comparison_operator"
1125                [(reg:CC FLAGS_REG)
1126                 (const_int 0)])
1127               (label_ref (match_operand 3 "" ""))
1128               (pc)))]
1129   "TARGET_80387"
1130 {
1131   ix86_expand_branch (GET_CODE (operands[0]),
1132                       operands[1], operands[2], operands[3]);
1133   DONE;
1134 })
1135
1136 (define_expand "cstorexf4"
1137   [(set (reg:CC FLAGS_REG)
1138         (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1139                     (match_operand:XF 3 "nonmemory_operand" "")))
1140    (set (match_operand:QI 0 "register_operand" "")
1141               (match_operator 1 "ix86_fp_comparison_operator"
1142                [(reg:CC FLAGS_REG)
1143                 (const_int 0)]))]
1144   "TARGET_80387"
1145 {
1146   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1147                      operands[2], operands[3]);
1148   DONE;
1149 })
1150
1151 (define_expand "cbranch<mode>4"
1152   [(set (reg:CC FLAGS_REG)
1153         (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1154                     (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1155    (set (pc) (if_then_else
1156               (match_operator 0 "ix86_fp_comparison_operator"
1157                [(reg:CC FLAGS_REG)
1158                 (const_int 0)])
1159               (label_ref (match_operand 3 "" ""))
1160               (pc)))]
1161   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1162 {
1163   ix86_expand_branch (GET_CODE (operands[0]),
1164                       operands[1], operands[2], operands[3]);
1165   DONE;
1166 })
1167
1168 (define_expand "cstore<mode>4"
1169   [(set (reg:CC FLAGS_REG)
1170         (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1171                     (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1172    (set (match_operand:QI 0 "register_operand" "")
1173               (match_operator 1 "ix86_fp_comparison_operator"
1174                [(reg:CC FLAGS_REG)
1175                 (const_int 0)]))]
1176   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1177 {
1178   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1179                      operands[2], operands[3]);
1180   DONE;
1181 })
1182
1183 (define_expand "cbranchcc4"
1184   [(set (pc) (if_then_else
1185               (match_operator 0 "comparison_operator"
1186                [(match_operand 1 "flags_reg_operand" "")
1187                 (match_operand 2 "const0_operand" "")])
1188               (label_ref (match_operand 3 "" ""))
1189               (pc)))]
1190   ""
1191 {
1192   ix86_expand_branch (GET_CODE (operands[0]),
1193                       operands[1], operands[2], operands[3]);
1194   DONE;
1195 })
1196
1197 (define_expand "cstorecc4"
1198   [(set (match_operand:QI 0 "register_operand" "")
1199               (match_operator 1 "comparison_operator"
1200                [(match_operand 2 "flags_reg_operand" "")
1201                 (match_operand 3 "const0_operand" "")]))]
1202   ""
1203 {
1204   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1205                      operands[2], operands[3]);
1206   DONE;
1207 })
1208
1209
1210 ;; FP compares, step 1:
1211 ;; Set the FP condition codes.
1212 ;;
1213 ;; CCFPmode     compare with exceptions
1214 ;; CCFPUmode    compare with no exceptions
1215
1216 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1217 ;; used to manage the reg stack popping would not be preserved.
1218
1219 (define_insn "*cmpfp_0"
1220   [(set (match_operand:HI 0 "register_operand" "=a")
1221         (unspec:HI
1222           [(compare:CCFP
1223              (match_operand 1 "register_operand" "f")
1224              (match_operand 2 "const0_operand" ""))]
1225         UNSPEC_FNSTSW))]
1226   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1227    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1228   "* return output_fp_compare (insn, operands, 0, 0);"
1229   [(set_attr "type" "multi")
1230    (set_attr "unit" "i387")
1231    (set (attr "mode")
1232      (cond [(match_operand:SF 1 "" "")
1233               (const_string "SF")
1234             (match_operand:DF 1 "" "")
1235               (const_string "DF")
1236            ]
1237            (const_string "XF")))])
1238
1239 (define_insn_and_split "*cmpfp_0_cc"
1240   [(set (reg:CCFP FLAGS_REG)
1241         (compare:CCFP
1242           (match_operand 1 "register_operand" "f")
1243           (match_operand 2 "const0_operand" "")))
1244    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1245   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1246    && TARGET_SAHF && !TARGET_CMOVE
1247    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1248   "#"
1249   "&& reload_completed"
1250   [(set (match_dup 0)
1251         (unspec:HI
1252           [(compare:CCFP (match_dup 1)(match_dup 2))]
1253         UNSPEC_FNSTSW))
1254    (set (reg:CC FLAGS_REG)
1255         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1256   ""
1257   [(set_attr "type" "multi")
1258    (set_attr "unit" "i387")
1259    (set (attr "mode")
1260      (cond [(match_operand:SF 1 "" "")
1261               (const_string "SF")
1262             (match_operand:DF 1 "" "")
1263               (const_string "DF")
1264            ]
1265            (const_string "XF")))])
1266
1267 (define_insn "*cmpfp_xf"
1268   [(set (match_operand:HI 0 "register_operand" "=a")
1269         (unspec:HI
1270           [(compare:CCFP
1271              (match_operand:XF 1 "register_operand" "f")
1272              (match_operand:XF 2 "register_operand" "f"))]
1273           UNSPEC_FNSTSW))]
1274   "TARGET_80387"
1275   "* return output_fp_compare (insn, operands, 0, 0);"
1276   [(set_attr "type" "multi")
1277    (set_attr "unit" "i387")
1278    (set_attr "mode" "XF")])
1279
1280 (define_insn_and_split "*cmpfp_xf_cc"
1281   [(set (reg:CCFP FLAGS_REG)
1282         (compare:CCFP
1283           (match_operand:XF 1 "register_operand" "f")
1284           (match_operand:XF 2 "register_operand" "f")))
1285    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1286   "TARGET_80387
1287    && TARGET_SAHF && !TARGET_CMOVE"
1288   "#"
1289   "&& reload_completed"
1290   [(set (match_dup 0)
1291         (unspec:HI
1292           [(compare:CCFP (match_dup 1)(match_dup 2))]
1293         UNSPEC_FNSTSW))
1294    (set (reg:CC FLAGS_REG)
1295         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1296   ""
1297   [(set_attr "type" "multi")
1298    (set_attr "unit" "i387")
1299    (set_attr "mode" "XF")])
1300
1301 (define_insn "*cmpfp_<mode>"
1302   [(set (match_operand:HI 0 "register_operand" "=a")
1303         (unspec:HI
1304           [(compare:CCFP
1305              (match_operand:MODEF 1 "register_operand" "f")
1306              (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1307           UNSPEC_FNSTSW))]
1308   "TARGET_80387"
1309   "* return output_fp_compare (insn, operands, 0, 0);"
1310   [(set_attr "type" "multi")
1311    (set_attr "unit" "i387")
1312    (set_attr "mode" "<MODE>")])
1313
1314 (define_insn_and_split "*cmpfp_<mode>_cc"
1315   [(set (reg:CCFP FLAGS_REG)
1316         (compare:CCFP
1317           (match_operand:MODEF 1 "register_operand" "f")
1318           (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1319    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1320   "TARGET_80387
1321    && TARGET_SAHF && !TARGET_CMOVE"
1322   "#"
1323   "&& reload_completed"
1324   [(set (match_dup 0)
1325         (unspec:HI
1326           [(compare:CCFP (match_dup 1)(match_dup 2))]
1327         UNSPEC_FNSTSW))
1328    (set (reg:CC FLAGS_REG)
1329         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1330   ""
1331   [(set_attr "type" "multi")
1332    (set_attr "unit" "i387")
1333    (set_attr "mode" "<MODE>")])
1334
1335 (define_insn "*cmpfp_u"
1336   [(set (match_operand:HI 0 "register_operand" "=a")
1337         (unspec:HI
1338           [(compare:CCFPU
1339              (match_operand 1 "register_operand" "f")
1340              (match_operand 2 "register_operand" "f"))]
1341           UNSPEC_FNSTSW))]
1342   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1343    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1344   "* return output_fp_compare (insn, operands, 0, 1);"
1345   [(set_attr "type" "multi")
1346    (set_attr "unit" "i387")
1347    (set (attr "mode")
1348      (cond [(match_operand:SF 1 "" "")
1349               (const_string "SF")
1350             (match_operand:DF 1 "" "")
1351               (const_string "DF")
1352            ]
1353            (const_string "XF")))])
1354
1355 (define_insn_and_split "*cmpfp_u_cc"
1356   [(set (reg:CCFPU FLAGS_REG)
1357         (compare:CCFPU
1358           (match_operand 1 "register_operand" "f")
1359           (match_operand 2 "register_operand" "f")))
1360    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1361   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1362    && TARGET_SAHF && !TARGET_CMOVE
1363    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1364   "#"
1365   "&& reload_completed"
1366   [(set (match_dup 0)
1367         (unspec:HI
1368           [(compare:CCFPU (match_dup 1)(match_dup 2))]
1369         UNSPEC_FNSTSW))
1370    (set (reg:CC FLAGS_REG)
1371         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1372   ""
1373   [(set_attr "type" "multi")
1374    (set_attr "unit" "i387")
1375    (set (attr "mode")
1376      (cond [(match_operand:SF 1 "" "")
1377               (const_string "SF")
1378             (match_operand:DF 1 "" "")
1379               (const_string "DF")
1380            ]
1381            (const_string "XF")))])
1382
1383 (define_insn "*cmpfp_<mode>"
1384   [(set (match_operand:HI 0 "register_operand" "=a")
1385         (unspec:HI
1386           [(compare:CCFP
1387              (match_operand 1 "register_operand" "f")
1388              (match_operator 3 "float_operator"
1389                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1390           UNSPEC_FNSTSW))]
1391   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1392    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1393    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1394   "* return output_fp_compare (insn, operands, 0, 0);"
1395   [(set_attr "type" "multi")
1396    (set_attr "unit" "i387")
1397    (set_attr "fp_int_src" "true")
1398    (set_attr "mode" "<MODE>")])
1399
1400 (define_insn_and_split "*cmpfp_<mode>_cc"
1401   [(set (reg:CCFP FLAGS_REG)
1402         (compare:CCFP
1403           (match_operand 1 "register_operand" "f")
1404           (match_operator 3 "float_operator"
1405             [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1406    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1407   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1408    && TARGET_SAHF && !TARGET_CMOVE
1409    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1410    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1411   "#"
1412   "&& reload_completed"
1413   [(set (match_dup 0)
1414         (unspec:HI
1415           [(compare:CCFP
1416              (match_dup 1)
1417              (match_op_dup 3 [(match_dup 2)]))]
1418         UNSPEC_FNSTSW))
1419    (set (reg:CC FLAGS_REG)
1420         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1421   ""
1422   [(set_attr "type" "multi")
1423    (set_attr "unit" "i387")
1424    (set_attr "fp_int_src" "true")
1425    (set_attr "mode" "<MODE>")])
1426
1427 ;; FP compares, step 2
1428 ;; Move the fpsw to ax.
1429
1430 (define_insn "x86_fnstsw_1"
1431   [(set (match_operand:HI 0 "register_operand" "=a")
1432         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1433   "TARGET_80387"
1434   "fnstsw\t%0"
1435   [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1436    (set_attr "mode" "SI")
1437    (set_attr "unit" "i387")])
1438
1439 ;; FP compares, step 3
1440 ;; Get ax into flags, general case.
1441
1442 (define_insn "x86_sahf_1"
1443   [(set (reg:CC FLAGS_REG)
1444         (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1445                    UNSPEC_SAHF))]
1446   "TARGET_SAHF"
1447 {
1448 #ifndef HAVE_AS_IX86_SAHF
1449   if (TARGET_64BIT)
1450     return ASM_BYTE "0x9e";
1451   else
1452 #endif
1453   return "sahf";
1454 }
1455   [(set_attr "length" "1")
1456    (set_attr "athlon_decode" "vector")
1457    (set_attr "amdfam10_decode" "direct")
1458    (set_attr "mode" "SI")])
1459
1460 ;; Pentium Pro can do steps 1 through 3 in one go.
1461 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1462 (define_insn "*cmpfp_i_mixed"
1463   [(set (reg:CCFP FLAGS_REG)
1464         (compare:CCFP (match_operand 0 "register_operand" "f,x")
1465                       (match_operand 1 "nonimmediate_operand" "f,xm")))]
1466   "TARGET_MIX_SSE_I387
1467    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1468    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1469   "* return output_fp_compare (insn, operands, 1, 0);"
1470   [(set_attr "type" "fcmp,ssecomi")
1471    (set_attr "prefix" "orig,maybe_vex")
1472    (set (attr "mode")
1473      (if_then_else (match_operand:SF 1 "" "")
1474         (const_string "SF")
1475         (const_string "DF")))
1476    (set (attr "prefix_rep")
1477         (if_then_else (eq_attr "type" "ssecomi")
1478                       (const_string "0")
1479                       (const_string "*")))
1480    (set (attr "prefix_data16")
1481         (cond [(eq_attr "type" "fcmp")
1482                  (const_string "*")
1483                (eq_attr "mode" "DF")
1484                  (const_string "1")
1485               ]
1486               (const_string "0")))
1487    (set_attr "athlon_decode" "vector")
1488    (set_attr "amdfam10_decode" "direct")])
1489
1490 (define_insn "*cmpfp_i_sse"
1491   [(set (reg:CCFP FLAGS_REG)
1492         (compare:CCFP (match_operand 0 "register_operand" "x")
1493                       (match_operand 1 "nonimmediate_operand" "xm")))]
1494   "TARGET_SSE_MATH
1495    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1496    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1497   "* return output_fp_compare (insn, operands, 1, 0);"
1498   [(set_attr "type" "ssecomi")
1499    (set_attr "prefix" "maybe_vex")
1500    (set (attr "mode")
1501      (if_then_else (match_operand:SF 1 "" "")
1502         (const_string "SF")
1503         (const_string "DF")))
1504    (set_attr "prefix_rep" "0")
1505    (set (attr "prefix_data16")
1506         (if_then_else (eq_attr "mode" "DF")
1507                       (const_string "1")
1508                       (const_string "0")))
1509    (set_attr "athlon_decode" "vector")
1510    (set_attr "amdfam10_decode" "direct")])
1511
1512 (define_insn "*cmpfp_i_i387"
1513   [(set (reg:CCFP FLAGS_REG)
1514         (compare:CCFP (match_operand 0 "register_operand" "f")
1515                       (match_operand 1 "register_operand" "f")))]
1516   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1517    && TARGET_CMOVE
1518    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1519    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1520   "* return output_fp_compare (insn, operands, 1, 0);"
1521   [(set_attr "type" "fcmp")
1522    (set (attr "mode")
1523      (cond [(match_operand:SF 1 "" "")
1524               (const_string "SF")
1525             (match_operand:DF 1 "" "")
1526               (const_string "DF")
1527            ]
1528            (const_string "XF")))
1529    (set_attr "athlon_decode" "vector")
1530    (set_attr "amdfam10_decode" "direct")])
1531
1532 (define_insn "*cmpfp_iu_mixed"
1533   [(set (reg:CCFPU FLAGS_REG)
1534         (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1535                        (match_operand 1 "nonimmediate_operand" "f,xm")))]
1536   "TARGET_MIX_SSE_I387
1537    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1538    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1539   "* return output_fp_compare (insn, operands, 1, 1);"
1540   [(set_attr "type" "fcmp,ssecomi")
1541    (set_attr "prefix" "orig,maybe_vex")
1542    (set (attr "mode")
1543      (if_then_else (match_operand:SF 1 "" "")
1544         (const_string "SF")
1545         (const_string "DF")))
1546    (set (attr "prefix_rep")
1547         (if_then_else (eq_attr "type" "ssecomi")
1548                       (const_string "0")
1549                       (const_string "*")))
1550    (set (attr "prefix_data16")
1551         (cond [(eq_attr "type" "fcmp")
1552                  (const_string "*")
1553                (eq_attr "mode" "DF")
1554                  (const_string "1")
1555               ]
1556               (const_string "0")))
1557    (set_attr "athlon_decode" "vector")
1558    (set_attr "amdfam10_decode" "direct")])
1559
1560 (define_insn "*cmpfp_iu_sse"
1561   [(set (reg:CCFPU FLAGS_REG)
1562         (compare:CCFPU (match_operand 0 "register_operand" "x")
1563                        (match_operand 1 "nonimmediate_operand" "xm")))]
1564   "TARGET_SSE_MATH
1565    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1566    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1567   "* return output_fp_compare (insn, operands, 1, 1);"
1568   [(set_attr "type" "ssecomi")
1569    (set_attr "prefix" "maybe_vex")
1570    (set (attr "mode")
1571      (if_then_else (match_operand:SF 1 "" "")
1572         (const_string "SF")
1573         (const_string "DF")))
1574    (set_attr "prefix_rep" "0")
1575    (set (attr "prefix_data16")
1576         (if_then_else (eq_attr "mode" "DF")
1577                       (const_string "1")
1578                       (const_string "0")))
1579    (set_attr "athlon_decode" "vector")
1580    (set_attr "amdfam10_decode" "direct")])
1581
1582 (define_insn "*cmpfp_iu_387"
1583   [(set (reg:CCFPU FLAGS_REG)
1584         (compare:CCFPU (match_operand 0 "register_operand" "f")
1585                        (match_operand 1 "register_operand" "f")))]
1586   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1587    && TARGET_CMOVE
1588    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1589    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1590   "* return output_fp_compare (insn, operands, 1, 1);"
1591   [(set_attr "type" "fcmp")
1592    (set (attr "mode")
1593      (cond [(match_operand:SF 1 "" "")
1594               (const_string "SF")
1595             (match_operand:DF 1 "" "")
1596               (const_string "DF")
1597            ]
1598            (const_string "XF")))
1599    (set_attr "athlon_decode" "vector")
1600    (set_attr "amdfam10_decode" "direct")])
1601 \f
1602 ;; Push/pop instructions.
1603
1604 (define_insn "*pushdi2_rex64"
1605   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1606         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1607   "TARGET_64BIT"
1608   "@
1609    push{q}\t%1
1610    #"
1611   [(set_attr "type" "push,multi")
1612    (set_attr "mode" "DI")])
1613
1614 ;; Convert impossible pushes of immediate to existing instructions.
1615 ;; First try to get scratch register and go through it.  In case this
1616 ;; fails, push sign extended lower part first and then overwrite
1617 ;; upper part by 32bit move.
1618 (define_peephole2
1619   [(match_scratch:DI 2 "r")
1620    (set (match_operand:DI 0 "push_operand" "")
1621         (match_operand:DI 1 "immediate_operand" ""))]
1622   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1623    && !x86_64_immediate_operand (operands[1], DImode)"
1624   [(set (match_dup 2) (match_dup 1))
1625    (set (match_dup 0) (match_dup 2))])
1626
1627 ;; We need to define this as both peepholer and splitter for case
1628 ;; peephole2 pass is not run.
1629 ;; "&& 1" is needed to keep it from matching the previous pattern.
1630 (define_peephole2
1631   [(set (match_operand:DI 0 "push_operand" "")
1632         (match_operand:DI 1 "immediate_operand" ""))]
1633   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1634    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1635   [(set (match_dup 0) (match_dup 1))
1636    (set (match_dup 2) (match_dup 3))]
1637 {
1638   split_di (&operands[1], 1, &operands[2], &operands[3]);
1639
1640   operands[1] = gen_lowpart (DImode, operands[2]);
1641   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1642                                                    GEN_INT (4)));
1643 })
1644
1645 (define_split
1646   [(set (match_operand:DI 0 "push_operand" "")
1647         (match_operand:DI 1 "immediate_operand" ""))]
1648   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1649                     ? epilogue_completed : reload_completed)
1650    && !symbolic_operand (operands[1], DImode)
1651    && !x86_64_immediate_operand (operands[1], DImode)"
1652   [(set (match_dup 0) (match_dup 1))
1653    (set (match_dup 2) (match_dup 3))]
1654 {
1655   split_di (&operands[1], 1, &operands[2], &operands[3]);
1656
1657   operands[1] = gen_lowpart (DImode, operands[2]);
1658   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1659                                                    GEN_INT (4)));
1660 })
1661
1662 (define_insn "*pushdi2"
1663   [(set (match_operand:DI 0 "push_operand" "=<")
1664         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1665   "!TARGET_64BIT"
1666   "#")
1667
1668 (define_split
1669   [(set (match_operand:DI 0 "push_operand" "")
1670         (match_operand:DI 1 "general_operand" ""))]
1671   "!TARGET_64BIT && reload_completed
1672    && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1673   [(const_int 0)]
1674   "ix86_split_long_move (operands); DONE;")
1675
1676 (define_insn "*pushsi2"
1677   [(set (match_operand:SI 0 "push_operand" "=<")
1678         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1679   "!TARGET_64BIT"
1680   "push{l}\t%1"
1681   [(set_attr "type" "push")
1682    (set_attr "mode" "SI")])
1683
1684 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1685 ;; "push a byte/word".  But actually we use pushl, which has the effect
1686 ;; of rounding the amount pushed up to a word.
1687
1688 ;; For TARGET_64BIT we always round up to 8 bytes.
1689 (define_insn "*push<mode>2_rex64"
1690   [(set (match_operand:SWI124 0 "push_operand" "=X")
1691         (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1692   "TARGET_64BIT"
1693   "push{q}\t%q1"
1694   [(set_attr "type" "push")
1695    (set_attr "mode" "DI")])
1696
1697 (define_insn "*push<mode>2"
1698   [(set (match_operand:SWI12 0 "push_operand" "=X")
1699         (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1700   "!TARGET_64BIT"
1701   "push{l}\t%k1"
1702   [(set_attr "type" "push")
1703    (set_attr "mode" "SI")])
1704
1705 (define_insn "*push<mode>2_prologue"
1706   [(set (match_operand:P 0 "push_operand" "=<")
1707         (match_operand:P 1 "general_no_elim_operand" "r<i>*m"))
1708    (clobber (mem:BLK (scratch)))]
1709   ""
1710   "push{<imodesuffix>}\t%1"
1711   [(set_attr "type" "push")
1712    (set_attr "mode" "<MODE>")])
1713
1714 (define_insn "*pop<mode>1"
1715   [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1716         (match_operand:P 1 "pop_operand" ">"))]
1717   ""
1718   "pop{<imodesuffix>}\t%0"
1719   [(set_attr "type" "pop")
1720    (set_attr "mode" "<MODE>")])
1721
1722 (define_insn "*pop<mode>1_epilogue"
1723   [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1724         (match_operand:P 1 "pop_operand" ">"))
1725    (clobber (mem:BLK (scratch)))]
1726   ""
1727   "pop{<imodesuffix>}\t%0"
1728   [(set_attr "type" "pop")
1729    (set_attr "mode" "<MODE>")])
1730 \f
1731 ;; Move instructions.
1732
1733 (define_expand "movoi"
1734   [(set (match_operand:OI 0 "nonimmediate_operand" "")
1735         (match_operand:OI 1 "general_operand" ""))]
1736   "TARGET_AVX"
1737   "ix86_expand_move (OImode, operands); DONE;")
1738
1739 (define_expand "movti"
1740   [(set (match_operand:TI 0 "nonimmediate_operand" "")
1741         (match_operand:TI 1 "nonimmediate_operand" ""))]
1742   "TARGET_64BIT || TARGET_SSE"
1743 {
1744   if (TARGET_64BIT)
1745     ix86_expand_move (TImode, operands);
1746   else if (push_operand (operands[0], TImode))
1747     ix86_expand_push (TImode, operands[1]);
1748   else
1749     ix86_expand_vector_move (TImode, operands);
1750   DONE;
1751 })
1752
1753 ;; This expands to what emit_move_complex would generate if we didn't
1754 ;; have a movti pattern.  Having this avoids problems with reload on
1755 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1756 ;; to have around all the time.
1757 (define_expand "movcdi"
1758   [(set (match_operand:CDI 0 "nonimmediate_operand" "")
1759         (match_operand:CDI 1 "general_operand" ""))]
1760   ""
1761 {
1762   if (push_operand (operands[0], CDImode))
1763     emit_move_complex_push (CDImode, operands[0], operands[1]);
1764   else
1765     emit_move_complex_parts (operands[0], operands[1]);
1766   DONE;
1767 })
1768
1769 (define_expand "mov<mode>"
1770   [(set (match_operand:SWI1248x 0 "nonimmediate_operand" "")
1771         (match_operand:SWI1248x 1 "general_operand" ""))]
1772   ""
1773   "ix86_expand_move (<MODE>mode, operands); DONE;")
1774
1775 (define_insn "*mov<mode>_xor"
1776   [(set (match_operand:SWI48 0 "register_operand" "=r")
1777         (match_operand:SWI48 1 "const0_operand" ""))
1778    (clobber (reg:CC FLAGS_REG))]
1779   "reload_completed"
1780   "xor{l}\t%k0, %k0"
1781   [(set_attr "type" "alu1")
1782    (set_attr "mode" "SI")
1783    (set_attr "length_immediate" "0")])
1784
1785 (define_insn "*mov<mode>_or"
1786   [(set (match_operand:SWI48 0 "register_operand" "=r")
1787         (match_operand:SWI48 1 "const_int_operand" ""))
1788    (clobber (reg:CC FLAGS_REG))]
1789   "reload_completed
1790    && operands[1] == constm1_rtx"
1791   "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1792   [(set_attr "type" "alu1")
1793    (set_attr "mode" "<MODE>")
1794    (set_attr "length_immediate" "1")])
1795
1796 (define_insn "*movoi_internal_avx"
1797   [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
1798         (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
1799   "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1800 {
1801   switch (which_alternative)
1802     {
1803     case 0:
1804       return "vxorps\t%0, %0, %0";
1805     case 1:
1806     case 2:
1807       if (misaligned_operand (operands[0], OImode)
1808           || misaligned_operand (operands[1], OImode))
1809         return "vmovdqu\t{%1, %0|%0, %1}";
1810       else
1811         return "vmovdqa\t{%1, %0|%0, %1}";
1812     default:
1813       gcc_unreachable ();
1814     }
1815 }
1816   [(set_attr "type" "sselog1,ssemov,ssemov")
1817    (set_attr "prefix" "vex")
1818    (set_attr "mode" "OI")])
1819
1820 (define_insn "*movti_internal_rex64"
1821   [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
1822         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
1823   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1824 {
1825   switch (which_alternative)
1826     {
1827     case 0:
1828     case 1:
1829       return "#";
1830     case 2:
1831       if (get_attr_mode (insn) == MODE_V4SF)
1832         return "%vxorps\t%0, %d0";
1833       else
1834         return "%vpxor\t%0, %d0";
1835     case 3:
1836     case 4:
1837       /* TDmode values are passed as TImode on the stack.  Moving them
1838          to stack may result in unaligned memory access.  */
1839       if (misaligned_operand (operands[0], TImode)
1840           || misaligned_operand (operands[1], TImode))
1841         {
1842           if (get_attr_mode (insn) == MODE_V4SF)
1843             return "%vmovups\t{%1, %0|%0, %1}";
1844          else
1845            return "%vmovdqu\t{%1, %0|%0, %1}";
1846         }
1847       else
1848         {
1849           if (get_attr_mode (insn) == MODE_V4SF)
1850             return "%vmovaps\t{%1, %0|%0, %1}";
1851          else
1852            return "%vmovdqa\t{%1, %0|%0, %1}";
1853         }
1854     default:
1855       gcc_unreachable ();
1856     }
1857 }
1858   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1859    (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1860    (set (attr "mode")
1861         (cond [(eq_attr "alternative" "2,3")
1862                  (if_then_else
1863                    (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1864                        (const_int 0))
1865                    (const_string "V4SF")
1866                    (const_string "TI"))
1867                (eq_attr "alternative" "4")
1868                  (if_then_else
1869                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
1870                             (const_int 0))
1871                         (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1872                             (const_int 0)))
1873                    (const_string "V4SF")
1874                    (const_string "TI"))]
1875                (const_string "DI")))])
1876
1877 (define_split
1878   [(set (match_operand:TI 0 "nonimmediate_operand" "")
1879         (match_operand:TI 1 "general_operand" ""))]
1880   "reload_completed
1881    && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1882   [(const_int 0)]
1883   "ix86_split_long_move (operands); DONE;")
1884
1885 (define_insn "*movti_internal_sse"
1886   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
1887         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
1888   "TARGET_SSE && !TARGET_64BIT
1889    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1890 {
1891   switch (which_alternative)
1892     {
1893     case 0:
1894       if (get_attr_mode (insn) == MODE_V4SF)
1895         return "%vxorps\t%0, %d0";
1896       else
1897         return "%vpxor\t%0, %d0";
1898     case 1:
1899     case 2:
1900       /* TDmode values are passed as TImode on the stack.  Moving them
1901          to stack may result in unaligned memory access.  */
1902       if (misaligned_operand (operands[0], TImode)
1903           || misaligned_operand (operands[1], TImode))
1904         {
1905           if (get_attr_mode (insn) == MODE_V4SF)
1906             return "%vmovups\t{%1, %0|%0, %1}";
1907          else
1908            return "%vmovdqu\t{%1, %0|%0, %1}";
1909         }
1910       else
1911         {
1912           if (get_attr_mode (insn) == MODE_V4SF)
1913             return "%vmovaps\t{%1, %0|%0, %1}";
1914          else
1915            return "%vmovdqa\t{%1, %0|%0, %1}";
1916         }
1917     default:
1918       gcc_unreachable ();
1919     }
1920 }
1921   [(set_attr "type" "sselog1,ssemov,ssemov")
1922    (set_attr "prefix" "maybe_vex")
1923    (set (attr "mode")
1924         (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1925                     (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1926                         (const_int 0)))
1927                  (const_string "V4SF")
1928                (and (eq_attr "alternative" "2")
1929                     (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
1930                         (const_int 0)))
1931                  (const_string "V4SF")]
1932               (const_string "TI")))])
1933
1934 (define_insn "*movdi_internal_rex64"
1935   [(set (match_operand:DI 0 "nonimmediate_operand"
1936           "=r,r  ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
1937         (match_operand:DI 1 "general_operand"
1938           "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r   ,m  ,C ,*x,*Yi,*x,r  ,m ,*Ym,*x"))]
1939   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1940 {
1941   switch (get_attr_type (insn))
1942     {
1943     case TYPE_SSECVT:
1944       if (SSE_REG_P (operands[0]))
1945         return "movq2dq\t{%1, %0|%0, %1}";
1946       else
1947         return "movdq2q\t{%1, %0|%0, %1}";
1948
1949     case TYPE_SSEMOV:
1950       if (TARGET_AVX)
1951         {
1952           if (get_attr_mode (insn) == MODE_TI)
1953             return "vmovdqa\t{%1, %0|%0, %1}";
1954           else
1955             return "vmovq\t{%1, %0|%0, %1}";
1956         }
1957
1958       if (get_attr_mode (insn) == MODE_TI)
1959         return "movdqa\t{%1, %0|%0, %1}";
1960       /* FALLTHRU */
1961
1962     case TYPE_MMXMOV:
1963       /* Moves from and into integer register is done using movd
1964          opcode with REX prefix.  */
1965       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1966         return "movd\t{%1, %0|%0, %1}";
1967       return "movq\t{%1, %0|%0, %1}";
1968
1969     case TYPE_SSELOG1:
1970       return "%vpxor\t%0, %d0";
1971
1972     case TYPE_MMX:
1973       return "pxor\t%0, %0";
1974
1975     case TYPE_MULTI:
1976       return "#";
1977
1978     case TYPE_LEA:
1979       return "lea{q}\t{%a1, %0|%0, %a1}";
1980
1981     default:
1982       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1983       if (get_attr_mode (insn) == MODE_SI)
1984         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1985       else if (which_alternative == 2)
1986         return "movabs{q}\t{%1, %0|%0, %1}";
1987       else
1988         return "mov{q}\t{%1, %0|%0, %1}";
1989     }
1990 }
1991   [(set (attr "type")
1992      (cond [(eq_attr "alternative" "5")
1993               (const_string "mmx")
1994             (eq_attr "alternative" "6,7,8,9,10")
1995               (const_string "mmxmov")
1996             (eq_attr "alternative" "11")
1997               (const_string "sselog1")
1998             (eq_attr "alternative" "12,13,14,15,16")
1999               (const_string "ssemov")
2000             (eq_attr "alternative" "17,18")
2001               (const_string "ssecvt")
2002             (eq_attr "alternative" "4")
2003               (const_string "multi")
2004             (match_operand:DI 1 "pic_32bit_operand" "")
2005               (const_string "lea")
2006            ]
2007            (const_string "imov")))
2008    (set (attr "modrm")
2009      (if_then_else
2010        (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2011          (const_string "0")
2012          (const_string "*")))
2013    (set (attr "length_immediate")
2014      (if_then_else
2015        (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2016          (const_string "8")
2017          (const_string "*")))
2018    (set_attr "prefix_rex" "*,*,*,*,*,*,*,1,*,1,*,*,*,*,*,*,*,*,*")
2019    (set_attr "prefix_data16" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,1,*,*,*")
2020    (set (attr "prefix")
2021      (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
2022        (const_string "maybe_vex")
2023        (const_string "orig")))
2024    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2025
2026 ;; Convert impossible stores of immediate to existing instructions.
2027 ;; First try to get scratch register and go through it.  In case this
2028 ;; fails, move by 32bit parts.
2029 (define_peephole2
2030   [(match_scratch:DI 2 "r")
2031    (set (match_operand:DI 0 "memory_operand" "")
2032         (match_operand:DI 1 "immediate_operand" ""))]
2033   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2034    && !x86_64_immediate_operand (operands[1], DImode)"
2035   [(set (match_dup 2) (match_dup 1))
2036    (set (match_dup 0) (match_dup 2))])
2037
2038 ;; We need to define this as both peepholer and splitter for case
2039 ;; peephole2 pass is not run.
2040 ;; "&& 1" is needed to keep it from matching the previous pattern.
2041 (define_peephole2
2042   [(set (match_operand:DI 0 "memory_operand" "")
2043         (match_operand:DI 1 "immediate_operand" ""))]
2044   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2045    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2046   [(set (match_dup 2) (match_dup 3))
2047    (set (match_dup 4) (match_dup 5))]
2048   "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2049
2050 (define_split
2051   [(set (match_operand:DI 0 "memory_operand" "")
2052         (match_operand:DI 1 "immediate_operand" ""))]
2053   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2054                     ? epilogue_completed : reload_completed)
2055    && !symbolic_operand (operands[1], DImode)
2056    && !x86_64_immediate_operand (operands[1], DImode)"
2057   [(set (match_dup 2) (match_dup 3))
2058    (set (match_dup 4) (match_dup 5))]
2059   "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2060
2061 (define_insn "*movdi_internal"
2062   [(set (match_operand:DI 0 "nonimmediate_operand"
2063                         "=r  ,o  ,*y,m*y,*y,*Y2,m  ,*Y2,*Y2,*x,m ,*x,*x")
2064         (match_operand:DI 1 "general_operand"
2065                         "riFo,riF,C ,*y ,m ,C  ,*Y2,*Y2,m  ,C ,*x,*x,m "))]
2066   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2067   "@
2068    #
2069    #
2070    pxor\t%0, %0
2071    movq\t{%1, %0|%0, %1}
2072    movq\t{%1, %0|%0, %1}
2073    %vpxor\t%0, %d0
2074    %vmovq\t{%1, %0|%0, %1}
2075    %vmovdqa\t{%1, %0|%0, %1}
2076    %vmovq\t{%1, %0|%0, %1}
2077    xorps\t%0, %0
2078    movlps\t{%1, %0|%0, %1}
2079    movaps\t{%1, %0|%0, %1}
2080    movlps\t{%1, %0|%0, %1}"
2081   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2082    (set (attr "prefix")
2083      (if_then_else (eq_attr "alternative" "5,6,7,8")
2084        (const_string "vex")
2085        (const_string "orig")))
2086    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2087
2088 (define_split
2089   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2090         (match_operand:DI 1 "general_operand" ""))]
2091   "!TARGET_64BIT && reload_completed
2092    && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2093    && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2094   [(const_int 0)]
2095   "ix86_split_long_move (operands); DONE;")
2096
2097 (define_insn "*movsi_internal"
2098   [(set (match_operand:SI 0 "nonimmediate_operand"
2099                         "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2100         (match_operand:SI 1 "general_operand"
2101                         "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r   ,m "))]
2102   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2103 {
2104   switch (get_attr_type (insn))
2105     {
2106     case TYPE_SSELOG1:
2107       if (get_attr_mode (insn) == MODE_TI)
2108         return "%vpxor\t%0, %d0";
2109       return "%vxorps\t%0, %d0";
2110
2111     case TYPE_SSEMOV:
2112       switch (get_attr_mode (insn))
2113         {
2114         case MODE_TI:
2115           return "%vmovdqa\t{%1, %0|%0, %1}";
2116         case MODE_V4SF:
2117           return "%vmovaps\t{%1, %0|%0, %1}";
2118         case MODE_SI:
2119           return "%vmovd\t{%1, %0|%0, %1}";
2120         case MODE_SF:
2121           return "%vmovss\t{%1, %0|%0, %1}";
2122         default:
2123           gcc_unreachable ();
2124         }
2125
2126     case TYPE_MMX:
2127       return "pxor\t%0, %0";
2128
2129     case TYPE_MMXMOV:
2130       if (get_attr_mode (insn) == MODE_DI)
2131         return "movq\t{%1, %0|%0, %1}";
2132       return "movd\t{%1, %0|%0, %1}";
2133
2134     case TYPE_LEA:
2135       return "lea{l}\t{%a1, %0|%0, %a1}";
2136
2137     default:
2138       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2139       return "mov{l}\t{%1, %0|%0, %1}";
2140     }
2141 }
2142   [(set (attr "type")
2143      (cond [(eq_attr "alternative" "2")
2144               (const_string "mmx")
2145             (eq_attr "alternative" "3,4,5")
2146               (const_string "mmxmov")
2147             (eq_attr "alternative" "6")
2148               (const_string "sselog1")
2149             (eq_attr "alternative" "7,8,9,10,11")
2150               (const_string "ssemov")
2151             (match_operand:DI 1 "pic_32bit_operand" "")
2152               (const_string "lea")
2153            ]
2154            (const_string "imov")))
2155    (set (attr "prefix")
2156      (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2157        (const_string "orig")
2158        (const_string "maybe_vex")))
2159    (set (attr "prefix_data16")
2160      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2161        (const_string "1")
2162        (const_string "*")))
2163    (set (attr "mode")
2164      (cond [(eq_attr "alternative" "2,3")
2165               (const_string "DI")
2166             (eq_attr "alternative" "6,7")
2167               (if_then_else
2168                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2169                 (const_string "V4SF")
2170                 (const_string "TI"))
2171             (and (eq_attr "alternative" "8,9,10,11")
2172                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
2173               (const_string "SF")
2174            ]
2175            (const_string "SI")))])
2176
2177 (define_insn "*movhi_internal"
2178   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2179         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2180   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2181 {
2182   switch (get_attr_type (insn))
2183     {
2184     case TYPE_IMOVX:
2185       /* movzwl is faster than movw on p2 due to partial word stalls,
2186          though not as fast as an aligned movl.  */
2187       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2188     default:
2189       if (get_attr_mode (insn) == MODE_SI)
2190         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2191       else
2192         return "mov{w}\t{%1, %0|%0, %1}";
2193     }
2194 }
2195   [(set (attr "type")
2196      (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
2197                 (const_int 0))
2198               (const_string "imov")
2199             (and (eq_attr "alternative" "0")
2200                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2201                           (const_int 0))
2202                       (eq (symbol_ref "TARGET_HIMODE_MATH")
2203                           (const_int 0))))
2204               (const_string "imov")
2205             (and (eq_attr "alternative" "1,2")
2206                  (match_operand:HI 1 "aligned_operand" ""))
2207               (const_string "imov")
2208             (and (ne (symbol_ref "TARGET_MOVX")
2209                      (const_int 0))
2210                  (eq_attr "alternative" "0,2"))
2211               (const_string "imovx")
2212            ]
2213            (const_string "imov")))
2214     (set (attr "mode")
2215       (cond [(eq_attr "type" "imovx")
2216                (const_string "SI")
2217              (and (eq_attr "alternative" "1,2")
2218                   (match_operand:HI 1 "aligned_operand" ""))
2219                (const_string "SI")
2220              (and (eq_attr "alternative" "0")
2221                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2222                            (const_int 0))
2223                        (eq (symbol_ref "TARGET_HIMODE_MATH")
2224                            (const_int 0))))
2225                (const_string "SI")
2226             ]
2227             (const_string "HI")))])
2228
2229 ;; Situation is quite tricky about when to choose full sized (SImode) move
2230 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
2231 ;; partial register dependency machines (such as AMD Athlon), where QImode
2232 ;; moves issue extra dependency and for partial register stalls machines
2233 ;; that don't use QImode patterns (and QImode move cause stall on the next
2234 ;; instruction).
2235 ;;
2236 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2237 ;; register stall machines with, where we use QImode instructions, since
2238 ;; partial register stall can be caused there.  Then we use movzx.
2239 (define_insn "*movqi_internal"
2240   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2241         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
2242   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2243 {
2244   switch (get_attr_type (insn))
2245     {
2246     case TYPE_IMOVX:
2247       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2248       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2249     default:
2250       if (get_attr_mode (insn) == MODE_SI)
2251         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2252       else
2253         return "mov{b}\t{%1, %0|%0, %1}";
2254     }
2255 }
2256   [(set (attr "type")
2257      (cond [(and (eq_attr "alternative" "5")
2258                  (not (match_operand:QI 1 "aligned_operand" "")))
2259               (const_string "imovx")
2260             (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2261                 (const_int 0))
2262               (const_string "imov")
2263             (and (eq_attr "alternative" "3")
2264                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2265                           (const_int 0))
2266                       (eq (symbol_ref "TARGET_QIMODE_MATH")
2267                           (const_int 0))))
2268               (const_string "imov")
2269             (eq_attr "alternative" "3,5")
2270               (const_string "imovx")
2271             (and (ne (symbol_ref "TARGET_MOVX")
2272                      (const_int 0))
2273                  (eq_attr "alternative" "2"))
2274               (const_string "imovx")
2275            ]
2276            (const_string "imov")))
2277    (set (attr "mode")
2278       (cond [(eq_attr "alternative" "3,4,5")
2279                (const_string "SI")
2280              (eq_attr "alternative" "6")
2281                (const_string "QI")
2282              (eq_attr "type" "imovx")
2283                (const_string "SI")
2284              (and (eq_attr "type" "imov")
2285                   (and (eq_attr "alternative" "0,1")
2286                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
2287                                 (const_int 0))
2288                             (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2289                                      (const_int 0))
2290                                  (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2291                                      (const_int 0))))))
2292                (const_string "SI")
2293              ;; Avoid partial register stalls when not using QImode arithmetic
2294              (and (eq_attr "type" "imov")
2295                   (and (eq_attr "alternative" "0,1")
2296                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
2297                                 (const_int 0))
2298                             (eq (symbol_ref "TARGET_QIMODE_MATH")
2299                                 (const_int 0)))))
2300                (const_string "SI")
2301            ]
2302            (const_string "QI")))])
2303
2304 ;; Stores and loads of ax to arbitrary constant address.
2305 ;; We fake an second form of instruction to force reload to load address
2306 ;; into register when rax is not available
2307 (define_insn "*movabs<mode>_1"
2308   [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2309         (match_operand:SWI1248x 1 "nonmemory_operand" "a,er"))]
2310   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2311   "@
2312    movabs{<imodesuffix>}\t{%1, %P0|%P0, %1}
2313    mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2314   [(set_attr "type" "imov")
2315    (set_attr "modrm" "0,*")
2316    (set_attr "length_address" "8,0")
2317    (set_attr "length_immediate" "0,*")
2318    (set_attr "memory" "store")
2319    (set_attr "mode" "<MODE>")])
2320
2321 (define_insn "*movabs<mode>_2"
2322   [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2323         (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2324   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2325   "@
2326    movabs{<imodesuffix>}\t{%P1, %0|%0, %P1}
2327    mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2328   [(set_attr "type" "imov")
2329    (set_attr "modrm" "0,*")
2330    (set_attr "length_address" "8,0")
2331    (set_attr "length_immediate" "0")
2332    (set_attr "memory" "load")
2333    (set_attr "mode" "<MODE>")])
2334
2335 (define_insn "*swap<mode>"
2336   [(set (match_operand:SWI48 0 "register_operand" "+r")
2337         (match_operand:SWI48 1 "register_operand" "+r"))
2338    (set (match_dup 1)
2339         (match_dup 0))]
2340   ""
2341   "xchg{<imodesuffix>}\t%1, %0"
2342   [(set_attr "type" "imov")
2343    (set_attr "mode" "<MODE>")
2344    (set_attr "pent_pair" "np")
2345    (set_attr "athlon_decode" "vector")
2346    (set_attr "amdfam10_decode" "double")])
2347
2348 (define_insn "*swap<mode>_1"
2349   [(set (match_operand:SWI12 0 "register_operand" "+r")
2350         (match_operand:SWI12 1 "register_operand" "+r"))
2351    (set (match_dup 1)
2352         (match_dup 0))]
2353   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2354   "xchg{l}\t%k1, %k0"
2355   [(set_attr "type" "imov")
2356    (set_attr "mode" "SI")
2357    (set_attr "pent_pair" "np")
2358    (set_attr "athlon_decode" "vector")
2359    (set_attr "amdfam10_decode" "double")])
2360
2361 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2362 ;; is disabled for AMDFAM10
2363 (define_insn "*swap<mode>_2"
2364   [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2365         (match_operand:SWI12 1 "register_operand" "+<r>"))
2366    (set (match_dup 1)
2367         (match_dup 0))]
2368   "TARGET_PARTIAL_REG_STALL"
2369   "xchg{<imodesuffix>}\t%1, %0"
2370   [(set_attr "type" "imov")
2371    (set_attr "mode" "<MODE>")
2372    (set_attr "pent_pair" "np")
2373    (set_attr "athlon_decode" "vector")])
2374
2375 (define_expand "movstrict<mode>"
2376   [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand" ""))
2377         (match_operand:SWI12 1 "general_operand" ""))]
2378   ""
2379 {
2380   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2381     FAIL;
2382   /* Don't generate memory->memory moves, go through a register */
2383   if (MEM_P (operands[0]) && MEM_P (operands[1]))
2384     operands[1] = force_reg (<MODE>mode, operands[1]);
2385 })
2386
2387 (define_insn "*movstrict<mode>_1"
2388   [(set (strict_low_part
2389           (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2390         (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2391   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2392    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2393   "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2394   [(set_attr "type" "imov")
2395    (set_attr "mode" "<MODE>")])
2396
2397 (define_insn "*movstrict<mode>_xor"
2398   [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2399         (match_operand:SWI12 1 "const0_operand" ""))
2400    (clobber (reg:CC FLAGS_REG))]
2401   "reload_completed"
2402   "xor{<imodesuffix>}\t%0, %0"
2403   [(set_attr "type" "alu1")
2404    (set_attr "mode" "<MODE>")
2405    (set_attr "length_immediate" "0")])
2406
2407 (define_insn "*mov<mode>_extv_1"
2408   [(set (match_operand:SWI24 0 "register_operand" "=R")
2409         (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2410                             (const_int 8)
2411                             (const_int 8)))]
2412   ""
2413   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2414   [(set_attr "type" "imovx")
2415    (set_attr "mode" "SI")])
2416
2417 (define_insn "*movqi_extv_1_rex64"
2418   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2419         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2420                          (const_int 8)
2421                          (const_int 8)))]
2422   "TARGET_64BIT"
2423 {
2424   switch (get_attr_type (insn))
2425     {
2426     case TYPE_IMOVX:
2427       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2428     default:
2429       return "mov{b}\t{%h1, %0|%0, %h1}";
2430     }
2431 }
2432   [(set (attr "type")
2433      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2434                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2435                              (ne (symbol_ref "TARGET_MOVX")
2436                                  (const_int 0))))
2437         (const_string "imovx")
2438         (const_string "imov")))
2439    (set (attr "mode")
2440      (if_then_else (eq_attr "type" "imovx")
2441         (const_string "SI")
2442         (const_string "QI")))])
2443
2444 (define_insn "*movqi_extv_1"
2445   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?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 "*mov<mode>_extzv_1"
2472   [(set (match_operand:SWI48 0 "register_operand" "=R")
2473         (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2474                             (const_int 8)
2475                             (const_int 8)))]
2476   ""
2477   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2478   [(set_attr "type" "imovx")
2479    (set_attr "mode" "SI")])
2480
2481 (define_insn "*movqi_extzv_2_rex64"
2482   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2483         (subreg:QI
2484           (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2485                            (const_int 8)
2486                            (const_int 8)) 0))]
2487   "TARGET_64BIT"
2488 {
2489   switch (get_attr_type (insn))
2490     {
2491     case TYPE_IMOVX:
2492       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2493     default:
2494       return "mov{b}\t{%h1, %0|%0, %h1}";
2495     }
2496 }
2497   [(set (attr "type")
2498      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2499                         (ne (symbol_ref "TARGET_MOVX")
2500                             (const_int 0)))
2501         (const_string "imovx")
2502         (const_string "imov")))
2503    (set (attr "mode")
2504      (if_then_else (eq_attr "type" "imovx")
2505         (const_string "SI")
2506         (const_string "QI")))])
2507
2508 (define_insn "*movqi_extzv_2"
2509   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?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 (and (match_operand:QI 0 "register_operand" "")
2526                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2527                              (ne (symbol_ref "TARGET_MOVX")
2528                                  (const_int 0))))
2529         (const_string "imovx")
2530         (const_string "imov")))
2531    (set (attr "mode")
2532      (if_then_else (eq_attr "type" "imovx")
2533         (const_string "SI")
2534         (const_string "QI")))])
2535
2536 (define_expand "mov<mode>_insv_1"
2537   [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "")
2538                             (const_int 8)
2539                             (const_int 8))
2540         (match_operand:SWI48 1 "nonmemory_operand" ""))]
2541   ""
2542   "")
2543
2544 (define_insn "*mov<mode>_insv_1_rex64"
2545   [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2546                              (const_int 8)
2547                              (const_int 8))
2548         (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2549   "TARGET_64BIT"
2550   "mov{b}\t{%b1, %h0|%h0, %b1}"
2551   [(set_attr "type" "imov")
2552    (set_attr "mode" "QI")])
2553
2554 (define_insn "*movsi_insv_1"
2555   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2556                          (const_int 8)
2557                          (const_int 8))
2558         (match_operand:SI 1 "general_operand" "Qmn"))]
2559   "!TARGET_64BIT"
2560   "mov{b}\t{%b1, %h0|%h0, %b1}"
2561   [(set_attr "type" "imov")
2562    (set_attr "mode" "QI")])
2563
2564 (define_insn "*movqi_insv_2"
2565   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2566                          (const_int 8)
2567                          (const_int 8))
2568         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2569                      (const_int 8)))]
2570   ""
2571   "mov{b}\t{%h1, %h0|%h0, %h1}"
2572   [(set_attr "type" "imov")
2573    (set_attr "mode" "QI")])
2574 \f
2575 ;; Floating point push instructions.
2576
2577 (define_insn "*pushtf"
2578   [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2579         (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2580   "TARGET_SSE2"
2581 {
2582   /* This insn should be already split before reg-stack.  */
2583   gcc_unreachable ();
2584 }
2585   [(set_attr "type" "multi")
2586    (set_attr "unit" "sse,*,*")
2587    (set_attr "mode" "TF,SI,SI")])
2588
2589 (define_split
2590   [(set (match_operand:TF 0 "push_operand" "")
2591         (match_operand:TF 1 "sse_reg_operand" ""))]
2592   "TARGET_SSE2 && reload_completed"
2593   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2594    (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2595
2596 (define_split
2597   [(set (match_operand:TF 0 "push_operand" "")
2598         (match_operand:TF 1 "general_operand" ""))]
2599   "TARGET_SSE2 && reload_completed
2600    && !SSE_REG_P (operands[1])"
2601   [(const_int 0)]
2602   "ix86_split_long_move (operands); DONE;")
2603
2604 (define_insn "*pushxf"
2605   [(set (match_operand:XF 0 "push_operand" "=<,<")
2606         (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2607   "optimize_function_for_speed_p (cfun)"
2608 {
2609   /* This insn should be already split before reg-stack.  */
2610   gcc_unreachable ();
2611 }
2612   [(set_attr "type" "multi")
2613    (set_attr "unit" "i387,*")
2614    (set_attr "mode" "XF,SI")])
2615
2616 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2617 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2618 ;; Pushing using integer instructions is longer except for constants
2619 ;; and direct memory references (assuming that any given constant is pushed
2620 ;; only once, but this ought to be handled elsewhere).
2621
2622 (define_insn "*pushxf_nointeger"
2623   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2624         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2625   "optimize_function_for_size_p (cfun)"
2626 {
2627   /* This insn should be already split before reg-stack.  */
2628   gcc_unreachable ();
2629 }
2630   [(set_attr "type" "multi")
2631    (set_attr "unit" "i387,*,*")
2632    (set_attr "mode" "XF,SI,SI")])
2633
2634 (define_split
2635   [(set (match_operand:XF 0 "push_operand" "")
2636         (match_operand:XF 1 "fp_register_operand" ""))]
2637   "reload_completed"
2638   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2639    (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2640   "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2641
2642 (define_split
2643   [(set (match_operand:XF 0 "push_operand" "")
2644         (match_operand:XF 1 "general_operand" ""))]
2645   "reload_completed
2646    && !FP_REG_P (operands[1])"
2647   [(const_int 0)]
2648   "ix86_split_long_move (operands); DONE;")
2649
2650 (define_insn "*pushdf"
2651   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2652         (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2653   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2654 {
2655   /* This insn should be already split before reg-stack.  */
2656   gcc_unreachable ();
2657 }
2658   [(set_attr "type" "multi")
2659    (set_attr "unit" "i387,*,*")
2660    (set_attr "mode" "DF,SI,DF")])
2661
2662 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2663 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2664 ;; On the average, pushdf using integers can be still shorter.  Allow this
2665 ;; pattern for optimize_size too.
2666
2667 (define_insn "*pushdf_nointeger"
2668   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2669         (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2670   "!(TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES)"
2671 {
2672   /* This insn should be already split before reg-stack.  */
2673   gcc_unreachable ();
2674 }
2675   [(set_attr "type" "multi")
2676    (set_attr "unit" "i387,*,*,*")
2677    (set_attr "mode" "DF,SI,SI,DF")])
2678
2679 ;; %%% Kill this when call knows how to work this out.
2680 (define_split
2681   [(set (match_operand:DF 0 "push_operand" "")
2682         (match_operand:DF 1 "any_fp_register_operand" ""))]
2683   "reload_completed"
2684   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2685    (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2686
2687 (define_split
2688   [(set (match_operand:DF 0 "push_operand" "")
2689         (match_operand:DF 1 "general_operand" ""))]
2690   "reload_completed
2691    && !ANY_FP_REG_P (operands[1])"
2692   [(const_int 0)]
2693   "ix86_split_long_move (operands); DONE;")
2694
2695 (define_insn "*pushsf_rex64"
2696   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2697         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2698   "TARGET_64BIT"
2699 {
2700   /* Anything else should be already split before reg-stack.  */
2701   gcc_assert (which_alternative == 1);
2702   return "push{q}\t%q1";
2703 }
2704   [(set_attr "type" "multi,push,multi")
2705    (set_attr "unit" "i387,*,*")
2706    (set_attr "mode" "SF,DI,SF")])
2707
2708 (define_insn "*pushsf"
2709   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2710         (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2711   "!TARGET_64BIT"
2712 {
2713   /* Anything else should be already split before reg-stack.  */
2714   gcc_assert (which_alternative == 1);
2715   return "push{l}\t%1";
2716 }
2717   [(set_attr "type" "multi,push,multi")
2718    (set_attr "unit" "i387,*,*")
2719    (set_attr "mode" "SF,SI,SF")])
2720
2721 (define_split
2722   [(set (match_operand:SF 0 "push_operand" "")
2723         (match_operand:SF 1 "memory_operand" ""))]
2724   "reload_completed
2725    && MEM_P (operands[1])
2726    && (operands[2] = find_constant_src (insn))"
2727   [(set (match_dup 0)
2728         (match_dup 2))])
2729
2730 ;; %%% Kill this when call knows how to work this out.
2731 (define_split
2732   [(set (match_operand:SF 0 "push_operand" "")
2733         (match_operand:SF 1 "any_fp_register_operand" ""))]
2734   "reload_completed"
2735   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2736    (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2737   "operands[2] = GEN_INT (-GET_MODE_SIZE (<MODE>mode));")
2738 \f
2739 ;; Floating point move instructions.
2740
2741 (define_expand "movtf"
2742   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2743         (match_operand:TF 1 "nonimmediate_operand" ""))]
2744   "TARGET_SSE2"
2745 {
2746   ix86_expand_move (TFmode, operands);
2747   DONE;
2748 })
2749
2750 (define_expand "mov<mode>"
2751   [(set (match_operand:X87MODEF 0 "nonimmediate_operand" "")
2752         (match_operand:X87MODEF 1 "general_operand" ""))]
2753   ""
2754   "ix86_expand_move (<MODE>mode, operands); DONE;")
2755
2756 (define_insn "*movtf_internal"
2757   [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
2758         (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
2759   "TARGET_SSE2
2760    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2761 {
2762   switch (which_alternative)
2763     {
2764     case 0:
2765     case 1:
2766       if (get_attr_mode (insn) == MODE_V4SF)
2767         return "%vmovaps\t{%1, %0|%0, %1}";
2768       else
2769         return "%vmovdqa\t{%1, %0|%0, %1}";
2770     case 2:
2771       if (get_attr_mode (insn) == MODE_V4SF)
2772         return "%vxorps\t%0, %d0";
2773       else
2774         return "%vpxor\t%0, %d0";
2775     case 3:
2776     case 4:
2777         return "#";
2778     default:
2779       gcc_unreachable ();
2780     }
2781 }
2782   [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
2783    (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2784    (set (attr "mode")
2785         (cond [(eq_attr "alternative" "0,2")
2786                  (if_then_else
2787                    (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2788                        (const_int 0))
2789                    (const_string "V4SF")
2790                    (const_string "TI"))
2791                (eq_attr "alternative" "1")
2792                  (if_then_else
2793                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2794                             (const_int 0))
2795                         (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2796                             (const_int 0)))
2797                    (const_string "V4SF")
2798                    (const_string "TI"))]
2799                (const_string "DI")))])
2800
2801 (define_split
2802   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2803         (match_operand:TF 1 "general_operand" ""))]
2804   "reload_completed
2805    && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
2806   [(const_int 0)]
2807   "ix86_split_long_move (operands); DONE;")
2808
2809 (define_insn "*movxf_internal"
2810   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
2811         (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
2812   "optimize_function_for_speed_p (cfun)
2813    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2814    && (reload_in_progress || reload_completed
2815        || GET_CODE (operands[1]) != CONST_DOUBLE
2816        || memory_operand (operands[0], XFmode))"
2817 {
2818   switch (which_alternative)
2819     {
2820     case 0:
2821     case 1:
2822       return output_387_reg_move (insn, operands);
2823
2824     case 2:
2825       return standard_80387_constant_opcode (operands[1]);
2826
2827     case 3: case 4:
2828       return "#";
2829
2830     default:
2831       gcc_unreachable ();
2832     }
2833 }
2834   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2835    (set_attr "mode" "XF,XF,XF,SI,SI")])
2836
2837 ;; Do not use integer registers when optimizing for size
2838 (define_insn "*movxf_internal_nointeger"
2839   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2840         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2841   "optimize_function_for_size_p (cfun)
2842    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2843    && (reload_in_progress || reload_completed
2844        || standard_80387_constant_p (operands[1])
2845        || GET_CODE (operands[1]) != CONST_DOUBLE
2846        || memory_operand (operands[0], XFmode))"
2847 {
2848   switch (which_alternative)
2849     {
2850     case 0:
2851     case 1:
2852       return output_387_reg_move (insn, operands);
2853
2854     case 2:
2855       return standard_80387_constant_opcode (operands[1]);
2856
2857     case 3: case 4:
2858       return "#";
2859     default:
2860       gcc_unreachable ();
2861     }
2862 }
2863   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2864    (set_attr "mode" "XF,XF,XF,SI,SI")])
2865
2866 (define_split
2867   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2868         (match_operand:XF 1 "general_operand" ""))]
2869   "reload_completed
2870    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2871    && ! (ANY_FP_REG_P (operands[0]) ||
2872          (GET_CODE (operands[0]) == SUBREG
2873           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2874    && ! (ANY_FP_REG_P (operands[1]) ||
2875          (GET_CODE (operands[1]) == SUBREG
2876           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2877   [(const_int 0)]
2878   "ix86_split_long_move (operands); DONE;")
2879
2880 (define_insn "*movdf_internal_rex64"
2881   [(set (match_operand:DF 0 "nonimmediate_operand"
2882                 "=f,m,f,r  ,m ,Y2*x,Y2*x,Y2*x,m   ,Yi,r ")
2883         (match_operand:DF 1 "general_operand"
2884                 "fm,f,G,rmF,Fr,C   ,Y2*x,m   ,Y2*x,r ,Yi"))]
2885   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2886    && (reload_in_progress || reload_completed
2887        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2888        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
2889            && optimize_function_for_size_p (cfun)
2890            && standard_80387_constant_p (operands[1]))
2891        || GET_CODE (operands[1]) != CONST_DOUBLE
2892        || memory_operand (operands[0], DFmode))"
2893 {
2894   switch (which_alternative)
2895     {
2896     case 0:
2897     case 1:
2898       return output_387_reg_move (insn, operands);
2899
2900     case 2:
2901       return standard_80387_constant_opcode (operands[1]);
2902
2903     case 3:
2904     case 4:
2905       return "#";
2906
2907     case 5:
2908       switch (get_attr_mode (insn))
2909         {
2910         case MODE_V4SF:
2911           return "%vxorps\t%0, %d0";
2912         case MODE_V2DF:
2913           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2914             return "%vxorps\t%0, %d0";
2915           else
2916             return "%vxorpd\t%0, %d0";
2917         case MODE_TI:
2918           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2919             return "%vxorps\t%0, %d0";
2920           else
2921             return "%vpxor\t%0, %d0";
2922         default:
2923           gcc_unreachable ();
2924         }
2925     case 6:
2926     case 7:
2927     case 8:
2928       switch (get_attr_mode (insn))
2929         {
2930         case MODE_V4SF:
2931           return "%vmovaps\t{%1, %0|%0, %1}";
2932         case MODE_V2DF:
2933           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2934             return "%vmovaps\t{%1, %0|%0, %1}";
2935           else
2936             return "%vmovapd\t{%1, %0|%0, %1}";
2937         case MODE_TI:
2938           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2939             return "%vmovaps\t{%1, %0|%0, %1}";
2940           else
2941             return "%vmovdqa\t{%1, %0|%0, %1}";
2942         case MODE_DI:
2943           return "%vmovq\t{%1, %0|%0, %1}";
2944         case MODE_DF:
2945           if (TARGET_AVX)
2946             {
2947               if (REG_P (operands[0]) && REG_P (operands[1]))
2948                 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
2949               else
2950                 return "vmovsd\t{%1, %0|%0, %1}";
2951             }
2952           else
2953             return "movsd\t{%1, %0|%0, %1}";
2954         case MODE_V1DF:
2955           return "%vmovlpd\t{%1, %d0|%d0, %1}";
2956         case MODE_V2SF:
2957           return "%vmovlps\t{%1, %d0|%d0, %1}";
2958         default:
2959           gcc_unreachable ();
2960         }
2961
2962     case 9:
2963     case 10:
2964     return "%vmovd\t{%1, %0|%0, %1}";
2965
2966     default:
2967       gcc_unreachable();
2968     }
2969 }
2970   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
2971    (set (attr "prefix")
2972      (if_then_else (eq_attr "alternative" "0,1,2,3,4")
2973        (const_string "orig")
2974        (const_string "maybe_vex")))
2975    (set (attr "prefix_data16")
2976      (if_then_else (eq_attr "mode" "V1DF")
2977        (const_string "1")
2978        (const_string "*")))
2979    (set (attr "mode")
2980         (cond [(eq_attr "alternative" "0,1,2")
2981                  (const_string "DF")
2982                (eq_attr "alternative" "3,4,9,10")
2983                  (const_string "DI")
2984
2985                /* For SSE1, we have many fewer alternatives.  */
2986                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2987                  (cond [(eq_attr "alternative" "5,6")
2988                           (const_string "V4SF")
2989                        ]
2990                    (const_string "V2SF"))
2991
2992                /* xorps is one byte shorter.  */
2993                (eq_attr "alternative" "5")
2994                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
2995                             (const_int 0))
2996                           (const_string "V4SF")
2997                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2998                             (const_int 0))
2999                           (const_string "TI")
3000                        ]
3001                        (const_string "V2DF"))
3002
3003                /* For architectures resolving dependencies on
3004                   whole SSE registers use APD move to break dependency
3005                   chains, otherwise use short move to avoid extra work.
3006
3007                   movaps encodes one byte shorter.  */
3008                (eq_attr "alternative" "6")
3009                  (cond
3010                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3011                         (const_int 0))
3012                       (const_string "V4SF")
3013                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3014                         (const_int 0))
3015                       (const_string "V2DF")
3016                    ]
3017                    (const_string "DF"))
3018                /* For architectures resolving dependencies on register
3019                   parts we may avoid extra work to zero out upper part
3020                   of register.  */
3021                (eq_attr "alternative" "7")
3022                  (if_then_else
3023                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3024                        (const_int 0))
3025                    (const_string "V1DF")
3026                    (const_string "DF"))
3027               ]
3028               (const_string "DF")))])
3029
3030 (define_insn "*movdf_internal"
3031   [(set (match_operand:DF 0 "nonimmediate_operand"
3032                 "=f,m,f,r  ,o ,Y2*x,Y2*x,Y2*x,m   ")
3033         (match_operand:DF 1 "general_operand"
3034                 "fm,f,G,roF,Fr,C   ,Y2*x,m   ,Y2*x"))]
3035   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3036    && optimize_function_for_speed_p (cfun)
3037    && TARGET_INTEGER_DFMODE_MOVES
3038    && (reload_in_progress || reload_completed
3039        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3040        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3041            && optimize_function_for_size_p (cfun)
3042            && standard_80387_constant_p (operands[1]))
3043        || GET_CODE (operands[1]) != CONST_DOUBLE
3044        || memory_operand (operands[0], DFmode))"
3045 {
3046   switch (which_alternative)
3047     {
3048     case 0:
3049     case 1:
3050       return output_387_reg_move (insn, operands);
3051
3052     case 2:
3053       return standard_80387_constant_opcode (operands[1]);
3054
3055     case 3:
3056     case 4:
3057       return "#";
3058
3059     case 5:
3060       switch (get_attr_mode (insn))
3061         {
3062         case MODE_V4SF:
3063           return "xorps\t%0, %0";
3064         case MODE_V2DF:
3065           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3066             return "xorps\t%0, %0";
3067           else
3068             return "xorpd\t%0, %0";
3069         case MODE_TI:
3070           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3071             return "xorps\t%0, %0";
3072           else
3073             return "pxor\t%0, %0";
3074         default:
3075           gcc_unreachable ();
3076         }
3077     case 6:
3078     case 7:
3079     case 8:
3080       switch (get_attr_mode (insn))
3081         {
3082         case MODE_V4SF:
3083           return "movaps\t{%1, %0|%0, %1}";
3084         case MODE_V2DF:
3085           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3086             return "movaps\t{%1, %0|%0, %1}";
3087           else
3088             return "movapd\t{%1, %0|%0, %1}";
3089         case MODE_TI:
3090           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3091             return "movaps\t{%1, %0|%0, %1}";
3092           else
3093             return "movdqa\t{%1, %0|%0, %1}";
3094         case MODE_DI:
3095           return "movq\t{%1, %0|%0, %1}";
3096         case MODE_DF:
3097           return "movsd\t{%1, %0|%0, %1}";
3098         case MODE_V1DF:
3099           return "movlpd\t{%1, %0|%0, %1}";
3100         case MODE_V2SF:
3101           return "movlps\t{%1, %0|%0, %1}";
3102         default:
3103           gcc_unreachable ();
3104         }
3105
3106     default:
3107       gcc_unreachable();
3108     }
3109 }
3110   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3111    (set (attr "prefix_data16")
3112      (if_then_else (eq_attr "mode" "V1DF")
3113        (const_string "1")
3114        (const_string "*")))
3115    (set (attr "mode")
3116         (cond [(eq_attr "alternative" "0,1,2")
3117                  (const_string "DF")
3118                (eq_attr "alternative" "3,4")
3119                  (const_string "SI")
3120
3121                /* For SSE1, we have many fewer alternatives.  */
3122                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3123                  (cond [(eq_attr "alternative" "5,6")
3124                           (const_string "V4SF")
3125                        ]
3126                    (const_string "V2SF"))
3127
3128                /* xorps is one byte shorter.  */
3129                (eq_attr "alternative" "5")
3130                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3131                             (const_int 0))
3132                           (const_string "V4SF")
3133                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3134                             (const_int 0))
3135                           (const_string "TI")
3136                        ]
3137                        (const_string "V2DF"))
3138
3139                /* For architectures resolving dependencies on
3140                   whole SSE registers use APD move to break dependency
3141                   chains, otherwise use short move to avoid extra work.
3142
3143                   movaps encodes one byte shorter.  */
3144                (eq_attr "alternative" "6")
3145                  (cond
3146                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3147                         (const_int 0))
3148                       (const_string "V4SF")
3149                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3150                         (const_int 0))
3151                       (const_string "V2DF")
3152                    ]
3153                    (const_string "DF"))
3154                /* For architectures resolving dependencies on register
3155                   parts we may avoid extra work to zero out upper part
3156                   of register.  */
3157                (eq_attr "alternative" "7")
3158                  (if_then_else
3159                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3160                        (const_int 0))
3161                    (const_string "V1DF")
3162                    (const_string "DF"))
3163               ]
3164               (const_string "DF")))])
3165
3166 ;; Moving is usually shorter when only FP registers are used. This separate
3167 ;; movdf pattern avoids the use of integer registers for FP operations
3168 ;; when optimizing for size.
3169
3170 (define_insn "*movdf_internal_nointeger"
3171   [(set (match_operand:DF 0 "nonimmediate_operand"
3172                         "=f,m,f,*r  ,o  ,Y2*x,Y2*x,Y2*x ,m  ")
3173         (match_operand:DF 1 "general_operand"
3174                         "fm,f,G,*roF,*Fr,C   ,Y2*x,mY2*x,Y2*x"))]
3175   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3176    && ((optimize_function_for_size_p (cfun)
3177        || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
3178    && (reload_in_progress || reload_completed
3179        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3180        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3181            && optimize_function_for_size_p (cfun)
3182            && !memory_operand (operands[0], DFmode)
3183            && standard_80387_constant_p (operands[1]))
3184        || GET_CODE (operands[1]) != CONST_DOUBLE
3185        || ((optimize_function_for_size_p (cfun)
3186             || !TARGET_MEMORY_MISMATCH_STALL
3187             || reload_in_progress || reload_completed)
3188            && memory_operand (operands[0], DFmode)))"
3189 {
3190   switch (which_alternative)
3191     {
3192     case 0:
3193     case 1:
3194       return output_387_reg_move (insn, operands);
3195
3196     case 2:
3197       return standard_80387_constant_opcode (operands[1]);
3198
3199     case 3:
3200     case 4:
3201       return "#";
3202
3203     case 5:
3204       switch (get_attr_mode (insn))
3205         {
3206         case MODE_V4SF:
3207           return "%vxorps\t%0, %d0";
3208         case MODE_V2DF:
3209           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3210             return "%vxorps\t%0, %d0";
3211           else
3212             return "%vxorpd\t%0, %d0";
3213         case MODE_TI:
3214           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3215             return "%vxorps\t%0, %d0";
3216           else
3217             return "%vpxor\t%0, %d0";
3218         default:
3219           gcc_unreachable ();
3220         }
3221     case 6:
3222     case 7:
3223     case 8:
3224       switch (get_attr_mode (insn))
3225         {
3226         case MODE_V4SF:
3227           return "%vmovaps\t{%1, %0|%0, %1}";
3228         case MODE_V2DF:
3229           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3230             return "%vmovaps\t{%1, %0|%0, %1}";
3231           else
3232             return "%vmovapd\t{%1, %0|%0, %1}";
3233         case MODE_TI:
3234           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3235             return "%vmovaps\t{%1, %0|%0, %1}";
3236           else
3237             return "%vmovdqa\t{%1, %0|%0, %1}";
3238         case MODE_DI:
3239           return "%vmovq\t{%1, %0|%0, %1}";
3240         case MODE_DF:
3241           if (TARGET_AVX)
3242             {
3243               if (REG_P (operands[0]) && REG_P (operands[1]))
3244                 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3245               else
3246                 return "vmovsd\t{%1, %0|%0, %1}";
3247             }
3248           else
3249             return "movsd\t{%1, %0|%0, %1}";
3250         case MODE_V1DF:
3251           if (TARGET_AVX)
3252             {
3253               if (REG_P (operands[0]))
3254                 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
3255               else
3256                 return "vmovlpd\t{%1, %0|%0, %1}";
3257             }
3258           else
3259             return "movlpd\t{%1, %0|%0, %1}";
3260         case MODE_V2SF:
3261           if (TARGET_AVX)
3262             {
3263               if (REG_P (operands[0]))
3264                 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
3265               else
3266                 return "vmovlps\t{%1, %0|%0, %1}";
3267             }
3268           else
3269             return "movlps\t{%1, %0|%0, %1}";
3270         default:
3271           gcc_unreachable ();
3272         }
3273
3274     default:
3275       gcc_unreachable ();
3276     }
3277 }
3278   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3279    (set (attr "prefix")
3280      (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3281        (const_string "orig")
3282        (const_string "maybe_vex")))
3283    (set (attr "prefix_data16")
3284      (if_then_else (eq_attr "mode" "V1DF")
3285        (const_string "1")
3286        (const_string "*")))
3287    (set (attr "mode")
3288         (cond [(eq_attr "alternative" "0,1,2")
3289                  (const_string "DF")
3290                (eq_attr "alternative" "3,4")
3291                  (const_string "SI")
3292
3293                /* For SSE1, we have many fewer alternatives.  */
3294                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3295                  (cond [(eq_attr "alternative" "5,6")
3296                           (const_string "V4SF")
3297                        ]
3298                    (const_string "V2SF"))
3299
3300                /* xorps is one byte shorter.  */
3301                (eq_attr "alternative" "5")
3302                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3303                             (const_int 0))
3304                           (const_string "V4SF")
3305                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3306                             (const_int 0))
3307                           (const_string "TI")
3308                        ]
3309                        (const_string "V2DF"))
3310
3311                /* For architectures resolving dependencies on
3312                   whole SSE registers use APD move to break dependency
3313                   chains, otherwise use short move to avoid extra work.
3314
3315                   movaps encodes one byte shorter.  */
3316                (eq_attr "alternative" "6")
3317                  (cond
3318                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3319                         (const_int 0))
3320                       (const_string "V4SF")
3321                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3322                         (const_int 0))
3323                       (const_string "V2DF")
3324                    ]
3325                    (const_string "DF"))
3326                /* For architectures resolving dependencies on register
3327                   parts we may avoid extra work to zero out upper part
3328                   of register.  */
3329                (eq_attr "alternative" "7")
3330                  (if_then_else
3331                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3332                        (const_int 0))
3333                    (const_string "V1DF")
3334                    (const_string "DF"))
3335               ]
3336               (const_string "DF")))])
3337
3338 (define_split
3339   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3340         (match_operand:DF 1 "general_operand" ""))]
3341   "reload_completed
3342    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3343    && ! (ANY_FP_REG_P (operands[0]) ||
3344          (GET_CODE (operands[0]) == SUBREG
3345           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3346    && ! (ANY_FP_REG_P (operands[1]) ||
3347          (GET_CODE (operands[1]) == SUBREG
3348           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3349   [(const_int 0)]
3350   "ix86_split_long_move (operands); DONE;")
3351
3352 (define_insn "*movsf_internal"
3353   [(set (match_operand:SF 0 "nonimmediate_operand"
3354           "=f,m,f,r  ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3355         (match_operand:SF 1 "general_operand"
3356           "fm,f,G,rmF,Fr,C,x,xm,x,m  ,*y,*y ,r  ,Yi,r   ,*Ym"))]
3357   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3358    && (reload_in_progress || reload_completed
3359        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3360        || (!TARGET_SSE_MATH && optimize_function_for_size_p (cfun)
3361            && standard_80387_constant_p (operands[1]))
3362        || GET_CODE (operands[1]) != CONST_DOUBLE
3363        || memory_operand (operands[0], SFmode))"
3364 {
3365   switch (which_alternative)
3366     {
3367     case 0:
3368     case 1:
3369       return output_387_reg_move (insn, operands);
3370
3371     case 2:
3372       return standard_80387_constant_opcode (operands[1]);
3373
3374     case 3:
3375     case 4:
3376       return "mov{l}\t{%1, %0|%0, %1}";
3377     case 5:
3378       if (get_attr_mode (insn) == MODE_TI)
3379         return "%vpxor\t%0, %d0";
3380       else
3381         return "%vxorps\t%0, %d0";
3382     case 6:
3383       if (get_attr_mode (insn) == MODE_V4SF)
3384         return "%vmovaps\t{%1, %0|%0, %1}";
3385       else
3386         return "%vmovss\t{%1, %d0|%d0, %1}";
3387     case 7:
3388       if (TARGET_AVX)
3389         return REG_P (operands[1]) ? "vmovss\t{%1, %0, %0|%0, %0, %1}"
3390                                    : "vmovss\t{%1, %0|%0, %1}";
3391       else
3392         return "movss\t{%1, %0|%0, %1}";
3393     case 8:
3394       return "%vmovss\t{%1, %0|%0, %1}";
3395
3396     case 9: case 10: case 14: case 15:
3397       return "movd\t{%1, %0|%0, %1}";
3398     case 12: case 13:
3399       return "%vmovd\t{%1, %0|%0, %1}";
3400
3401     case 11:
3402       return "movq\t{%1, %0|%0, %1}";
3403
3404     default:
3405       gcc_unreachable ();
3406     }
3407 }
3408   [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
3409    (set (attr "prefix")
3410      (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3411        (const_string "maybe_vex")
3412        (const_string "orig")))
3413    (set (attr "mode")
3414         (cond [(eq_attr "alternative" "3,4,9,10")
3415                  (const_string "SI")
3416                (eq_attr "alternative" "5")
3417                  (if_then_else
3418                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3419                                  (const_int 0))
3420                              (ne (symbol_ref "TARGET_SSE2")
3421                                  (const_int 0)))
3422                         (eq (symbol_ref "optimize_function_for_size_p (cfun)")
3423                             (const_int 0)))
3424                    (const_string "TI")
3425                    (const_string "V4SF"))
3426                /* For architectures resolving dependencies on
3427                   whole SSE registers use APS move to break dependency
3428                   chains, otherwise use short move to avoid extra work.
3429
3430                   Do the same for architectures resolving dependencies on
3431                   the parts.  While in DF mode it is better to always handle
3432                   just register parts, the SF mode is different due to lack
3433                   of instructions to load just part of the register.  It is
3434                   better to maintain the whole registers in single format
3435                   to avoid problems on using packed logical operations.  */
3436                (eq_attr "alternative" "6")
3437                  (if_then_else
3438                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3439                             (const_int 0))
3440                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3441                             (const_int 0)))
3442                    (const_string "V4SF")
3443                    (const_string "SF"))
3444                (eq_attr "alternative" "11")
3445                  (const_string "DI")]
3446                (const_string "SF")))])
3447
3448 (define_split
3449   [(set (match_operand 0 "register_operand" "")
3450         (match_operand 1 "memory_operand" ""))]
3451   "reload_completed
3452    && MEM_P (operands[1])
3453    && (GET_MODE (operands[0]) == TFmode
3454        || GET_MODE (operands[0]) == XFmode
3455        || GET_MODE (operands[0]) == DFmode
3456        || GET_MODE (operands[0]) == SFmode)
3457    && (operands[2] = find_constant_src (insn))"
3458   [(set (match_dup 0) (match_dup 2))]
3459 {
3460   rtx c = operands[2];
3461   rtx r = operands[0];
3462
3463   if (GET_CODE (r) == SUBREG)
3464     r = SUBREG_REG (r);
3465
3466   if (SSE_REG_P (r))
3467     {
3468       if (!standard_sse_constant_p (c))
3469         FAIL;
3470     }
3471   else if (FP_REG_P (r))
3472     {
3473       if (!standard_80387_constant_p (c))
3474         FAIL;
3475     }
3476   else if (MMX_REG_P (r))
3477     FAIL;
3478 })
3479
3480 (define_split
3481   [(set (match_operand 0 "register_operand" "")
3482         (float_extend (match_operand 1 "memory_operand" "")))]
3483   "reload_completed
3484    && MEM_P (operands[1])
3485    && (GET_MODE (operands[0]) == TFmode
3486        || GET_MODE (operands[0]) == XFmode
3487        || GET_MODE (operands[0]) == DFmode
3488        || GET_MODE (operands[0]) == SFmode)
3489    && (operands[2] = find_constant_src (insn))"
3490   [(set (match_dup 0) (match_dup 2))]
3491 {
3492   rtx c = operands[2];
3493   rtx r = operands[0];
3494
3495   if (GET_CODE (r) == SUBREG)
3496     r = SUBREG_REG (r);
3497
3498   if (SSE_REG_P (r))
3499     {
3500       if (!standard_sse_constant_p (c))
3501         FAIL;
3502     }
3503   else if (FP_REG_P (r))
3504     {
3505       if (!standard_80387_constant_p (c))
3506         FAIL;
3507     }
3508   else if (MMX_REG_P (r))
3509     FAIL;
3510 })
3511
3512 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3513 (define_split
3514   [(set (match_operand:X87MODEF 0 "register_operand" "")
3515         (match_operand:X87MODEF 1 "immediate_operand" ""))]
3516   "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3517    && (standard_80387_constant_p (operands[1]) == 8
3518        || standard_80387_constant_p (operands[1]) == 9)"
3519   [(set (match_dup 0)(match_dup 1))
3520    (set (match_dup 0)
3521         (neg:X87MODEF (match_dup 0)))]
3522 {
3523   REAL_VALUE_TYPE r;
3524
3525   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3526   if (real_isnegzero (&r))
3527     operands[1] = CONST0_RTX (<MODE>mode);
3528   else
3529     operands[1] = CONST1_RTX (<MODE>mode);
3530 })
3531
3532 (define_insn "swapxf"
3533   [(set (match_operand:XF 0 "register_operand" "+f")
3534         (match_operand:XF 1 "register_operand" "+f"))
3535    (set (match_dup 1)
3536         (match_dup 0))]
3537   "TARGET_80387"
3538 {
3539   if (STACK_TOP_P (operands[0]))
3540     return "fxch\t%1";
3541   else
3542     return "fxch\t%0";
3543 }
3544   [(set_attr "type" "fxch")
3545    (set_attr "mode" "XF")])
3546
3547 (define_insn "*swap<mode>"
3548   [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3549         (match_operand:MODEF 1 "fp_register_operand" "+f"))
3550    (set (match_dup 1)
3551         (match_dup 0))]
3552   "TARGET_80387 || reload_completed"
3553 {
3554   if (STACK_TOP_P (operands[0]))
3555     return "fxch\t%1";
3556   else
3557     return "fxch\t%0";
3558 }
3559   [(set_attr "type" "fxch")
3560    (set_attr "mode" "<MODE>")])
3561 \f
3562 ;; Zero extension instructions
3563
3564 (define_expand "zero_extendsidi2"
3565   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3566         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3567   ""
3568 {
3569   if (!TARGET_64BIT)
3570     {
3571       emit_insn (gen_zero_extendsidi2_1 (operands[0], operands[1]));
3572       DONE;
3573     }
3574 })
3575
3576 (define_insn "*zero_extendsidi2_rex64"
3577   [(set (match_operand:DI 0 "nonimmediate_operand"  "=r,o,?*Ym,?*y,?*Yi,*Y2")
3578         (zero_extend:DI
3579          (match_operand:SI 1 "nonimmediate_operand" "rm,0,r   ,m  ,r   ,m")))]
3580   "TARGET_64BIT"
3581   "@
3582    mov\t{%k1, %k0|%k0, %k1}
3583    #
3584    movd\t{%1, %0|%0, %1}
3585    movd\t{%1, %0|%0, %1}
3586    %vmovd\t{%1, %0|%0, %1}
3587    %vmovd\t{%1, %0|%0, %1}"
3588   [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3589    (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3590    (set_attr "prefix_0f" "0,*,*,*,*,*")
3591    (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3592
3593 (define_split
3594   [(set (match_operand:DI 0 "memory_operand" "")
3595         (zero_extend:DI (match_dup 0)))]
3596   "TARGET_64BIT"
3597   [(set (match_dup 4) (const_int 0))]
3598   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3599
3600 ;; %%% Kill me once multi-word ops are sane.
3601 (define_insn "zero_extendsidi2_1"
3602   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3603         (zero_extend:DI
3604          (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r   ,m  ,r   ,m")))
3605    (clobber (reg:CC FLAGS_REG))]
3606   "!TARGET_64BIT"
3607   "@
3608    #
3609    #
3610    #
3611    movd\t{%1, %0|%0, %1}
3612    movd\t{%1, %0|%0, %1}
3613    %vmovd\t{%1, %0|%0, %1}
3614    %vmovd\t{%1, %0|%0, %1}"
3615   [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3616    (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3617    (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3618
3619 (define_split
3620   [(set (match_operand:DI 0 "register_operand" "")
3621         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3622    (clobber (reg:CC FLAGS_REG))]
3623   "!TARGET_64BIT && reload_completed
3624    && true_regnum (operands[0]) == true_regnum (operands[1])"
3625   [(set (match_dup 4) (const_int 0))]
3626   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3627
3628 (define_split
3629   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3630         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3631    (clobber (reg:CC FLAGS_REG))]
3632   "!TARGET_64BIT && reload_completed
3633    && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3634   [(set (match_dup 3) (match_dup 1))
3635    (set (match_dup 4) (const_int 0))]
3636   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3637
3638 (define_insn "zero_extend<mode>di2"
3639   [(set (match_operand:DI 0 "register_operand" "=r")
3640         (zero_extend:DI
3641          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3642   "TARGET_64BIT"
3643   "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3644   [(set_attr "type" "imovx")
3645    (set_attr "mode" "SI")])
3646
3647 (define_expand "zero_extendhisi2"
3648   [(set (match_operand:SI 0 "register_operand" "")
3649         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3650   ""
3651 {
3652   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3653     {
3654       operands[1] = force_reg (HImode, operands[1]);
3655       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3656       DONE;
3657     }
3658 })
3659
3660 (define_insn_and_split "zero_extendhisi2_and"
3661   [(set (match_operand:SI 0 "register_operand" "=r")
3662         (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3663    (clobber (reg:CC FLAGS_REG))]
3664   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3665   "#"
3666   "&& reload_completed"
3667   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3668               (clobber (reg:CC FLAGS_REG))])]
3669   ""
3670   [(set_attr "type" "alu1")
3671    (set_attr "mode" "SI")])
3672
3673 (define_insn "*zero_extendhisi2_movzwl"
3674   [(set (match_operand:SI 0 "register_operand" "=r")
3675         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3676   "!TARGET_ZERO_EXTEND_WITH_AND
3677    || optimize_function_for_size_p (cfun)"
3678   "movz{wl|x}\t{%1, %0|%0, %1}"
3679   [(set_attr "type" "imovx")
3680    (set_attr "mode" "SI")])
3681
3682 (define_expand "zero_extendqi<mode>2"
3683   [(parallel
3684     [(set (match_operand:SWI24 0 "register_operand" "")
3685           (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3686      (clobber (reg:CC FLAGS_REG))])]
3687   ""
3688   "")
3689
3690 (define_insn "*zero_extendqi<mode>2_and"
3691   [(set (match_operand:SWI24 0 "register_operand" "=r,?&q")
3692         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3693    (clobber (reg:CC FLAGS_REG))]
3694   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3695   "#"
3696   [(set_attr "type" "alu1")
3697    (set_attr "mode" "<MODE>")])
3698
3699 ;; When source and destination does not overlap, clear destination
3700 ;; first and then do the movb
3701 (define_split
3702   [(set (match_operand:SWI24 0 "register_operand" "")
3703         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3704    (clobber (reg:CC FLAGS_REG))]
3705   "reload_completed
3706    && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3707    && ANY_QI_REG_P (operands[0])
3708    && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3709    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3710   [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3711 {
3712   operands[2] = gen_lowpart (QImode, operands[0]);
3713   ix86_expand_clear (operands[0]);
3714 })
3715
3716 (define_insn "*zero_extendqi<mode>2_movzbl_and"
3717   [(set (match_operand:SWI24 0 "register_operand" "=r,r")
3718         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3719    (clobber (reg:CC FLAGS_REG))]
3720   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3721   "#"
3722   [(set_attr "type" "imovx,alu1")
3723    (set_attr "mode" "<MODE>")])
3724
3725 ;; For the movzbl case strip only the clobber
3726 (define_split
3727   [(set (match_operand:SWI24 0 "register_operand" "")
3728         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3729    (clobber (reg:CC FLAGS_REG))]
3730   "reload_completed
3731    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3732    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3733   [(set (match_dup 0)
3734         (zero_extend:SWI24 (match_dup 1)))])
3735
3736 ; zero extend to SImode to avoid partial register stalls
3737 (define_insn "*zero_extendqi<mode>2_movzbl"
3738   [(set (match_operand:SWI24 0 "register_operand" "=r")
3739         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3740   "reload_completed
3741    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
3742   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3743   [(set_attr "type" "imovx")
3744    (set_attr "mode" "SI")])
3745
3746 ;; Rest is handled by single and.
3747 (define_split
3748   [(set (match_operand:SWI24 0 "register_operand" "")
3749         (zero_extend:SWI24 (match_operand:QI 1 "register_operand" "")))
3750    (clobber (reg:CC FLAGS_REG))]
3751   "reload_completed
3752    && true_regnum (operands[0]) == true_regnum (operands[1])"
3753   [(parallel [(set (match_dup 0) (and:SWI24 (match_dup 0) (const_int 255)))
3754               (clobber (reg:CC FLAGS_REG))])])
3755 \f
3756 ;; Sign extension instructions
3757
3758 (define_expand "extendsidi2"
3759   [(set (match_operand:DI 0 "register_operand" "")
3760         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3761   ""
3762 {
3763   if (!TARGET_64BIT)
3764     {
3765       emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3766       DONE;
3767     }
3768 })
3769
3770 (define_insn "*extendsidi2_rex64"
3771   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3772         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3773   "TARGET_64BIT"
3774   "@
3775    {cltq|cdqe}
3776    movs{lq|x}\t{%1, %0|%0, %1}"
3777   [(set_attr "type" "imovx")
3778    (set_attr "mode" "DI")
3779    (set_attr "prefix_0f" "0")
3780    (set_attr "modrm" "0,1")])
3781
3782 (define_insn "extendsidi2_1"
3783   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3784         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3785    (clobber (reg:CC FLAGS_REG))
3786    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3787   "!TARGET_64BIT"
3788   "#")
3789
3790 ;; Extend to memory case when source register does die.
3791 (define_split
3792   [(set (match_operand:DI 0 "memory_operand" "")
3793         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3794    (clobber (reg:CC FLAGS_REG))
3795    (clobber (match_operand:SI 2 "register_operand" ""))]
3796   "(reload_completed
3797     && dead_or_set_p (insn, operands[1])
3798     && !reg_mentioned_p (operands[1], operands[0]))"
3799   [(set (match_dup 3) (match_dup 1))
3800    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3801               (clobber (reg:CC FLAGS_REG))])
3802    (set (match_dup 4) (match_dup 1))]
3803   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3804
3805 ;; Extend to memory case when source register does not die.
3806 (define_split
3807   [(set (match_operand:DI 0 "memory_operand" "")
3808         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3809    (clobber (reg:CC FLAGS_REG))
3810    (clobber (match_operand:SI 2 "register_operand" ""))]
3811   "reload_completed"
3812   [(const_int 0)]
3813 {
3814   split_di (&operands[0], 1, &operands[3], &operands[4]);
3815
3816   emit_move_insn (operands[3], operands[1]);
3817
3818   /* Generate a cltd if possible and doing so it profitable.  */
3819   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3820       && true_regnum (operands[1]) == AX_REG
3821       && true_regnum (operands[2]) == DX_REG)
3822     {
3823       emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3824     }
3825   else
3826     {
3827       emit_move_insn (operands[2], operands[1]);
3828       emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3829     }
3830   emit_move_insn (operands[4], operands[2]);
3831   DONE;
3832 })
3833
3834 ;; Extend to register case.  Optimize case where source and destination
3835 ;; registers match and cases where we can use cltd.
3836 (define_split
3837   [(set (match_operand:DI 0 "register_operand" "")
3838         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3839    (clobber (reg:CC FLAGS_REG))
3840    (clobber (match_scratch:SI 2 ""))]
3841   "reload_completed"
3842   [(const_int 0)]
3843 {
3844   split_di (&operands[0], 1, &operands[3], &operands[4]);
3845
3846   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3847     emit_move_insn (operands[3], operands[1]);
3848
3849   /* Generate a cltd if possible and doing so it profitable.  */
3850   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3851       && true_regnum (operands[3]) == AX_REG
3852       && true_regnum (operands[4]) == DX_REG)
3853     {
3854       emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3855       DONE;
3856     }
3857
3858   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3859     emit_move_insn (operands[4], operands[1]);
3860
3861   emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3862   DONE;
3863 })
3864
3865 (define_insn "extend<mode>di2"
3866   [(set (match_operand:DI 0 "register_operand" "=r")
3867         (sign_extend:DI
3868          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3869   "TARGET_64BIT"
3870   "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3871   [(set_attr "type" "imovx")
3872    (set_attr "mode" "DI")])
3873
3874 (define_insn "extendhisi2"
3875   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3876         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3877   ""
3878 {
3879   switch (get_attr_prefix_0f (insn))
3880     {
3881     case 0:
3882       return "{cwtl|cwde}";
3883     default:
3884       return "movs{wl|x}\t{%1, %0|%0, %1}";
3885     }
3886 }
3887   [(set_attr "type" "imovx")
3888    (set_attr "mode" "SI")
3889    (set (attr "prefix_0f")
3890      ;; movsx is short decodable while cwtl is vector decoded.
3891      (if_then_else (and (eq_attr "cpu" "!k6")
3892                         (eq_attr "alternative" "0"))
3893         (const_string "0")
3894         (const_string "1")))
3895    (set (attr "modrm")
3896      (if_then_else (eq_attr "prefix_0f" "0")
3897         (const_string "0")
3898         (const_string "1")))])
3899
3900 (define_insn "*extendhisi2_zext"
3901   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3902         (zero_extend:DI
3903          (sign_extend:SI
3904           (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3905   "TARGET_64BIT"
3906 {
3907   switch (get_attr_prefix_0f (insn))
3908     {
3909     case 0:
3910       return "{cwtl|cwde}";
3911     default:
3912       return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3913     }
3914 }
3915   [(set_attr "type" "imovx")
3916    (set_attr "mode" "SI")
3917    (set (attr "prefix_0f")
3918      ;; movsx is short decodable while cwtl is vector decoded.
3919      (if_then_else (and (eq_attr "cpu" "!k6")
3920                         (eq_attr "alternative" "0"))
3921         (const_string "0")
3922         (const_string "1")))
3923    (set (attr "modrm")
3924      (if_then_else (eq_attr "prefix_0f" "0")
3925         (const_string "0")
3926         (const_string "1")))])
3927
3928 (define_insn "extendqisi2"
3929   [(set (match_operand:SI 0 "register_operand" "=r")
3930         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3931   ""
3932   "movs{bl|x}\t{%1, %0|%0, %1}"
3933    [(set_attr "type" "imovx")
3934     (set_attr "mode" "SI")])
3935
3936 (define_insn "*extendqisi2_zext"
3937   [(set (match_operand:DI 0 "register_operand" "=r")
3938         (zero_extend:DI
3939           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3940   "TARGET_64BIT"
3941   "movs{bl|x}\t{%1, %k0|%k0, %1}"
3942    [(set_attr "type" "imovx")
3943     (set_attr "mode" "SI")])
3944
3945 (define_insn "extendqihi2"
3946   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3947         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3948   ""
3949 {
3950   switch (get_attr_prefix_0f (insn))
3951     {
3952     case 0:
3953       return "{cbtw|cbw}";
3954     default:
3955       return "movs{bw|x}\t{%1, %0|%0, %1}";
3956     }
3957 }
3958   [(set_attr "type" "imovx")
3959    (set_attr "mode" "HI")
3960    (set (attr "prefix_0f")
3961      ;; movsx is short decodable while cwtl is vector decoded.
3962      (if_then_else (and (eq_attr "cpu" "!k6")
3963                         (eq_attr "alternative" "0"))
3964         (const_string "0")
3965         (const_string "1")))
3966    (set (attr "modrm")
3967      (if_then_else (eq_attr "prefix_0f" "0")
3968         (const_string "0")
3969         (const_string "1")))])
3970 \f
3971 ;; Conversions between float and double.
3972
3973 ;; These are all no-ops in the model used for the 80387.
3974 ;; So just emit moves.
3975
3976 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3977 (define_split
3978   [(set (match_operand:DF 0 "push_operand" "")
3979         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3980   "reload_completed"
3981   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3982    (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3983
3984 (define_split
3985   [(set (match_operand:XF 0 "push_operand" "")
3986         (float_extend:XF (match_operand:MODEF 1 "fp_register_operand" "")))]
3987   "reload_completed"
3988   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3989    (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3990   "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3991
3992 (define_expand "extendsfdf2"
3993   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3994         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3995   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3996 {
3997   /* ??? Needed for compress_float_constant since all fp constants
3998      are LEGITIMATE_CONSTANT_P.  */
3999   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4000     {
4001       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4002           && standard_80387_constant_p (operands[1]) > 0)
4003         {
4004           operands[1] = simplify_const_unary_operation
4005             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4006           emit_move_insn_1 (operands[0], operands[1]);
4007           DONE;
4008         }
4009       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4010     }
4011 })
4012
4013 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4014    cvtss2sd:
4015       unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4016       cvtps2pd xmm2,xmm1
4017    We do the conversion post reload to avoid producing of 128bit spills
4018    that might lead to ICE on 32bit target.  The sequence unlikely combine
4019    anyway.  */
4020 (define_split
4021   [(set (match_operand:DF 0 "register_operand" "")
4022         (float_extend:DF
4023           (match_operand:SF 1 "nonimmediate_operand" "")))]
4024   "TARGET_USE_VECTOR_FP_CONVERTS
4025    && optimize_insn_for_speed_p ()
4026    && reload_completed && SSE_REG_P (operands[0])"
4027    [(set (match_dup 2)
4028          (float_extend:V2DF
4029            (vec_select:V2SF
4030              (match_dup 3)
4031              (parallel [(const_int 0) (const_int 1)]))))]
4032 {
4033   operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4034   operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4035   /* Use movss for loading from memory, unpcklps reg, reg for registers.
4036      Try to avoid move when unpacking can be done in source.  */
4037   if (REG_P (operands[1]))
4038     {
4039       /* If it is unsafe to overwrite upper half of source, we need
4040          to move to destination and unpack there.  */
4041       if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4042            || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4043           && true_regnum (operands[0]) != true_regnum (operands[1]))
4044         {
4045           rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4046           emit_move_insn (tmp, operands[1]);
4047         }
4048       else
4049         operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4050       emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4051                                              operands[3]));
4052     }
4053   else
4054     emit_insn (gen_vec_setv4sf_0 (operands[3],
4055                                   CONST0_RTX (V4SFmode), operands[1]));
4056 })
4057
4058 (define_insn "*extendsfdf2_mixed"
4059   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4060         (float_extend:DF
4061           (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4062   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4063 {
4064   switch (which_alternative)
4065     {
4066     case 0:
4067     case 1:
4068       return output_387_reg_move (insn, operands);
4069
4070     case 2:
4071       return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4072
4073     default:
4074       gcc_unreachable ();
4075     }
4076 }
4077   [(set_attr "type" "fmov,fmov,ssecvt")
4078    (set_attr "prefix" "orig,orig,maybe_vex")
4079    (set_attr "mode" "SF,XF,DF")])
4080
4081 (define_insn "*extendsfdf2_sse"
4082   [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4083         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4084   "TARGET_SSE2 && TARGET_SSE_MATH"
4085   "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4086   [(set_attr "type" "ssecvt")
4087    (set_attr "prefix" "maybe_vex")
4088    (set_attr "mode" "DF")])
4089
4090 (define_insn "*extendsfdf2_i387"
4091   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4092         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4093   "TARGET_80387"
4094   "* return output_387_reg_move (insn, operands);"
4095   [(set_attr "type" "fmov")
4096    (set_attr "mode" "SF,XF")])
4097
4098 (define_expand "extend<mode>xf2"
4099   [(set (match_operand:XF 0 "nonimmediate_operand" "")
4100         (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4101   "TARGET_80387"
4102 {
4103   /* ??? Needed for compress_float_constant since all fp constants
4104      are LEGITIMATE_CONSTANT_P.  */
4105   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4106     {
4107       if (standard_80387_constant_p (operands[1]) > 0)
4108         {
4109           operands[1] = simplify_const_unary_operation
4110             (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4111           emit_move_insn_1 (operands[0], operands[1]);
4112           DONE;
4113         }
4114       operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4115     }
4116 })
4117
4118 (define_insn "*extend<mode>xf2_i387"
4119   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4120         (float_extend:XF
4121           (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4122   "TARGET_80387"
4123   "* return output_387_reg_move (insn, operands);"
4124   [(set_attr "type" "fmov")
4125    (set_attr "mode" "<MODE>,XF")])
4126
4127 ;; %%% This seems bad bad news.
4128 ;; This cannot output into an f-reg because there is no way to be sure
4129 ;; of truncating in that case.  Otherwise this is just like a simple move
4130 ;; insn.  So we pretend we can output to a reg in order to get better
4131 ;; register preferencing, but we really use a stack slot.
4132
4133 ;; Conversion from DFmode to SFmode.
4134
4135 (define_expand "truncdfsf2"
4136   [(set (match_operand:SF 0 "nonimmediate_operand" "")
4137         (float_truncate:SF
4138           (match_operand:DF 1 "nonimmediate_operand" "")))]
4139   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4140 {
4141   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4142     ;
4143   else if (flag_unsafe_math_optimizations)
4144     ;
4145   else
4146     {
4147       enum ix86_stack_slot slot = (virtuals_instantiated
4148                                    ? SLOT_TEMP
4149                                    : SLOT_VIRTUAL);
4150       rtx temp = assign_386_stack_local (SFmode, slot);
4151       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4152       DONE;
4153     }
4154 })
4155
4156 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4157    cvtsd2ss:
4158       unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4159       cvtpd2ps 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:SF 0 "register_operand" "")
4165         (float_truncate:SF
4166           (match_operand:DF 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          (vec_concat:V4SF
4172            (float_truncate:V2SF
4173              (match_dup 4))
4174            (match_dup 3)))]
4175 {
4176   operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4177   operands[3] = CONST0_RTX (V2SFmode);
4178   operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4179   /* Use movsd for loading from memory, unpcklpd for registers.
4180      Try to avoid move when unpacking can be done in source, or SSE3
4181      movddup is available.  */
4182   if (REG_P (operands[1]))
4183     {
4184       if (!TARGET_SSE3
4185           && true_regnum (operands[0]) != true_regnum (operands[1])
4186           && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4187               || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4188         {
4189           rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4190           emit_move_insn (tmp, operands[1]);
4191           operands[1] = tmp;
4192         }
4193       else if (!TARGET_SSE3)
4194         operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4195       emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4196     }
4197   else
4198     emit_insn (gen_sse2_loadlpd (operands[4],
4199                                  CONST0_RTX (V2DFmode), operands[1]));
4200 })
4201
4202 (define_expand "truncdfsf2_with_temp"
4203   [(parallel [(set (match_operand:SF 0 "" "")
4204                    (float_truncate:SF (match_operand:DF 1 "" "")))
4205               (clobber (match_operand:SF 2 "" ""))])]
4206   "")
4207
4208 (define_insn "*truncdfsf_fast_mixed"
4209   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm,x")
4210         (float_truncate:SF
4211           (match_operand:DF 1 "nonimmediate_operand" "f  ,xm")))]
4212   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4213 {
4214   switch (which_alternative)
4215     {
4216     case 0:
4217       return output_387_reg_move (insn, operands);
4218     case 1:
4219       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4220     default:
4221       gcc_unreachable ();
4222     }
4223 }
4224   [(set_attr "type" "fmov,ssecvt")
4225    (set_attr "prefix" "orig,maybe_vex")
4226    (set_attr "mode" "SF")])
4227
4228 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4229 ;; because nothing we do here is unsafe.
4230 (define_insn "*truncdfsf_fast_sse"
4231   [(set (match_operand:SF 0 "nonimmediate_operand"   "=x")
4232         (float_truncate:SF
4233           (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4234   "TARGET_SSE2 && TARGET_SSE_MATH"
4235   "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4236   [(set_attr "type" "ssecvt")
4237    (set_attr "prefix" "maybe_vex")
4238    (set_attr "mode" "SF")])
4239
4240 (define_insn "*truncdfsf_fast_i387"
4241   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
4242         (float_truncate:SF
4243           (match_operand:DF 1 "nonimmediate_operand" "f")))]
4244   "TARGET_80387 && flag_unsafe_math_optimizations"
4245   "* return output_387_reg_move (insn, operands);"
4246   [(set_attr "type" "fmov")
4247    (set_attr "mode" "SF")])
4248
4249 (define_insn "*truncdfsf_mixed"
4250   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,Y2 ,?f,?x,?*r")
4251         (float_truncate:SF
4252           (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4253    (clobber (match_operand:SF 2 "memory_operand"     "=X,X  ,m ,m ,m"))]
4254   "TARGET_MIX_SSE_I387"
4255 {
4256   switch (which_alternative)
4257     {
4258     case 0:
4259       return output_387_reg_move (insn, operands);
4260     case 1:
4261       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4262
4263     default:
4264       return "#";
4265     }
4266 }
4267   [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4268    (set_attr "unit" "*,*,i387,i387,i387")
4269    (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4270    (set_attr "mode" "SF")])
4271
4272 (define_insn "*truncdfsf_i387"
4273   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?f,?x,?*r")
4274         (float_truncate:SF
4275           (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4276    (clobber (match_operand:SF 2 "memory_operand"     "=X,m ,m ,m"))]
4277   "TARGET_80387"
4278 {
4279   switch (which_alternative)
4280     {
4281     case 0:
4282       return output_387_reg_move (insn, operands);
4283
4284     default:
4285       return "#";
4286     }
4287 }
4288   [(set_attr "type" "fmov,multi,multi,multi")
4289    (set_attr "unit" "*,i387,i387,i387")
4290    (set_attr "mode" "SF")])
4291
4292 (define_insn "*truncdfsf2_i387_1"
4293   [(set (match_operand:SF 0 "memory_operand" "=m")
4294         (float_truncate:SF
4295           (match_operand:DF 1 "register_operand" "f")))]
4296   "TARGET_80387
4297    && !(TARGET_SSE2 && TARGET_SSE_MATH)
4298    && !TARGET_MIX_SSE_I387"
4299   "* return output_387_reg_move (insn, operands);"
4300   [(set_attr "type" "fmov")
4301    (set_attr "mode" "SF")])
4302
4303 (define_split
4304   [(set (match_operand:SF 0 "register_operand" "")
4305         (float_truncate:SF
4306          (match_operand:DF 1 "fp_register_operand" "")))
4307    (clobber (match_operand 2 "" ""))]
4308   "reload_completed"
4309   [(set (match_dup 2) (match_dup 1))
4310    (set (match_dup 0) (match_dup 2))]
4311   "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4312
4313 ;; Conversion from XFmode to {SF,DF}mode
4314
4315 (define_expand "truncxf<mode>2"
4316   [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4317                    (float_truncate:MODEF
4318                      (match_operand:XF 1 "register_operand" "")))
4319               (clobber (match_dup 2))])]
4320   "TARGET_80387"
4321 {
4322   if (flag_unsafe_math_optimizations)
4323     {
4324       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4325       emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4326       if (reg != operands[0])
4327         emit_move_insn (operands[0], reg);
4328       DONE;
4329     }
4330   else
4331     {
4332      enum ix86_stack_slot slot = (virtuals_instantiated
4333                                   ? SLOT_TEMP
4334                                   : SLOT_VIRTUAL);
4335       operands[2] = assign_386_stack_local (<MODE>mode, slot);
4336     }
4337 })
4338
4339 (define_insn "*truncxfsf2_mixed"
4340   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4341         (float_truncate:SF
4342           (match_operand:XF 1 "register_operand"   "f ,f ,f ,f")))
4343    (clobber (match_operand:SF 2 "memory_operand"   "=X,m ,m ,m"))]
4344   "TARGET_80387"
4345 {
4346   gcc_assert (!which_alternative);
4347   return output_387_reg_move (insn, operands);
4348 }
4349   [(set_attr "type" "fmov,multi,multi,multi")
4350    (set_attr "unit" "*,i387,i387,i387")
4351    (set_attr "mode" "SF")])
4352
4353 (define_insn "*truncxfdf2_mixed"
4354   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4355         (float_truncate:DF
4356           (match_operand:XF 1 "register_operand"   "f ,f ,f  ,f")))
4357    (clobber (match_operand:DF 2 "memory_operand"   "=X,m ,m  ,m"))]
4358   "TARGET_80387"
4359 {
4360   gcc_assert (!which_alternative);
4361   return output_387_reg_move (insn, operands);
4362 }
4363   [(set_attr "type" "fmov,multi,multi,multi")
4364    (set_attr "unit" "*,i387,i387,i387")
4365    (set_attr "mode" "DF")])
4366
4367 (define_insn "truncxf<mode>2_i387_noop"
4368   [(set (match_operand:MODEF 0 "register_operand" "=f")
4369         (float_truncate:MODEF
4370           (match_operand:XF 1 "register_operand" "f")))]
4371   "TARGET_80387 && flag_unsafe_math_optimizations"
4372   "* return output_387_reg_move (insn, operands);"
4373   [(set_attr "type" "fmov")
4374    (set_attr "mode" "<MODE>")])
4375
4376 (define_insn "*truncxf<mode>2_i387"
4377   [(set (match_operand:MODEF 0 "memory_operand" "=m")
4378         (float_truncate:MODEF
4379           (match_operand:XF 1 "register_operand" "f")))]
4380   "TARGET_80387"
4381   "* return output_387_reg_move (insn, operands);"
4382   [(set_attr "type" "fmov")
4383    (set_attr "mode" "<MODE>")])
4384
4385 (define_split
4386   [(set (match_operand:MODEF 0 "register_operand" "")
4387         (float_truncate:MODEF
4388           (match_operand:XF 1 "register_operand" "")))
4389    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4390   "TARGET_80387 && reload_completed"
4391   [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4392    (set (match_dup 0) (match_dup 2))])
4393
4394 (define_split
4395   [(set (match_operand:MODEF 0 "memory_operand" "")
4396         (float_truncate:MODEF
4397           (match_operand:XF 1 "register_operand" "")))
4398    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4399   "TARGET_80387"
4400   [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4401 \f
4402 ;; Signed conversion to DImode.
4403
4404 (define_expand "fix_truncxfdi2"
4405   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4406                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4407               (clobber (reg:CC FLAGS_REG))])]
4408   "TARGET_80387"
4409 {
4410   if (TARGET_FISTTP)
4411    {
4412      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4413      DONE;
4414    }
4415 })
4416
4417 (define_expand "fix_trunc<mode>di2"
4418   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4419                    (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4420               (clobber (reg:CC FLAGS_REG))])]
4421   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4422 {
4423   if (TARGET_FISTTP
4424       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4425    {
4426      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4427      DONE;
4428    }
4429   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4430    {
4431      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4432      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4433      if (out != operands[0])
4434         emit_move_insn (operands[0], out);
4435      DONE;
4436    }
4437 })
4438
4439 ;; Signed conversion to SImode.
4440
4441 (define_expand "fix_truncxfsi2"
4442   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4443                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4444               (clobber (reg:CC FLAGS_REG))])]
4445   "TARGET_80387"
4446 {
4447   if (TARGET_FISTTP)
4448    {
4449      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4450      DONE;
4451    }
4452 })
4453
4454 (define_expand "fix_trunc<mode>si2"
4455   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4456                    (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4457               (clobber (reg:CC FLAGS_REG))])]
4458   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4459 {
4460   if (TARGET_FISTTP
4461       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4462    {
4463      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4464      DONE;
4465    }
4466   if (SSE_FLOAT_MODE_P (<MODE>mode))
4467    {
4468      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4469      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4470      if (out != operands[0])
4471         emit_move_insn (operands[0], out);
4472      DONE;
4473    }
4474 })
4475
4476 ;; Signed conversion to HImode.
4477
4478 (define_expand "fix_trunc<mode>hi2"
4479   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4480                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4481               (clobber (reg:CC FLAGS_REG))])]
4482   "TARGET_80387
4483    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4484 {
4485   if (TARGET_FISTTP)
4486    {
4487      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4488      DONE;
4489    }
4490 })
4491
4492 ;; Unsigned conversion to SImode.
4493
4494 (define_expand "fixuns_trunc<mode>si2"
4495   [(parallel
4496     [(set (match_operand:SI 0 "register_operand" "")
4497           (unsigned_fix:SI
4498             (match_operand:MODEF 1 "nonimmediate_operand" "")))
4499      (use (match_dup 2))
4500      (clobber (match_scratch:<ssevecmode> 3 ""))
4501      (clobber (match_scratch:<ssevecmode> 4 ""))])]
4502   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4503 {
4504   enum machine_mode mode = <MODE>mode;
4505   enum machine_mode vecmode = <ssevecmode>mode;
4506   REAL_VALUE_TYPE TWO31r;
4507   rtx two31;
4508
4509   if (optimize_insn_for_size_p ())
4510     FAIL;
4511
4512   real_ldexp (&TWO31r, &dconst1, 31);
4513   two31 = const_double_from_real_value (TWO31r, mode);
4514   two31 = ix86_build_const_vector (mode, true, two31);
4515   operands[2] = force_reg (vecmode, two31);
4516 })
4517
4518 (define_insn_and_split "*fixuns_trunc<mode>_1"
4519   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4520         (unsigned_fix:SI
4521           (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4522    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
4523    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4524    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4525   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4526    && optimize_function_for_speed_p (cfun)"
4527   "#"
4528   "&& reload_completed"
4529   [(const_int 0)]
4530 {
4531   ix86_split_convert_uns_si_sse (operands);
4532   DONE;
4533 })
4534
4535 ;; Unsigned conversion to HImode.
4536 ;; Without these patterns, we'll try the unsigned SI conversion which
4537 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4538
4539 (define_expand "fixuns_trunc<mode>hi2"
4540   [(set (match_dup 2)
4541         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4542    (set (match_operand:HI 0 "nonimmediate_operand" "")
4543         (subreg:HI (match_dup 2) 0))]
4544   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4545   "operands[2] = gen_reg_rtx (SImode);")
4546
4547 ;; When SSE is available, it is always faster to use it!
4548 (define_insn "fix_trunc<mode>di_sse"
4549   [(set (match_operand:DI 0 "register_operand" "=r,r")
4550         (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4551   "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4552    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4553   "%vcvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4554   [(set_attr "type" "sseicvt")
4555    (set_attr "prefix" "maybe_vex")
4556    (set_attr "prefix_rex" "1")
4557    (set_attr "mode" "<MODE>")
4558    (set_attr "athlon_decode" "double,vector")
4559    (set_attr "amdfam10_decode" "double,double")])
4560
4561 (define_insn "fix_trunc<mode>si_sse"
4562   [(set (match_operand:SI 0 "register_operand" "=r,r")
4563         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4564   "SSE_FLOAT_MODE_P (<MODE>mode)
4565    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4566   "%vcvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4567   [(set_attr "type" "sseicvt")
4568    (set_attr "prefix" "maybe_vex")
4569    (set_attr "mode" "<MODE>")
4570    (set_attr "athlon_decode" "double,vector")
4571    (set_attr "amdfam10_decode" "double,double")])
4572
4573 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4574 (define_peephole2
4575   [(set (match_operand:MODEF 0 "register_operand" "")
4576         (match_operand:MODEF 1 "memory_operand" ""))
4577    (set (match_operand:SSEMODEI24 2 "register_operand" "")
4578         (fix:SSEMODEI24 (match_dup 0)))]
4579   "TARGET_SHORTEN_X87_SSE
4580    && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4581    && peep2_reg_dead_p (2, operands[0])"
4582   [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))])
4583
4584 ;; Avoid vector decoded forms of the instruction.
4585 (define_peephole2
4586   [(match_scratch:DF 2 "Y2")
4587    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4588         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4589   "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4590   [(set (match_dup 2) (match_dup 1))
4591    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))])
4592
4593 (define_peephole2
4594   [(match_scratch:SF 2 "x")
4595    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4596         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4597   "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4598   [(set (match_dup 2) (match_dup 1))
4599    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))])
4600
4601 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4602   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4603         (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4604   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4605    && TARGET_FISTTP
4606    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4607          && (TARGET_64BIT || <MODE>mode != DImode))
4608         && TARGET_SSE_MATH)
4609    && can_create_pseudo_p ()"
4610   "#"
4611   "&& 1"
4612   [(const_int 0)]
4613 {
4614   if (memory_operand (operands[0], VOIDmode))
4615     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4616   else
4617     {
4618       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4619       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4620                                                             operands[1],
4621                                                             operands[2]));
4622     }
4623   DONE;
4624 }
4625   [(set_attr "type" "fisttp")
4626    (set_attr "mode" "<MODE>")])
4627
4628 (define_insn "fix_trunc<mode>_i387_fisttp"
4629   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4630         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4631    (clobber (match_scratch:XF 2 "=&1f"))]
4632   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4633    && TARGET_FISTTP
4634    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4635          && (TARGET_64BIT || <MODE>mode != DImode))
4636         && TARGET_SSE_MATH)"
4637   "* return output_fix_trunc (insn, operands, 1);"
4638   [(set_attr "type" "fisttp")
4639    (set_attr "mode" "<MODE>")])
4640
4641 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4642   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4643         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4644    (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
4645    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4646   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4647    && TARGET_FISTTP
4648    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4649         && (TARGET_64BIT || <MODE>mode != DImode))
4650         && TARGET_SSE_MATH)"
4651   "#"
4652   [(set_attr "type" "fisttp")
4653    (set_attr "mode" "<MODE>")])
4654
4655 (define_split
4656   [(set (match_operand:X87MODEI 0 "register_operand" "")
4657         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4658    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4659    (clobber (match_scratch 3 ""))]
4660   "reload_completed"
4661   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4662               (clobber (match_dup 3))])
4663    (set (match_dup 0) (match_dup 2))])
4664
4665 (define_split
4666   [(set (match_operand:X87MODEI 0 "memory_operand" "")
4667         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4668    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4669    (clobber (match_scratch 3 ""))]
4670   "reload_completed"
4671   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4672               (clobber (match_dup 3))])])
4673
4674 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4675 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4676 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4677 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4678 ;; function in i386.c.
4679 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4680   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4681         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4682    (clobber (reg:CC FLAGS_REG))]
4683   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4684    && !TARGET_FISTTP
4685    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4686          && (TARGET_64BIT || <MODE>mode != DImode))
4687    && can_create_pseudo_p ()"
4688   "#"
4689   "&& 1"
4690   [(const_int 0)]
4691 {
4692   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4693
4694   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4695   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4696   if (memory_operand (operands[0], VOIDmode))
4697     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4698                                          operands[2], operands[3]));
4699   else
4700     {
4701       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4702       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4703                                                      operands[2], operands[3],
4704                                                      operands[4]));
4705     }
4706   DONE;
4707 }
4708   [(set_attr "type" "fistp")
4709    (set_attr "i387_cw" "trunc")
4710    (set_attr "mode" "<MODE>")])
4711
4712 (define_insn "fix_truncdi_i387"
4713   [(set (match_operand:DI 0 "memory_operand" "=m")
4714         (fix:DI (match_operand 1 "register_operand" "f")))
4715    (use (match_operand:HI 2 "memory_operand" "m"))
4716    (use (match_operand:HI 3 "memory_operand" "m"))
4717    (clobber (match_scratch:XF 4 "=&1f"))]
4718   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4719    && !TARGET_FISTTP
4720    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4721   "* return output_fix_trunc (insn, operands, 0);"
4722   [(set_attr "type" "fistp")
4723    (set_attr "i387_cw" "trunc")
4724    (set_attr "mode" "DI")])
4725
4726 (define_insn "fix_truncdi_i387_with_temp"
4727   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4728         (fix:DI (match_operand 1 "register_operand" "f,f")))
4729    (use (match_operand:HI 2 "memory_operand" "m,m"))
4730    (use (match_operand:HI 3 "memory_operand" "m,m"))
4731    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4732    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4733   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4734    && !TARGET_FISTTP
4735    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4736   "#"
4737   [(set_attr "type" "fistp")
4738    (set_attr "i387_cw" "trunc")
4739    (set_attr "mode" "DI")])
4740
4741 (define_split
4742   [(set (match_operand:DI 0 "register_operand" "")
4743         (fix:DI (match_operand 1 "register_operand" "")))
4744    (use (match_operand:HI 2 "memory_operand" ""))
4745    (use (match_operand:HI 3 "memory_operand" ""))
4746    (clobber (match_operand:DI 4 "memory_operand" ""))
4747    (clobber (match_scratch 5 ""))]
4748   "reload_completed"
4749   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4750               (use (match_dup 2))
4751               (use (match_dup 3))
4752               (clobber (match_dup 5))])
4753    (set (match_dup 0) (match_dup 4))])
4754
4755 (define_split
4756   [(set (match_operand:DI 0 "memory_operand" "")
4757         (fix:DI (match_operand 1 "register_operand" "")))
4758    (use (match_operand:HI 2 "memory_operand" ""))
4759    (use (match_operand:HI 3 "memory_operand" ""))
4760    (clobber (match_operand:DI 4 "memory_operand" ""))
4761    (clobber (match_scratch 5 ""))]
4762   "reload_completed"
4763   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4764               (use (match_dup 2))
4765               (use (match_dup 3))
4766               (clobber (match_dup 5))])])
4767
4768 (define_insn "fix_trunc<mode>_i387"
4769   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4770         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4771    (use (match_operand:HI 2 "memory_operand" "m"))
4772    (use (match_operand:HI 3 "memory_operand" "m"))]
4773   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4774    && !TARGET_FISTTP
4775    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4776   "* return output_fix_trunc (insn, operands, 0);"
4777   [(set_attr "type" "fistp")
4778    (set_attr "i387_cw" "trunc")
4779    (set_attr "mode" "<MODE>")])
4780
4781 (define_insn "fix_trunc<mode>_i387_with_temp"
4782   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4783         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4784    (use (match_operand:HI 2 "memory_operand" "m,m"))
4785    (use (match_operand:HI 3 "memory_operand" "m,m"))
4786    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
4787   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4788    && !TARGET_FISTTP
4789    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4790   "#"
4791   [(set_attr "type" "fistp")
4792    (set_attr "i387_cw" "trunc")
4793    (set_attr "mode" "<MODE>")])
4794
4795 (define_split
4796   [(set (match_operand:X87MODEI12 0 "register_operand" "")
4797         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4798    (use (match_operand:HI 2 "memory_operand" ""))
4799    (use (match_operand:HI 3 "memory_operand" ""))
4800    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4801   "reload_completed"
4802   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4803               (use (match_dup 2))
4804               (use (match_dup 3))])
4805    (set (match_dup 0) (match_dup 4))])
4806
4807 (define_split
4808   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4809         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4810    (use (match_operand:HI 2 "memory_operand" ""))
4811    (use (match_operand:HI 3 "memory_operand" ""))
4812    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4813   "reload_completed"
4814   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4815               (use (match_dup 2))
4816               (use (match_dup 3))])])
4817
4818 (define_insn "x86_fnstcw_1"
4819   [(set (match_operand:HI 0 "memory_operand" "=m")
4820         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4821   "TARGET_80387"
4822   "fnstcw\t%0"
4823   [(set (attr "length")
4824         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4825    (set_attr "mode" "HI")
4826    (set_attr "unit" "i387")])
4827
4828 (define_insn "x86_fldcw_1"
4829   [(set (reg:HI FPCR_REG)
4830         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4831   "TARGET_80387"
4832   "fldcw\t%0"
4833   [(set (attr "length")
4834         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4835    (set_attr "mode" "HI")
4836    (set_attr "unit" "i387")
4837    (set_attr "athlon_decode" "vector")
4838    (set_attr "amdfam10_decode" "vector")])
4839 \f
4840 ;; Conversion between fixed point and floating point.
4841
4842 ;; Even though we only accept memory inputs, the backend _really_
4843 ;; wants to be able to do this between registers.
4844
4845 (define_expand "floathi<mode>2"
4846   [(set (match_operand:X87MODEF 0 "register_operand" "")
4847         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4848   "TARGET_80387
4849    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4850        || TARGET_MIX_SSE_I387)"
4851   "")
4852
4853 ;; Pre-reload splitter to add memory clobber to the pattern.
4854 (define_insn_and_split "*floathi<mode>2_1"
4855   [(set (match_operand:X87MODEF 0 "register_operand" "")
4856         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4857   "TARGET_80387
4858    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4859        || TARGET_MIX_SSE_I387)
4860    && can_create_pseudo_p ()"
4861   "#"
4862   "&& 1"
4863   [(parallel [(set (match_dup 0)
4864               (float:X87MODEF (match_dup 1)))
4865    (clobber (match_dup 2))])]
4866   "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4867
4868 (define_insn "*floathi<mode>2_i387_with_temp"
4869   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4870         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4871   (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
4872   "TARGET_80387
4873    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4874        || TARGET_MIX_SSE_I387)"
4875   "#"
4876   [(set_attr "type" "fmov,multi")
4877    (set_attr "mode" "<MODE>")
4878    (set_attr "unit" "*,i387")
4879    (set_attr "fp_int_src" "true")])
4880
4881 (define_insn "*floathi<mode>2_i387"
4882   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4883         (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4884   "TARGET_80387
4885    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4886        || TARGET_MIX_SSE_I387)"
4887   "fild%Z1\t%1"
4888   [(set_attr "type" "fmov")
4889    (set_attr "mode" "<MODE>")
4890    (set_attr "fp_int_src" "true")])
4891
4892 (define_split
4893   [(set (match_operand:X87MODEF 0 "register_operand" "")
4894         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4895    (clobber (match_operand:HI 2 "memory_operand" ""))]
4896   "TARGET_80387
4897    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4898        || TARGET_MIX_SSE_I387)
4899    && reload_completed"
4900   [(set (match_dup 2) (match_dup 1))
4901    (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4902
4903 (define_split
4904   [(set (match_operand:X87MODEF 0 "register_operand" "")
4905         (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
4906    (clobber (match_operand:HI 2 "memory_operand" ""))]
4907    "TARGET_80387
4908     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4909         || TARGET_MIX_SSE_I387)
4910     && reload_completed"
4911   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4912
4913 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
4914   [(set (match_operand:X87MODEF 0 "register_operand" "")
4915         (float:X87MODEF
4916           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
4917   "TARGET_80387
4918    || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4919        && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4920 {
4921   if (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4922         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4923       && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode))
4924     {
4925       rtx reg = gen_reg_rtx (XFmode);
4926       rtx insn;
4927
4928       emit_insn (gen_float<SSEMODEI24:mode>xf2 (reg, operands[1]));
4929
4930       if (<X87MODEF:MODE>mode == SFmode)
4931         insn = gen_truncxfsf2 (operands[0], reg);
4932       else if (<X87MODEF:MODE>mode == DFmode)
4933         insn = gen_truncxfdf2 (operands[0], reg);
4934       else
4935         gcc_unreachable ();
4936
4937       emit_insn (insn);
4938       DONE;
4939     }
4940 })
4941
4942 ;; Pre-reload splitter to add memory clobber to the pattern.
4943 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
4944   [(set (match_operand:X87MODEF 0 "register_operand" "")
4945         (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
4946   "((TARGET_80387
4947      && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
4948      && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4949            && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4950          || TARGET_MIX_SSE_I387))
4951     || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4952         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4953         && ((<SSEMODEI24:MODE>mode == SImode
4954              && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4955              && optimize_function_for_speed_p (cfun)
4956              && flag_trapping_math)
4957             || !(TARGET_INTER_UNIT_CONVERSIONS
4958                  || optimize_function_for_size_p (cfun)))))
4959    && can_create_pseudo_p ()"
4960   "#"
4961   "&& 1"
4962   [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4963               (clobber (match_dup 2))])]
4964 {
4965   operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
4966
4967   /* Avoid store forwarding (partial memory) stall penalty
4968      by passing DImode value through XMM registers.  */
4969   if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
4970       && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4971       && optimize_function_for_speed_p (cfun))
4972     {
4973       emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4974                                                             operands[1],
4975                                                             operands[2]));
4976       DONE;
4977     }
4978 })
4979
4980 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4981   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4982         (float:MODEF
4983           (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4984    (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4985   "TARGET_SSE2 && TARGET_MIX_SSE_I387
4986    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4987   "#"
4988   [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4989    (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4990    (set_attr "unit" "*,i387,*,*,*")
4991    (set_attr "athlon_decode" "*,*,double,direct,double")
4992    (set_attr "amdfam10_decode" "*,*,vector,double,double")
4993    (set_attr "fp_int_src" "true")])
4994
4995 (define_insn "*floatsi<mode>2_vector_mixed"
4996   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4997         (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4998   "TARGET_SSE2 && TARGET_MIX_SSE_I387
4999    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5000   "@
5001    fild%Z1\t%1
5002    #"
5003   [(set_attr "type" "fmov,sseicvt")
5004    (set_attr "mode" "<MODE>,<ssevecmode>")
5005    (set_attr "unit" "i387,*")
5006    (set_attr "athlon_decode" "*,direct")
5007    (set_attr "amdfam10_decode" "*,double")
5008    (set_attr "fp_int_src" "true")])
5009
5010 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
5011   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
5012         (float:MODEF
5013           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
5014   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
5015   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5016    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
5017   "#"
5018   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5019    (set_attr "mode" "<MODEF:MODE>")
5020    (set_attr "unit" "*,i387,*,*")
5021    (set_attr "athlon_decode" "*,*,double,direct")
5022    (set_attr "amdfam10_decode" "*,*,vector,double")
5023    (set_attr "fp_int_src" "true")])
5024
5025 (define_split
5026   [(set (match_operand:MODEF 0 "register_operand" "")
5027         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5028    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5029   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5030    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5031    && TARGET_INTER_UNIT_CONVERSIONS
5032    && reload_completed
5033    && (SSE_REG_P (operands[0])
5034        || (GET_CODE (operands[0]) == SUBREG
5035            && SSE_REG_P (operands[0])))"
5036   [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5037
5038 (define_split
5039   [(set (match_operand:MODEF 0 "register_operand" "")
5040         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5041    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5042   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5043    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5044    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5045    && reload_completed
5046    && (SSE_REG_P (operands[0])
5047        || (GET_CODE (operands[0]) == SUBREG
5048            && SSE_REG_P (operands[0])))"
5049   [(set (match_dup 2) (match_dup 1))
5050    (set (match_dup 0) (float:MODEF (match_dup 2)))])
5051
5052 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5053   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5054         (float:MODEF
5055           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
5056   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5057    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5058    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5059   "@
5060    fild%Z1\t%1
5061    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
5062    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5063   [(set_attr "type" "fmov,sseicvt,sseicvt")
5064    (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5065    (set_attr "mode" "<MODEF:MODE>")
5066    (set (attr "prefix_rex")
5067      (if_then_else
5068        (and (eq_attr "prefix" "maybe_vex")
5069             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5070        (const_string "1")
5071        (const_string "*")))
5072    (set_attr "unit" "i387,*,*")
5073    (set_attr "athlon_decode" "*,double,direct")
5074    (set_attr "amdfam10_decode" "*,vector,double")
5075    (set_attr "fp_int_src" "true")])
5076
5077 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5078   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5079         (float:MODEF
5080           (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5081   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5082    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5083    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5084   "@
5085    fild%Z1\t%1
5086    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5087   [(set_attr "type" "fmov,sseicvt")
5088    (set_attr "prefix" "orig,maybe_vex")
5089    (set_attr "mode" "<MODEF:MODE>")
5090    (set (attr "prefix_rex")
5091      (if_then_else
5092        (and (eq_attr "prefix" "maybe_vex")
5093             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5094        (const_string "1")
5095        (const_string "*")))
5096    (set_attr "athlon_decode" "*,direct")
5097    (set_attr "amdfam10_decode" "*,double")
5098    (set_attr "fp_int_src" "true")])
5099
5100 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5101   [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5102         (float:MODEF
5103           (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5104    (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5105   "TARGET_SSE2 && TARGET_SSE_MATH
5106    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5107   "#"
5108   [(set_attr "type" "sseicvt")
5109    (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5110    (set_attr "athlon_decode" "double,direct,double")
5111    (set_attr "amdfam10_decode" "vector,double,double")
5112    (set_attr "fp_int_src" "true")])
5113
5114 (define_insn "*floatsi<mode>2_vector_sse"
5115   [(set (match_operand:MODEF 0 "register_operand" "=x")
5116         (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5117   "TARGET_SSE2 && TARGET_SSE_MATH
5118    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5119   "#"
5120   [(set_attr "type" "sseicvt")
5121    (set_attr "mode" "<MODE>")
5122    (set_attr "athlon_decode" "direct")
5123    (set_attr "amdfam10_decode" "double")
5124    (set_attr "fp_int_src" "true")])
5125
5126 (define_split
5127   [(set (match_operand:MODEF 0 "register_operand" "")
5128         (float:MODEF (match_operand:SI 1 "register_operand" "")))
5129    (clobber (match_operand:SI 2 "memory_operand" ""))]
5130   "TARGET_SSE2 && TARGET_SSE_MATH
5131    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5132    && reload_completed
5133    && (SSE_REG_P (operands[0])
5134        || (GET_CODE (operands[0]) == SUBREG
5135            && SSE_REG_P (operands[0])))"
5136   [(const_int 0)]
5137 {
5138   rtx op1 = operands[1];
5139
5140   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5141                                      <MODE>mode, 0);
5142   if (GET_CODE (op1) == SUBREG)
5143     op1 = SUBREG_REG (op1);
5144
5145   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5146     {
5147       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5148       emit_insn (gen_sse2_loadld (operands[4],
5149                                   CONST0_RTX (V4SImode), operands[1]));
5150     }
5151   /* We can ignore possible trapping value in the
5152      high part of SSE register for non-trapping math. */
5153   else if (SSE_REG_P (op1) && !flag_trapping_math)
5154     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5155   else
5156     {
5157       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5158       emit_move_insn (operands[2], operands[1]);
5159       emit_insn (gen_sse2_loadld (operands[4],
5160                                   CONST0_RTX (V4SImode), operands[2]));
5161     }
5162   emit_insn
5163     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5164   DONE;
5165 })
5166
5167 (define_split
5168   [(set (match_operand:MODEF 0 "register_operand" "")
5169         (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5170    (clobber (match_operand:SI 2 "memory_operand" ""))]
5171   "TARGET_SSE2 && TARGET_SSE_MATH
5172    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5173    && reload_completed
5174    && (SSE_REG_P (operands[0])
5175        || (GET_CODE (operands[0]) == SUBREG
5176            && SSE_REG_P (operands[0])))"
5177   [(const_int 0)]
5178 {
5179   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5180                                      <MODE>mode, 0);
5181   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5182
5183   emit_insn (gen_sse2_loadld (operands[4],
5184                               CONST0_RTX (V4SImode), operands[1]));
5185   emit_insn
5186     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5187   DONE;
5188 })
5189
5190 (define_split
5191   [(set (match_operand:MODEF 0 "register_operand" "")
5192         (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5193   "TARGET_SSE2 && TARGET_SSE_MATH
5194    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5195    && reload_completed
5196    && (SSE_REG_P (operands[0])
5197        || (GET_CODE (operands[0]) == SUBREG
5198            && SSE_REG_P (operands[0])))"
5199   [(const_int 0)]
5200 {
5201   rtx op1 = operands[1];
5202
5203   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5204                                      <MODE>mode, 0);
5205   if (GET_CODE (op1) == SUBREG)
5206     op1 = SUBREG_REG (op1);
5207
5208   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5209     {
5210       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5211       emit_insn (gen_sse2_loadld (operands[4],
5212                                   CONST0_RTX (V4SImode), operands[1]));
5213     }
5214   /* We can ignore possible trapping value in the
5215      high part of SSE register for non-trapping math. */
5216   else if (SSE_REG_P (op1) && !flag_trapping_math)
5217     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5218   else
5219     gcc_unreachable ();
5220   emit_insn
5221     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5222   DONE;
5223 })
5224
5225 (define_split
5226   [(set (match_operand:MODEF 0 "register_operand" "")
5227         (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5228   "TARGET_SSE2 && TARGET_SSE_MATH
5229    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5230    && reload_completed
5231    && (SSE_REG_P (operands[0])
5232        || (GET_CODE (operands[0]) == SUBREG
5233            && SSE_REG_P (operands[0])))"
5234   [(const_int 0)]
5235 {
5236   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5237                                      <MODE>mode, 0);
5238   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5239
5240   emit_insn (gen_sse2_loadld (operands[4],
5241                               CONST0_RTX (V4SImode), operands[1]));
5242   emit_insn
5243     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5244   DONE;
5245 })
5246
5247 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5248   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5249         (float:MODEF
5250           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5251   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5252   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5253    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5254   "#"
5255   [(set_attr "type" "sseicvt")
5256    (set_attr "mode" "<MODEF:MODE>")
5257    (set_attr "athlon_decode" "double,direct")
5258    (set_attr "amdfam10_decode" "vector,double")
5259    (set_attr "fp_int_src" "true")])
5260
5261 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5262   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5263         (float:MODEF
5264           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5265   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5266    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5267    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5268   "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5269   [(set_attr "type" "sseicvt")
5270    (set_attr "prefix" "maybe_vex")
5271    (set_attr "mode" "<MODEF:MODE>")
5272    (set (attr "prefix_rex")
5273      (if_then_else
5274        (and (eq_attr "prefix" "maybe_vex")
5275             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5276        (const_string "1")
5277        (const_string "*")))
5278    (set_attr "athlon_decode" "double,direct")
5279    (set_attr "amdfam10_decode" "vector,double")
5280    (set_attr "fp_int_src" "true")])
5281
5282 (define_split
5283   [(set (match_operand:MODEF 0 "register_operand" "")
5284         (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5285    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5286   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5287    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5288    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5289    && reload_completed
5290    && (SSE_REG_P (operands[0])
5291        || (GET_CODE (operands[0]) == SUBREG
5292            && SSE_REG_P (operands[0])))"
5293   [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5294
5295 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5296   [(set (match_operand:MODEF 0 "register_operand" "=x")
5297         (float:MODEF
5298           (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5299   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5300    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5301    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5302   "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5303   [(set_attr "type" "sseicvt")
5304    (set_attr "prefix" "maybe_vex")
5305    (set_attr "mode" "<MODEF:MODE>")
5306    (set (attr "prefix_rex")
5307      (if_then_else
5308        (and (eq_attr "prefix" "maybe_vex")
5309             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5310        (const_string "1")
5311        (const_string "*")))
5312    (set_attr "athlon_decode" "direct")
5313    (set_attr "amdfam10_decode" "double")
5314    (set_attr "fp_int_src" "true")])
5315
5316 (define_split
5317   [(set (match_operand:MODEF 0 "register_operand" "")
5318         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5319    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5320   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5321    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5322    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5323    && reload_completed
5324    && (SSE_REG_P (operands[0])
5325        || (GET_CODE (operands[0]) == SUBREG
5326            && SSE_REG_P (operands[0])))"
5327   [(set (match_dup 2) (match_dup 1))
5328    (set (match_dup 0) (float:MODEF (match_dup 2)))])
5329
5330 (define_split
5331   [(set (match_operand:MODEF 0 "register_operand" "")
5332         (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5333    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5334   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5335    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5336    && reload_completed
5337    && (SSE_REG_P (operands[0])
5338        || (GET_CODE (operands[0]) == SUBREG
5339            && SSE_REG_P (operands[0])))"
5340   [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5341
5342 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5343   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5344         (float:X87MODEF
5345           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5346   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5347   "TARGET_80387
5348    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5349   "@
5350    fild%Z1\t%1
5351    #"
5352   [(set_attr "type" "fmov,multi")
5353    (set_attr "mode" "<X87MODEF:MODE>")
5354    (set_attr "unit" "*,i387")
5355    (set_attr "fp_int_src" "true")])
5356
5357 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5358   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5359         (float:X87MODEF
5360           (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5361   "TARGET_80387
5362    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5363   "fild%Z1\t%1"
5364   [(set_attr "type" "fmov")
5365    (set_attr "mode" "<X87MODEF:MODE>")
5366    (set_attr "fp_int_src" "true")])
5367
5368 (define_split
5369   [(set (match_operand:X87MODEF 0 "register_operand" "")
5370         (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5371    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5372   "TARGET_80387
5373    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5374    && reload_completed
5375    && FP_REG_P (operands[0])"
5376   [(set (match_dup 2) (match_dup 1))
5377    (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5378
5379 (define_split
5380   [(set (match_operand:X87MODEF 0 "register_operand" "")
5381         (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5382    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5383   "TARGET_80387
5384    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5385    && reload_completed
5386    && FP_REG_P (operands[0])"
5387   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5388
5389 ;; Avoid store forwarding (partial memory) stall penalty
5390 ;; by passing DImode value through XMM registers.  */
5391
5392 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5393   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5394         (float:X87MODEF
5395           (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5396    (clobber (match_scratch:V4SI 3 "=X,x"))
5397    (clobber (match_scratch:V4SI 4 "=X,x"))
5398    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5399   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5400    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5401    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5402   "#"
5403   [(set_attr "type" "multi")
5404    (set_attr "mode" "<X87MODEF:MODE>")
5405    (set_attr "unit" "i387")
5406    (set_attr "fp_int_src" "true")])
5407
5408 (define_split
5409   [(set (match_operand:X87MODEF 0 "register_operand" "")
5410         (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5411    (clobber (match_scratch:V4SI 3 ""))
5412    (clobber (match_scratch:V4SI 4 ""))
5413    (clobber (match_operand:DI 2 "memory_operand" ""))]
5414   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5415    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5416    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5417    && reload_completed
5418    && FP_REG_P (operands[0])"
5419   [(set (match_dup 2) (match_dup 3))
5420    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5421 {
5422   /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5423      Assemble the 64-bit DImode value in an xmm register.  */
5424   emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5425                               gen_rtx_SUBREG (SImode, operands[1], 0)));
5426   emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5427                               gen_rtx_SUBREG (SImode, operands[1], 4)));
5428   emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5429                                          operands[4]));
5430
5431   operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5432 })
5433
5434 (define_split
5435   [(set (match_operand:X87MODEF 0 "register_operand" "")
5436         (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5437    (clobber (match_scratch:V4SI 3 ""))
5438    (clobber (match_scratch:V4SI 4 ""))
5439    (clobber (match_operand:DI 2 "memory_operand" ""))]
5440   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5441    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5442    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5443    && reload_completed
5444    && FP_REG_P (operands[0])"
5445   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5446
5447 ;; Avoid store forwarding (partial memory) stall penalty by extending
5448 ;; SImode value to DImode through XMM register instead of pushing two
5449 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5450 ;; targets benefit from this optimization. Also note that fild
5451 ;; loads from memory only.
5452
5453 (define_insn "*floatunssi<mode>2_1"
5454   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5455         (unsigned_float:X87MODEF
5456           (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5457    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5458    (clobber (match_scratch:SI 3 "=X,x"))]
5459   "!TARGET_64BIT
5460    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5461    && TARGET_SSE"
5462   "#"
5463   [(set_attr "type" "multi")
5464    (set_attr "mode" "<MODE>")])
5465
5466 (define_split
5467   [(set (match_operand:X87MODEF 0 "register_operand" "")
5468         (unsigned_float:X87MODEF
5469           (match_operand:SI 1 "register_operand" "")))
5470    (clobber (match_operand:DI 2 "memory_operand" ""))
5471    (clobber (match_scratch:SI 3 ""))]
5472   "!TARGET_64BIT
5473    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5474    && TARGET_SSE
5475    && reload_completed"
5476   [(set (match_dup 2) (match_dup 1))
5477    (set (match_dup 0)
5478         (float:X87MODEF (match_dup 2)))]
5479   "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5480
5481 (define_split
5482   [(set (match_operand:X87MODEF 0 "register_operand" "")
5483         (unsigned_float:X87MODEF
5484           (match_operand:SI 1 "memory_operand" "")))
5485    (clobber (match_operand:DI 2 "memory_operand" ""))
5486    (clobber (match_scratch:SI 3 ""))]
5487   "!TARGET_64BIT
5488    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5489    && TARGET_SSE
5490    && reload_completed"
5491   [(set (match_dup 2) (match_dup 3))
5492    (set (match_dup 0)
5493         (float:X87MODEF (match_dup 2)))]
5494 {
5495   emit_move_insn (operands[3], operands[1]);
5496   operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5497 })
5498
5499 (define_expand "floatunssi<mode>2"
5500   [(parallel
5501      [(set (match_operand:X87MODEF 0 "register_operand" "")
5502            (unsigned_float:X87MODEF
5503              (match_operand:SI 1 "nonimmediate_operand" "")))
5504       (clobber (match_dup 2))
5505       (clobber (match_scratch:SI 3 ""))])]
5506   "!TARGET_64BIT
5507    && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5508         && TARGET_SSE)
5509        || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5510 {
5511   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5512     {
5513       ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5514       DONE;
5515     }
5516   else
5517     {
5518       enum ix86_stack_slot slot = (virtuals_instantiated
5519                                    ? SLOT_TEMP
5520                                    : SLOT_VIRTUAL);
5521       operands[2] = assign_386_stack_local (DImode, slot);
5522     }
5523 })
5524
5525 (define_expand "floatunsdisf2"
5526   [(use (match_operand:SF 0 "register_operand" ""))
5527    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5528   "TARGET_64BIT && TARGET_SSE_MATH"
5529   "x86_emit_floatuns (operands); DONE;")
5530
5531 (define_expand "floatunsdidf2"
5532   [(use (match_operand:DF 0 "register_operand" ""))
5533    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5534   "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5535    && TARGET_SSE2 && TARGET_SSE_MATH"
5536 {
5537   if (TARGET_64BIT)
5538     x86_emit_floatuns (operands);
5539   else
5540     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5541   DONE;
5542 })
5543 \f
5544 ;; Add instructions
5545
5546 (define_expand "add<mode>3"
5547   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5548         (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5549                     (match_operand:SDWIM 2 "<general_operand>" "")))]
5550   ""
5551   "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5552
5553 (define_insn_and_split "*add<dwi>3_doubleword"
5554   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5555         (plus:<DWI>
5556           (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5557           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5558    (clobber (reg:CC FLAGS_REG))]
5559   "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5560   "#"
5561   "reload_completed"
5562   [(parallel [(set (reg:CC FLAGS_REG)
5563                    (unspec:CC [(match_dup 1) (match_dup 2)]
5564                               UNSPEC_ADD_CARRY))
5565               (set (match_dup 0)
5566                    (plus:DWIH (match_dup 1) (match_dup 2)))])
5567    (parallel [(set (match_dup 3)
5568                    (plus:DWIH
5569                      (match_dup 4)
5570                      (plus:DWIH
5571                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5572                        (match_dup 5))))
5573               (clobber (reg:CC FLAGS_REG))])]
5574   "split_<dwi> (&operands[0], 3, &operands[0], &operands[3]);")
5575
5576 (define_insn "*add<mode>3_cc"
5577   [(set (reg:CC FLAGS_REG)
5578         (unspec:CC
5579           [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5580            (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5581           UNSPEC_ADD_CARRY))
5582    (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5583         (plus:SWI48 (match_dup 1) (match_dup 2)))]
5584   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5585   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5586   [(set_attr "type" "alu")
5587    (set_attr "mode" "<MODE>")])
5588
5589 (define_insn "addqi3_cc"
5590   [(set (reg:CC FLAGS_REG)
5591         (unspec:CC
5592           [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5593            (match_operand:QI 2 "general_operand" "qn,qm")]
5594           UNSPEC_ADD_CARRY))
5595    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5596         (plus:QI (match_dup 1) (match_dup 2)))]
5597   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5598   "add{b}\t{%2, %0|%0, %2}"
5599   [(set_attr "type" "alu")
5600    (set_attr "mode" "QI")])
5601
5602 (define_insn "*lea_1"
5603   [(set (match_operand:P 0 "register_operand" "=r")
5604         (match_operand:P 1 "no_seg_address_operand" "p"))]
5605   ""
5606   "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
5607   [(set_attr "type" "lea")
5608    (set_attr "mode" "<MODE>")])
5609
5610 (define_insn "*lea_2"
5611   [(set (match_operand:SI 0 "register_operand" "=r")
5612         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5613   "TARGET_64BIT"
5614   "lea{l}\t{%a1, %0|%0, %a1}"
5615   [(set_attr "type" "lea")
5616    (set_attr "mode" "SI")])
5617
5618 (define_insn "*lea_2_zext"
5619   [(set (match_operand:DI 0 "register_operand" "=r")
5620         (zero_extend:DI
5621           (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5622   "TARGET_64BIT"
5623   "lea{l}\t{%a1, %k0|%k0, %a1}"
5624   [(set_attr "type" "lea")
5625    (set_attr "mode" "SI")])
5626
5627 (define_insn "*add<mode>_1"
5628   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5629         (plus:SWI48
5630           (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5631           (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,0,l<i>")))
5632    (clobber (reg:CC FLAGS_REG))]
5633   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5634 {
5635   switch (get_attr_type (insn))
5636     {
5637     case TYPE_LEA:
5638       return "#";
5639
5640     case TYPE_INCDEC:
5641       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5642       if (operands[2] == const1_rtx)
5643         return "inc{<imodesuffix>}\t%0";
5644       else
5645         {
5646           gcc_assert (operands[2] == constm1_rtx);
5647           return "dec{<imodesuffix>}\t%0";
5648         }
5649
5650     default:
5651       /* For most processors, ADD is faster than LEA.  This alternative
5652          was added to use ADD as much as possible.  */
5653       if (which_alternative == 2)
5654         {
5655           rtx tmp;
5656           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5657         }
5658         
5659       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5660       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5661         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5662
5663       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5664     }
5665 }
5666   [(set (attr "type")
5667      (cond [(eq_attr "alternative" "3")
5668               (const_string "lea")
5669             (match_operand:SWI48 2 "incdec_operand" "")
5670               (const_string "incdec")
5671            ]
5672            (const_string "alu")))
5673    (set (attr "length_immediate")
5674       (if_then_else
5675         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5676         (const_string "1")
5677         (const_string "*")))
5678    (set_attr "mode" "<MODE>")])
5679
5680 ;; It may seem that nonimmediate operand is proper one for operand 1.
5681 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5682 ;; we take care in ix86_binary_operator_ok to not allow two memory
5683 ;; operands so proper swapping will be done in reload.  This allow
5684 ;; patterns constructed from addsi_1 to match.
5685
5686 (define_insn "*addsi_1_zext"
5687   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5688         (zero_extend:DI
5689           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5690                    (match_operand:SI 2 "general_operand" "g,0,li"))))
5691    (clobber (reg:CC FLAGS_REG))]
5692   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5693 {
5694   switch (get_attr_type (insn))
5695     {
5696     case TYPE_LEA:
5697       return "#";
5698
5699     case TYPE_INCDEC:
5700       if (operands[2] == const1_rtx)
5701         return "inc{l}\t%k0";
5702       else
5703         {
5704           gcc_assert (operands[2] == constm1_rtx);
5705           return "dec{l}\t%k0";
5706         }
5707
5708     default:
5709       /* For most processors, ADD is faster than LEA.  This alternative
5710          was added to use ADD as much as possible.  */
5711       if (which_alternative == 1)
5712         {
5713           rtx tmp;
5714           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5715         }
5716
5717       if (x86_maybe_negate_const_int (&operands[2], SImode))
5718         return "sub{l}\t{%2, %k0|%k0, %2}";
5719
5720       return "add{l}\t{%2, %k0|%k0, %2}";
5721     }
5722 }
5723   [(set (attr "type")
5724      (cond [(eq_attr "alternative" "2")
5725               (const_string "lea")
5726             (match_operand:SI 2 "incdec_operand" "")
5727               (const_string "incdec")
5728            ]
5729            (const_string "alu")))
5730    (set (attr "length_immediate")
5731       (if_then_else
5732         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5733         (const_string "1")
5734         (const_string "*")))
5735    (set_attr "mode" "SI")])
5736
5737 (define_insn "*addhi_1"
5738   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5739         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5740                  (match_operand:HI 2 "general_operand" "rn,rm")))
5741    (clobber (reg:CC FLAGS_REG))]
5742   "TARGET_PARTIAL_REG_STALL
5743    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5744 {
5745   switch (get_attr_type (insn))
5746     {
5747     case TYPE_INCDEC:
5748       if (operands[2] == const1_rtx)
5749         return "inc{w}\t%0";
5750       else
5751         {
5752           gcc_assert (operands[2] == constm1_rtx);
5753           return "dec{w}\t%0";
5754         }
5755
5756     default:
5757       if (x86_maybe_negate_const_int (&operands[2], HImode))
5758         return "sub{w}\t{%2, %0|%0, %2}";
5759
5760       return "add{w}\t{%2, %0|%0, %2}";
5761     }
5762 }
5763   [(set (attr "type")
5764      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5765         (const_string "incdec")
5766         (const_string "alu")))
5767    (set (attr "length_immediate")
5768       (if_then_else
5769         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5770         (const_string "1")
5771         (const_string "*")))
5772    (set_attr "mode" "HI")])
5773
5774 (define_insn "*addhi_1_lea"
5775   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm,r,r")
5776         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,r")
5777                  (match_operand:HI 2 "general_operand" "rmn,rn,0,ln")))
5778    (clobber (reg:CC FLAGS_REG))]
5779   "!TARGET_PARTIAL_REG_STALL
5780    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5781 {
5782   switch (get_attr_type (insn))
5783     {
5784     case TYPE_LEA:
5785       return "#";
5786
5787     case TYPE_INCDEC:
5788       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5789       if (operands[2] == const1_rtx)
5790         return "inc{w}\t%0";
5791       else
5792         {
5793           gcc_assert (operands[2] == constm1_rtx);
5794           return "dec{w}\t%0";
5795         }
5796
5797     default:
5798       /* For most processors, ADD is faster than LEA.  This alternative
5799          was added to use ADD as much as possible.  */
5800       if (which_alternative == 2)
5801         {
5802           rtx tmp;
5803           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5804         }
5805
5806       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5807       if (x86_maybe_negate_const_int (&operands[2], HImode))
5808         return "sub{w}\t{%2, %0|%0, %2}";
5809
5810       return "add{w}\t{%2, %0|%0, %2}";
5811     }
5812 }
5813   [(set (attr "type")
5814      (cond [(eq_attr "alternative" "3")
5815               (const_string "lea")
5816             (match_operand:HI 2 "incdec_operand" "")
5817               (const_string "incdec")
5818            ]
5819            (const_string "alu")))
5820    (set (attr "length_immediate")
5821       (if_then_else
5822         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5823         (const_string "1")
5824         (const_string "*")))
5825    (set_attr "mode" "HI,HI,HI,SI")])
5826
5827 ;; %%% Potential partial reg stall on alternative 2.  What to do?
5828 (define_insn "*addqi_1"
5829   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
5830         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
5831                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
5832    (clobber (reg:CC FLAGS_REG))]
5833   "TARGET_PARTIAL_REG_STALL
5834    && ix86_binary_operator_ok (PLUS, QImode, operands)"
5835 {
5836   int widen = (which_alternative == 2);
5837   switch (get_attr_type (insn))
5838     {
5839     case TYPE_INCDEC:
5840       if (operands[2] == const1_rtx)
5841         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5842       else
5843         {
5844           gcc_assert (operands[2] == constm1_rtx);
5845           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5846         }
5847
5848     default:
5849       if (x86_maybe_negate_const_int (&operands[2], QImode))
5850         {
5851           if (widen)
5852             return "sub{l}\t{%2, %k0|%k0, %2}";
5853           else
5854             return "sub{b}\t{%2, %0|%0, %2}";
5855         }
5856       if (widen)
5857         return "add{l}\t{%k2, %k0|%k0, %k2}";
5858       else
5859         return "add{b}\t{%2, %0|%0, %2}";
5860     }
5861 }
5862   [(set (attr "type")
5863      (if_then_else (match_operand:QI 2 "incdec_operand" "")
5864         (const_string "incdec")
5865         (const_string "alu")))
5866    (set (attr "length_immediate")
5867       (if_then_else
5868         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5869         (const_string "1")
5870         (const_string "*")))
5871    (set_attr "mode" "QI,QI,SI")])
5872
5873 ;; %%% Potential partial reg stall on alternatives 3 and 4.  What to do?
5874 (define_insn "*addqi_1_lea"
5875   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,q,r,r,r")
5876         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,r")
5877                  (match_operand:QI 2 "general_operand" "qmn,qn,0,rn,0,ln")))
5878    (clobber (reg:CC FLAGS_REG))]
5879   "!TARGET_PARTIAL_REG_STALL
5880    && ix86_binary_operator_ok (PLUS, QImode, operands)"
5881 {
5882   int widen = (which_alternative == 3 || which_alternative == 4);
5883
5884   switch (get_attr_type (insn))
5885     {
5886     case TYPE_LEA:
5887       return "#";
5888
5889     case TYPE_INCDEC:
5890       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5891       if (operands[2] == const1_rtx)
5892         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5893       else
5894         {
5895           gcc_assert (operands[2] == constm1_rtx);
5896           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5897         }
5898
5899     default:
5900       /* For most processors, ADD is faster than LEA.  These alternatives
5901          were added to use ADD as much as possible.  */
5902       if (which_alternative == 2 || which_alternative == 4)
5903         {
5904           rtx tmp;
5905           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5906         }
5907
5908       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5909       if (x86_maybe_negate_const_int (&operands[2], QImode))
5910         {
5911           if (widen)
5912             return "sub{l}\t{%2, %k0|%k0, %2}";
5913           else
5914             return "sub{b}\t{%2, %0|%0, %2}";
5915         }
5916       if (widen)
5917         return "add{l}\t{%k2, %k0|%k0, %k2}";
5918       else
5919         return "add{b}\t{%2, %0|%0, %2}";
5920     }
5921 }
5922   [(set (attr "type")
5923      (cond [(eq_attr "alternative" "5")
5924               (const_string "lea")
5925             (match_operand:QI 2 "incdec_operand" "")
5926               (const_string "incdec")
5927            ]
5928            (const_string "alu")))
5929    (set (attr "length_immediate")
5930       (if_then_else
5931         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5932         (const_string "1")
5933         (const_string "*")))
5934    (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5935
5936 (define_insn "*addqi_1_slp"
5937   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5938         (plus:QI (match_dup 0)
5939                  (match_operand:QI 1 "general_operand" "qn,qnm")))
5940    (clobber (reg:CC FLAGS_REG))]
5941   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5942    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5943 {
5944   switch (get_attr_type (insn))
5945     {
5946     case TYPE_INCDEC:
5947       if (operands[1] == const1_rtx)
5948         return "inc{b}\t%0";
5949       else
5950         {
5951           gcc_assert (operands[1] == constm1_rtx);
5952           return "dec{b}\t%0";
5953         }
5954
5955     default:
5956       if (x86_maybe_negate_const_int (&operands[1], QImode))
5957         return "sub{b}\t{%1, %0|%0, %1}";
5958
5959       return "add{b}\t{%1, %0|%0, %1}";
5960     }
5961 }
5962   [(set (attr "type")
5963      (if_then_else (match_operand:QI 1 "incdec_operand" "")
5964         (const_string "incdec")
5965         (const_string "alu1")))
5966    (set (attr "memory")
5967      (if_then_else (match_operand 1 "memory_operand" "")
5968         (const_string "load")
5969         (const_string "none")))
5970    (set_attr "mode" "QI")])
5971
5972 ;; Convert lea to the lea pattern to avoid flags dependency.
5973 (define_split
5974   [(set (match_operand 0 "register_operand" "")
5975         (plus (match_operand 1 "register_operand" "")
5976               (match_operand 2 "nonmemory_operand" "")))
5977    (clobber (reg:CC FLAGS_REG))]
5978   "reload_completed && ix86_lea_for_add_ok (insn, operands)" 
5979   [(const_int 0)]
5980 {
5981   rtx pat;
5982   enum machine_mode mode = GET_MODE (operands[0]);
5983
5984   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5985      may confuse gen_lowpart.  */
5986   if (mode != Pmode)
5987     {
5988       operands[1] = gen_lowpart (Pmode, operands[1]);
5989       operands[2] = gen_lowpart (Pmode, operands[2]);
5990     }
5991
5992   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5993
5994   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
5995     operands[0] = gen_lowpart (SImode, operands[0]);
5996
5997   if (TARGET_64BIT && mode != Pmode)
5998     pat = gen_rtx_SUBREG (SImode, pat, 0);
5999
6000   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6001   DONE;
6002 })
6003
6004 ;; Convert lea to the lea pattern to avoid flags dependency.
6005 ;; ??? This pattern handles immediate operands that do not satisfy immediate
6006 ;; operand predicate (LEGITIMATE_CONSTANT_P) in the previous pattern.
6007 (define_split
6008   [(set (match_operand:DI 0 "register_operand" "")
6009         (plus:DI (match_operand:DI 1 "register_operand" "")
6010                  (match_operand:DI 2 "x86_64_immediate_operand" "")))
6011    (clobber (reg:CC FLAGS_REG))]
6012   "TARGET_64BIT && reload_completed 
6013    && true_regnum (operands[0]) != true_regnum (operands[1])"
6014   [(set (match_dup 0)
6015         (plus:DI (match_dup 1) (match_dup 2)))])
6016
6017 ;; Convert lea to the lea pattern to avoid flags dependency.
6018 (define_split
6019   [(set (match_operand:DI 0 "register_operand" "")
6020         (zero_extend:DI
6021           (plus:SI (match_operand:SI 1 "register_operand" "")
6022                    (match_operand:SI 2 "nonmemory_operand" ""))))
6023    (clobber (reg:CC FLAGS_REG))]
6024   "TARGET_64BIT && reload_completed
6025    && ix86_lea_for_add_ok (insn, operands)"
6026   [(set (match_dup 0)
6027         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
6028 {
6029   operands[1] = gen_lowpart (DImode, operands[1]);
6030   operands[2] = gen_lowpart (DImode, operands[2]);
6031 })
6032
6033 (define_insn "*add<mode>_2"
6034   [(set (reg FLAGS_REG)
6035         (compare
6036           (plus:SWI
6037             (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6038             (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
6039           (const_int 0)))
6040    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
6041         (plus:SWI (match_dup 1) (match_dup 2)))]
6042   "ix86_match_ccmode (insn, CCGOCmode)
6043    && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6044 {
6045   switch (get_attr_type (insn))
6046     {
6047     case TYPE_INCDEC:
6048       if (operands[2] == const1_rtx)
6049         return "inc{<imodesuffix>}\t%0";
6050       else
6051         {
6052           gcc_assert (operands[2] == constm1_rtx);
6053           return "dec{<imodesuffix>}\t%0";
6054         }
6055
6056     default:
6057       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6058         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6059
6060       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6061     }
6062 }
6063   [(set (attr "type")
6064      (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6065         (const_string "incdec")
6066         (const_string "alu")))
6067    (set (attr "length_immediate")
6068       (if_then_else
6069         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6070         (const_string "1")
6071         (const_string "*")))
6072    (set_attr "mode" "<MODE>")])
6073
6074 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6075 (define_insn "*addsi_2_zext"
6076   [(set (reg FLAGS_REG)
6077         (compare
6078           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6079                    (match_operand:SI 2 "general_operand" "g"))
6080           (const_int 0)))
6081    (set (match_operand:DI 0 "register_operand" "=r")
6082         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6083   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6084    && ix86_binary_operator_ok (PLUS, SImode, operands)"
6085 {
6086   switch (get_attr_type (insn))
6087     {
6088     case TYPE_INCDEC:
6089       if (operands[2] == const1_rtx)
6090         return "inc{l}\t%k0";
6091       else
6092         {
6093           gcc_assert (operands[2] == constm1_rtx);
6094           return "dec{l}\t%k0";
6095         }
6096
6097     default:
6098       if (x86_maybe_negate_const_int (&operands[2], SImode))
6099         return "sub{l}\t{%2, %k0|%k0, %2}";
6100
6101       return "add{l}\t{%2, %k0|%k0, %2}";
6102     }
6103 }
6104   [(set (attr "type")
6105      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6106         (const_string "incdec")
6107         (const_string "alu")))
6108    (set (attr "length_immediate")
6109       (if_then_else
6110         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6111         (const_string "1")
6112         (const_string "*")))
6113    (set_attr "mode" "SI")])
6114
6115 (define_insn "*add<mode>_3"
6116   [(set (reg FLAGS_REG)
6117         (compare
6118           (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>"))
6119           (match_operand:SWI 1 "nonimmediate_operand" "%0")))
6120    (clobber (match_scratch:SWI 0 "=<r>"))]
6121   "ix86_match_ccmode (insn, CCZmode)
6122    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6123 {
6124   switch (get_attr_type (insn))
6125     {
6126     case TYPE_INCDEC:
6127       if (operands[2] == const1_rtx)
6128         return "inc{<imodesuffix>}\t%0";
6129       else
6130         {
6131           gcc_assert (operands[2] == constm1_rtx);
6132           return "dec{<imodesuffix>}\t%0";
6133         }
6134
6135     default:
6136       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6137         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6138
6139       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6140     }
6141 }
6142   [(set (attr "type")
6143      (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6144         (const_string "incdec")
6145         (const_string "alu")))
6146    (set (attr "length_immediate")
6147       (if_then_else
6148         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6149         (const_string "1")
6150         (const_string "*")))
6151    (set_attr "mode" "<MODE>")])
6152
6153 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6154 (define_insn "*addsi_3_zext"
6155   [(set (reg FLAGS_REG)
6156         (compare
6157           (neg:SI (match_operand:SI 2 "general_operand" "g"))
6158           (match_operand:SI 1 "nonimmediate_operand" "%0")))
6159    (set (match_operand:DI 0 "register_operand" "=r")
6160         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6161   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6162    && ix86_binary_operator_ok (PLUS, SImode, operands)"
6163 {
6164   switch (get_attr_type (insn))
6165     {
6166     case TYPE_INCDEC:
6167       if (operands[2] == const1_rtx)
6168         return "inc{l}\t%k0";
6169       else
6170         {
6171           gcc_assert (operands[2] == constm1_rtx);
6172           return "dec{l}\t%k0";
6173         }
6174
6175     default:
6176       if (x86_maybe_negate_const_int (&operands[2], SImode))
6177         return "sub{l}\t{%2, %k0|%k0, %2}";
6178
6179       return "add{l}\t{%2, %k0|%k0, %2}";
6180     }
6181 }
6182   [(set (attr "type")
6183      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6184         (const_string "incdec")
6185         (const_string "alu")))
6186    (set (attr "length_immediate")
6187       (if_then_else
6188         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6189         (const_string "1")
6190         (const_string "*")))
6191    (set_attr "mode" "SI")])
6192
6193 ; For comparisons against 1, -1 and 128, we may generate better code
6194 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6195 ; is matched then.  We can't accept general immediate, because for
6196 ; case of overflows,  the result is messed up.
6197 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6198 ; only for comparisons not depending on it.
6199
6200 (define_insn "*adddi_4"
6201   [(set (reg FLAGS_REG)
6202         (compare
6203           (match_operand:DI 1 "nonimmediate_operand" "0")
6204           (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6205    (clobber (match_scratch:DI 0 "=rm"))]
6206   "TARGET_64BIT
6207    && ix86_match_ccmode (insn, CCGCmode)"
6208 {
6209   switch (get_attr_type (insn))
6210     {
6211     case TYPE_INCDEC:
6212       if (operands[2] == constm1_rtx)
6213         return "inc{q}\t%0";
6214       else
6215         {
6216           gcc_assert (operands[2] == const1_rtx);
6217           return "dec{q}\t%0";
6218         }
6219
6220     default:
6221       if (x86_maybe_negate_const_int (&operands[2], DImode))
6222         return "add{q}\t{%2, %0|%0, %2}";
6223
6224       return "sub{q}\t{%2, %0|%0, %2}";
6225     }
6226 }
6227   [(set (attr "type")
6228      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6229         (const_string "incdec")
6230         (const_string "alu")))
6231    (set (attr "length_immediate")
6232       (if_then_else
6233         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6234         (const_string "1")
6235         (const_string "*")))
6236    (set_attr "mode" "DI")])
6237
6238 ; For comparisons against 1, -1 and 128, we may generate better code
6239 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6240 ; is matched then.  We can't accept general immediate, because for
6241 ; case of overflows,  the result is messed up.
6242 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6243 ; only for comparisons not depending on it.
6244
6245 (define_insn "*add<mode>_4"
6246   [(set (reg FLAGS_REG)
6247         (compare
6248           (match_operand:SWI124 1 "nonimmediate_operand" "0")
6249           (match_operand:SWI124 2 "const_int_operand" "n")))
6250    (clobber (match_scratch:SWI124 0 "=<r>m"))]
6251   "ix86_match_ccmode (insn, CCGCmode)"
6252 {
6253   switch (get_attr_type (insn))
6254     {
6255     case TYPE_INCDEC:
6256       if (operands[2] == constm1_rtx)
6257         return "inc{<imodesuffix>}\t%0";
6258       else
6259         {
6260           gcc_assert (operands[2] == const1_rtx);
6261           return "dec{<imodesuffix>}\t%0";
6262         }
6263
6264     default:
6265       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6266         return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6267
6268       return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6269     }
6270 }
6271   [(set (attr "type")
6272      (if_then_else (match_operand:<MODE> 2 "incdec_operand" "")
6273         (const_string "incdec")
6274         (const_string "alu")))
6275    (set (attr "length_immediate")
6276       (if_then_else
6277         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6278         (const_string "1")
6279         (const_string "*")))
6280    (set_attr "mode" "<MODE>")])
6281
6282 (define_insn "*add<mode>_5"
6283   [(set (reg FLAGS_REG)
6284         (compare
6285           (plus:SWI
6286             (match_operand:SWI 1 "nonimmediate_operand" "%0")
6287             (match_operand:SWI 2 "<general_operand>" "<g>"))
6288           (const_int 0)))
6289    (clobber (match_scratch:SWI 0 "=<r>"))]
6290   "ix86_match_ccmode (insn, CCGOCmode)
6291    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6292 {
6293   switch (get_attr_type (insn))
6294     {
6295     case TYPE_INCDEC:
6296       if (operands[2] == const1_rtx)
6297         return "inc{<imodesuffix>}\t%0";
6298       else
6299         {
6300           gcc_assert (operands[2] == constm1_rtx);
6301           return "dec{<imodesuffix>}\t%0";
6302         }
6303
6304     default:
6305       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6306         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6307
6308       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6309     }
6310 }
6311   [(set (attr "type")
6312      (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6313         (const_string "incdec")
6314         (const_string "alu")))
6315    (set (attr "length_immediate")
6316       (if_then_else
6317         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6318         (const_string "1")
6319         (const_string "*")))
6320    (set_attr "mode" "<MODE>")])
6321
6322 (define_insn "*addqi_ext_1_rex64"
6323   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6324                          (const_int 8)
6325                          (const_int 8))
6326         (plus:SI
6327           (zero_extract:SI
6328             (match_operand 1 "ext_register_operand" "0")
6329             (const_int 8)
6330             (const_int 8))
6331           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6332    (clobber (reg:CC FLAGS_REG))]
6333   "TARGET_64BIT"
6334 {
6335   switch (get_attr_type (insn))
6336     {
6337     case TYPE_INCDEC:
6338       if (operands[2] == const1_rtx)
6339         return "inc{b}\t%h0";
6340       else
6341         {
6342           gcc_assert (operands[2] == constm1_rtx);
6343           return "dec{b}\t%h0";
6344         }
6345
6346     default:
6347       return "add{b}\t{%2, %h0|%h0, %2}";
6348     }
6349 }
6350   [(set (attr "type")
6351      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6352         (const_string "incdec")
6353         (const_string "alu")))
6354    (set_attr "modrm" "1")
6355    (set_attr "mode" "QI")])
6356
6357 (define_insn "addqi_ext_1"
6358   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6359                          (const_int 8)
6360                          (const_int 8))
6361         (plus:SI
6362           (zero_extract:SI
6363             (match_operand 1 "ext_register_operand" "0")
6364             (const_int 8)
6365             (const_int 8))
6366           (match_operand:QI 2 "general_operand" "Qmn")))
6367    (clobber (reg:CC FLAGS_REG))]
6368   "!TARGET_64BIT"
6369 {
6370   switch (get_attr_type (insn))
6371     {
6372     case TYPE_INCDEC:
6373       if (operands[2] == const1_rtx)
6374         return "inc{b}\t%h0";
6375       else
6376         {
6377           gcc_assert (operands[2] == constm1_rtx);
6378           return "dec{b}\t%h0";
6379         }
6380
6381     default:
6382       return "add{b}\t{%2, %h0|%h0, %2}";
6383     }
6384 }
6385   [(set (attr "type")
6386      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6387         (const_string "incdec")
6388         (const_string "alu")))
6389    (set_attr "modrm" "1")
6390    (set_attr "mode" "QI")])
6391
6392 (define_insn "*addqi_ext_2"
6393   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6394                          (const_int 8)
6395                          (const_int 8))
6396         (plus:SI
6397           (zero_extract:SI
6398             (match_operand 1 "ext_register_operand" "%0")
6399             (const_int 8)
6400             (const_int 8))
6401           (zero_extract:SI
6402             (match_operand 2 "ext_register_operand" "Q")
6403             (const_int 8)
6404             (const_int 8))))
6405    (clobber (reg:CC FLAGS_REG))]
6406   ""
6407   "add{b}\t{%h2, %h0|%h0, %h2}"
6408   [(set_attr "type" "alu")
6409    (set_attr "mode" "QI")])
6410
6411 ;; The lea patterns for non-Pmodes needs to be matched by
6412 ;; several insns converted to real lea by splitters.
6413
6414 (define_insn_and_split "*lea_general_1"
6415   [(set (match_operand 0 "register_operand" "=r")
6416         (plus (plus (match_operand 1 "index_register_operand" "l")
6417                     (match_operand 2 "register_operand" "r"))
6418               (match_operand 3 "immediate_operand" "i")))]
6419   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6420     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6421    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6422    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6423    && GET_MODE (operands[0]) == GET_MODE (operands[2])
6424    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6425        || GET_MODE (operands[3]) == VOIDmode)"
6426   "#"
6427   "&& reload_completed"
6428   [(const_int 0)]
6429 {
6430   rtx pat;
6431   operands[0] = gen_lowpart (SImode, operands[0]);
6432   operands[1] = gen_lowpart (Pmode, operands[1]);
6433   operands[2] = gen_lowpart (Pmode, operands[2]);
6434   operands[3] = gen_lowpart (Pmode, operands[3]);
6435   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
6436                       operands[3]);
6437   if (Pmode != SImode)
6438     pat = gen_rtx_SUBREG (SImode, pat, 0);
6439   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6440   DONE;
6441 }
6442   [(set_attr "type" "lea")
6443    (set_attr "mode" "SI")])
6444
6445 (define_insn_and_split "*lea_general_1_zext"
6446   [(set (match_operand:DI 0 "register_operand" "=r")
6447         (zero_extend:DI
6448           (plus:SI (plus:SI
6449                      (match_operand:SI 1 "index_register_operand" "l")
6450                      (match_operand:SI 2 "register_operand" "r"))
6451                    (match_operand:SI 3 "immediate_operand" "i"))))]
6452   "TARGET_64BIT"
6453   "#"
6454   "&& reload_completed"
6455   [(set (match_dup 0)
6456         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
6457                                                      (match_dup 2))
6458                                             (match_dup 3)) 0)))]
6459 {
6460   operands[1] = gen_lowpart (Pmode, operands[1]);
6461   operands[2] = gen_lowpart (Pmode, operands[2]);
6462   operands[3] = gen_lowpart (Pmode, operands[3]);
6463 }
6464   [(set_attr "type" "lea")
6465    (set_attr "mode" "SI")])
6466
6467 (define_insn_and_split "*lea_general_2"
6468   [(set (match_operand 0 "register_operand" "=r")
6469         (plus (mult (match_operand 1 "index_register_operand" "l")
6470                     (match_operand 2 "const248_operand" "i"))
6471               (match_operand 3 "nonmemory_operand" "ri")))]
6472   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6473     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6474    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6475    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6476    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6477        || GET_MODE (operands[3]) == VOIDmode)"
6478   "#"
6479   "&& reload_completed"
6480   [(const_int 0)]
6481 {
6482   rtx pat;
6483   operands[0] = gen_lowpart (SImode, operands[0]);
6484   operands[1] = gen_lowpart (Pmode, operands[1]);
6485   operands[3] = gen_lowpart (Pmode, operands[3]);
6486   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
6487                       operands[3]);
6488   if (Pmode != SImode)
6489     pat = gen_rtx_SUBREG (SImode, pat, 0);
6490   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6491   DONE;
6492 }
6493   [(set_attr "type" "lea")
6494    (set_attr "mode" "SI")])
6495
6496 (define_insn_and_split "*lea_general_2_zext"
6497   [(set (match_operand:DI 0 "register_operand" "=r")
6498         (zero_extend:DI
6499           (plus:SI (mult:SI
6500                      (match_operand:SI 1 "index_register_operand" "l")
6501                      (match_operand:SI 2 "const248_operand" "n"))
6502                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
6503   "TARGET_64BIT"
6504   "#"
6505   "&& reload_completed"
6506   [(set (match_dup 0)
6507         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
6508                                                      (match_dup 2))
6509                                             (match_dup 3)) 0)))]
6510 {
6511   operands[1] = gen_lowpart (Pmode, operands[1]);
6512   operands[3] = gen_lowpart (Pmode, operands[3]);
6513 }
6514   [(set_attr "type" "lea")
6515    (set_attr "mode" "SI")])
6516
6517 (define_insn_and_split "*lea_general_3"
6518   [(set (match_operand 0 "register_operand" "=r")
6519         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6520                           (match_operand 2 "const248_operand" "i"))
6521                     (match_operand 3 "register_operand" "r"))
6522               (match_operand 4 "immediate_operand" "i")))]
6523   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6524     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6525    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6526    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6527    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6528   "#"
6529   "&& reload_completed"
6530   [(const_int 0)]
6531 {
6532   rtx pat;
6533   operands[0] = gen_lowpart (SImode, operands[0]);
6534   operands[1] = gen_lowpart (Pmode, operands[1]);
6535   operands[3] = gen_lowpart (Pmode, operands[3]);
6536   operands[4] = gen_lowpart (Pmode, operands[4]);
6537   pat = gen_rtx_PLUS (Pmode,
6538                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
6539                                                          operands[2]),
6540                                     operands[3]),
6541                       operands[4]);
6542   if (Pmode != SImode)
6543     pat = gen_rtx_SUBREG (SImode, pat, 0);
6544   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6545   DONE;
6546 }
6547   [(set_attr "type" "lea")
6548    (set_attr "mode" "SI")])
6549
6550 (define_insn_and_split "*lea_general_3_zext"
6551   [(set (match_operand:DI 0 "register_operand" "=r")
6552         (zero_extend:DI
6553           (plus:SI (plus:SI
6554                      (mult:SI
6555                        (match_operand:SI 1 "index_register_operand" "l")
6556                        (match_operand:SI 2 "const248_operand" "n"))
6557                      (match_operand:SI 3 "register_operand" "r"))
6558                    (match_operand:SI 4 "immediate_operand" "i"))))]
6559   "TARGET_64BIT"
6560   "#"
6561   "&& reload_completed"
6562   [(set (match_dup 0)
6563         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
6564                                                               (match_dup 2))
6565                                                      (match_dup 3))
6566                                             (match_dup 4)) 0)))]
6567 {
6568   operands[1] = gen_lowpart (Pmode, operands[1]);
6569   operands[3] = gen_lowpart (Pmode, operands[3]);
6570   operands[4] = gen_lowpart (Pmode, operands[4]);
6571 }
6572   [(set_attr "type" "lea")
6573    (set_attr "mode" "SI")])
6574 \f
6575 ;; Subtract instructions
6576
6577 (define_expand "sub<mode>3"
6578   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
6579         (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6580                      (match_operand:SDWIM 2 "<general_operand>" "")))]
6581   ""
6582   "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6583
6584 (define_insn_and_split "*sub<dwi>3_doubleword"
6585   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6586         (minus:<DWI>
6587           (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6588           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6589    (clobber (reg:CC FLAGS_REG))]
6590   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6591   "#"
6592   "reload_completed"
6593   [(parallel [(set (reg:CC FLAGS_REG)
6594                    (compare:CC (match_dup 1) (match_dup 2)))
6595               (set (match_dup 0)
6596                    (minus:DWIH (match_dup 1) (match_dup 2)))])
6597    (parallel [(set (match_dup 3)
6598                    (minus:DWIH
6599                      (match_dup 4)
6600                      (plus:DWIH
6601                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6602                        (match_dup 5))))
6603               (clobber (reg:CC FLAGS_REG))])]
6604   "split_<dwi> (&operands[0], 3, &operands[0], &operands[3]);")
6605
6606 (define_insn "*sub<mode>_1"
6607   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6608         (minus:SWI
6609           (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6610           (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6611    (clobber (reg:CC FLAGS_REG))]
6612   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6613   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6614   [(set_attr "type" "alu")
6615    (set_attr "mode" "<MODE>")])
6616
6617 (define_insn "*subsi_1_zext"
6618   [(set (match_operand:DI 0 "register_operand" "=r")
6619         (zero_extend:DI
6620           (minus:SI (match_operand:SI 1 "register_operand" "0")
6621                     (match_operand:SI 2 "general_operand" "g"))))
6622    (clobber (reg:CC FLAGS_REG))]
6623   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6624   "sub{l}\t{%2, %k0|%k0, %2}"
6625   [(set_attr "type" "alu")
6626    (set_attr "mode" "SI")])
6627
6628 (define_insn "*subqi_1_slp"
6629   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6630         (minus:QI (match_dup 0)
6631                   (match_operand:QI 1 "general_operand" "qn,qm")))
6632    (clobber (reg:CC FLAGS_REG))]
6633   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6634    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6635   "sub{b}\t{%1, %0|%0, %1}"
6636   [(set_attr "type" "alu1")
6637    (set_attr "mode" "QI")])
6638
6639 (define_insn "*sub<mode>_2"
6640   [(set (reg FLAGS_REG)
6641         (compare
6642           (minus:SWI
6643             (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6644             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6645           (const_int 0)))
6646    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6647         (minus:SWI (match_dup 1) (match_dup 2)))]
6648   "ix86_match_ccmode (insn, CCGOCmode)
6649    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6650   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6651   [(set_attr "type" "alu")
6652    (set_attr "mode" "<MODE>")])
6653
6654 (define_insn "*subsi_2_zext"
6655   [(set (reg FLAGS_REG)
6656         (compare
6657           (minus:SI (match_operand:SI 1 "register_operand" "0")
6658                     (match_operand:SI 2 "general_operand" "g"))
6659           (const_int 0)))
6660    (set (match_operand:DI 0 "register_operand" "=r")
6661         (zero_extend:DI
6662           (minus:SI (match_dup 1)
6663                     (match_dup 2))))]
6664   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6665    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6666   "sub{l}\t{%2, %k0|%k0, %2}"
6667   [(set_attr "type" "alu")
6668    (set_attr "mode" "SI")])
6669
6670 (define_insn "*sub<mode>_3"
6671   [(set (reg FLAGS_REG)
6672         (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6673                  (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6674    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6675         (minus:SWI (match_dup 1) (match_dup 2)))]
6676   "ix86_match_ccmode (insn, CCmode)
6677    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6678   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6679   [(set_attr "type" "alu")
6680    (set_attr "mode" "<MODE>")])
6681
6682 (define_insn "*subsi_3_zext"
6683   [(set (reg FLAGS_REG)
6684         (compare (match_operand:SI 1 "register_operand" "0")
6685                  (match_operand:SI 2 "general_operand" "g")))
6686    (set (match_operand:DI 0 "register_operand" "=r")
6687         (zero_extend:DI
6688           (minus:SI (match_dup 1)
6689                     (match_dup 2))))]
6690   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6691    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6692   "sub{l}\t{%2, %1|%1, %2}"
6693   [(set_attr "type" "alu")
6694    (set_attr "mode" "SI")])
6695 \f
6696 ;; Add with carry and subtract with borrow
6697
6698 (define_expand "<plusminus_insn><mode>3_carry"
6699   [(parallel
6700     [(set (match_operand:SWI 0 "nonimmediate_operand" "")
6701           (plusminus:SWI
6702             (match_operand:SWI 1 "nonimmediate_operand" "")
6703             (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6704                        [(match_operand 3 "flags_reg_operand" "")
6705                         (const_int 0)])
6706                       (match_operand:SWI 2 "<general_operand>" ""))))
6707      (clobber (reg:CC FLAGS_REG))])]
6708   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6709   "")
6710
6711 (define_insn "*<plusminus_insn><mode>3_carry"
6712   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6713         (plusminus:SWI
6714           (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6715           (plus:SWI
6716             (match_operator 3 "ix86_carry_flag_operator"
6717              [(reg FLAGS_REG) (const_int 0)])
6718             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6719    (clobber (reg:CC FLAGS_REG))]
6720   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6721   "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6722   [(set_attr "type" "alu")
6723    (set_attr "use_carry" "1")
6724    (set_attr "pent_pair" "pu")
6725    (set_attr "mode" "<MODE>")])
6726
6727 (define_insn "*addsi3_carry_zext"
6728   [(set (match_operand:DI 0 "register_operand" "=r")
6729         (zero_extend:DI
6730           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6731                    (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6732                              [(reg FLAGS_REG) (const_int 0)])
6733                             (match_operand:SI 2 "general_operand" "g")))))
6734    (clobber (reg:CC FLAGS_REG))]
6735   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6736   "adc{l}\t{%2, %k0|%k0, %2}"
6737   [(set_attr "type" "alu")
6738    (set_attr "use_carry" "1")
6739    (set_attr "pent_pair" "pu")
6740    (set_attr "mode" "SI")])
6741
6742 (define_insn "*subsi3_carry_zext"
6743   [(set (match_operand:DI 0 "register_operand" "=r")
6744         (zero_extend:DI
6745           (minus:SI (match_operand:SI 1 "register_operand" "0")
6746                     (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6747                               [(reg FLAGS_REG) (const_int 0)])
6748                              (match_operand:SI 2 "general_operand" "g")))))
6749    (clobber (reg:CC FLAGS_REG))]
6750   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6751   "sbb{l}\t{%2, %k0|%k0, %2}"
6752   [(set_attr "type" "alu")
6753    (set_attr "pent_pair" "pu")
6754    (set_attr "mode" "SI")])
6755 \f
6756 ;; Overflow setting add and subtract instructions
6757
6758 (define_insn "*add<mode>3_cconly_overflow"
6759   [(set (reg:CCC FLAGS_REG)
6760         (compare:CCC
6761           (plus:SWI
6762             (match_operand:SWI 1 "nonimmediate_operand" "%0")
6763             (match_operand:SWI 2 "<general_operand>" "<g>"))
6764           (match_dup 1)))
6765    (clobber (match_scratch:SWI 0 "=<r>"))]
6766   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6767   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6768   [(set_attr "type" "alu")
6769    (set_attr "mode" "<MODE>")])
6770
6771 (define_insn "*sub<mode>3_cconly_overflow"
6772   [(set (reg:CCC FLAGS_REG)
6773         (compare:CCC
6774           (minus:SWI
6775             (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6776             (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6777           (match_dup 0)))]
6778   ""
6779   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6780   [(set_attr "type" "icmp")
6781    (set_attr "mode" "<MODE>")])
6782
6783 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6784   [(set (reg:CCC FLAGS_REG)
6785         (compare:CCC
6786             (plusminus:SWI
6787                 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6788                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6789             (match_dup 1)))
6790    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6791         (plusminus:SWI (match_dup 1) (match_dup 2)))]
6792   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6793   "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6794   [(set_attr "type" "alu")
6795    (set_attr "mode" "<MODE>")])
6796
6797 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6798   [(set (reg:CCC FLAGS_REG)
6799         (compare:CCC
6800           (plusminus:SI
6801             (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6802             (match_operand:SI 2 "general_operand" "g"))
6803           (match_dup 1)))
6804    (set (match_operand:DI 0 "register_operand" "=r")
6805         (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6806   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6807   "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6808   [(set_attr "type" "alu")
6809    (set_attr "mode" "SI")])
6810
6811 ;; The patterns that match these are at the end of this file.
6812
6813 (define_expand "<plusminus_insn>xf3"
6814   [(set (match_operand:XF 0 "register_operand" "")
6815         (plusminus:XF
6816           (match_operand:XF 1 "register_operand" "")
6817           (match_operand:XF 2 "register_operand" "")))]
6818   "TARGET_80387"
6819   "")
6820
6821 (define_expand "<plusminus_insn><mode>3"
6822   [(set (match_operand:MODEF 0 "register_operand" "")
6823         (plusminus:MODEF
6824           (match_operand:MODEF 1 "register_operand" "")
6825           (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6826   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6827     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
6828   "")
6829 \f
6830 ;; Multiply instructions
6831
6832 (define_expand "mul<mode>3"
6833   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
6834                    (mult:SWIM248
6835                      (match_operand:SWIM248 1 "register_operand" "")
6836                      (match_operand:SWIM248 2 "<general_operand>" "")))
6837               (clobber (reg:CC FLAGS_REG))])]
6838   ""
6839   "")
6840
6841 (define_expand "mulqi3"
6842   [(parallel [(set (match_operand:QI 0 "register_operand" "")
6843                    (mult:QI
6844                      (match_operand:QI 1 "register_operand" "")
6845                      (match_operand:QI 2 "nonimmediate_operand" "")))
6846               (clobber (reg:CC FLAGS_REG))])]
6847   "TARGET_QIMODE_MATH"
6848   "")
6849
6850 ;; On AMDFAM10
6851 ;; IMUL reg32/64, reg32/64, imm8        Direct
6852 ;; IMUL reg32/64, mem32/64, imm8        VectorPath
6853 ;; IMUL reg32/64, reg32/64, imm32       Direct
6854 ;; IMUL reg32/64, mem32/64, imm32       VectorPath
6855 ;; IMUL reg32/64, reg32/64              Direct
6856 ;; IMUL reg32/64, mem32/64              Direct
6857
6858 (define_insn "*mul<mode>3_1"
6859   [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6860         (mult:SWI48
6861           (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6862           (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6863    (clobber (reg:CC FLAGS_REG))]
6864   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6865   "@
6866    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6867    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6868    imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6869   [(set_attr "type" "imul")
6870    (set_attr "prefix_0f" "0,0,1")
6871    (set (attr "athlon_decode")
6872         (cond [(eq_attr "cpu" "athlon")
6873                   (const_string "vector")
6874                (eq_attr "alternative" "1")
6875                   (const_string "vector")
6876                (and (eq_attr "alternative" "2")
6877                     (match_operand 1 "memory_operand" ""))
6878                   (const_string "vector")]
6879               (const_string "direct")))
6880    (set (attr "amdfam10_decode")
6881         (cond [(and (eq_attr "alternative" "0,1")
6882                     (match_operand 1 "memory_operand" ""))
6883                   (const_string "vector")]
6884               (const_string "direct")))
6885    (set_attr "mode" "<MODE>")])
6886
6887 (define_insn "*mulsi3_1_zext"
6888   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6889         (zero_extend:DI
6890           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6891                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
6892    (clobber (reg:CC FLAGS_REG))]
6893   "TARGET_64BIT
6894    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6895   "@
6896    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6897    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6898    imul{l}\t{%2, %k0|%k0, %2}"
6899   [(set_attr "type" "imul")
6900    (set_attr "prefix_0f" "0,0,1")
6901    (set (attr "athlon_decode")
6902         (cond [(eq_attr "cpu" "athlon")
6903                   (const_string "vector")
6904                (eq_attr "alternative" "1")
6905                   (const_string "vector")
6906                (and (eq_attr "alternative" "2")
6907                     (match_operand 1 "memory_operand" ""))
6908                   (const_string "vector")]
6909               (const_string "direct")))
6910    (set (attr "amdfam10_decode")
6911         (cond [(and (eq_attr "alternative" "0,1")
6912                     (match_operand 1 "memory_operand" ""))
6913                   (const_string "vector")]
6914               (const_string "direct")))
6915    (set_attr "mode" "SI")])
6916
6917 ;; On AMDFAM10
6918 ;; IMUL reg16, reg16, imm8      VectorPath
6919 ;; IMUL reg16, mem16, imm8      VectorPath
6920 ;; IMUL reg16, reg16, imm16     VectorPath
6921 ;; IMUL reg16, mem16, imm16     VectorPath
6922 ;; IMUL reg16, reg16            Direct
6923 ;; IMUL reg16, mem16            Direct
6924
6925 (define_insn "*mulhi3_1"
6926   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6927         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6928                  (match_operand:HI 2 "general_operand" "K,n,mr")))
6929    (clobber (reg:CC FLAGS_REG))]
6930   "TARGET_HIMODE_MATH
6931    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6932   "@
6933    imul{w}\t{%2, %1, %0|%0, %1, %2}
6934    imul{w}\t{%2, %1, %0|%0, %1, %2}
6935    imul{w}\t{%2, %0|%0, %2}"
6936   [(set_attr "type" "imul")
6937    (set_attr "prefix_0f" "0,0,1")
6938    (set (attr "athlon_decode")
6939         (cond [(eq_attr "cpu" "athlon")
6940                   (const_string "vector")
6941                (eq_attr "alternative" "1,2")
6942                   (const_string "vector")]
6943               (const_string "direct")))
6944    (set (attr "amdfam10_decode")
6945         (cond [(eq_attr "alternative" "0,1")
6946                   (const_string "vector")]
6947               (const_string "direct")))
6948    (set_attr "mode" "HI")])
6949
6950 ;;On AMDFAM10
6951 ;; MUL reg8     Direct
6952 ;; MUL mem8     Direct
6953
6954 (define_insn "*mulqi3_1"
6955   [(set (match_operand:QI 0 "register_operand" "=a")
6956         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6957                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
6958    (clobber (reg:CC FLAGS_REG))]
6959   "TARGET_QIMODE_MATH
6960    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6961   "mul{b}\t%2"
6962   [(set_attr "type" "imul")
6963    (set_attr "length_immediate" "0")
6964    (set (attr "athlon_decode")
6965      (if_then_else (eq_attr "cpu" "athlon")
6966         (const_string "vector")
6967         (const_string "direct")))
6968    (set_attr "amdfam10_decode" "direct")
6969    (set_attr "mode" "QI")])
6970
6971 (define_expand "<u>mul<mode><dwi>3"
6972   [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
6973                    (mult:<DWI>
6974                      (any_extend:<DWI>
6975                        (match_operand:DWIH 1 "nonimmediate_operand" ""))
6976                      (any_extend:<DWI>
6977                        (match_operand:DWIH 2 "register_operand" ""))))
6978               (clobber (reg:CC FLAGS_REG))])]
6979   ""
6980   "")
6981
6982 (define_expand "<u>mulqihi3"
6983   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6984                    (mult:HI
6985                      (any_extend:HI
6986                        (match_operand:QI 1 "nonimmediate_operand" ""))
6987                      (any_extend:HI
6988                        (match_operand:QI 2 "register_operand" ""))))
6989               (clobber (reg:CC FLAGS_REG))])]
6990   "TARGET_QIMODE_MATH"
6991   "")
6992
6993 (define_insn "*<u>mul<mode><dwi>3_1"
6994   [(set (match_operand:<DWI> 0 "register_operand" "=A")
6995         (mult:<DWI>
6996           (any_extend:<DWI>
6997             (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6998           (any_extend:<DWI>
6999             (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7000    (clobber (reg:CC FLAGS_REG))]
7001   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7002   "<sgnprefix>mul{<imodesuffix>}\t%2"
7003   [(set_attr "type" "imul")
7004    (set_attr "length_immediate" "0")
7005    (set (attr "athlon_decode")
7006      (if_then_else (eq_attr "cpu" "athlon")
7007         (const_string "vector")
7008         (const_string "double")))
7009    (set_attr "amdfam10_decode" "double")
7010    (set_attr "mode" "<MODE>")])
7011
7012 (define_insn "*<u>mulqihi3_1"
7013   [(set (match_operand:HI 0 "register_operand" "=a")
7014         (mult:HI
7015           (any_extend:HI
7016             (match_operand:QI 1 "nonimmediate_operand" "%0"))
7017           (any_extend:HI
7018             (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7019    (clobber (reg:CC FLAGS_REG))]
7020   "TARGET_QIMODE_MATH
7021    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7022   "<sgnprefix>mul{b}\t%2"
7023   [(set_attr "type" "imul")
7024    (set_attr "length_immediate" "0")
7025    (set (attr "athlon_decode")
7026      (if_then_else (eq_attr "cpu" "athlon")
7027         (const_string "vector")
7028         (const_string "direct")))
7029    (set_attr "amdfam10_decode" "direct")
7030    (set_attr "mode" "QI")])
7031
7032 (define_expand "<s>mul<mode>3_highpart"
7033   [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
7034                    (truncate:SWI48
7035                      (lshiftrt:<DWI>
7036                        (mult:<DWI>
7037                          (any_extend:<DWI>
7038                            (match_operand:SWI48 1 "nonimmediate_operand" ""))
7039                          (any_extend:<DWI>
7040                            (match_operand:SWI48 2 "register_operand" "")))
7041                        (match_dup 4))))
7042               (clobber (match_scratch:SWI48 3 ""))
7043               (clobber (reg:CC FLAGS_REG))])]
7044   ""
7045   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7046
7047 (define_insn "*<s>muldi3_highpart_1"
7048   [(set (match_operand:DI 0 "register_operand" "=d")
7049         (truncate:DI
7050           (lshiftrt:TI
7051             (mult:TI
7052               (any_extend:TI
7053                 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7054               (any_extend:TI
7055                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7056             (const_int 64))))
7057    (clobber (match_scratch:DI 3 "=1"))
7058    (clobber (reg:CC FLAGS_REG))]
7059   "TARGET_64BIT
7060    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7061   "<sgnprefix>mul{q}\t%2"
7062   [(set_attr "type" "imul")
7063    (set_attr "length_immediate" "0")
7064    (set (attr "athlon_decode")
7065      (if_then_else (eq_attr "cpu" "athlon")
7066         (const_string "vector")
7067         (const_string "double")))
7068    (set_attr "amdfam10_decode" "double")
7069    (set_attr "mode" "DI")])
7070
7071 (define_insn "*<s>mulsi3_highpart_1"
7072   [(set (match_operand:SI 0 "register_operand" "=d")
7073         (truncate:SI
7074           (lshiftrt:DI
7075             (mult:DI
7076               (any_extend:DI
7077                 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7078               (any_extend:DI
7079                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7080             (const_int 32))))
7081    (clobber (match_scratch:SI 3 "=1"))
7082    (clobber (reg:CC FLAGS_REG))]
7083   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7084   "<sgnprefix>mul{l}\t%2"
7085   [(set_attr "type" "imul")
7086    (set_attr "length_immediate" "0")
7087    (set (attr "athlon_decode")
7088      (if_then_else (eq_attr "cpu" "athlon")
7089         (const_string "vector")
7090         (const_string "double")))
7091    (set_attr "amdfam10_decode" "double")
7092    (set_attr "mode" "SI")])
7093
7094 (define_insn "*<s>mulsi3_highpart_zext"
7095   [(set (match_operand:DI 0 "register_operand" "=d")
7096         (zero_extend:DI (truncate:SI
7097           (lshiftrt:DI
7098             (mult:DI (any_extend:DI
7099                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7100                      (any_extend:DI
7101                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7102             (const_int 32)))))
7103    (clobber (match_scratch:SI 3 "=1"))
7104    (clobber (reg:CC FLAGS_REG))]
7105   "TARGET_64BIT
7106    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7107   "<sgnprefix>mul{l}\t%2"
7108   [(set_attr "type" "imul")
7109    (set_attr "length_immediate" "0")
7110    (set (attr "athlon_decode")
7111      (if_then_else (eq_attr "cpu" "athlon")
7112         (const_string "vector")
7113         (const_string "double")))
7114    (set_attr "amdfam10_decode" "double")
7115    (set_attr "mode" "SI")])
7116
7117 ;; The patterns that match these are at the end of this file.
7118
7119 (define_expand "mulxf3"
7120   [(set (match_operand:XF 0 "register_operand" "")
7121         (mult:XF (match_operand:XF 1 "register_operand" "")
7122                  (match_operand:XF 2 "register_operand" "")))]
7123   "TARGET_80387"
7124   "")
7125
7126 (define_expand "mul<mode>3"
7127   [(set (match_operand:MODEF 0 "register_operand" "")
7128         (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
7129                     (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7130   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7131     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7132   "")
7133 \f
7134 ;; Divide instructions
7135
7136 ;; The patterns that match these are at the end of this file.
7137
7138 (define_expand "divxf3"
7139   [(set (match_operand:XF 0 "register_operand" "")
7140         (div:XF (match_operand:XF 1 "register_operand" "")
7141                 (match_operand:XF 2 "register_operand" "")))]
7142   "TARGET_80387"
7143   "")
7144
7145 (define_expand "divdf3"
7146   [(set (match_operand:DF 0 "register_operand" "")
7147         (div:DF (match_operand:DF 1 "register_operand" "")
7148                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7149    "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7150     || (TARGET_SSE2 && TARGET_SSE_MATH)"
7151    "")
7152
7153 (define_expand "divsf3"
7154   [(set (match_operand:SF 0 "register_operand" "")
7155         (div:SF (match_operand:SF 1 "register_operand" "")
7156                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7157   "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7158     || TARGET_SSE_MATH"
7159 {
7160   if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
7161       && flag_finite_math_only && !flag_trapping_math
7162       && flag_unsafe_math_optimizations)
7163     {
7164       ix86_emit_swdivsf (operands[0], operands[1],
7165                          operands[2], SFmode);
7166       DONE;
7167     }
7168 })
7169 \f
7170 ;; Divmod instructions.
7171
7172 (define_expand "divmodqi4"
7173   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7174                    (div:QI
7175                      (match_operand:QI 1 "register_operand" "")
7176                      (match_operand:QI 2 "nonimmediate_operand" "")))
7177               (set (match_operand:QI 3 "register_operand" "")
7178                    (mod:QI (match_dup 1) (match_dup 2)))
7179               (clobber (reg:CC FLAGS_REG))])]
7180   "TARGET_QIMODE_MATH"
7181 {
7182   rtx div, mod, insn;
7183   rtx tmp0, tmp1;
7184   
7185   tmp0 = gen_reg_rtx (HImode);
7186   tmp1 = gen_reg_rtx (HImode);
7187
7188   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is
7189      in AX.  */
7190   emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7191   emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7192
7193   /* Extract remainder from AH.  */
7194   tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7195   insn = emit_move_insn (operands[3], tmp1);
7196
7197   mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7198   set_unique_reg_note (insn, REG_EQUAL, mod);
7199
7200   /* Extract quotient from AL.  */
7201   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7202
7203   div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7204   set_unique_reg_note (insn, REG_EQUAL, div);
7205
7206   DONE;
7207 })
7208
7209 (define_expand "udivmodqi4"
7210   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7211                    (udiv:QI
7212                      (match_operand:QI 1 "register_operand" "")
7213                      (match_operand:QI 2 "nonimmediate_operand" "")))
7214               (set (match_operand:QI 3 "register_operand" "")
7215                    (umod:QI (match_dup 1) (match_dup 2)))
7216               (clobber (reg:CC FLAGS_REG))])]
7217   "TARGET_QIMODE_MATH"
7218 {
7219   rtx div, mod, insn;
7220   rtx tmp0, tmp1;
7221   
7222   tmp0 = gen_reg_rtx (HImode);
7223   tmp1 = gen_reg_rtx (HImode);
7224
7225   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is
7226      in AX.  */
7227   emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7228   emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7229
7230   /* Extract remainder from AH.  */
7231   tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7232   tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7233   insn = emit_move_insn (operands[3], tmp1);
7234
7235   mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7236   set_unique_reg_note (insn, REG_EQUAL, mod);
7237
7238   /* Extract quotient from AL.  */
7239   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7240
7241   div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7242   set_unique_reg_note (insn, REG_EQUAL, div);
7243
7244   DONE;
7245 })
7246
7247 ;; Divide AX by r/m8, with result stored in
7248 ;; AL <- Quotient
7249 ;; AH <- Remainder
7250 ;; Change div/mod to HImode and extend the second argument to HImode
7251 ;; so that mode of div/mod matches with mode of arguments.  Otherwise
7252 ;; combine may fail.
7253 (define_insn "divmodhiqi3"
7254   [(set (match_operand:HI 0 "register_operand" "=a")
7255         (ior:HI
7256           (ashift:HI
7257             (zero_extend:HI
7258               (truncate:QI
7259                 (mod:HI (match_operand:HI 1 "register_operand" "0")
7260                         (sign_extend:HI
7261                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7262             (const_int 8))
7263           (zero_extend:HI
7264             (truncate:QI
7265               (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7266    (clobber (reg:CC FLAGS_REG))]
7267   "TARGET_QIMODE_MATH"
7268   "idiv{b}\t%2"
7269   [(set_attr "type" "idiv")
7270    (set_attr "mode" "QI")])
7271
7272 (define_insn "udivmodhiqi3"
7273   [(set (match_operand:HI 0 "register_operand" "=a")
7274         (ior:HI
7275           (ashift:HI
7276             (zero_extend:HI
7277               (truncate:QI
7278                 (mod:HI (match_operand:HI 1 "register_operand" "0")
7279                         (zero_extend:HI
7280                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7281             (const_int 8))
7282           (zero_extend:HI
7283             (truncate:QI
7284               (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7285    (clobber (reg:CC FLAGS_REG))]
7286   "TARGET_QIMODE_MATH"
7287   "div{b}\t%2"
7288   [(set_attr "type" "idiv")
7289    (set_attr "mode" "QI")])
7290
7291 (define_expand "divmod<mode>4"
7292   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7293                    (div:SWIM248
7294                      (match_operand:SWIM248 1 "register_operand" "")
7295                      (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7296               (set (match_operand:SWIM248 3 "register_operand" "")
7297                    (mod:SWIM248 (match_dup 1) (match_dup 2)))
7298               (clobber (reg:CC FLAGS_REG))])]
7299   ""
7300   "")
7301
7302 (define_insn_and_split "*divmod<mode>4"
7303   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7304         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7305                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7306    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7307         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7308    (clobber (reg:CC FLAGS_REG))]
7309   ""
7310   "#"
7311   "reload_completed"
7312   [(parallel [(set (match_dup 1)
7313                    (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7314               (clobber (reg:CC FLAGS_REG))])
7315    (parallel [(set (match_dup 0)
7316                    (div:SWIM248 (match_dup 2) (match_dup 3)))
7317               (set (match_dup 1)
7318                    (mod:SWIM248 (match_dup 2) (match_dup 3)))
7319               (use (match_dup 1))
7320               (clobber (reg:CC FLAGS_REG))])]
7321 {
7322   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7323
7324   if (<MODE>mode != HImode
7325       && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7326     operands[4] = operands[2];
7327   else
7328     {
7329       /* Avoid use of cltd in favor of a mov+shift.  */
7330       emit_move_insn (operands[1], operands[2]);
7331       operands[4] = operands[1];
7332     }
7333 }
7334   [(set_attr "type" "multi")
7335    (set_attr "mode" "<MODE>")])
7336
7337 (define_insn "*divmod<mode>4_noext"
7338   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7339         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7340                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7341    (set (match_operand:SWIM248 1 "register_operand" "=d")
7342         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7343    (use (match_operand:SWIM248 4 "register_operand" "1"))
7344    (clobber (reg:CC FLAGS_REG))]
7345   ""
7346   "idiv{<imodesuffix>}\t%3"
7347   [(set_attr "type" "idiv")
7348    (set_attr "mode" "<MODE>")])
7349
7350 (define_expand "udivmod<mode>4"
7351   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7352                    (udiv:SWIM248
7353                      (match_operand:SWIM248 1 "register_operand" "")
7354                      (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7355               (set (match_operand:SWIM248 3 "register_operand" "")
7356                    (umod:SWIM248 (match_dup 1) (match_dup 2)))
7357               (clobber (reg:CC FLAGS_REG))])]
7358   ""
7359   "")
7360
7361 (define_insn_and_split "*udivmod<mode>4"
7362   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7363         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7364                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7365    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7366         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7367    (clobber (reg:CC FLAGS_REG))]
7368   ""
7369   "#"
7370   "reload_completed"
7371   [(set (match_dup 1) (const_int 0))
7372    (parallel [(set (match_dup 0)
7373                    (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7374               (set (match_dup 1)
7375                    (umod:SWIM248 (match_dup 2) (match_dup 3)))
7376               (use (match_dup 1))
7377               (clobber (reg:CC FLAGS_REG))])]
7378   ""
7379   [(set_attr "type" "multi")
7380    (set_attr "mode" "<MODE>")])
7381
7382 (define_insn "*udivmod<mode>4_noext"
7383   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7384         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7385                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7386    (set (match_operand:SWIM248 1 "register_operand" "=d")
7387         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7388    (use (match_operand:SWIM248 4 "register_operand" "1"))
7389    (clobber (reg:CC FLAGS_REG))]
7390   ""
7391   "div{<imodesuffix>}\t%3"
7392   [(set_attr "type" "idiv")
7393    (set_attr "mode" "<MODE>")])
7394
7395 ;; We cannot use div/idiv for double division, because it causes
7396 ;; "division by zero" on the overflow and that's not what we expect
7397 ;; from truncate.  Because true (non truncating) double division is
7398 ;; never generated, we can't create this insn anyway.
7399 ;
7400 ;(define_insn ""
7401 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7402 ;       (truncate:SI
7403 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7404 ;                  (zero_extend:DI
7405 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7406 ;   (set (match_operand:SI 3 "register_operand" "=d")
7407 ;       (truncate:SI
7408 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7409 ;   (clobber (reg:CC FLAGS_REG))]
7410 ;  ""
7411 ;  "div{l}\t{%2, %0|%0, %2}"
7412 ;  [(set_attr "type" "idiv")])
7413 \f
7414 ;;- Logical AND instructions
7415
7416 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7417 ;; Note that this excludes ah.
7418
7419 (define_expand "testsi_ccno_1"
7420   [(set (reg:CCNO FLAGS_REG)
7421         (compare:CCNO
7422           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7423                   (match_operand:SI 1 "nonmemory_operand" ""))
7424           (const_int 0)))]
7425   ""
7426   "")
7427
7428 (define_expand "testqi_ccz_1"
7429   [(set (reg:CCZ FLAGS_REG)
7430         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7431                              (match_operand:QI 1 "nonmemory_operand" ""))
7432                  (const_int 0)))]
7433   ""
7434   "")
7435
7436 (define_insn "*testdi_1"
7437   [(set (reg FLAGS_REG)
7438         (compare
7439          (and:DI
7440           (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7441           (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7442          (const_int 0)))]
7443   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7444    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7445   "@
7446    test{l}\t{%k1, %k0|%k0, %k1}
7447    test{l}\t{%k1, %k0|%k0, %k1}
7448    test{q}\t{%1, %0|%0, %1}
7449    test{q}\t{%1, %0|%0, %1}
7450    test{q}\t{%1, %0|%0, %1}"
7451   [(set_attr "type" "test")
7452    (set_attr "modrm" "0,1,0,1,1")
7453    (set_attr "mode" "SI,SI,DI,DI,DI")])
7454
7455 (define_insn "*testqi_1_maybe_si"
7456   [(set (reg FLAGS_REG)
7457         (compare
7458           (and:QI
7459             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7460             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7461           (const_int 0)))]
7462    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7463     && ix86_match_ccmode (insn,
7464                          CONST_INT_P (operands[1])
7465                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7466 {
7467   if (which_alternative == 3)
7468     {
7469       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7470         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7471       return "test{l}\t{%1, %k0|%k0, %1}";
7472     }
7473   return "test{b}\t{%1, %0|%0, %1}";
7474 }
7475   [(set_attr "type" "test")
7476    (set_attr "modrm" "0,1,1,1")
7477    (set_attr "mode" "QI,QI,QI,SI")
7478    (set_attr "pent_pair" "uv,np,uv,np")])
7479
7480 (define_insn "*test<mode>_1"
7481   [(set (reg FLAGS_REG)
7482         (compare
7483          (and:SWI124
7484           (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7485           (match_operand:SWI124 1 "general_operand" "<i>,<i>,<r><i>"))
7486          (const_int 0)))]
7487   "ix86_match_ccmode (insn, CCNOmode)
7488    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7489   "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7490   [(set_attr "type" "test")
7491    (set_attr "modrm" "0,1,1")
7492    (set_attr "mode" "<MODE>")
7493    (set_attr "pent_pair" "uv,np,uv")])
7494
7495 (define_expand "testqi_ext_ccno_0"
7496   [(set (reg:CCNO FLAGS_REG)
7497         (compare:CCNO
7498           (and:SI
7499             (zero_extract:SI
7500               (match_operand 0 "ext_register_operand" "")
7501               (const_int 8)
7502               (const_int 8))
7503             (match_operand 1 "const_int_operand" ""))
7504           (const_int 0)))]
7505   ""
7506   "")
7507
7508 (define_insn "*testqi_ext_0"
7509   [(set (reg FLAGS_REG)
7510         (compare
7511           (and:SI
7512             (zero_extract:SI
7513               (match_operand 0 "ext_register_operand" "Q")
7514               (const_int 8)
7515               (const_int 8))
7516             (match_operand 1 "const_int_operand" "n"))
7517           (const_int 0)))]
7518   "ix86_match_ccmode (insn, CCNOmode)"
7519   "test{b}\t{%1, %h0|%h0, %1}"
7520   [(set_attr "type" "test")
7521    (set_attr "mode" "QI")
7522    (set_attr "length_immediate" "1")
7523    (set_attr "modrm" "1")
7524    (set_attr "pent_pair" "np")])
7525
7526 (define_insn "*testqi_ext_1_rex64"
7527   [(set (reg FLAGS_REG)
7528         (compare
7529           (and:SI
7530             (zero_extract:SI
7531               (match_operand 0 "ext_register_operand" "Q")
7532               (const_int 8)
7533               (const_int 8))
7534             (zero_extend:SI
7535               (match_operand:QI 1 "register_operand" "Q")))
7536           (const_int 0)))]
7537   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7538   "test{b}\t{%1, %h0|%h0, %1}"
7539   [(set_attr "type" "test")
7540    (set_attr "mode" "QI")])
7541
7542 (define_insn "*testqi_ext_1"
7543   [(set (reg FLAGS_REG)
7544         (compare
7545           (and:SI
7546             (zero_extract:SI
7547               (match_operand 0 "ext_register_operand" "Q")
7548               (const_int 8)
7549               (const_int 8))
7550             (zero_extend:SI
7551               (match_operand:QI 1 "general_operand" "Qm")))
7552           (const_int 0)))]
7553   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7554   "test{b}\t{%1, %h0|%h0, %1}"
7555   [(set_attr "type" "test")
7556    (set_attr "mode" "QI")])
7557
7558 (define_insn "*testqi_ext_2"
7559   [(set (reg FLAGS_REG)
7560         (compare
7561           (and:SI
7562             (zero_extract:SI
7563               (match_operand 0 "ext_register_operand" "Q")
7564               (const_int 8)
7565               (const_int 8))
7566             (zero_extract:SI
7567               (match_operand 1 "ext_register_operand" "Q")
7568               (const_int 8)
7569               (const_int 8)))
7570           (const_int 0)))]
7571   "ix86_match_ccmode (insn, CCNOmode)"
7572   "test{b}\t{%h1, %h0|%h0, %h1}"
7573   [(set_attr "type" "test")
7574    (set_attr "mode" "QI")])
7575
7576 (define_insn "*testqi_ext_3_rex64"
7577   [(set (reg FLAGS_REG)
7578         (compare (zero_extract:DI
7579                    (match_operand 0 "nonimmediate_operand" "rm")
7580                    (match_operand:DI 1 "const_int_operand" "")
7581                    (match_operand:DI 2 "const_int_operand" ""))
7582                  (const_int 0)))]
7583   "TARGET_64BIT
7584    && ix86_match_ccmode (insn, CCNOmode)
7585    && INTVAL (operands[1]) > 0
7586    && INTVAL (operands[2]) >= 0
7587    /* Ensure that resulting mask is zero or sign extended operand.  */
7588    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7589        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7590            && INTVAL (operands[1]) > 32))
7591    && (GET_MODE (operands[0]) == SImode
7592        || GET_MODE (operands[0]) == DImode
7593        || GET_MODE (operands[0]) == HImode
7594        || GET_MODE (operands[0]) == QImode)"
7595   "#")
7596
7597 ;; Combine likes to form bit extractions for some tests.  Humor it.
7598 (define_insn "*testqi_ext_3"
7599   [(set (reg FLAGS_REG)
7600         (compare (zero_extract:SI
7601                    (match_operand 0 "nonimmediate_operand" "rm")
7602                    (match_operand:SI 1 "const_int_operand" "")
7603                    (match_operand:SI 2 "const_int_operand" ""))
7604                  (const_int 0)))]
7605   "ix86_match_ccmode (insn, CCNOmode)
7606    && INTVAL (operands[1]) > 0
7607    && INTVAL (operands[2]) >= 0
7608    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7609    && (GET_MODE (operands[0]) == SImode
7610        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7611        || GET_MODE (operands[0]) == HImode
7612        || GET_MODE (operands[0]) == QImode)"
7613   "#")
7614
7615 (define_split
7616   [(set (match_operand 0 "flags_reg_operand" "")
7617         (match_operator 1 "compare_operator"
7618           [(zero_extract
7619              (match_operand 2 "nonimmediate_operand" "")
7620              (match_operand 3 "const_int_operand" "")
7621              (match_operand 4 "const_int_operand" ""))
7622            (const_int 0)]))]
7623   "ix86_match_ccmode (insn, CCNOmode)"
7624   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7625 {
7626   rtx val = operands[2];
7627   HOST_WIDE_INT len = INTVAL (operands[3]);
7628   HOST_WIDE_INT pos = INTVAL (operands[4]);
7629   HOST_WIDE_INT mask;
7630   enum machine_mode mode, submode;
7631
7632   mode = GET_MODE (val);
7633   if (MEM_P (val))
7634     {
7635       /* ??? Combine likes to put non-volatile mem extractions in QImode
7636          no matter the size of the test.  So find a mode that works.  */
7637       if (! MEM_VOLATILE_P (val))
7638         {
7639           mode = smallest_mode_for_size (pos + len, MODE_INT);
7640           val = adjust_address (val, mode, 0);
7641         }
7642     }
7643   else if (GET_CODE (val) == SUBREG
7644            && (submode = GET_MODE (SUBREG_REG (val)),
7645                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7646            && pos + len <= GET_MODE_BITSIZE (submode)
7647            && GET_MODE_CLASS (submode) == MODE_INT)
7648     {
7649       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
7650       mode = submode;
7651       val = SUBREG_REG (val);
7652     }
7653   else if (mode == HImode && pos + len <= 8)
7654     {
7655       /* Small HImode tests can be converted to QImode.  */
7656       mode = QImode;
7657       val = gen_lowpart (QImode, val);
7658     }
7659
7660   if (len == HOST_BITS_PER_WIDE_INT)
7661     mask = -1;
7662   else
7663     mask = ((HOST_WIDE_INT)1 << len) - 1;
7664   mask <<= pos;
7665
7666   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7667 })
7668
7669 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7670 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7671 ;; this is relatively important trick.
7672 ;; Do the conversion only post-reload to avoid limiting of the register class
7673 ;; to QI regs.
7674 (define_split
7675   [(set (match_operand 0 "flags_reg_operand" "")
7676         (match_operator 1 "compare_operator"
7677           [(and (match_operand 2 "register_operand" "")
7678                 (match_operand 3 "const_int_operand" ""))
7679            (const_int 0)]))]
7680    "reload_completed
7681     && QI_REG_P (operands[2])
7682     && GET_MODE (operands[2]) != QImode
7683     && ((ix86_match_ccmode (insn, CCZmode)
7684          && !(INTVAL (operands[3]) & ~(255 << 8)))
7685         || (ix86_match_ccmode (insn, CCNOmode)
7686             && !(INTVAL (operands[3]) & ~(127 << 8))))"
7687   [(set (match_dup 0)
7688         (match_op_dup 1
7689           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7690                    (match_dup 3))
7691            (const_int 0)]))]
7692   "operands[2] = gen_lowpart (SImode, operands[2]);
7693    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7694
7695 (define_split
7696   [(set (match_operand 0 "flags_reg_operand" "")
7697         (match_operator 1 "compare_operator"
7698           [(and (match_operand 2 "nonimmediate_operand" "")
7699                 (match_operand 3 "const_int_operand" ""))
7700            (const_int 0)]))]
7701    "reload_completed
7702     && GET_MODE (operands[2]) != QImode
7703     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7704     && ((ix86_match_ccmode (insn, CCZmode)
7705          && !(INTVAL (operands[3]) & ~255))
7706         || (ix86_match_ccmode (insn, CCNOmode)
7707             && !(INTVAL (operands[3]) & ~127)))"
7708   [(set (match_dup 0)
7709         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7710                          (const_int 0)]))]
7711   "operands[2] = gen_lowpart (QImode, operands[2]);
7712    operands[3] = gen_lowpart (QImode, operands[3]);")
7713
7714 ;; %%% This used to optimize known byte-wide and operations to memory,
7715 ;; and sometimes to QImode registers.  If this is considered useful,
7716 ;; it should be done with splitters.
7717
7718 (define_expand "and<mode>3"
7719   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
7720         (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
7721                   (match_operand:SWIM 2 "<general_szext_operand>" "")))]
7722   ""
7723   "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
7724
7725 (define_insn "*anddi_1"
7726   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7727         (and:DI
7728          (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7729          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7730    (clobber (reg:CC FLAGS_REG))]
7731   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7732 {
7733   switch (get_attr_type (insn))
7734     {
7735     case TYPE_IMOVX:
7736       {
7737         enum machine_mode mode;
7738
7739         gcc_assert (CONST_INT_P (operands[2]));
7740         if (INTVAL (operands[2]) == 0xff)
7741           mode = QImode;
7742         else
7743           {
7744             gcc_assert (INTVAL (operands[2]) == 0xffff);
7745             mode = HImode;
7746           }
7747
7748         operands[1] = gen_lowpart (mode, operands[1]);
7749         if (mode == QImode)
7750           return "movz{bl|x}\t{%1, %k0|%k0, %1}";
7751         else
7752           return "movz{wl|x}\t{%1, %k0|%k0, %1}";
7753       }
7754
7755     default:
7756       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7757       if (get_attr_mode (insn) == MODE_SI)
7758         return "and{l}\t{%k2, %k0|%k0, %k2}";
7759       else
7760         return "and{q}\t{%2, %0|%0, %2}";
7761     }
7762 }
7763   [(set_attr "type" "alu,alu,alu,imovx")
7764    (set_attr "length_immediate" "*,*,*,0")
7765    (set (attr "prefix_rex")
7766      (if_then_else
7767        (and (eq_attr "type" "imovx")
7768             (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7769                  (match_operand 1 "ext_QIreg_nomode_operand" "")))
7770        (const_string "1")
7771        (const_string "*")))
7772    (set_attr "mode" "SI,DI,DI,SI")])
7773
7774 (define_insn "*andsi_1"
7775   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7776         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7777                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
7778    (clobber (reg:CC FLAGS_REG))]
7779   "ix86_binary_operator_ok (AND, SImode, operands)"
7780 {
7781   switch (get_attr_type (insn))
7782     {
7783     case TYPE_IMOVX:
7784       {
7785         enum machine_mode mode;
7786
7787         gcc_assert (CONST_INT_P (operands[2]));
7788         if (INTVAL (operands[2]) == 0xff)
7789           mode = QImode;
7790         else
7791           {
7792             gcc_assert (INTVAL (operands[2]) == 0xffff);
7793             mode = HImode;
7794           }
7795
7796         operands[1] = gen_lowpart (mode, operands[1]);
7797         if (mode == QImode)
7798           return "movz{bl|x}\t{%1, %0|%0, %1}";
7799         else
7800           return "movz{wl|x}\t{%1, %0|%0, %1}";
7801       }
7802
7803     default:
7804       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7805       return "and{l}\t{%2, %0|%0, %2}";
7806     }
7807 }
7808   [(set_attr "type" "alu,alu,imovx")
7809    (set (attr "prefix_rex")
7810      (if_then_else
7811        (and (eq_attr "type" "imovx")
7812             (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7813                  (match_operand 1 "ext_QIreg_nomode_operand" "")))
7814        (const_string "1")
7815        (const_string "*")))
7816    (set_attr "length_immediate" "*,*,0")
7817    (set_attr "mode" "SI")])
7818
7819 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7820 (define_insn "*andsi_1_zext"
7821   [(set (match_operand:DI 0 "register_operand" "=r")
7822         (zero_extend:DI
7823           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7824                   (match_operand:SI 2 "general_operand" "g"))))
7825    (clobber (reg:CC FLAGS_REG))]
7826   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7827   "and{l}\t{%2, %k0|%k0, %2}"
7828   [(set_attr "type" "alu")
7829    (set_attr "mode" "SI")])
7830
7831 (define_insn "*andhi_1"
7832   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
7833         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7834                 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7835    (clobber (reg:CC FLAGS_REG))]
7836   "ix86_binary_operator_ok (AND, HImode, operands)"
7837 {
7838   switch (get_attr_type (insn))
7839     {
7840     case TYPE_IMOVX:
7841       gcc_assert (CONST_INT_P (operands[2]));
7842       gcc_assert (INTVAL (operands[2]) == 0xff);
7843       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
7844
7845     default:
7846       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7847
7848       return "and{w}\t{%2, %0|%0, %2}";
7849     }
7850 }
7851   [(set_attr "type" "alu,alu,imovx")
7852    (set_attr "length_immediate" "*,*,0")
7853    (set (attr "prefix_rex")
7854      (if_then_else
7855        (and (eq_attr "type" "imovx")
7856             (match_operand 1 "ext_QIreg_nomode_operand" ""))
7857        (const_string "1")
7858        (const_string "*")))
7859    (set_attr "mode" "HI,HI,SI")])
7860
7861 ;; %%% Potential partial reg stall on alternative 2.  What to do?
7862 (define_insn "*andqi_1"
7863   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7864         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7865                 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7866    (clobber (reg:CC FLAGS_REG))]
7867   "ix86_binary_operator_ok (AND, QImode, operands)"
7868   "@
7869    and{b}\t{%2, %0|%0, %2}
7870    and{b}\t{%2, %0|%0, %2}
7871    and{l}\t{%k2, %k0|%k0, %k2}"
7872   [(set_attr "type" "alu")
7873    (set_attr "mode" "QI,QI,SI")])
7874
7875 (define_insn "*andqi_1_slp"
7876   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7877         (and:QI (match_dup 0)
7878                 (match_operand:QI 1 "general_operand" "qn,qmn")))
7879    (clobber (reg:CC FLAGS_REG))]
7880   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7881    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7882   "and{b}\t{%1, %0|%0, %1}"
7883   [(set_attr "type" "alu1")
7884    (set_attr "mode" "QI")])
7885
7886 (define_split
7887   [(set (match_operand 0 "register_operand" "")
7888         (and (match_dup 0)
7889              (const_int -65536)))
7890    (clobber (reg:CC FLAGS_REG))]
7891   "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7892     || optimize_function_for_size_p (cfun)"
7893   [(set (strict_low_part (match_dup 1)) (const_int 0))]
7894   "operands[1] = gen_lowpart (HImode, operands[0]);")
7895
7896 (define_split
7897   [(set (match_operand 0 "ext_register_operand" "")
7898         (and (match_dup 0)
7899              (const_int -256)))
7900    (clobber (reg:CC FLAGS_REG))]
7901   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7902    && reload_completed"
7903   [(set (strict_low_part (match_dup 1)) (const_int 0))]
7904   "operands[1] = gen_lowpart (QImode, operands[0]);")
7905
7906 (define_split
7907   [(set (match_operand 0 "ext_register_operand" "")
7908         (and (match_dup 0)
7909              (const_int -65281)))
7910    (clobber (reg:CC FLAGS_REG))]
7911   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7912    && reload_completed"
7913   [(parallel [(set (zero_extract:SI (match_dup 0)
7914                                     (const_int 8)
7915                                     (const_int 8))
7916                    (xor:SI
7917                      (zero_extract:SI (match_dup 0)
7918                                       (const_int 8)
7919                                       (const_int 8))
7920                      (zero_extract:SI (match_dup 0)
7921                                       (const_int 8)
7922                                       (const_int 8))))
7923               (clobber (reg:CC FLAGS_REG))])]
7924   "operands[0] = gen_lowpart (SImode, operands[0]);")
7925
7926 (define_insn "*anddi_2"
7927   [(set (reg FLAGS_REG)
7928         (compare
7929          (and:DI
7930           (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7931           (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7932          (const_int 0)))
7933    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7934         (and:DI (match_dup 1) (match_dup 2)))]
7935   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7936    && ix86_binary_operator_ok (AND, DImode, operands)"
7937   "@
7938    and{l}\t{%k2, %k0|%k0, %k2}
7939    and{q}\t{%2, %0|%0, %2}
7940    and{q}\t{%2, %0|%0, %2}"
7941   [(set_attr "type" "alu")
7942    (set_attr "mode" "SI,DI,DI")])
7943
7944 (define_insn "*andqi_2_maybe_si"
7945   [(set (reg FLAGS_REG)
7946         (compare (and:QI
7947                   (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7948                   (match_operand:QI 2 "general_operand" "qmn,qn,n"))
7949                  (const_int 0)))
7950    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
7951         (and:QI (match_dup 1) (match_dup 2)))]
7952   "ix86_binary_operator_ok (AND, QImode, operands)
7953    && ix86_match_ccmode (insn,
7954                          CONST_INT_P (operands[2])
7955                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
7956 {
7957   if (which_alternative == 2)
7958     {
7959       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
7960         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
7961       return "and{l}\t{%2, %k0|%k0, %2}";
7962     }
7963   return "and{b}\t{%2, %0|%0, %2}";
7964 }
7965   [(set_attr "type" "alu")
7966    (set_attr "mode" "QI,QI,SI")])
7967
7968 (define_insn "*and<mode>_2"
7969   [(set (reg FLAGS_REG)
7970         (compare (and:SWI124
7971                   (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
7972                   (match_operand:SWI124 2 "general_operand" "<g>,<r><i>"))
7973                  (const_int 0)))
7974    (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
7975         (and:SWI124 (match_dup 1) (match_dup 2)))]
7976   "ix86_match_ccmode (insn, CCNOmode)
7977    && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
7978   "and{<imodesuffix>}\t{%2, %0|%0, %2}"
7979   [(set_attr "type" "alu")
7980    (set_attr "mode" "<MODE>")])
7981
7982 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7983 (define_insn "*andsi_2_zext"
7984   [(set (reg FLAGS_REG)
7985         (compare (and:SI
7986                   (match_operand:SI 1 "nonimmediate_operand" "%0")
7987                   (match_operand:SI 2 "general_operand" "g"))
7988                  (const_int 0)))
7989    (set (match_operand:DI 0 "register_operand" "=r")
7990         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
7991   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7992    && ix86_binary_operator_ok (AND, SImode, operands)"
7993   "and{l}\t{%2, %k0|%k0, %2}"
7994   [(set_attr "type" "alu")
7995    (set_attr "mode" "SI")])
7996
7997 (define_insn "*andqi_2_slp"
7998   [(set (reg FLAGS_REG)
7999         (compare (and:QI
8000                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8001                    (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8002                  (const_int 0)))
8003    (set (strict_low_part (match_dup 0))
8004         (and:QI (match_dup 0) (match_dup 1)))]
8005   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8006    && ix86_match_ccmode (insn, CCNOmode)
8007    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8008   "and{b}\t{%1, %0|%0, %1}"
8009   [(set_attr "type" "alu1")
8010    (set_attr "mode" "QI")])
8011
8012 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8013 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8014 ;; for a QImode operand, which of course failed.
8015 (define_insn "andqi_ext_0"
8016   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8017                          (const_int 8)
8018                          (const_int 8))
8019         (and:SI
8020           (zero_extract:SI
8021             (match_operand 1 "ext_register_operand" "0")
8022             (const_int 8)
8023             (const_int 8))
8024           (match_operand 2 "const_int_operand" "n")))
8025    (clobber (reg:CC FLAGS_REG))]
8026   ""
8027   "and{b}\t{%2, %h0|%h0, %2}"
8028   [(set_attr "type" "alu")
8029    (set_attr "length_immediate" "1")
8030    (set_attr "modrm" "1")
8031    (set_attr "mode" "QI")])
8032
8033 ;; Generated by peephole translating test to and.  This shows up
8034 ;; often in fp comparisons.
8035 (define_insn "*andqi_ext_0_cc"
8036   [(set (reg FLAGS_REG)
8037         (compare
8038           (and:SI
8039             (zero_extract:SI
8040               (match_operand 1 "ext_register_operand" "0")
8041               (const_int 8)
8042               (const_int 8))
8043             (match_operand 2 "const_int_operand" "n"))
8044           (const_int 0)))
8045    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8046                          (const_int 8)
8047                          (const_int 8))
8048         (and:SI
8049           (zero_extract:SI
8050             (match_dup 1)
8051             (const_int 8)
8052             (const_int 8))
8053           (match_dup 2)))]
8054   "ix86_match_ccmode (insn, CCNOmode)"
8055   "and{b}\t{%2, %h0|%h0, %2}"
8056   [(set_attr "type" "alu")
8057    (set_attr "length_immediate" "1")
8058    (set_attr "modrm" "1")
8059    (set_attr "mode" "QI")])
8060
8061 (define_insn "*andqi_ext_1_rex64"
8062   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8063                          (const_int 8)
8064                          (const_int 8))
8065         (and:SI
8066           (zero_extract:SI
8067             (match_operand 1 "ext_register_operand" "0")
8068             (const_int 8)
8069             (const_int 8))
8070           (zero_extend:SI
8071             (match_operand 2 "ext_register_operand" "Q"))))
8072    (clobber (reg:CC FLAGS_REG))]
8073   "TARGET_64BIT"
8074   "and{b}\t{%2, %h0|%h0, %2}"
8075   [(set_attr "type" "alu")
8076    (set_attr "length_immediate" "0")
8077    (set_attr "mode" "QI")])
8078
8079 (define_insn "*andqi_ext_1"
8080   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8081                          (const_int 8)
8082                          (const_int 8))
8083         (and:SI
8084           (zero_extract:SI
8085             (match_operand 1 "ext_register_operand" "0")
8086             (const_int 8)
8087             (const_int 8))
8088           (zero_extend:SI
8089             (match_operand:QI 2 "general_operand" "Qm"))))
8090    (clobber (reg:CC FLAGS_REG))]
8091   "!TARGET_64BIT"
8092   "and{b}\t{%2, %h0|%h0, %2}"
8093   [(set_attr "type" "alu")
8094    (set_attr "length_immediate" "0")
8095    (set_attr "mode" "QI")])
8096
8097 (define_insn "*andqi_ext_2"
8098   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8099                          (const_int 8)
8100                          (const_int 8))
8101         (and:SI
8102           (zero_extract:SI
8103             (match_operand 1 "ext_register_operand" "%0")
8104             (const_int 8)
8105             (const_int 8))
8106           (zero_extract:SI
8107             (match_operand 2 "ext_register_operand" "Q")
8108             (const_int 8)
8109             (const_int 8))))
8110    (clobber (reg:CC FLAGS_REG))]
8111   ""
8112   "and{b}\t{%h2, %h0|%h0, %h2}"
8113   [(set_attr "type" "alu")
8114    (set_attr "length_immediate" "0")
8115    (set_attr "mode" "QI")])
8116
8117 ;; Convert wide AND instructions with immediate operand to shorter QImode
8118 ;; equivalents when possible.
8119 ;; Don't do the splitting with memory operands, since it introduces risk
8120 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8121 ;; for size, but that can (should?) be handled by generic code instead.
8122 (define_split
8123   [(set (match_operand 0 "register_operand" "")
8124         (and (match_operand 1 "register_operand" "")
8125              (match_operand 2 "const_int_operand" "")))
8126    (clobber (reg:CC FLAGS_REG))]
8127    "reload_completed
8128     && QI_REG_P (operands[0])
8129     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8130     && !(~INTVAL (operands[2]) & ~(255 << 8))
8131     && GET_MODE (operands[0]) != QImode"
8132   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8133                    (and:SI (zero_extract:SI (match_dup 1)
8134                                             (const_int 8) (const_int 8))
8135                            (match_dup 2)))
8136               (clobber (reg:CC FLAGS_REG))])]
8137   "operands[0] = gen_lowpart (SImode, operands[0]);
8138    operands[1] = gen_lowpart (SImode, operands[1]);
8139    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8140
8141 ;; Since AND can be encoded with sign extended immediate, this is only
8142 ;; profitable when 7th bit is not set.
8143 (define_split
8144   [(set (match_operand 0 "register_operand" "")
8145         (and (match_operand 1 "general_operand" "")
8146              (match_operand 2 "const_int_operand" "")))
8147    (clobber (reg:CC FLAGS_REG))]
8148    "reload_completed
8149     && ANY_QI_REG_P (operands[0])
8150     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8151     && !(~INTVAL (operands[2]) & ~255)
8152     && !(INTVAL (operands[2]) & 128)
8153     && GET_MODE (operands[0]) != QImode"
8154   [(parallel [(set (strict_low_part (match_dup 0))
8155                    (and:QI (match_dup 1)
8156                            (match_dup 2)))
8157               (clobber (reg:CC FLAGS_REG))])]
8158   "operands[0] = gen_lowpart (QImode, operands[0]);
8159    operands[1] = gen_lowpart (QImode, operands[1]);
8160    operands[2] = gen_lowpart (QImode, operands[2]);")
8161 \f
8162 ;; Logical inclusive and exclusive OR instructions
8163
8164 ;; %%% This used to optimize known byte-wide and operations to memory.
8165 ;; If this is considered useful, it should be done with splitters.
8166
8167 (define_expand "<code><mode>3"
8168   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8169         (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8170                      (match_operand:SWIM 2 "<general_operand>" "")))]
8171   ""
8172   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8173
8174 (define_insn "*<code><mode>_1"
8175   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8176         (any_or:SWI248
8177          (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8178          (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8179    (clobber (reg:CC FLAGS_REG))]
8180   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8181   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8182   [(set_attr "type" "alu")
8183    (set_attr "mode" "<MODE>")])
8184
8185 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8186 (define_insn "*<code>qi_1"
8187   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8188         (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8189                    (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8190    (clobber (reg:CC FLAGS_REG))]
8191   "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8192   "@
8193    <logic>{b}\t{%2, %0|%0, %2}
8194    <logic>{b}\t{%2, %0|%0, %2}
8195    <logic>{l}\t{%k2, %k0|%k0, %k2}"
8196   [(set_attr "type" "alu")
8197    (set_attr "mode" "QI,QI,SI")])
8198
8199 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8200 (define_insn "*<code>si_1_zext"
8201   [(set (match_operand:DI 0 "register_operand" "=r")
8202         (zero_extend:DI
8203          (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8204                     (match_operand:SI 2 "general_operand" "g"))))
8205    (clobber (reg:CC FLAGS_REG))]
8206   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8207   "<logic>{l}\t{%2, %k0|%k0, %2}"
8208   [(set_attr "type" "alu")
8209    (set_attr "mode" "SI")])
8210
8211 (define_insn "*<code>si_1_zext_imm"
8212   [(set (match_operand:DI 0 "register_operand" "=r")
8213         (any_or:DI
8214          (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8215          (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8216    (clobber (reg:CC FLAGS_REG))]
8217   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8218   "<logic>{l}\t{%2, %k0|%k0, %2}"
8219   [(set_attr "type" "alu")
8220    (set_attr "mode" "SI")])
8221
8222 (define_insn "*<code>qi_1_slp"
8223   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8224         (any_or:QI (match_dup 0)
8225                    (match_operand:QI 1 "general_operand" "qmn,qn")))
8226    (clobber (reg:CC FLAGS_REG))]
8227   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8228    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8229   "<logic>{b}\t{%1, %0|%0, %1}"
8230   [(set_attr "type" "alu1")
8231    (set_attr "mode" "QI")])
8232
8233 (define_insn "*<code><mode>_2"
8234   [(set (reg FLAGS_REG)
8235         (compare (any_or:SWI
8236                   (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8237                   (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8238                  (const_int 0)))
8239    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8240         (any_or:SWI (match_dup 1) (match_dup 2)))]
8241   "ix86_match_ccmode (insn, CCNOmode)
8242    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8243   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8244   [(set_attr "type" "alu")
8245    (set_attr "mode" "<MODE>")])
8246
8247 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8248 ;; ??? Special case for immediate operand is missing - it is tricky.
8249 (define_insn "*<code>si_2_zext"
8250   [(set (reg FLAGS_REG)
8251         (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8252                             (match_operand:SI 2 "general_operand" "g"))
8253                  (const_int 0)))
8254    (set (match_operand:DI 0 "register_operand" "=r")
8255         (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8256   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8257    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8258   "<logic>{l}\t{%2, %k0|%k0, %2}"
8259   [(set_attr "type" "alu")
8260    (set_attr "mode" "SI")])
8261
8262 (define_insn "*<code>si_2_zext_imm"
8263   [(set (reg FLAGS_REG)
8264         (compare (any_or:SI
8265                   (match_operand:SI 1 "nonimmediate_operand" "%0")
8266                   (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8267                  (const_int 0)))
8268    (set (match_operand:DI 0 "register_operand" "=r")
8269         (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8270   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8271    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8272   "<logic>{l}\t{%2, %k0|%k0, %2}"
8273   [(set_attr "type" "alu")
8274    (set_attr "mode" "SI")])
8275
8276 (define_insn "*<code>qi_2_slp"
8277   [(set (reg FLAGS_REG)
8278         (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8279                             (match_operand:QI 1 "general_operand" "qmn,qn"))
8280                  (const_int 0)))
8281    (set (strict_low_part (match_dup 0))
8282         (any_or:QI (match_dup 0) (match_dup 1)))]
8283   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8284    && ix86_match_ccmode (insn, CCNOmode)
8285    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8286   "<logic>{b}\t{%1, %0|%0, %1}"
8287   [(set_attr "type" "alu1")
8288    (set_attr "mode" "QI")])
8289
8290 (define_insn "*<code><mode>_3"
8291   [(set (reg FLAGS_REG)
8292         (compare (any_or:SWI
8293                   (match_operand:SWI 1 "nonimmediate_operand" "%0")
8294                   (match_operand:SWI 2 "<general_operand>" "<g>"))
8295                  (const_int 0)))
8296    (clobber (match_scratch:SWI 0 "=<r>"))]
8297   "ix86_match_ccmode (insn, CCNOmode)
8298    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8299   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8300   [(set_attr "type" "alu")
8301    (set_attr "mode" "<MODE>")])
8302
8303 (define_insn "*<code>qi_ext_0"
8304   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8305                          (const_int 8)
8306                          (const_int 8))
8307         (any_or:SI
8308           (zero_extract:SI
8309             (match_operand 1 "ext_register_operand" "0")
8310             (const_int 8)
8311             (const_int 8))
8312           (match_operand 2 "const_int_operand" "n")))
8313    (clobber (reg:CC FLAGS_REG))]
8314   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8315   "<logic>{b}\t{%2, %h0|%h0, %2}"
8316   [(set_attr "type" "alu")
8317    (set_attr "length_immediate" "1")
8318    (set_attr "modrm" "1")
8319    (set_attr "mode" "QI")])
8320
8321 (define_insn "*<code>qi_ext_1_rex64"
8322   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8323                          (const_int 8)
8324                          (const_int 8))
8325         (any_or:SI
8326           (zero_extract:SI
8327             (match_operand 1 "ext_register_operand" "0")
8328             (const_int 8)
8329             (const_int 8))
8330           (zero_extend:SI
8331             (match_operand 2 "ext_register_operand" "Q"))))
8332    (clobber (reg:CC FLAGS_REG))]
8333   "TARGET_64BIT
8334    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8335   "<logic>{b}\t{%2, %h0|%h0, %2}"
8336   [(set_attr "type" "alu")
8337    (set_attr "length_immediate" "0")
8338    (set_attr "mode" "QI")])
8339
8340 (define_insn "*<code>qi_ext_1"
8341   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8342                          (const_int 8)
8343                          (const_int 8))
8344         (any_or:SI
8345           (zero_extract:SI
8346             (match_operand 1 "ext_register_operand" "0")
8347             (const_int 8)
8348             (const_int 8))
8349           (zero_extend:SI
8350             (match_operand:QI 2 "general_operand" "Qm"))))
8351    (clobber (reg:CC FLAGS_REG))]
8352   "!TARGET_64BIT
8353    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8354   "<logic>{b}\t{%2, %h0|%h0, %2}"
8355   [(set_attr "type" "alu")
8356    (set_attr "length_immediate" "0")
8357    (set_attr "mode" "QI")])
8358
8359 (define_insn "*<code>qi_ext_2"
8360   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8361                          (const_int 8)
8362                          (const_int 8))
8363         (any_or:SI
8364           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8365                            (const_int 8)
8366                            (const_int 8))
8367           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8368                            (const_int 8)
8369                            (const_int 8))))
8370    (clobber (reg:CC FLAGS_REG))]
8371   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8372   "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8373   [(set_attr "type" "alu")
8374    (set_attr "length_immediate" "0")
8375    (set_attr "mode" "QI")])
8376
8377 (define_split
8378   [(set (match_operand 0 "register_operand" "")
8379         (any_or (match_operand 1 "register_operand" "")
8380                 (match_operand 2 "const_int_operand" "")))
8381    (clobber (reg:CC FLAGS_REG))]
8382    "reload_completed
8383     && QI_REG_P (operands[0])
8384     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8385     && !(INTVAL (operands[2]) & ~(255 << 8))
8386     && GET_MODE (operands[0]) != QImode"
8387   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8388                    (any_or:SI (zero_extract:SI (match_dup 1)
8389                                                (const_int 8) (const_int 8))
8390                               (match_dup 2)))
8391               (clobber (reg:CC FLAGS_REG))])]
8392   "operands[0] = gen_lowpart (SImode, operands[0]);
8393    operands[1] = gen_lowpart (SImode, operands[1]);
8394    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8395
8396 ;; Since OR can be encoded with sign extended immediate, this is only
8397 ;; profitable when 7th bit is set.
8398 (define_split
8399   [(set (match_operand 0 "register_operand" "")
8400         (any_or (match_operand 1 "general_operand" "")
8401                 (match_operand 2 "const_int_operand" "")))
8402    (clobber (reg:CC FLAGS_REG))]
8403    "reload_completed
8404     && ANY_QI_REG_P (operands[0])
8405     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8406     && !(INTVAL (operands[2]) & ~255)
8407     && (INTVAL (operands[2]) & 128)
8408     && GET_MODE (operands[0]) != QImode"
8409   [(parallel [(set (strict_low_part (match_dup 0))
8410                    (any_or:QI (match_dup 1)
8411                               (match_dup 2)))
8412               (clobber (reg:CC FLAGS_REG))])]
8413   "operands[0] = gen_lowpart (QImode, operands[0]);
8414    operands[1] = gen_lowpart (QImode, operands[1]);
8415    operands[2] = gen_lowpart (QImode, operands[2]);")
8416
8417 (define_expand "xorqi_cc_ext_1"
8418   [(parallel [
8419      (set (reg:CCNO FLAGS_REG)
8420           (compare:CCNO
8421             (xor:SI
8422               (zero_extract:SI
8423                 (match_operand 1 "ext_register_operand" "")
8424                 (const_int 8)
8425                 (const_int 8))
8426               (match_operand:QI 2 "general_operand" ""))
8427             (const_int 0)))
8428      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8429                            (const_int 8)
8430                            (const_int 8))
8431           (xor:SI
8432             (zero_extract:SI
8433              (match_dup 1)
8434              (const_int 8)
8435              (const_int 8))
8436             (match_dup 2)))])]
8437   ""
8438   "")
8439
8440 (define_insn "*xorqi_cc_ext_1_rex64"
8441   [(set (reg FLAGS_REG)
8442         (compare
8443           (xor:SI
8444             (zero_extract:SI
8445               (match_operand 1 "ext_register_operand" "0")
8446               (const_int 8)
8447               (const_int 8))
8448             (match_operand:QI 2 "nonmemory_operand" "Qn"))
8449           (const_int 0)))
8450    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8451                          (const_int 8)
8452                          (const_int 8))
8453         (xor:SI
8454           (zero_extract:SI
8455            (match_dup 1)
8456            (const_int 8)
8457            (const_int 8))
8458           (match_dup 2)))]
8459   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8460   "xor{b}\t{%2, %h0|%h0, %2}"
8461   [(set_attr "type" "alu")
8462    (set_attr "modrm" "1")
8463    (set_attr "mode" "QI")])
8464
8465 (define_insn "*xorqi_cc_ext_1"
8466   [(set (reg FLAGS_REG)
8467         (compare
8468           (xor:SI
8469             (zero_extract:SI
8470               (match_operand 1 "ext_register_operand" "0")
8471               (const_int 8)
8472               (const_int 8))
8473             (match_operand:QI 2 "general_operand" "qmn"))
8474           (const_int 0)))
8475    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8476                          (const_int 8)
8477                          (const_int 8))
8478         (xor:SI
8479           (zero_extract:SI
8480            (match_dup 1)
8481            (const_int 8)
8482            (const_int 8))
8483           (match_dup 2)))]
8484   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8485   "xor{b}\t{%2, %h0|%h0, %2}"
8486   [(set_attr "type" "alu")
8487    (set_attr "modrm" "1")
8488    (set_attr "mode" "QI")])
8489 \f
8490 ;; Negation instructions
8491
8492 (define_expand "neg<mode>2"
8493   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
8494         (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
8495   ""
8496   "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8497
8498 (define_insn_and_split "*neg<dwi>2_doubleword"
8499   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8500         (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8501    (clobber (reg:CC FLAGS_REG))]
8502   "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8503   "#"
8504   "reload_completed"
8505   [(parallel
8506     [(set (reg:CCZ FLAGS_REG)
8507           (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8508      (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8509    (parallel
8510     [(set (match_dup 2)
8511           (plus:DWIH (match_dup 3)
8512                      (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8513                                 (const_int 0))))
8514      (clobber (reg:CC FLAGS_REG))])
8515    (parallel
8516     [(set (match_dup 2)
8517           (neg:DWIH (match_dup 2)))
8518      (clobber (reg:CC FLAGS_REG))])]
8519   "split_<dwi> (&operands[0], 2, &operands[0], &operands[2]);")
8520
8521 (define_insn "*neg<mode>2_1"
8522   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8523         (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8524    (clobber (reg:CC FLAGS_REG))]
8525   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8526   "neg{<imodesuffix>}\t%0"
8527   [(set_attr "type" "negnot")
8528    (set_attr "mode" "<MODE>")])
8529
8530 ;; Combine is quite creative about this pattern.
8531 (define_insn "*negsi2_1_zext"
8532   [(set (match_operand:DI 0 "register_operand" "=r")
8533         (lshiftrt:DI
8534           (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8535                              (const_int 32)))
8536         (const_int 32)))
8537    (clobber (reg:CC FLAGS_REG))]
8538   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8539   "neg{l}\t%k0"
8540   [(set_attr "type" "negnot")
8541    (set_attr "mode" "SI")])
8542
8543 ;; The problem with neg is that it does not perform (compare x 0),
8544 ;; it really performs (compare 0 x), which leaves us with the zero
8545 ;; flag being the only useful item.
8546
8547 (define_insn "*neg<mode>2_cmpz"
8548   [(set (reg:CCZ FLAGS_REG)
8549         (compare:CCZ
8550           (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8551                    (const_int 0)))
8552    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8553         (neg:SWI (match_dup 1)))]
8554   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8555   "neg{<imodesuffix>}\t%0"
8556   [(set_attr "type" "negnot")
8557    (set_attr "mode" "<MODE>")])
8558
8559 (define_insn "*negsi2_cmpz_zext"
8560   [(set (reg:CCZ FLAGS_REG)
8561         (compare:CCZ
8562           (lshiftrt:DI
8563             (neg:DI (ashift:DI
8564                       (match_operand:DI 1 "register_operand" "0")
8565                       (const_int 32)))
8566             (const_int 32))
8567           (const_int 0)))
8568    (set (match_operand:DI 0 "register_operand" "=r")
8569         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8570                                         (const_int 32)))
8571                      (const_int 32)))]
8572   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8573   "neg{l}\t%k0"
8574   [(set_attr "type" "negnot")
8575    (set_attr "mode" "SI")])
8576
8577 ;; Changing of sign for FP values is doable using integer unit too.
8578
8579 (define_expand "<code><mode>2"
8580   [(set (match_operand:X87MODEF 0 "register_operand" "")
8581         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
8582   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8583   "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8584
8585 (define_insn "*absneg<mode>2_mixed"
8586   [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8587         (match_operator:MODEF 3 "absneg_operator"
8588           [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8589    (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8590    (clobber (reg:CC FLAGS_REG))]
8591   "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8592   "#")
8593
8594 (define_insn "*absneg<mode>2_sse"
8595   [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8596         (match_operator:MODEF 3 "absneg_operator"
8597           [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8598    (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8599    (clobber (reg:CC FLAGS_REG))]
8600   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8601   "#")
8602
8603 (define_insn "*absneg<mode>2_i387"
8604   [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8605         (match_operator:X87MODEF 3 "absneg_operator"
8606           [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8607    (use (match_operand 2 "" ""))
8608    (clobber (reg:CC FLAGS_REG))]
8609   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8610   "#")
8611
8612 (define_expand "<code>tf2"
8613   [(set (match_operand:TF 0 "register_operand" "")
8614         (absneg:TF (match_operand:TF 1 "register_operand" "")))]
8615   "TARGET_SSE2"
8616   "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8617
8618 (define_insn "*absnegtf2_sse"
8619   [(set (match_operand:TF 0 "register_operand" "=x,x")
8620         (match_operator:TF 3 "absneg_operator"
8621           [(match_operand:TF 1 "register_operand" "0,x")]))
8622    (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8623    (clobber (reg:CC FLAGS_REG))]
8624   "TARGET_SSE2"
8625   "#")
8626
8627 ;; Splitters for fp abs and neg.
8628
8629 (define_split
8630   [(set (match_operand 0 "fp_register_operand" "")
8631         (match_operator 1 "absneg_operator" [(match_dup 0)]))
8632    (use (match_operand 2 "" ""))
8633    (clobber (reg:CC FLAGS_REG))]
8634   "reload_completed"
8635   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8636
8637 (define_split
8638   [(set (match_operand 0 "register_operand" "")
8639         (match_operator 3 "absneg_operator"
8640           [(match_operand 1 "register_operand" "")]))
8641    (use (match_operand 2 "nonimmediate_operand" ""))
8642    (clobber (reg:CC FLAGS_REG))]
8643   "reload_completed && SSE_REG_P (operands[0])"
8644   [(set (match_dup 0) (match_dup 3))]
8645 {
8646   enum machine_mode mode = GET_MODE (operands[0]);
8647   enum machine_mode vmode = GET_MODE (operands[2]);
8648   rtx tmp;
8649
8650   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8651   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8652   if (operands_match_p (operands[0], operands[2]))
8653     {
8654       tmp = operands[1];
8655       operands[1] = operands[2];
8656       operands[2] = tmp;
8657     }
8658   if (GET_CODE (operands[3]) == ABS)
8659     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8660   else
8661     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8662   operands[3] = tmp;
8663 })
8664
8665 (define_split
8666   [(set (match_operand:SF 0 "register_operand" "")
8667         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8668    (use (match_operand:V4SF 2 "" ""))
8669    (clobber (reg:CC FLAGS_REG))]
8670   "reload_completed"
8671   [(parallel [(set (match_dup 0) (match_dup 1))
8672               (clobber (reg:CC FLAGS_REG))])]
8673 {
8674   rtx tmp;
8675   operands[0] = gen_lowpart (SImode, operands[0]);
8676   if (GET_CODE (operands[1]) == ABS)
8677     {
8678       tmp = gen_int_mode (0x7fffffff, SImode);
8679       tmp = gen_rtx_AND (SImode, operands[0], tmp);
8680     }
8681   else
8682     {
8683       tmp = gen_int_mode (0x80000000, SImode);
8684       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8685     }
8686   operands[1] = tmp;
8687 })
8688
8689 (define_split
8690   [(set (match_operand:DF 0 "register_operand" "")
8691         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8692    (use (match_operand 2 "" ""))
8693    (clobber (reg:CC FLAGS_REG))]
8694   "reload_completed"
8695   [(parallel [(set (match_dup 0) (match_dup 1))
8696               (clobber (reg:CC FLAGS_REG))])]
8697 {
8698   rtx tmp;
8699   if (TARGET_64BIT)
8700     {
8701       tmp = gen_lowpart (DImode, operands[0]);
8702       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8703       operands[0] = tmp;
8704
8705       if (GET_CODE (operands[1]) == ABS)
8706         tmp = const0_rtx;
8707       else
8708         tmp = gen_rtx_NOT (DImode, tmp);
8709     }
8710   else
8711     {
8712       operands[0] = gen_highpart (SImode, operands[0]);
8713       if (GET_CODE (operands[1]) == ABS)
8714         {
8715           tmp = gen_int_mode (0x7fffffff, SImode);
8716           tmp = gen_rtx_AND (SImode, operands[0], tmp);
8717         }
8718       else
8719         {
8720           tmp = gen_int_mode (0x80000000, SImode);
8721           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8722         }
8723     }
8724   operands[1] = tmp;
8725 })
8726
8727 (define_split
8728   [(set (match_operand:XF 0 "register_operand" "")
8729         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8730    (use (match_operand 2 "" ""))
8731    (clobber (reg:CC FLAGS_REG))]
8732   "reload_completed"
8733   [(parallel [(set (match_dup 0) (match_dup 1))
8734               (clobber (reg:CC FLAGS_REG))])]
8735 {
8736   rtx tmp;
8737   operands[0] = gen_rtx_REG (SImode,
8738                              true_regnum (operands[0])
8739                              + (TARGET_64BIT ? 1 : 2));
8740   if (GET_CODE (operands[1]) == ABS)
8741     {
8742       tmp = GEN_INT (0x7fff);
8743       tmp = gen_rtx_AND (SImode, operands[0], tmp);
8744     }
8745   else
8746     {
8747       tmp = GEN_INT (0x8000);
8748       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8749     }
8750   operands[1] = tmp;
8751 })
8752
8753 ;; Conditionalize these after reload. If they match before reload, we
8754 ;; lose the clobber and ability to use integer instructions.
8755
8756 (define_insn "*<code><mode>2_1"
8757   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8758         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8759   "TARGET_80387
8760    && (reload_completed
8761        || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8762   "f<absneg_mnemonic>"
8763   [(set_attr "type" "fsgn")
8764    (set_attr "mode" "<MODE>")])
8765
8766 (define_insn "*<code>extendsfdf2"
8767   [(set (match_operand:DF 0 "register_operand" "=f")
8768         (absneg:DF (float_extend:DF
8769                      (match_operand:SF 1 "register_operand" "0"))))]
8770   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8771   "f<absneg_mnemonic>"
8772   [(set_attr "type" "fsgn")
8773    (set_attr "mode" "DF")])
8774
8775 (define_insn "*<code>extendsfxf2"
8776   [(set (match_operand:XF 0 "register_operand" "=f")
8777         (absneg:XF (float_extend:XF
8778                      (match_operand:SF 1 "register_operand" "0"))))]
8779   "TARGET_80387"
8780   "f<absneg_mnemonic>"
8781   [(set_attr "type" "fsgn")
8782    (set_attr "mode" "XF")])
8783
8784 (define_insn "*<code>extenddfxf2"
8785   [(set (match_operand:XF 0 "register_operand" "=f")
8786         (absneg:XF (float_extend:XF
8787                      (match_operand:DF 1 "register_operand" "0"))))]
8788   "TARGET_80387"
8789   "f<absneg_mnemonic>"
8790   [(set_attr "type" "fsgn")
8791    (set_attr "mode" "XF")])
8792
8793 ;; Copysign instructions
8794
8795 (define_mode_iterator CSGNMODE [SF DF TF])
8796 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8797
8798 (define_expand "copysign<mode>3"
8799   [(match_operand:CSGNMODE 0 "register_operand" "")
8800    (match_operand:CSGNMODE 1 "nonmemory_operand" "")
8801    (match_operand:CSGNMODE 2 "register_operand" "")]
8802   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8803    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8804   "ix86_expand_copysign (operands); DONE;")
8805
8806 (define_insn_and_split "copysign<mode>3_const"
8807   [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8808         (unspec:CSGNMODE
8809           [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8810            (match_operand:CSGNMODE 2 "register_operand" "0")
8811            (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8812           UNSPEC_COPYSIGN))]
8813   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8814    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8815   "#"
8816   "&& reload_completed"
8817   [(const_int 0)]
8818   "ix86_split_copysign_const (operands); DONE;")
8819
8820 (define_insn "copysign<mode>3_var"
8821   [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8822         (unspec:CSGNMODE
8823           [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8824            (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8825            (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8826            (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8827           UNSPEC_COPYSIGN))
8828    (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8829   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8830    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8831   "#")
8832
8833 (define_split
8834   [(set (match_operand:CSGNMODE 0 "register_operand" "")
8835         (unspec:CSGNMODE
8836           [(match_operand:CSGNMODE 2 "register_operand" "")
8837            (match_operand:CSGNMODE 3 "register_operand" "")
8838            (match_operand:<CSGNVMODE> 4 "" "")
8839            (match_operand:<CSGNVMODE> 5 "" "")]
8840           UNSPEC_COPYSIGN))
8841    (clobber (match_scratch:<CSGNVMODE> 1 ""))]
8842   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8843     || (TARGET_SSE2 && (<MODE>mode == TFmode)))
8844    && reload_completed"
8845   [(const_int 0)]
8846   "ix86_split_copysign_var (operands); DONE;")
8847 \f
8848 ;; One complement instructions
8849
8850 (define_expand "one_cmpl<mode>2"
8851   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8852         (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
8853   ""
8854   "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8855
8856 (define_insn "*one_cmpl<mode>2_1"
8857   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8858         (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8859   "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8860   "not{<imodesuffix>}\t%0"
8861   [(set_attr "type" "negnot")
8862    (set_attr "mode" "<MODE>")])
8863
8864 ;; %%% Potential partial reg stall on alternative 1.  What to do?
8865 (define_insn "*one_cmplqi2_1"
8866   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8867         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8868   "ix86_unary_operator_ok (NOT, QImode, operands)"
8869   "@
8870    not{b}\t%0
8871    not{l}\t%k0"
8872   [(set_attr "type" "negnot")
8873    (set_attr "mode" "QI,SI")])
8874
8875 ;; ??? Currently never generated - xor is used instead.
8876 (define_insn "*one_cmplsi2_1_zext"
8877   [(set (match_operand:DI 0 "register_operand" "=r")
8878         (zero_extend:DI
8879           (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8880   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8881   "not{l}\t%k0"
8882   [(set_attr "type" "negnot")
8883    (set_attr "mode" "SI")])
8884
8885 (define_insn "*one_cmpl<mode>2_2"
8886   [(set (reg FLAGS_REG)
8887         (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8888                  (const_int 0)))
8889    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8890         (not:SWI (match_dup 1)))]
8891   "ix86_match_ccmode (insn, CCNOmode)
8892    && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8893   "#"
8894   [(set_attr "type" "alu1")
8895    (set_attr "mode" "<MODE>")])
8896
8897 (define_split
8898   [(set (match_operand 0 "flags_reg_operand" "")
8899         (match_operator 2 "compare_operator"
8900           [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
8901            (const_int 0)]))
8902    (set (match_operand:SWI 1 "nonimmediate_operand" "")
8903         (not:SWI (match_dup 3)))]
8904   "ix86_match_ccmode (insn, CCNOmode)"
8905   [(parallel [(set (match_dup 0)
8906                    (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
8907                                     (const_int 0)]))
8908               (set (match_dup 1)
8909                    (xor:SWI (match_dup 3) (const_int -1)))])])
8910
8911 ;; ??? Currently never generated - xor is used instead.
8912 (define_insn "*one_cmplsi2_2_zext"
8913   [(set (reg FLAGS_REG)
8914         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
8915                  (const_int 0)))
8916    (set (match_operand:DI 0 "register_operand" "=r")
8917         (zero_extend:DI (not:SI (match_dup 1))))]
8918   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8919    && ix86_unary_operator_ok (NOT, SImode, operands)"
8920   "#"
8921   [(set_attr "type" "alu1")
8922    (set_attr "mode" "SI")])
8923
8924 (define_split
8925   [(set (match_operand 0 "flags_reg_operand" "")
8926         (match_operator 2 "compare_operator"
8927           [(not:SI (match_operand:SI 3 "register_operand" ""))
8928            (const_int 0)]))
8929    (set (match_operand:DI 1 "register_operand" "")
8930         (zero_extend:DI (not:SI (match_dup 3))))]
8931   "ix86_match_ccmode (insn, CCNOmode)"
8932   [(parallel [(set (match_dup 0)
8933                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
8934                                     (const_int 0)]))
8935               (set (match_dup 1)
8936                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
8937 \f
8938 ;; Shift instructions
8939
8940 ;; DImode shifts are implemented using the i386 "shift double" opcode,
8941 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
8942 ;; is variable, then the count is in %cl and the "imm" operand is dropped
8943 ;; from the assembler input.
8944 ;;
8945 ;; This instruction shifts the target reg/mem as usual, but instead of
8946 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
8947 ;; is a left shift double, bits are taken from the high order bits of
8948 ;; reg, else if the insn is a shift right double, bits are taken from the
8949 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
8950 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
8951 ;;
8952 ;; Since sh[lr]d does not change the `reg' operand, that is done
8953 ;; separately, making all shifts emit pairs of shift double and normal
8954 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
8955 ;; support a 63 bit shift, each shift where the count is in a reg expands
8956 ;; to a pair of shifts, a branch, a shift by 32 and a label.
8957 ;;
8958 ;; If the shift count is a constant, we need never emit more than one
8959 ;; shift pair, instead using moves and sign extension for counts greater
8960 ;; than 31.
8961
8962 (define_expand "ashl<mode>3"
8963   [(set (match_operand:SDWIM 0 "<shift_operand>" "")
8964         (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
8965                       (match_operand:QI 2 "nonmemory_operand" "")))]
8966   ""
8967   "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
8968
8969 (define_insn "*ashl<mode>3_doubleword"
8970   [(set (match_operand:DWI 0 "register_operand" "=&r,r")
8971         (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
8972                     (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
8973    (clobber (reg:CC FLAGS_REG))]
8974   ""
8975   "#"
8976   [(set_attr "type" "multi")])
8977
8978 (define_split
8979   [(set (match_operand:DWI 0 "register_operand" "")
8980         (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
8981                     (match_operand:QI 2 "nonmemory_operand" "")))
8982    (clobber (reg:CC FLAGS_REG))]
8983   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
8984   [(const_int 0)]
8985   "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
8986
8987 ;; By default we don't ask for a scratch register, because when DWImode
8988 ;; values are manipulated, registers are already at a premium.  But if
8989 ;; we have one handy, we won't turn it away.
8990
8991 (define_peephole2
8992   [(match_scratch:DWIH 3 "r")
8993    (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
8994                    (ashift:<DWI>
8995                      (match_operand:<DWI> 1 "nonmemory_operand" "")
8996                      (match_operand:QI 2 "nonmemory_operand" "")))
8997               (clobber (reg:CC FLAGS_REG))])
8998    (match_dup 3)]
8999   "TARGET_CMOVE"
9000   [(const_int 0)]
9001   "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9002
9003 (define_insn "x86_64_shld"
9004   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9005         (ior:DI (ashift:DI (match_dup 0)
9006                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
9007                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9008                   (minus:QI (const_int 64) (match_dup 2)))))
9009    (clobber (reg:CC FLAGS_REG))]
9010   "TARGET_64BIT"
9011   "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9012   [(set_attr "type" "ishift")
9013    (set_attr "prefix_0f" "1")
9014    (set_attr "mode" "DI")
9015    (set_attr "athlon_decode" "vector")
9016    (set_attr "amdfam10_decode" "vector")])
9017
9018 (define_insn "x86_shld"
9019   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9020         (ior:SI (ashift:SI (match_dup 0)
9021                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
9022                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9023                   (minus:QI (const_int 32) (match_dup 2)))))
9024    (clobber (reg:CC FLAGS_REG))]
9025   ""
9026   "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9027   [(set_attr "type" "ishift")
9028    (set_attr "prefix_0f" "1")
9029    (set_attr "mode" "SI")
9030    (set_attr "pent_pair" "np")
9031    (set_attr "athlon_decode" "vector")
9032    (set_attr "amdfam10_decode" "vector")])
9033
9034 (define_expand "x86_shift<mode>_adj_1"
9035   [(set (reg:CCZ FLAGS_REG)
9036         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
9037                              (match_dup 4))
9038                      (const_int 0)))
9039    (set (match_operand:SWI48 0 "register_operand" "")
9040         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9041                             (match_operand:SWI48 1 "register_operand" "")
9042                             (match_dup 0)))
9043    (set (match_dup 1)
9044         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9045                             (match_operand:SWI48 3 "register_operand" "r")
9046                             (match_dup 1)))]
9047   "TARGET_CMOVE"
9048   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9049
9050 (define_expand "x86_shift<mode>_adj_2"
9051   [(use (match_operand:SWI48 0 "register_operand" ""))
9052    (use (match_operand:SWI48 1 "register_operand" ""))
9053    (use (match_operand:QI 2 "register_operand" ""))]
9054   ""
9055 {
9056   rtx label = gen_label_rtx ();
9057   rtx tmp;
9058
9059   emit_insn (gen_testqi_ccz_1 (operands[2],
9060                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9061
9062   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9063   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9064   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9065                               gen_rtx_LABEL_REF (VOIDmode, label),
9066                               pc_rtx);
9067   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9068   JUMP_LABEL (tmp) = label;
9069
9070   emit_move_insn (operands[0], operands[1]);
9071   ix86_expand_clear (operands[1]);
9072
9073   emit_label (label);
9074   LABEL_NUSES (label) = 1;
9075
9076   DONE;
9077 })
9078
9079 (define_insn "*ashl<mode>3_1"
9080   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9081         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l")
9082                       (match_operand:QI 2 "nonmemory_operand" "c<S>,M")))
9083    (clobber (reg:CC FLAGS_REG))]
9084   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9085 {
9086   switch (get_attr_type (insn))
9087     {
9088     case TYPE_LEA:
9089       return "#";
9090
9091     case TYPE_ALU:
9092       gcc_assert (operands[2] == const1_rtx);
9093       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9094       return "add{<imodesuffix>}\t%0, %0";
9095
9096     default:
9097       if (operands[2] == const1_rtx
9098           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9099         return "sal{<imodesuffix>}\t%0";
9100       else
9101         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9102     }
9103 }
9104   [(set (attr "type")
9105      (cond [(eq_attr "alternative" "1")
9106               (const_string "lea")
9107             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9108                           (const_int 0))
9109                       (match_operand 0 "register_operand" ""))
9110                  (match_operand 2 "const1_operand" ""))
9111               (const_string "alu")
9112            ]
9113            (const_string "ishift")))
9114    (set (attr "length_immediate")
9115      (if_then_else
9116        (ior (eq_attr "type" "alu")
9117             (and (eq_attr "type" "ishift")
9118                  (and (match_operand 2 "const1_operand" "")
9119                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9120                           (const_int 0)))))
9121        (const_string "0")
9122        (const_string "*")))
9123    (set_attr "mode" "<MODE>")])
9124
9125 (define_insn "*ashlsi3_1_zext"
9126   [(set (match_operand:DI 0 "register_operand" "=r,r")
9127         (zero_extend:DI
9128           (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
9129                      (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
9130    (clobber (reg:CC FLAGS_REG))]
9131   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9132 {
9133   switch (get_attr_type (insn))
9134     {
9135     case TYPE_LEA:
9136       return "#";
9137
9138     case TYPE_ALU:
9139       gcc_assert (operands[2] == const1_rtx);
9140       return "add{l}\t%k0, %k0";
9141
9142     default:
9143       if (operands[2] == const1_rtx
9144           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9145         return "sal{l}\t%k0";
9146       else
9147         return "sal{l}\t{%2, %k0|%k0, %2}";
9148     }
9149 }
9150   [(set (attr "type")
9151      (cond [(eq_attr "alternative" "1")
9152               (const_string "lea")
9153             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9154                      (const_int 0))
9155                  (match_operand 2 "const1_operand" ""))
9156               (const_string "alu")
9157            ]
9158            (const_string "ishift")))
9159    (set (attr "length_immediate")
9160      (if_then_else
9161        (ior (eq_attr "type" "alu")
9162             (and (eq_attr "type" "ishift")
9163                  (and (match_operand 2 "const1_operand" "")
9164                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9165                           (const_int 0)))))
9166        (const_string "0")
9167        (const_string "*")))
9168    (set_attr "mode" "SI")])
9169
9170 (define_insn "*ashlhi3_1"
9171   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9172         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
9173                    (match_operand:QI 2 "nonmemory_operand" "cI")))
9174    (clobber (reg:CC FLAGS_REG))]
9175   "TARGET_PARTIAL_REG_STALL
9176    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9177 {
9178   switch (get_attr_type (insn))
9179     {
9180     case TYPE_ALU:
9181       gcc_assert (operands[2] == const1_rtx);
9182       return "add{w}\t%0, %0";
9183
9184     default:
9185       if (operands[2] == const1_rtx
9186           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9187         return "sal{w}\t%0";
9188       else
9189         return "sal{w}\t{%2, %0|%0, %2}";
9190     }
9191 }
9192   [(set (attr "type")
9193      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9194                           (const_int 0))
9195                       (match_operand 0 "register_operand" ""))
9196                  (match_operand 2 "const1_operand" ""))
9197               (const_string "alu")
9198            ]
9199            (const_string "ishift")))
9200    (set (attr "length_immediate")
9201      (if_then_else
9202        (ior (eq_attr "type" "alu")
9203             (and (eq_attr "type" "ishift")
9204                  (and (match_operand 2 "const1_operand" "")
9205                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9206                           (const_int 0)))))
9207        (const_string "0")
9208        (const_string "*")))
9209    (set_attr "mode" "HI")])
9210
9211 (define_insn "*ashlhi3_1_lea"
9212   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
9213         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9214                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9215    (clobber (reg:CC FLAGS_REG))]
9216   "!TARGET_PARTIAL_REG_STALL
9217    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9218 {
9219   switch (get_attr_type (insn))
9220     {
9221     case TYPE_LEA:
9222       return "#";
9223
9224     case TYPE_ALU:
9225       gcc_assert (operands[2] == const1_rtx);
9226       return "add{w}\t%0, %0";
9227
9228     default:
9229       if (operands[2] == const1_rtx
9230           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9231         return "sal{w}\t%0";
9232       else
9233         return "sal{w}\t{%2, %0|%0, %2}";
9234     }
9235 }
9236   [(set (attr "type")
9237      (cond [(eq_attr "alternative" "1")
9238               (const_string "lea")
9239             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9240                           (const_int 0))
9241                       (match_operand 0 "register_operand" ""))
9242                  (match_operand 2 "const1_operand" ""))
9243               (const_string "alu")
9244            ]
9245            (const_string "ishift")))
9246    (set (attr "length_immediate")
9247      (if_then_else
9248        (ior (eq_attr "type" "alu")
9249             (and (eq_attr "type" "ishift")
9250                  (and (match_operand 2 "const1_operand" "")
9251                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9252                           (const_int 0)))))
9253        (const_string "0")
9254        (const_string "*")))
9255    (set_attr "mode" "HI,SI")])
9256
9257 (define_insn "*ashlqi3_1"
9258   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9259         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
9260                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
9261    (clobber (reg:CC FLAGS_REG))]
9262   "TARGET_PARTIAL_REG_STALL
9263    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9264 {
9265   switch (get_attr_type (insn))
9266     {
9267     case TYPE_ALU:
9268       gcc_assert (operands[2] == const1_rtx);
9269       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9270         return "add{l}\t%k0, %k0";
9271       else
9272         return "add{b}\t%0, %0";
9273
9274     default:
9275       if (operands[2] == const1_rtx
9276           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9277         {
9278           if (get_attr_mode (insn) == MODE_SI)
9279             return "sal{l}\t%k0";
9280           else
9281             return "sal{b}\t%0";
9282         }
9283       else
9284         {
9285           if (get_attr_mode (insn) == MODE_SI)
9286             return "sal{l}\t{%2, %k0|%k0, %2}";
9287           else
9288             return "sal{b}\t{%2, %0|%0, %2}";
9289         }
9290     }
9291 }
9292   [(set (attr "type")
9293      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9294                           (const_int 0))
9295                       (match_operand 0 "register_operand" ""))
9296                  (match_operand 2 "const1_operand" ""))
9297               (const_string "alu")
9298            ]
9299            (const_string "ishift")))
9300    (set (attr "length_immediate")
9301      (if_then_else
9302        (ior (eq_attr "type" "alu")
9303             (and (eq_attr "type" "ishift")
9304                  (and (match_operand 2 "const1_operand" "")
9305                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9306                           (const_int 0)))))
9307        (const_string "0")
9308        (const_string "*")))
9309    (set_attr "mode" "QI,SI")])
9310
9311 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9312 (define_insn "*ashlqi3_1_lea"
9313   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
9314         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9315                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9316    (clobber (reg:CC FLAGS_REG))]
9317   "!TARGET_PARTIAL_REG_STALL
9318    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9319 {
9320   switch (get_attr_type (insn))
9321     {
9322     case TYPE_LEA:
9323       return "#";
9324
9325     case TYPE_ALU:
9326       gcc_assert (operands[2] == const1_rtx);
9327       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9328         return "add{l}\t%k0, %k0";
9329       else
9330         return "add{b}\t%0, %0";
9331
9332     default:
9333       if (operands[2] == const1_rtx
9334           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9335         {
9336           if (get_attr_mode (insn) == MODE_SI)
9337             return "sal{l}\t%k0";
9338           else
9339             return "sal{b}\t%0";
9340         }
9341       else
9342         {
9343           if (get_attr_mode (insn) == MODE_SI)
9344             return "sal{l}\t{%2, %k0|%k0, %2}";
9345           else
9346             return "sal{b}\t{%2, %0|%0, %2}";
9347         }
9348     }
9349 }
9350   [(set (attr "type")
9351      (cond [(eq_attr "alternative" "2")
9352               (const_string "lea")
9353             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9354                           (const_int 0))
9355                       (match_operand 0 "register_operand" ""))
9356                  (match_operand 2 "const1_operand" ""))
9357               (const_string "alu")
9358            ]
9359            (const_string "ishift")))
9360    (set (attr "length_immediate")
9361      (if_then_else
9362        (ior (eq_attr "type" "alu")
9363             (and (eq_attr "type" "ishift")
9364                  (and (match_operand 2 "const1_operand" "")
9365                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9366                           (const_int 0)))))
9367        (const_string "0")
9368        (const_string "*")))
9369    (set_attr "mode" "QI,SI,SI")])
9370
9371 (define_insn "*ashlqi3_1_slp"
9372   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9373         (ashift:QI (match_dup 0)
9374                    (match_operand:QI 1 "nonmemory_operand" "cI")))
9375    (clobber (reg:CC FLAGS_REG))]
9376   "(optimize_function_for_size_p (cfun)
9377     || !TARGET_PARTIAL_FLAG_REG_STALL
9378     || (operands[1] == const1_rtx
9379         && (TARGET_SHIFT1
9380             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9381 {
9382   switch (get_attr_type (insn))
9383     {
9384     case TYPE_ALU:
9385       gcc_assert (operands[1] == const1_rtx);
9386       return "add{b}\t%0, %0";
9387
9388     default:
9389       if (operands[1] == const1_rtx
9390           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9391         return "sal{b}\t%0";
9392       else
9393         return "sal{b}\t{%1, %0|%0, %1}";
9394     }
9395 }
9396   [(set (attr "type")
9397      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9398                           (const_int 0))
9399                       (match_operand 0 "register_operand" ""))
9400                  (match_operand 1 "const1_operand" ""))
9401               (const_string "alu")
9402            ]
9403            (const_string "ishift1")))
9404    (set (attr "length_immediate")
9405      (if_then_else
9406        (ior (eq_attr "type" "alu")
9407             (and (eq_attr "type" "ishift1")
9408                  (and (match_operand 1 "const1_operand" "")
9409                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9410                           (const_int 0)))))
9411        (const_string "0")
9412        (const_string "*")))
9413    (set_attr "mode" "QI")])
9414
9415 ;; Convert lea to the lea pattern to avoid flags dependency.
9416 (define_split
9417   [(set (match_operand 0 "register_operand" "")
9418         (ashift (match_operand 1 "index_register_operand" "")
9419                 (match_operand:QI 2 "const_int_operand" "")))
9420    (clobber (reg:CC FLAGS_REG))]
9421   "reload_completed
9422    && true_regnum (operands[0]) != true_regnum (operands[1])"
9423   [(const_int 0)]
9424 {
9425   rtx pat;
9426   enum machine_mode mode = GET_MODE (operands[0]);
9427
9428   if (mode != Pmode)
9429     operands[1] = gen_lowpart (Pmode, operands[1]);
9430   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
9431
9432   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
9433
9434   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9435     operands[0] = gen_lowpart (SImode, operands[0]);
9436
9437   if (TARGET_64BIT && mode != Pmode)
9438     pat = gen_rtx_SUBREG (SImode, pat, 0);
9439
9440   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9441   DONE;
9442 })
9443
9444 ;; Convert lea to the lea pattern to avoid flags dependency.
9445 (define_split
9446   [(set (match_operand:DI 0 "register_operand" "")
9447         (zero_extend:DI
9448           (ashift:SI (match_operand:SI 1 "index_register_operand" "")
9449                      (match_operand:QI 2 "const_int_operand" ""))))
9450    (clobber (reg:CC FLAGS_REG))]
9451   "TARGET_64BIT && reload_completed
9452    && true_regnum (operands[0]) != true_regnum (operands[1])"
9453   [(set (match_dup 0)
9454         (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9455 {
9456   operands[1] = gen_lowpart (DImode, operands[1]);
9457   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9458 })
9459
9460 ;; This pattern can't accept a variable shift count, since shifts by
9461 ;; zero don't affect the flags.  We assume that shifts by constant
9462 ;; zero are optimized away.
9463 (define_insn "*ashl<mode>3_cmp"
9464   [(set (reg FLAGS_REG)
9465         (compare
9466           (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9467                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9468           (const_int 0)))
9469    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9470         (ashift:SWI (match_dup 1) (match_dup 2)))]
9471   "(optimize_function_for_size_p (cfun)
9472     || !TARGET_PARTIAL_FLAG_REG_STALL
9473     || (operands[2] == const1_rtx
9474         && (TARGET_SHIFT1
9475             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9476    && ix86_match_ccmode (insn, CCGOCmode)
9477    && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9478 {
9479   switch (get_attr_type (insn))
9480     {
9481     case TYPE_ALU:
9482       gcc_assert (operands[2] == const1_rtx);
9483       return "add{<imodesuffix>}\t%0, %0";
9484
9485     default:
9486       if (operands[2] == const1_rtx
9487           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9488         return "sal{<imodesuffix>}\t%0";
9489       else
9490         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9491     }
9492 }
9493   [(set (attr "type")
9494      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9495                           (const_int 0))
9496                       (match_operand 0 "register_operand" ""))
9497                  (match_operand 2 "const1_operand" ""))
9498               (const_string "alu")
9499            ]
9500            (const_string "ishift")))
9501    (set (attr "length_immediate")
9502      (if_then_else
9503        (ior (eq_attr "type" "alu")
9504             (and (eq_attr "type" "ishift")
9505                  (and (match_operand 2 "const1_operand" "")
9506                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9507                           (const_int 0)))))
9508        (const_string "0")
9509        (const_string "*")))
9510    (set_attr "mode" "<MODE>")])
9511
9512 (define_insn "*ashlsi3_cmp_zext"
9513   [(set (reg FLAGS_REG)
9514         (compare
9515           (ashift:SI (match_operand:SI 1 "register_operand" "0")
9516                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
9517           (const_int 0)))
9518    (set (match_operand:DI 0 "register_operand" "=r")
9519         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9520   "TARGET_64BIT
9521    && (optimize_function_for_size_p (cfun)
9522        || !TARGET_PARTIAL_FLAG_REG_STALL
9523        || (operands[2] == const1_rtx
9524            && (TARGET_SHIFT1
9525                || TARGET_DOUBLE_WITH_ADD)))
9526    && ix86_match_ccmode (insn, CCGOCmode)
9527    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9528 {
9529   switch (get_attr_type (insn))
9530     {
9531     case TYPE_ALU:
9532       gcc_assert (operands[2] == const1_rtx);
9533       return "add{l}\t%k0, %k0";
9534
9535     default:
9536       if (operands[2] == const1_rtx
9537           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9538         return "sal{l}\t%k0";
9539       else
9540         return "sal{l}\t{%2, %k0|%k0, %2}";
9541     }
9542 }
9543   [(set (attr "type")
9544      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9545                      (const_int 0))
9546                  (match_operand 2 "const1_operand" ""))
9547               (const_string "alu")
9548            ]
9549            (const_string "ishift")))
9550    (set (attr "length_immediate")
9551      (if_then_else
9552        (ior (eq_attr "type" "alu")
9553             (and (eq_attr "type" "ishift")
9554                  (and (match_operand 2 "const1_operand" "")
9555                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9556                           (const_int 0)))))
9557        (const_string "0")
9558        (const_string "*")))
9559    (set_attr "mode" "SI")])
9560
9561 (define_insn "*ashl<mode>3_cconly"
9562   [(set (reg FLAGS_REG)
9563         (compare
9564           (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9565                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9566           (const_int 0)))
9567    (clobber (match_scratch:SWI 0 "=<r>"))]
9568   "(optimize_function_for_size_p (cfun)
9569     || !TARGET_PARTIAL_FLAG_REG_STALL
9570     || (operands[2] == const1_rtx
9571         && (TARGET_SHIFT1
9572             || TARGET_DOUBLE_WITH_ADD)))
9573    && ix86_match_ccmode (insn, CCGOCmode)
9574    && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9575 {
9576   switch (get_attr_type (insn))
9577     {
9578     case TYPE_ALU:
9579       gcc_assert (operands[2] == const1_rtx);
9580       return "add{<imodesuffix>}\t%0, %0";
9581
9582     default:
9583       if (operands[2] == const1_rtx
9584           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9585         return "sal{<imodesuffix>}\t%0";
9586       else
9587         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9588     }
9589 }
9590   [(set (attr "type")
9591      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9592                           (const_int 0))
9593                       (match_operand 0 "register_operand" ""))
9594                  (match_operand 2 "const1_operand" ""))
9595               (const_string "alu")
9596            ]
9597            (const_string "ishift")))
9598    (set (attr "length_immediate")
9599      (if_then_else
9600        (ior (eq_attr "type" "alu")
9601             (and (eq_attr "type" "ishift")
9602                  (and (match_operand 2 "const1_operand" "")
9603                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9604                           (const_int 0)))))
9605        (const_string "0")
9606        (const_string "*")))
9607    (set_attr "mode" "<MODE>")])
9608
9609 ;; See comment above `ashl<mode>3' about how this works.
9610
9611 (define_expand "<shiftrt_insn><mode>3"
9612   [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9613         (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
9614                            (match_operand:QI 2 "nonmemory_operand" "")))]
9615   ""
9616   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9617
9618 (define_insn_and_split "*<shiftrt_insn><mode>3_doubleword"
9619   [(set (match_operand:DWI 0 "register_operand" "=r")
9620         (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9621                          (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9622    (clobber (reg:CC FLAGS_REG))]
9623   ""
9624   "#"
9625   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9626   [(const_int 0)]
9627   "ix86_split_<shiftrt_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9628   [(set_attr "type" "multi")])
9629
9630 ;; By default we don't ask for a scratch register, because when DWImode
9631 ;; values are manipulated, registers are already at a premium.  But if
9632 ;; we have one handy, we won't turn it away.
9633
9634 (define_peephole2
9635   [(match_scratch:DWIH 3 "r")
9636    (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9637                    (any_shiftrt:<DWI>
9638                      (match_operand:<DWI> 1 "register_operand" "")
9639                      (match_operand:QI 2 "nonmemory_operand" "")))
9640               (clobber (reg:CC FLAGS_REG))])
9641    (match_dup 3)]
9642   "TARGET_CMOVE"
9643   [(const_int 0)]
9644   "ix86_split_<shiftrt_insn> (operands, operands[3], <DWI>mode); DONE;")
9645
9646 (define_insn "x86_64_shrd"
9647   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9648         (ior:DI (ashiftrt:DI (match_dup 0)
9649                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
9650                 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9651                   (minus:QI (const_int 64) (match_dup 2)))))
9652    (clobber (reg:CC FLAGS_REG))]
9653   "TARGET_64BIT"
9654   "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9655   [(set_attr "type" "ishift")
9656    (set_attr "prefix_0f" "1")
9657    (set_attr "mode" "DI")
9658    (set_attr "athlon_decode" "vector")
9659    (set_attr "amdfam10_decode" "vector")])
9660
9661 (define_insn "x86_shrd"
9662   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9663         (ior:SI (ashiftrt:SI (match_dup 0)
9664                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
9665                 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9666                   (minus:QI (const_int 32) (match_dup 2)))))
9667    (clobber (reg:CC FLAGS_REG))]
9668   ""
9669   "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9670   [(set_attr "type" "ishift")
9671    (set_attr "prefix_0f" "1")
9672    (set_attr "mode" "SI")
9673    (set_attr "pent_pair" "np")
9674    (set_attr "athlon_decode" "vector")
9675    (set_attr "amdfam10_decode" "vector")])
9676
9677 (define_insn "ashrdi3_cvt"
9678   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9679         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9680                      (match_operand:QI 2 "const_int_operand" "")))
9681    (clobber (reg:CC FLAGS_REG))]
9682   "TARGET_64BIT && INTVAL (operands[2]) == 63
9683    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9684    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9685   "@
9686    {cqto|cqo}
9687    sar{q}\t{%2, %0|%0, %2}"
9688   [(set_attr "type" "imovx,ishift")
9689    (set_attr "prefix_0f" "0,*")
9690    (set_attr "length_immediate" "0,*")
9691    (set_attr "modrm" "0,1")
9692    (set_attr "mode" "DI")])
9693
9694 (define_insn "ashrsi3_cvt"
9695   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9696         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9697                      (match_operand:QI 2 "const_int_operand" "")))
9698    (clobber (reg:CC FLAGS_REG))]
9699   "INTVAL (operands[2]) == 31
9700    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9701    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9702   "@
9703    {cltd|cdq}
9704    sar{l}\t{%2, %0|%0, %2}"
9705   [(set_attr "type" "imovx,ishift")
9706    (set_attr "prefix_0f" "0,*")
9707    (set_attr "length_immediate" "0,*")
9708    (set_attr "modrm" "0,1")
9709    (set_attr "mode" "SI")])
9710
9711 (define_insn "*ashrsi3_cvt_zext"
9712   [(set (match_operand:DI 0 "register_operand" "=*d,r")
9713         (zero_extend:DI
9714           (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9715                        (match_operand:QI 2 "const_int_operand" ""))))
9716    (clobber (reg:CC FLAGS_REG))]
9717   "TARGET_64BIT && INTVAL (operands[2]) == 31
9718    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9719    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9720   "@
9721    {cltd|cdq}
9722    sar{l}\t{%2, %k0|%k0, %2}"
9723   [(set_attr "type" "imovx,ishift")
9724    (set_attr "prefix_0f" "0,*")
9725    (set_attr "length_immediate" "0,*")
9726    (set_attr "modrm" "0,1")
9727    (set_attr "mode" "SI")])
9728
9729 (define_expand "x86_shift<mode>_adj_3"
9730   [(use (match_operand:SWI48 0 "register_operand" ""))
9731    (use (match_operand:SWI48 1 "register_operand" ""))
9732    (use (match_operand:QI 2 "register_operand" ""))]
9733   ""
9734 {
9735   rtx label = gen_label_rtx ();
9736   rtx tmp;
9737
9738   emit_insn (gen_testqi_ccz_1 (operands[2],
9739                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9740
9741   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9742   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9743   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9744                               gen_rtx_LABEL_REF (VOIDmode, label),
9745                               pc_rtx);
9746   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9747   JUMP_LABEL (tmp) = label;
9748
9749   emit_move_insn (operands[0], operands[1]);
9750   emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9751                                   GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9752   emit_label (label);
9753   LABEL_NUSES (label) = 1;
9754
9755   DONE;
9756 })
9757
9758 (define_insn "*<shiftrt_insn><mode>3_1"
9759   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9760         (any_shiftrt:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9761                          (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9762    (clobber (reg:CC FLAGS_REG))]
9763   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9764 {
9765   if (operands[2] == const1_rtx
9766       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9767     return "<shiftrt>{<imodesuffix>}\t%0";
9768   else
9769     return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9770 }
9771   [(set_attr "type" "ishift")
9772    (set (attr "length_immediate")
9773      (if_then_else
9774        (and (match_operand 2 "const1_operand" "")
9775             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9776                 (const_int 0)))
9777        (const_string "0")
9778        (const_string "*")))
9779    (set_attr "mode" "<MODE>")])
9780
9781 (define_insn "*<shiftrt_insn>si3_1_zext"
9782   [(set (match_operand:DI 0 "register_operand" "=r")
9783         (zero_extend:DI
9784           (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9785                           (match_operand:QI 2 "nonmemory_operand" "cI"))))
9786    (clobber (reg:CC FLAGS_REG))]
9787   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9788 {
9789   if (operands[2] == const1_rtx
9790       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9791     return "<shiftrt>{l}\t%k0";
9792   else
9793     return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
9794 }
9795   [(set_attr "type" "ishift")
9796    (set (attr "length_immediate")
9797      (if_then_else
9798        (and (match_operand 2 "const1_operand" "")
9799             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9800                 (const_int 0)))
9801        (const_string "0")
9802        (const_string "*")))
9803    (set_attr "mode" "SI")])
9804
9805 (define_insn "*<shiftrt_insn>qi3_1_slp"
9806   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9807         (any_shiftrt:QI (match_dup 0)
9808                         (match_operand:QI 1 "nonmemory_operand" "cI")))
9809    (clobber (reg:CC FLAGS_REG))]
9810   "(optimize_function_for_size_p (cfun)
9811     || !TARGET_PARTIAL_REG_STALL
9812     || (operands[1] == const1_rtx
9813         && TARGET_SHIFT1))"
9814 {
9815   if (operands[1] == const1_rtx
9816       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9817     return "<shiftrt>{b}\t%0";
9818   else
9819     return "<shiftrt>{b}\t{%1, %0|%0, %1}";
9820 }
9821   [(set_attr "type" "ishift1")
9822    (set (attr "length_immediate")
9823      (if_then_else
9824        (and (match_operand 1 "const1_operand" "")
9825             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9826                 (const_int 0)))
9827        (const_string "0")
9828        (const_string "*")))
9829    (set_attr "mode" "QI")])
9830
9831 ;; This pattern can't accept a variable shift count, since shifts by
9832 ;; zero don't affect the flags.  We assume that shifts by constant
9833 ;; zero are optimized away.
9834 (define_insn "*<shiftrt_insn><mode>3_cmp"
9835   [(set (reg FLAGS_REG)
9836         (compare
9837           (any_shiftrt:SWI
9838             (match_operand:SWI 1 "nonimmediate_operand" "0")
9839             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9840           (const_int 0)))
9841    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9842         (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
9843   "(optimize_function_for_size_p (cfun)
9844     || !TARGET_PARTIAL_FLAG_REG_STALL
9845     || (operands[2] == const1_rtx
9846         && TARGET_SHIFT1))
9847    && ix86_match_ccmode (insn, CCGOCmode)
9848    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9849 {
9850   if (operands[2] == const1_rtx
9851       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9852     return "<shiftrt>{<imodesuffix>}\t%0";
9853   else
9854     return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9855 }
9856   [(set_attr "type" "ishift")
9857    (set (attr "length_immediate")
9858      (if_then_else
9859        (and (match_operand 2 "const1_operand" "")
9860             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9861                 (const_int 0)))
9862        (const_string "0")
9863        (const_string "*")))
9864    (set_attr "mode" "<MODE>")])
9865
9866 (define_insn "*<shiftrt_insn>si3_cmp_zext"
9867   [(set (reg FLAGS_REG)
9868         (compare
9869           (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9870                           (match_operand:QI 2 "const_1_to_31_operand" "I"))
9871           (const_int 0)))
9872    (set (match_operand:DI 0 "register_operand" "=r")
9873         (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9874   "TARGET_64BIT
9875    && (optimize_function_for_size_p (cfun)
9876        || !TARGET_PARTIAL_FLAG_REG_STALL
9877        || (operands[2] == const1_rtx
9878            && TARGET_SHIFT1))
9879    && ix86_match_ccmode (insn, CCGOCmode)
9880    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9881 {
9882   if (operands[2] == const1_rtx
9883       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9884     return "<shiftrt>{l}\t%k0";
9885   else
9886     return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
9887 }
9888   [(set_attr "type" "ishift")
9889    (set (attr "length_immediate")
9890      (if_then_else
9891        (and (match_operand 2 "const1_operand" "")
9892             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9893                 (const_int 0)))
9894        (const_string "0")
9895        (const_string "*")))
9896    (set_attr "mode" "SI")])
9897
9898 (define_insn "*<shiftrt_insn><mode>3_cconly"
9899   [(set (reg FLAGS_REG)
9900         (compare
9901           (any_shiftrt:SWI
9902             (match_operand:SWI 1 "nonimmediate_operand" "0")
9903             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9904           (const_int 0)))
9905    (clobber (match_scratch:SWI 0 "=<r>"))]
9906   "(optimize_function_for_size_p (cfun)
9907     || !TARGET_PARTIAL_FLAG_REG_STALL
9908     || (operands[2] == const1_rtx
9909         && TARGET_SHIFT1))
9910    && ix86_match_ccmode (insn, CCGOCmode)
9911    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9912 {
9913   if (operands[2] == const1_rtx
9914       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9915     return "<shiftrt>{<imodesuffix>}\t%0";
9916   else
9917     return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9918 }
9919   [(set_attr "type" "ishift")
9920    (set (attr "length_immediate")
9921      (if_then_else
9922        (and (match_operand 2 "const1_operand" "")
9923             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9924                 (const_int 0)))
9925        (const_string "0")
9926        (const_string "*")))
9927    (set_attr "mode" "<MODE>")])
9928 \f
9929 ;; Rotate instructions
9930
9931 (define_expand "<rotate_insn>ti3"
9932   [(set (match_operand:TI 0 "register_operand" "")
9933         (any_rotate:TI (match_operand:TI 1 "register_operand" "")
9934                        (match_operand:QI 2 "nonmemory_operand" "")))]
9935   "TARGET_64BIT"
9936 {
9937   if (const_1_to_63_operand (operands[2], VOIDmode))
9938     emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
9939                 (operands[0], operands[1], operands[2]));
9940   else
9941     FAIL;
9942
9943   DONE;
9944 })
9945
9946 (define_expand "<rotate_insn>di3"
9947   [(set (match_operand:DI 0 "shiftdi_operand" "")
9948         (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
9949                        (match_operand:QI 2 "nonmemory_operand" "")))]
9950  ""
9951 {
9952   if (TARGET_64BIT)
9953     ix86_expand_binary_operator (<CODE>, DImode, operands);
9954   else if (const_1_to_31_operand (operands[2], VOIDmode))
9955     emit_insn (gen_ix86_<rotate_insn>di3_doubleword
9956                 (operands[0], operands[1], operands[2]));
9957   else
9958     FAIL;
9959
9960   DONE;
9961 })
9962
9963 (define_expand "<rotate_insn><mode>3"
9964   [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
9965         (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
9966                             (match_operand:QI 2 "nonmemory_operand" "")))]
9967   ""
9968   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9969
9970 ;; Implement rotation using two double-precision
9971 ;; shift instructions and a scratch register.
9972
9973 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
9974  [(set (match_operand:<DWI> 0 "register_operand" "=r")
9975        (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
9976                      (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
9977   (clobber (reg:CC FLAGS_REG))
9978   (clobber (match_scratch:DWIH 3 "=&r"))]
9979  ""
9980  "#"
9981  "reload_completed"
9982  [(set (match_dup 3) (match_dup 4))
9983   (parallel
9984    [(set (match_dup 4)
9985          (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
9986                    (lshiftrt:DWIH (match_dup 5)
9987                                   (minus:QI (match_dup 6) (match_dup 2)))))
9988     (clobber (reg:CC FLAGS_REG))])
9989   (parallel
9990    [(set (match_dup 5)
9991          (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
9992                    (lshiftrt:DWIH (match_dup 3)
9993                                   (minus:QI (match_dup 6) (match_dup 2)))))
9994     (clobber (reg:CC FLAGS_REG))])]
9995 {
9996   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
9997
9998   split_<dwi> (&operands[0], 1, &operands[4], &operands[5]);
9999 })
10000
10001 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10002  [(set (match_operand:<DWI> 0 "register_operand" "=r")
10003        (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10004                        (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10005   (clobber (reg:CC FLAGS_REG))
10006   (clobber (match_scratch:DWIH 3 "=&r"))]
10007  ""
10008  "#"
10009  "reload_completed"
10010  [(set (match_dup 3) (match_dup 4))
10011   (parallel
10012    [(set (match_dup 4)
10013          (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10014                    (ashift:DWIH (match_dup 5)
10015                                 (minus:QI (match_dup 6) (match_dup 2)))))
10016     (clobber (reg:CC FLAGS_REG))])
10017   (parallel
10018    [(set (match_dup 5)
10019          (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10020                    (ashift:DWIH (match_dup 3)
10021                                 (minus:QI (match_dup 6) (match_dup 2)))))
10022     (clobber (reg:CC FLAGS_REG))])]
10023 {
10024   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10025
10026   split_<dwi> (&operands[0], 1, &operands[4], &operands[5]);
10027 })
10028
10029 (define_insn "*<rotate_insn><mode>3_1"
10030   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10031         (any_rotate:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10032                         (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10033    (clobber (reg:CC FLAGS_REG))]
10034   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10035 {
10036   if (operands[2] == const1_rtx
10037       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10038     return "<rotate>{<imodesuffix>}\t%0";
10039   else
10040     return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10041 }
10042   [(set_attr "type" "rotate")
10043    (set (attr "length_immediate")
10044      (if_then_else
10045        (and (match_operand 2 "const1_operand" "")
10046             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10047                 (const_int 0)))
10048        (const_string "0")
10049        (const_string "*")))
10050    (set_attr "mode" "<MODE>")])
10051
10052 (define_insn "*<rotate_insn>si3_1_zext"
10053   [(set (match_operand:DI 0 "register_operand" "=r")
10054         (zero_extend:DI
10055           (any_rotate:SI (match_operand:SI 1 "register_operand" "0")
10056                          (match_operand:QI 2 "nonmemory_operand" "cI"))))
10057    (clobber (reg:CC FLAGS_REG))]
10058   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10059 {
10060     if (operands[2] == const1_rtx
10061         && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10062     return "<rotate>{l}\t%k0";
10063   else
10064     return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10065 }
10066   [(set_attr "type" "rotate")
10067    (set (attr "length_immediate")
10068      (if_then_else
10069        (and (match_operand 2 "const1_operand" "")
10070             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10071                 (const_int 0)))
10072        (const_string "0")
10073        (const_string "*")))
10074    (set_attr "mode" "SI")])
10075
10076 (define_insn "*<rotate_insn>qi3_1_slp"
10077   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10078         (any_rotate:QI (match_dup 0)
10079                        (match_operand:QI 1 "nonmemory_operand" "cI")))
10080    (clobber (reg:CC FLAGS_REG))]
10081   "(optimize_function_for_size_p (cfun)
10082     || !TARGET_PARTIAL_REG_STALL
10083     || (operands[1] == const1_rtx
10084         && TARGET_SHIFT1))"
10085 {
10086   if (operands[1] == const1_rtx
10087       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10088     return "<rotate>{b}\t%0";
10089   else
10090     return "<rotate>{b}\t{%1, %0|%0, %1}";
10091 }
10092   [(set_attr "type" "rotate1")
10093    (set (attr "length_immediate")
10094      (if_then_else
10095        (and (match_operand 1 "const1_operand" "")
10096             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10097                 (const_int 0)))
10098        (const_string "0")
10099        (const_string "*")))
10100    (set_attr "mode" "QI")])
10101
10102 (define_split
10103  [(set (match_operand:HI 0 "register_operand" "")
10104        (any_rotate:HI (match_dup 0) (const_int 8)))
10105   (clobber (reg:CC FLAGS_REG))]
10106  "reload_completed
10107   && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10108  [(parallel [(set (strict_low_part (match_dup 0))
10109                   (bswap:HI (match_dup 0)))
10110              (clobber (reg:CC FLAGS_REG))])])
10111 \f
10112 ;; Bit set / bit test instructions
10113
10114 (define_expand "extv"
10115   [(set (match_operand:SI 0 "register_operand" "")
10116         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10117                          (match_operand:SI 2 "const8_operand" "")
10118                          (match_operand:SI 3 "const8_operand" "")))]
10119   ""
10120 {
10121   /* Handle extractions from %ah et al.  */
10122   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10123     FAIL;
10124
10125   /* From mips.md: extract_bit_field doesn't verify that our source
10126      matches the predicate, so check it again here.  */
10127   if (! ext_register_operand (operands[1], VOIDmode))
10128     FAIL;
10129 })
10130
10131 (define_expand "extzv"
10132   [(set (match_operand:SI 0 "register_operand" "")
10133         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10134                          (match_operand:SI 2 "const8_operand" "")
10135                          (match_operand:SI 3 "const8_operand" "")))]
10136   ""
10137 {
10138   /* Handle extractions from %ah et al.  */
10139   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10140     FAIL;
10141
10142   /* From mips.md: extract_bit_field doesn't verify that our source
10143      matches the predicate, so check it again here.  */
10144   if (! ext_register_operand (operands[1], VOIDmode))
10145     FAIL;
10146 })
10147
10148 (define_expand "insv"
10149   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
10150                       (match_operand 1 "const8_operand" "")
10151                       (match_operand 2 "const8_operand" ""))
10152         (match_operand 3 "register_operand" ""))]
10153   ""
10154 {
10155   rtx (*gen_mov_insv_1) (rtx, rtx);
10156
10157   /* Handle insertions to %ah et al.  */
10158   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10159     FAIL;
10160
10161   /* From mips.md: insert_bit_field doesn't verify that our source
10162      matches the predicate, so check it again here.  */
10163   if (! ext_register_operand (operands[0], VOIDmode))
10164     FAIL;
10165
10166   gen_mov_insv_1 = (TARGET_64BIT
10167                     ? gen_movdi_insv_1 : gen_movsi_insv_1);
10168
10169   emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10170   DONE;
10171 })
10172
10173 ;; %%% bts, btr, btc, bt.
10174 ;; In general these instructions are *slow* when applied to memory,
10175 ;; since they enforce atomic operation.  When applied to registers,
10176 ;; it depends on the cpu implementation.  They're never faster than
10177 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10178 ;; no point.  But in 64-bit, we can't hold the relevant immediates
10179 ;; within the instruction itself, so operating on bits in the high
10180 ;; 32-bits of a register becomes easier.
10181 ;;
10182 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
10183 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10184 ;; negdf respectively, so they can never be disabled entirely.
10185
10186 (define_insn "*btsq"
10187   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10188                          (const_int 1)
10189                          (match_operand:DI 1 "const_0_to_63_operand" ""))
10190         (const_int 1))
10191    (clobber (reg:CC FLAGS_REG))]
10192   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10193   "bts{q}\t{%1, %0|%0, %1}"
10194   [(set_attr "type" "alu1")
10195    (set_attr "prefix_0f" "1")
10196    (set_attr "mode" "DI")])
10197
10198 (define_insn "*btrq"
10199   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10200                          (const_int 1)
10201                          (match_operand:DI 1 "const_0_to_63_operand" ""))
10202         (const_int 0))
10203    (clobber (reg:CC FLAGS_REG))]
10204   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10205   "btr{q}\t{%1, %0|%0, %1}"
10206   [(set_attr "type" "alu1")
10207    (set_attr "prefix_0f" "1")
10208    (set_attr "mode" "DI")])
10209
10210 (define_insn "*btcq"
10211   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10212                          (const_int 1)
10213                          (match_operand:DI 1 "const_0_to_63_operand" ""))
10214         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10215    (clobber (reg:CC FLAGS_REG))]
10216   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10217   "btc{q}\t{%1, %0|%0, %1}"
10218   [(set_attr "type" "alu1")
10219    (set_attr "prefix_0f" "1")
10220    (set_attr "mode" "DI")])
10221
10222 ;; Allow Nocona to avoid these instructions if a register is available.
10223
10224 (define_peephole2
10225   [(match_scratch:DI 2 "r")
10226    (parallel [(set (zero_extract:DI
10227                      (match_operand:DI 0 "register_operand" "")
10228                      (const_int 1)
10229                      (match_operand:DI 1 "const_0_to_63_operand" ""))
10230                    (const_int 1))
10231               (clobber (reg:CC FLAGS_REG))])]
10232   "TARGET_64BIT && !TARGET_USE_BT"
10233   [(const_int 0)]
10234 {
10235   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10236   rtx op1;
10237
10238   if (HOST_BITS_PER_WIDE_INT >= 64)
10239     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10240   else if (i < HOST_BITS_PER_WIDE_INT)
10241     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10242   else
10243     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10244
10245   op1 = immed_double_const (lo, hi, DImode);
10246   if (i >= 31)
10247     {
10248       emit_move_insn (operands[2], op1);
10249       op1 = operands[2];
10250     }
10251
10252   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10253   DONE;
10254 })
10255
10256 (define_peephole2
10257   [(match_scratch:DI 2 "r")
10258    (parallel [(set (zero_extract:DI
10259                      (match_operand:DI 0 "register_operand" "")
10260                      (const_int 1)
10261                      (match_operand:DI 1 "const_0_to_63_operand" ""))
10262                    (const_int 0))
10263               (clobber (reg:CC FLAGS_REG))])]
10264   "TARGET_64BIT && !TARGET_USE_BT"
10265   [(const_int 0)]
10266 {
10267   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10268   rtx op1;
10269
10270   if (HOST_BITS_PER_WIDE_INT >= 64)
10271     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10272   else if (i < HOST_BITS_PER_WIDE_INT)
10273     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10274   else
10275     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10276
10277   op1 = immed_double_const (~lo, ~hi, DImode);
10278   if (i >= 32)
10279     {
10280       emit_move_insn (operands[2], op1);
10281       op1 = operands[2];
10282     }
10283
10284   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10285   DONE;
10286 })
10287
10288 (define_peephole2
10289   [(match_scratch:DI 2 "r")
10290    (parallel [(set (zero_extract:DI
10291                      (match_operand:DI 0 "register_operand" "")
10292                      (const_int 1)
10293                      (match_operand:DI 1 "const_0_to_63_operand" ""))
10294               (not:DI (zero_extract:DI
10295                         (match_dup 0) (const_int 1) (match_dup 1))))
10296               (clobber (reg:CC FLAGS_REG))])]
10297   "TARGET_64BIT && !TARGET_USE_BT"
10298   [(const_int 0)]
10299 {
10300   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10301   rtx op1;
10302
10303   if (HOST_BITS_PER_WIDE_INT >= 64)
10304     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10305   else if (i < HOST_BITS_PER_WIDE_INT)
10306     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10307   else
10308     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10309
10310   op1 = immed_double_const (lo, hi, DImode);
10311   if (i >= 31)
10312     {
10313       emit_move_insn (operands[2], op1);
10314       op1 = operands[2];
10315     }
10316
10317   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10318   DONE;
10319 })
10320
10321 (define_insn "*bt<mode>"
10322   [(set (reg:CCC FLAGS_REG)
10323         (compare:CCC
10324           (zero_extract:SWI48
10325             (match_operand:SWI48 0 "register_operand" "r")
10326             (const_int 1)
10327             (match_operand:SWI48 1 "nonmemory_operand" "rN"))
10328           (const_int 0)))]
10329   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10330   "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10331   [(set_attr "type" "alu1")
10332    (set_attr "prefix_0f" "1")
10333    (set_attr "mode" "<MODE>")])
10334 \f
10335 ;; Store-flag instructions.
10336
10337 ;; For all sCOND expanders, also expand the compare or test insn that
10338 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
10339
10340 (define_insn_and_split "*setcc_di_1"
10341   [(set (match_operand:DI 0 "register_operand" "=q")
10342         (match_operator:DI 1 "ix86_comparison_operator"
10343           [(reg FLAGS_REG) (const_int 0)]))]
10344   "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10345   "#"
10346   "&& reload_completed"
10347   [(set (match_dup 2) (match_dup 1))
10348    (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10349 {
10350   PUT_MODE (operands[1], QImode);
10351   operands[2] = gen_lowpart (QImode, operands[0]);
10352 })
10353
10354 (define_insn_and_split "*setcc_si_1_and"
10355   [(set (match_operand:SI 0 "register_operand" "=q")
10356         (match_operator:SI 1 "ix86_comparison_operator"
10357           [(reg FLAGS_REG) (const_int 0)]))
10358    (clobber (reg:CC FLAGS_REG))]
10359   "!TARGET_PARTIAL_REG_STALL
10360    && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10361   "#"
10362   "&& reload_completed"
10363   [(set (match_dup 2) (match_dup 1))
10364    (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10365               (clobber (reg:CC FLAGS_REG))])]
10366 {
10367   PUT_MODE (operands[1], QImode);
10368   operands[2] = gen_lowpart (QImode, operands[0]);
10369 })
10370
10371 (define_insn_and_split "*setcc_si_1_movzbl"
10372   [(set (match_operand:SI 0 "register_operand" "=q")
10373         (match_operator:SI 1 "ix86_comparison_operator"
10374           [(reg FLAGS_REG) (const_int 0)]))]
10375   "!TARGET_PARTIAL_REG_STALL
10376    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10377   "#"
10378   "&& reload_completed"
10379   [(set (match_dup 2) (match_dup 1))
10380    (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10381 {
10382   PUT_MODE (operands[1], QImode);
10383   operands[2] = gen_lowpart (QImode, operands[0]);
10384 })
10385
10386 (define_insn "*setcc_qi"
10387   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10388         (match_operator:QI 1 "ix86_comparison_operator"
10389           [(reg FLAGS_REG) (const_int 0)]))]
10390   ""
10391   "set%C1\t%0"
10392   [(set_attr "type" "setcc")
10393    (set_attr "mode" "QI")])
10394
10395 (define_insn "*setcc_qi_slp"
10396   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10397         (match_operator:QI 1 "ix86_comparison_operator"
10398           [(reg FLAGS_REG) (const_int 0)]))]
10399   ""
10400   "set%C1\t%0"
10401   [(set_attr "type" "setcc")
10402    (set_attr "mode" "QI")])
10403
10404 ;; In general it is not safe to assume too much about CCmode registers,
10405 ;; so simplify-rtx stops when it sees a second one.  Under certain
10406 ;; conditions this is safe on x86, so help combine not create
10407 ;;
10408 ;;      seta    %al
10409 ;;      testb   %al, %al
10410 ;;      sete    %al
10411
10412 (define_split
10413   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10414         (ne:QI (match_operator 1 "ix86_comparison_operator"
10415                  [(reg FLAGS_REG) (const_int 0)])
10416             (const_int 0)))]
10417   ""
10418   [(set (match_dup 0) (match_dup 1))]
10419   "PUT_MODE (operands[1], QImode);")
10420
10421 (define_split
10422   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10423         (ne:QI (match_operator 1 "ix86_comparison_operator"
10424                  [(reg FLAGS_REG) (const_int 0)])
10425             (const_int 0)))]
10426   ""
10427   [(set (match_dup 0) (match_dup 1))]
10428   "PUT_MODE (operands[1], QImode);")
10429
10430 (define_split
10431   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10432         (eq:QI (match_operator 1 "ix86_comparison_operator"
10433                  [(reg FLAGS_REG) (const_int 0)])
10434             (const_int 0)))]
10435   ""
10436   [(set (match_dup 0) (match_dup 1))]
10437 {
10438   rtx new_op1 = copy_rtx (operands[1]);
10439   operands[1] = new_op1;
10440   PUT_MODE (new_op1, QImode);
10441   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10442                                              GET_MODE (XEXP (new_op1, 0))));
10443
10444   /* Make sure that (a) the CCmode we have for the flags is strong
10445      enough for the reversed compare or (b) we have a valid FP compare.  */
10446   if (! ix86_comparison_operator (new_op1, VOIDmode))
10447     FAIL;
10448 })
10449
10450 (define_split
10451   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10452         (eq:QI (match_operator 1 "ix86_comparison_operator"
10453                  [(reg FLAGS_REG) (const_int 0)])
10454             (const_int 0)))]
10455   ""
10456   [(set (match_dup 0) (match_dup 1))]
10457 {
10458   rtx new_op1 = copy_rtx (operands[1]);
10459   operands[1] = new_op1;
10460   PUT_MODE (new_op1, QImode);
10461   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10462                                              GET_MODE (XEXP (new_op1, 0))));
10463
10464   /* Make sure that (a) the CCmode we have for the flags is strong
10465      enough for the reversed compare or (b) we have a valid FP compare.  */
10466   if (! ix86_comparison_operator (new_op1, VOIDmode))
10467     FAIL;
10468 })
10469
10470 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10471 ;; subsequent logical operations are used to imitate conditional moves.
10472 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10473 ;; it directly.
10474
10475 (define_insn "*avx_setcc<mode>"
10476   [(set (match_operand:MODEF 0 "register_operand" "=x")
10477         (match_operator:MODEF 1 "avx_comparison_float_operator"
10478           [(match_operand:MODEF 2 "register_operand" "x")
10479            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
10480   "TARGET_AVX"
10481   "vcmp%D1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
10482   [(set_attr "type" "ssecmp")
10483    (set_attr "prefix" "vex")
10484    (set_attr "length_immediate" "1")
10485    (set_attr "mode" "<MODE>")])
10486
10487 (define_insn "*sse_setcc<mode>"
10488   [(set (match_operand:MODEF 0 "register_operand" "=x")
10489         (match_operator:MODEF 1 "sse_comparison_operator"
10490           [(match_operand:MODEF 2 "register_operand" "0")
10491            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
10492   "SSE_FLOAT_MODE_P (<MODE>mode)"
10493   "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
10494   [(set_attr "type" "ssecmp")
10495    (set_attr "length_immediate" "1")
10496    (set_attr "mode" "<MODE>")])
10497 \f
10498 ;; Basic conditional jump instructions.
10499 ;; We ignore the overflow flag for signed branch instructions.
10500
10501 (define_insn "*jcc_1"
10502   [(set (pc)
10503         (if_then_else (match_operator 1 "ix86_comparison_operator"
10504                                       [(reg FLAGS_REG) (const_int 0)])
10505                       (label_ref (match_operand 0 "" ""))
10506                       (pc)))]
10507   ""
10508   "%+j%C1\t%l0"
10509   [(set_attr "type" "ibr")
10510    (set_attr "modrm" "0")
10511    (set (attr "length")
10512            (if_then_else (and (ge (minus (match_dup 0) (pc))
10513                                   (const_int -126))
10514                               (lt (minus (match_dup 0) (pc))
10515                                   (const_int 128)))
10516              (const_int 2)
10517              (const_int 6)))])
10518
10519 (define_insn "*jcc_2"
10520   [(set (pc)
10521         (if_then_else (match_operator 1 "ix86_comparison_operator"
10522                                       [(reg FLAGS_REG) (const_int 0)])
10523                       (pc)
10524                       (label_ref (match_operand 0 "" ""))))]
10525   ""
10526   "%+j%c1\t%l0"
10527   [(set_attr "type" "ibr")
10528    (set_attr "modrm" "0")
10529    (set (attr "length")
10530            (if_then_else (and (ge (minus (match_dup 0) (pc))
10531                                   (const_int -126))
10532                               (lt (minus (match_dup 0) (pc))
10533                                   (const_int 128)))
10534              (const_int 2)
10535              (const_int 6)))])
10536
10537 ;; In general it is not safe to assume too much about CCmode registers,
10538 ;; so simplify-rtx stops when it sees a second one.  Under certain
10539 ;; conditions this is safe on x86, so help combine not create
10540 ;;
10541 ;;      seta    %al
10542 ;;      testb   %al, %al
10543 ;;      je      Lfoo
10544
10545 (define_split
10546   [(set (pc)
10547         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10548                                       [(reg FLAGS_REG) (const_int 0)])
10549                           (const_int 0))
10550                       (label_ref (match_operand 1 "" ""))
10551                       (pc)))]
10552   ""
10553   [(set (pc)
10554         (if_then_else (match_dup 0)
10555                       (label_ref (match_dup 1))
10556                       (pc)))]
10557   "PUT_MODE (operands[0], VOIDmode);")
10558
10559 (define_split
10560   [(set (pc)
10561         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10562                                       [(reg FLAGS_REG) (const_int 0)])
10563                           (const_int 0))
10564                       (label_ref (match_operand 1 "" ""))
10565                       (pc)))]
10566   ""
10567   [(set (pc)
10568         (if_then_else (match_dup 0)
10569                       (label_ref (match_dup 1))
10570                       (pc)))]
10571 {
10572   rtx new_op0 = copy_rtx (operands[0]);
10573   operands[0] = new_op0;
10574   PUT_MODE (new_op0, VOIDmode);
10575   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10576                                              GET_MODE (XEXP (new_op0, 0))));
10577
10578   /* Make sure that (a) the CCmode we have for the flags is strong
10579      enough for the reversed compare or (b) we have a valid FP compare.  */
10580   if (! ix86_comparison_operator (new_op0, VOIDmode))
10581     FAIL;
10582 })
10583
10584 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10585 ;; pass generates from shift insn with QImode operand.  Actually, the mode
10586 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10587 ;; appropriate modulo of the bit offset value.
10588
10589 (define_insn_and_split "*jcc_bt<mode>"
10590   [(set (pc)
10591         (if_then_else (match_operator 0 "bt_comparison_operator"
10592                         [(zero_extract:SWI48
10593                            (match_operand:SWI48 1 "register_operand" "r")
10594                            (const_int 1)
10595                            (zero_extend:SI
10596                              (match_operand:QI 2 "register_operand" "r")))
10597                          (const_int 0)])
10598                       (label_ref (match_operand 3 "" ""))
10599                       (pc)))
10600    (clobber (reg:CC FLAGS_REG))]
10601   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10602   "#"
10603   "&& 1"
10604   [(set (reg:CCC FLAGS_REG)
10605         (compare:CCC
10606           (zero_extract:SWI48
10607             (match_dup 1)
10608             (const_int 1)
10609             (match_dup 2))
10610           (const_int 0)))
10611    (set (pc)
10612         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10613                       (label_ref (match_dup 3))
10614                       (pc)))]
10615 {
10616   operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10617
10618   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10619 })
10620
10621 ;; Avoid useless masking of bit offset operand.  "and" in SImode is correct
10622 ;; also for DImode, this is what combine produces.
10623 (define_insn_and_split "*jcc_bt<mode>_mask"
10624   [(set (pc)
10625         (if_then_else (match_operator 0 "bt_comparison_operator"
10626                         [(zero_extract:SWI48
10627                            (match_operand:SWI48 1 "register_operand" "r")
10628                            (const_int 1)
10629                            (and:SI
10630                              (match_operand:SI 2 "register_operand" "r")
10631                              (match_operand:SI 3 "const_int_operand" "n")))])
10632                       (label_ref (match_operand 4 "" ""))
10633                       (pc)))
10634    (clobber (reg:CC FLAGS_REG))]
10635   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10636    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10637       == GET_MODE_BITSIZE (<MODE>mode)-1"
10638   "#"
10639   "&& 1"
10640   [(set (reg:CCC FLAGS_REG)
10641         (compare:CCC
10642           (zero_extract:SWI48
10643             (match_dup 1)
10644             (const_int 1)
10645             (match_dup 2))
10646           (const_int 0)))
10647    (set (pc)
10648         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10649                       (label_ref (match_dup 4))
10650                       (pc)))]
10651 {
10652   operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10653
10654   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10655 })
10656
10657 (define_insn_and_split "*jcc_btsi_1"
10658   [(set (pc)
10659         (if_then_else (match_operator 0 "bt_comparison_operator"
10660                         [(and:SI
10661                            (lshiftrt:SI
10662                              (match_operand:SI 1 "register_operand" "r")
10663                              (match_operand:QI 2 "register_operand" "r"))
10664                            (const_int 1))
10665                          (const_int 0)])
10666                       (label_ref (match_operand 3 "" ""))
10667                       (pc)))
10668    (clobber (reg:CC FLAGS_REG))]
10669   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10670   "#"
10671   "&& 1"
10672   [(set (reg:CCC FLAGS_REG)
10673         (compare:CCC
10674           (zero_extract:SI
10675             (match_dup 1)
10676             (const_int 1)
10677             (match_dup 2))
10678           (const_int 0)))
10679    (set (pc)
10680         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10681                       (label_ref (match_dup 3))
10682                       (pc)))]
10683 {
10684   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10685
10686   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10687 })
10688
10689 ;; avoid useless masking of bit offset operand
10690 (define_insn_and_split "*jcc_btsi_mask_1"
10691   [(set (pc)
10692         (if_then_else
10693           (match_operator 0 "bt_comparison_operator"
10694             [(and:SI
10695                (lshiftrt:SI
10696                  (match_operand:SI 1 "register_operand" "r")
10697                  (subreg:QI
10698                    (and:SI
10699                      (match_operand:SI 2 "register_operand" "r")
10700                      (match_operand:SI 3 "const_int_operand" "n")) 0))
10701                (const_int 1))
10702              (const_int 0)])
10703           (label_ref (match_operand 4 "" ""))
10704           (pc)))
10705    (clobber (reg:CC FLAGS_REG))]
10706   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10707    && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10708   "#"
10709   "&& 1"
10710   [(set (reg:CCC FLAGS_REG)
10711         (compare:CCC
10712           (zero_extract:SI
10713             (match_dup 1)
10714             (const_int 1)
10715             (match_dup 2))
10716           (const_int 0)))
10717    (set (pc)
10718         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10719                       (label_ref (match_dup 4))
10720                       (pc)))]
10721   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10722
10723 ;; Define combination compare-and-branch fp compare instructions to help
10724 ;; combine.
10725
10726 (define_insn "*fp_jcc_1_387"
10727   [(set (pc)
10728         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10729                         [(match_operand 1 "register_operand" "f")
10730                          (match_operand 2 "nonimmediate_operand" "fm")])
10731           (label_ref (match_operand 3 "" ""))
10732           (pc)))
10733    (clobber (reg:CCFP FPSR_REG))
10734    (clobber (reg:CCFP FLAGS_REG))
10735    (clobber (match_scratch:HI 4 "=a"))]
10736   "TARGET_80387
10737    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10738    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10739    && SELECT_CC_MODE (GET_CODE (operands[0]),
10740                       operands[1], operands[2]) == CCFPmode
10741    && !TARGET_CMOVE"
10742   "#")
10743
10744 (define_insn "*fp_jcc_1r_387"
10745   [(set (pc)
10746         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10747                         [(match_operand 1 "register_operand" "f")
10748                          (match_operand 2 "nonimmediate_operand" "fm")])
10749           (pc)
10750           (label_ref (match_operand 3 "" ""))))
10751    (clobber (reg:CCFP FPSR_REG))
10752    (clobber (reg:CCFP FLAGS_REG))
10753    (clobber (match_scratch:HI 4 "=a"))]
10754   "TARGET_80387
10755    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10756    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10757    && SELECT_CC_MODE (GET_CODE (operands[0]),
10758                       operands[1], operands[2]) == CCFPmode
10759    && !TARGET_CMOVE"
10760   "#")
10761
10762 (define_insn "*fp_jcc_2_387"
10763   [(set (pc)
10764         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10765                         [(match_operand 1 "register_operand" "f")
10766                          (match_operand 2 "register_operand" "f")])
10767           (label_ref (match_operand 3 "" ""))
10768           (pc)))
10769    (clobber (reg:CCFP FPSR_REG))
10770    (clobber (reg:CCFP FLAGS_REG))
10771    (clobber (match_scratch:HI 4 "=a"))]
10772   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10773    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10774    && !TARGET_CMOVE"
10775   "#")
10776
10777 (define_insn "*fp_jcc_2r_387"
10778   [(set (pc)
10779         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10780                         [(match_operand 1 "register_operand" "f")
10781                          (match_operand 2 "register_operand" "f")])
10782           (pc)
10783           (label_ref (match_operand 3 "" ""))))
10784    (clobber (reg:CCFP FPSR_REG))
10785    (clobber (reg:CCFP FLAGS_REG))
10786    (clobber (match_scratch:HI 4 "=a"))]
10787   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10788    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10789    && !TARGET_CMOVE"
10790   "#")
10791
10792 (define_insn "*fp_jcc_3_387"
10793   [(set (pc)
10794         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10795                         [(match_operand 1 "register_operand" "f")
10796                          (match_operand 2 "const0_operand" "")])
10797           (label_ref (match_operand 3 "" ""))
10798           (pc)))
10799    (clobber (reg:CCFP FPSR_REG))
10800    (clobber (reg:CCFP FLAGS_REG))
10801    (clobber (match_scratch:HI 4 "=a"))]
10802   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10803    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10804    && SELECT_CC_MODE (GET_CODE (operands[0]),
10805                       operands[1], operands[2]) == CCFPmode
10806    && !TARGET_CMOVE"
10807   "#")
10808
10809 (define_split
10810   [(set (pc)
10811         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10812                         [(match_operand 1 "register_operand" "")
10813                          (match_operand 2 "nonimmediate_operand" "")])
10814           (match_operand 3 "" "")
10815           (match_operand 4 "" "")))
10816    (clobber (reg:CCFP FPSR_REG))
10817    (clobber (reg:CCFP FLAGS_REG))]
10818   "reload_completed"
10819   [(const_int 0)]
10820 {
10821   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10822                         operands[3], operands[4], NULL_RTX, NULL_RTX);
10823   DONE;
10824 })
10825
10826 (define_split
10827   [(set (pc)
10828         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10829                         [(match_operand 1 "register_operand" "")
10830                          (match_operand 2 "general_operand" "")])
10831           (match_operand 3 "" "")
10832           (match_operand 4 "" "")))
10833    (clobber (reg:CCFP FPSR_REG))
10834    (clobber (reg:CCFP FLAGS_REG))
10835    (clobber (match_scratch:HI 5 "=a"))]
10836   "reload_completed"
10837   [(const_int 0)]
10838 {
10839   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10840                         operands[3], operands[4], operands[5], NULL_RTX);
10841   DONE;
10842 })
10843
10844 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
10845 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
10846 ;; with a precedence over other operators and is always put in the first
10847 ;; place. Swap condition and operands to match ficom instruction.
10848
10849 (define_insn "*fp_jcc_4_<mode>_387"
10850   [(set (pc)
10851         (if_then_else
10852           (match_operator 0 "ix86_swapped_fp_comparison_operator"
10853             [(match_operator 1 "float_operator"
10854               [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
10855              (match_operand 3 "register_operand" "f,f")])
10856           (label_ref (match_operand 4 "" ""))
10857           (pc)))
10858    (clobber (reg:CCFP FPSR_REG))
10859    (clobber (reg:CCFP FLAGS_REG))
10860    (clobber (match_scratch:HI 5 "=a,a"))]
10861   "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
10862    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
10863    && GET_MODE (operands[1]) == GET_MODE (operands[3])
10864    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
10865    && !TARGET_CMOVE"
10866   "#")
10867
10868 (define_split
10869   [(set (pc)
10870         (if_then_else
10871           (match_operator 0 "ix86_swapped_fp_comparison_operator"
10872             [(match_operator 1 "float_operator"
10873               [(match_operand:X87MODEI12 2 "memory_operand" "")])
10874              (match_operand 3 "register_operand" "")])
10875           (match_operand 4 "" "")
10876           (match_operand 5 "" "")))
10877    (clobber (reg:CCFP FPSR_REG))
10878    (clobber (reg:CCFP FLAGS_REG))
10879    (clobber (match_scratch:HI 6 "=a"))]
10880   "reload_completed"
10881   [(const_int 0)]
10882 {
10883   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
10884
10885   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
10886                         operands[3], operands[7],
10887                         operands[4], operands[5], operands[6], NULL_RTX);
10888   DONE;
10889 })
10890
10891 ;; %%% Kill this when reload knows how to do it.
10892 (define_split
10893   [(set (pc)
10894         (if_then_else
10895           (match_operator 0 "ix86_swapped_fp_comparison_operator"
10896             [(match_operator 1 "float_operator"
10897               [(match_operand:X87MODEI12 2 "register_operand" "")])
10898              (match_operand 3 "register_operand" "")])
10899           (match_operand 4 "" "")
10900           (match_operand 5 "" "")))
10901    (clobber (reg:CCFP FPSR_REG))
10902    (clobber (reg:CCFP FLAGS_REG))
10903    (clobber (match_scratch:HI 6 "=a"))]
10904   "reload_completed"
10905   [(const_int 0)]
10906 {
10907   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
10908   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
10909
10910   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
10911                         operands[3], operands[7],
10912                         operands[4], operands[5], operands[6], operands[2]);
10913   DONE;
10914 })
10915 \f
10916 ;; Unconditional and other jump instructions
10917
10918 (define_insn "jump"
10919   [(set (pc)
10920         (label_ref (match_operand 0 "" "")))]
10921   ""
10922   "jmp\t%l0"
10923   [(set_attr "type" "ibr")
10924    (set (attr "length")
10925            (if_then_else (and (ge (minus (match_dup 0) (pc))
10926                                   (const_int -126))
10927                               (lt (minus (match_dup 0) (pc))
10928                                   (const_int 128)))
10929              (const_int 2)
10930              (const_int 5)))
10931    (set_attr "modrm" "0")])
10932
10933 (define_expand "indirect_jump"
10934   [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
10935   ""
10936   "")
10937
10938 (define_insn "*indirect_jump"
10939   [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
10940   ""
10941   "jmp\t%A0"
10942   [(set_attr "type" "ibr")
10943    (set_attr "length_immediate" "0")])
10944
10945 (define_expand "tablejump"
10946   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
10947               (use (label_ref (match_operand 1 "" "")))])]
10948   ""
10949 {
10950   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
10951      relative.  Convert the relative address to an absolute address.  */
10952   if (flag_pic)
10953     {
10954       rtx op0, op1;
10955       enum rtx_code code;
10956
10957       /* We can't use @GOTOFF for text labels on VxWorks;
10958          see gotoff_operand.  */
10959       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
10960         {
10961           code = PLUS;
10962           op0 = operands[0];
10963           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
10964         }
10965       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
10966         {
10967           code = PLUS;
10968           op0 = operands[0];
10969           op1 = pic_offset_table_rtx;
10970         }
10971       else
10972         {
10973           code = MINUS;
10974           op0 = pic_offset_table_rtx;
10975           op1 = operands[0];
10976         }
10977
10978       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
10979                                          OPTAB_DIRECT);
10980     }
10981 })
10982
10983 (define_insn "*tablejump_1"
10984   [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
10985    (use (label_ref (match_operand 1 "" "")))]
10986   ""
10987   "jmp\t%A0"
10988   [(set_attr "type" "ibr")
10989    (set_attr "length_immediate" "0")])
10990 \f
10991 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
10992
10993 (define_peephole2
10994   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
10995    (set (match_operand:QI 1 "register_operand" "")
10996         (match_operator:QI 2 "ix86_comparison_operator"
10997           [(reg FLAGS_REG) (const_int 0)]))
10998    (set (match_operand 3 "q_regs_operand" "")
10999         (zero_extend (match_dup 1)))]
11000   "(peep2_reg_dead_p (3, operands[1])
11001     || operands_match_p (operands[1], operands[3]))
11002    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11003   [(set (match_dup 4) (match_dup 0))
11004    (set (strict_low_part (match_dup 5))
11005         (match_dup 2))]
11006 {
11007   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11008   operands[5] = gen_lowpart (QImode, operands[3]);
11009   ix86_expand_clear (operands[3]);
11010 })
11011
11012 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
11013
11014 (define_peephole2
11015   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11016    (set (match_operand:QI 1 "register_operand" "")
11017         (match_operator:QI 2 "ix86_comparison_operator"
11018           [(reg FLAGS_REG) (const_int 0)]))
11019    (parallel [(set (match_operand 3 "q_regs_operand" "")
11020                    (zero_extend (match_dup 1)))
11021               (clobber (reg:CC FLAGS_REG))])]
11022   "(peep2_reg_dead_p (3, operands[1])
11023     || operands_match_p (operands[1], operands[3]))
11024    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11025   [(set (match_dup 4) (match_dup 0))
11026    (set (strict_low_part (match_dup 5))
11027         (match_dup 2))]
11028 {
11029   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11030   operands[5] = gen_lowpart (QImode, operands[3]);
11031   ix86_expand_clear (operands[3]);
11032 })
11033 \f
11034 ;; Call instructions.
11035
11036 ;; The predicates normally associated with named expanders are not properly
11037 ;; checked for calls.  This is a bug in the generic code, but it isn't that
11038 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
11039
11040 ;; P6 processors will jump to the address after the decrement when %esp
11041 ;; is used as a call operand, so they will execute return address as a code.
11042 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11043  
11044 ;; Call subroutine returning no value.
11045
11046 (define_expand "call_pop"
11047   [(parallel [(call (match_operand:QI 0 "" "")
11048                     (match_operand:SI 1 "" ""))
11049               (set (reg:SI SP_REG)
11050                    (plus:SI (reg:SI SP_REG)
11051                             (match_operand:SI 3 "" "")))])]
11052   "!TARGET_64BIT"
11053 {
11054   ix86_expand_call (NULL, operands[0], operands[1],
11055                     operands[2], operands[3], 0);
11056   DONE;
11057 })
11058
11059 (define_insn "*call_pop_0"
11060   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
11061          (match_operand:SI 1 "" ""))
11062    (set (reg:SI SP_REG)
11063         (plus:SI (reg:SI SP_REG)
11064                  (match_operand:SI 2 "immediate_operand" "")))]
11065   "!TARGET_64BIT"
11066 {
11067   if (SIBLING_CALL_P (insn))
11068     return "jmp\t%P0";
11069   else
11070     return "call\t%P0";
11071 }
11072   [(set_attr "type" "call")])
11073
11074 (define_insn "*call_pop_1"
11075   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11076          (match_operand:SI 1 "" ""))
11077    (set (reg:SI SP_REG)
11078         (plus:SI (reg:SI SP_REG)
11079                  (match_operand:SI 2 "immediate_operand" "i")))]
11080   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11081 {
11082   if (constant_call_address_operand (operands[0], Pmode))
11083     return "call\t%P0";
11084   return "call\t%A0";
11085 }
11086   [(set_attr "type" "call")])
11087
11088 (define_insn "*sibcall_pop_1"
11089   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11090          (match_operand:SI 1 "" ""))
11091    (set (reg:SI SP_REG)
11092         (plus:SI (reg:SI SP_REG)
11093                  (match_operand:SI 2 "immediate_operand" "i,i")))]
11094   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11095   "@
11096    jmp\t%P0
11097    jmp\t%A0"
11098   [(set_attr "type" "call")])
11099
11100 (define_expand "call"
11101   [(call (match_operand:QI 0 "" "")
11102          (match_operand 1 "" ""))
11103    (use (match_operand 2 "" ""))]
11104   ""
11105 {
11106   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
11107   DONE;
11108 })
11109
11110 (define_expand "sibcall"
11111   [(call (match_operand:QI 0 "" "")
11112          (match_operand 1 "" ""))
11113    (use (match_operand 2 "" ""))]
11114   ""
11115 {
11116   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
11117   DONE;
11118 })
11119
11120 (define_insn "*call_0"
11121   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
11122          (match_operand 1 "" ""))]
11123   ""
11124 {
11125   if (SIBLING_CALL_P (insn))
11126     return "jmp\t%P0";
11127   else
11128     return "call\t%P0";
11129 }
11130   [(set_attr "type" "call")])
11131
11132 (define_insn "*call_1"
11133   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11134          (match_operand 1 "" ""))]
11135   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11136 {
11137   if (constant_call_address_operand (operands[0], Pmode))
11138     return "call\t%P0";
11139   return "call\t%A0";
11140 }
11141   [(set_attr "type" "call")])
11142
11143 (define_insn "*sibcall_1"
11144   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11145          (match_operand 1 "" ""))]
11146   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11147   "@
11148    jmp\t%P0
11149    jmp\t%A0"
11150   [(set_attr "type" "call")])
11151
11152 (define_insn "*call_1_rex64"
11153   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11154          (match_operand 1 "" ""))]
11155   "TARGET_64BIT && !SIBLING_CALL_P (insn)
11156    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
11157 {
11158   if (constant_call_address_operand (operands[0], Pmode))
11159     return "call\t%P0";
11160   return "call\t%A0";
11161 }
11162   [(set_attr "type" "call")])
11163
11164 (define_insn "*call_1_rex64_ms_sysv"
11165   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11166          (match_operand 1 "" ""))
11167    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11168    (clobber (reg:TI XMM6_REG))
11169    (clobber (reg:TI XMM7_REG))
11170    (clobber (reg:TI XMM8_REG))
11171    (clobber (reg:TI XMM9_REG))
11172    (clobber (reg:TI XMM10_REG))
11173    (clobber (reg:TI XMM11_REG))
11174    (clobber (reg:TI XMM12_REG))
11175    (clobber (reg:TI XMM13_REG))
11176    (clobber (reg:TI XMM14_REG))
11177    (clobber (reg:TI XMM15_REG))
11178    (clobber (reg:DI SI_REG))
11179    (clobber (reg:DI DI_REG))]
11180   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11181 {
11182   if (constant_call_address_operand (operands[0], Pmode))
11183     return "call\t%P0";
11184   return "call\t%A0";
11185 }
11186   [(set_attr "type" "call")])
11187
11188 (define_insn "*call_1_rex64_large"
11189   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
11190          (match_operand 1 "" ""))]
11191   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11192   "call\t%A0"
11193   [(set_attr "type" "call")])
11194
11195 (define_insn "*sibcall_1_rex64"
11196   [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
11197          (match_operand 1 "" ""))]
11198   "TARGET_64BIT && SIBLING_CALL_P (insn)"
11199   "@
11200    jmp\t%P0
11201    jmp\t%A0"
11202   [(set_attr "type" "call")])
11203
11204 ;; Call subroutine, returning value in operand 0
11205 (define_expand "call_value_pop"
11206   [(parallel [(set (match_operand 0 "" "")
11207                    (call (match_operand:QI 1 "" "")
11208                          (match_operand:SI 2 "" "")))
11209               (set (reg:SI SP_REG)
11210                    (plus:SI (reg:SI SP_REG)
11211                             (match_operand:SI 4 "" "")))])]
11212   "!TARGET_64BIT"
11213 {
11214   ix86_expand_call (operands[0], operands[1], operands[2],
11215                     operands[3], operands[4], 0);
11216   DONE;
11217 })
11218
11219 (define_expand "call_value"
11220   [(set (match_operand 0 "" "")
11221         (call (match_operand:QI 1 "" "")
11222               (match_operand:SI 2 "" "")))
11223    (use (match_operand:SI 3 "" ""))]
11224   ;; Operand 3 is not used on the i386.
11225   ""
11226 {
11227   ix86_expand_call (operands[0], operands[1], operands[2],
11228                     operands[3], NULL, 0);
11229   DONE;
11230 })
11231
11232 (define_expand "sibcall_value"
11233   [(set (match_operand 0 "" "")
11234         (call (match_operand:QI 1 "" "")
11235               (match_operand:SI 2 "" "")))
11236    (use (match_operand:SI 3 "" ""))]
11237   ;; Operand 3 is not used on the i386.
11238   ""
11239 {
11240   ix86_expand_call (operands[0], operands[1], operands[2],
11241                     operands[3], NULL, 1);
11242   DONE;
11243 })
11244
11245 ;; Call subroutine returning any type.
11246
11247 (define_expand "untyped_call"
11248   [(parallel [(call (match_operand 0 "" "")
11249                     (const_int 0))
11250               (match_operand 1 "" "")
11251               (match_operand 2 "" "")])]
11252   ""
11253 {
11254   int i;
11255
11256   /* In order to give reg-stack an easier job in validating two
11257      coprocessor registers as containing a possible return value,
11258      simply pretend the untyped call returns a complex long double
11259      value. 
11260
11261      We can't use SSE_REGPARM_MAX here since callee is unprototyped
11262      and should have the default ABI.  */
11263
11264   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11265                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11266                     operands[0], const0_rtx,
11267                     GEN_INT ((TARGET_64BIT
11268                               ? (ix86_abi == SYSV_ABI
11269                                  ? X86_64_SSE_REGPARM_MAX
11270                                  : X86_64_MS_SSE_REGPARM_MAX)
11271                               : X86_32_SSE_REGPARM_MAX)
11272                              - 1),
11273                     NULL, 0);
11274
11275   for (i = 0; i < XVECLEN (operands[2], 0); i++)
11276     {
11277       rtx set = XVECEXP (operands[2], 0, i);
11278       emit_move_insn (SET_DEST (set), SET_SRC (set));
11279     }
11280
11281   /* The optimizer does not know that the call sets the function value
11282      registers we stored in the result block.  We avoid problems by
11283      claiming that all hard registers are used and clobbered at this
11284      point.  */
11285   emit_insn (gen_blockage ());
11286
11287   DONE;
11288 })
11289 \f
11290 ;; Prologue and epilogue instructions
11291
11292 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11293 ;; all of memory.  This blocks insns from being moved across this point.
11294
11295 (define_insn "blockage"
11296   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11297   ""
11298   ""
11299   [(set_attr "length" "0")])
11300
11301 ;; Do not schedule instructions accessing memory across this point.
11302
11303 (define_expand "memory_blockage"
11304   [(set (match_dup 0)
11305         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11306   ""
11307 {
11308   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11309   MEM_VOLATILE_P (operands[0]) = 1;
11310 })
11311
11312 (define_insn "*memory_blockage"
11313   [(set (match_operand:BLK 0 "" "")
11314         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11315   ""
11316   ""
11317   [(set_attr "length" "0")])
11318
11319 ;; As USE insns aren't meaningful after reload, this is used instead
11320 ;; to prevent deleting instructions setting registers for PIC code
11321 (define_insn "prologue_use"
11322   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11323   ""
11324   ""
11325   [(set_attr "length" "0")])
11326
11327 ;; Insn emitted into the body of a function to return from a function.
11328 ;; This is only done if the function's epilogue is known to be simple.
11329 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11330
11331 (define_expand "return"
11332   [(return)]
11333   "ix86_can_use_return_insn_p ()"
11334 {
11335   if (crtl->args.pops_args)
11336     {
11337       rtx popc = GEN_INT (crtl->args.pops_args);
11338       emit_jump_insn (gen_return_pop_internal (popc));
11339       DONE;
11340     }
11341 })
11342
11343 (define_insn "return_internal"
11344   [(return)]
11345   "reload_completed"
11346   "ret"
11347   [(set_attr "length" "1")
11348    (set_attr "atom_unit" "jeu")
11349    (set_attr "length_immediate" "0")
11350    (set_attr "modrm" "0")])
11351
11352 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11353 ;; instruction Athlon and K8 have.
11354
11355 (define_insn "return_internal_long"
11356   [(return)
11357    (unspec [(const_int 0)] UNSPEC_REP)]
11358   "reload_completed"
11359   "rep\;ret"
11360   [(set_attr "length" "2")
11361    (set_attr "atom_unit" "jeu")
11362    (set_attr "length_immediate" "0")
11363    (set_attr "prefix_rep" "1")
11364    (set_attr "modrm" "0")])
11365
11366 (define_insn "return_pop_internal"
11367   [(return)
11368    (use (match_operand:SI 0 "const_int_operand" ""))]
11369   "reload_completed"
11370   "ret\t%0"
11371   [(set_attr "length" "3")
11372    (set_attr "atom_unit" "jeu")
11373    (set_attr "length_immediate" "2")
11374    (set_attr "modrm" "0")])
11375
11376 (define_insn "return_indirect_internal"
11377   [(return)
11378    (use (match_operand:SI 0 "register_operand" "r"))]
11379   "reload_completed"
11380   "jmp\t%A0"
11381   [(set_attr "type" "ibr")
11382    (set_attr "length_immediate" "0")])
11383
11384 (define_insn "nop"
11385   [(const_int 0)]
11386   ""
11387   "nop"
11388   [(set_attr "length" "1")
11389    (set_attr "length_immediate" "0")
11390    (set_attr "modrm" "0")])
11391
11392 ;; Pad to 16-byte boundary, max skip in op0.  Used to avoid
11393 ;; branch prediction penalty for the third jump in a 16-byte
11394 ;; block on K8.
11395
11396 (define_insn "pad"
11397   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
11398   ""
11399 {
11400 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11401   ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11402 #else
11403   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11404      The align insn is used to avoid 3 jump instructions in the row to improve
11405      branch prediction and the benefits hardly outweigh the cost of extra 8
11406      nops on the average inserted by full alignment pseudo operation.  */
11407 #endif
11408   return "";
11409 }
11410   [(set_attr "length" "16")])
11411
11412 (define_expand "prologue"
11413   [(const_int 0)]
11414   ""
11415   "ix86_expand_prologue (); DONE;")
11416
11417 (define_insn "set_got"
11418   [(set (match_operand:SI 0 "register_operand" "=r")
11419         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11420    (clobber (reg:CC FLAGS_REG))]
11421   "!TARGET_64BIT"
11422   { return output_set_got (operands[0], NULL_RTX); }
11423   [(set_attr "type" "multi")
11424    (set_attr "length" "12")])
11425
11426 (define_insn "set_got_labelled"
11427   [(set (match_operand:SI 0 "register_operand" "=r")
11428         (unspec:SI [(label_ref (match_operand 1 "" ""))]
11429          UNSPEC_SET_GOT))
11430    (clobber (reg:CC FLAGS_REG))]
11431   "!TARGET_64BIT"
11432   { return output_set_got (operands[0], operands[1]); }
11433   [(set_attr "type" "multi")
11434    (set_attr "length" "12")])
11435
11436 (define_insn "set_got_rex64"
11437   [(set (match_operand:DI 0 "register_operand" "=r")
11438         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11439   "TARGET_64BIT"
11440   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11441   [(set_attr "type" "lea")
11442    (set_attr "length_address" "4")
11443    (set_attr "mode" "DI")])
11444
11445 (define_insn "set_rip_rex64"
11446   [(set (match_operand:DI 0 "register_operand" "=r")
11447         (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
11448   "TARGET_64BIT"
11449   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11450   [(set_attr "type" "lea")
11451    (set_attr "length_address" "4")
11452    (set_attr "mode" "DI")])
11453
11454 (define_insn "set_got_offset_rex64"
11455   [(set (match_operand:DI 0 "register_operand" "=r")
11456         (unspec:DI
11457           [(label_ref (match_operand 1 "" ""))]
11458           UNSPEC_SET_GOT_OFFSET))]
11459   "TARGET_64BIT"
11460   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11461   [(set_attr "type" "imov")
11462    (set_attr "length_immediate" "0")
11463    (set_attr "length_address" "8")
11464    (set_attr "mode" "DI")])
11465
11466 (define_expand "epilogue"
11467   [(const_int 0)]
11468   ""
11469   "ix86_expand_epilogue (1); DONE;")
11470
11471 (define_expand "sibcall_epilogue"
11472   [(const_int 0)]
11473   ""
11474   "ix86_expand_epilogue (0); DONE;")
11475
11476 (define_expand "eh_return"
11477   [(use (match_operand 0 "register_operand" ""))]
11478   ""
11479 {
11480   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11481
11482   /* Tricky bit: we write the address of the handler to which we will
11483      be returning into someone else's stack frame, one word below the
11484      stack address we wish to restore.  */
11485   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11486   tmp = plus_constant (tmp, -UNITS_PER_WORD);
11487   tmp = gen_rtx_MEM (Pmode, tmp);
11488   emit_move_insn (tmp, ra);
11489
11490   emit_jump_insn (gen_eh_return_internal ());
11491   emit_barrier ();
11492   DONE;
11493 })
11494
11495 (define_insn_and_split "eh_return_internal"
11496   [(eh_return)]
11497   ""
11498   "#"
11499   "epilogue_completed"
11500   [(const_int 0)]
11501   "ix86_expand_epilogue (2); DONE;")
11502
11503 (define_insn "leave"
11504   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11505    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11506    (clobber (mem:BLK (scratch)))]
11507   "!TARGET_64BIT"
11508   "leave"
11509   [(set_attr "type" "leave")])
11510
11511 (define_insn "leave_rex64"
11512   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11513    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11514    (clobber (mem:BLK (scratch)))]
11515   "TARGET_64BIT"
11516   "leave"
11517   [(set_attr "type" "leave")])
11518 \f
11519 ;; Bit manipulation instructions.
11520
11521 (define_expand "ffs<mode>2"
11522   [(set (match_dup 2) (const_int -1))
11523    (parallel [(set (reg:CCZ FLAGS_REG)
11524                    (compare:CCZ
11525                      (match_operand:SWI48 1 "nonimmediate_operand" "")
11526                      (const_int 0)))
11527               (set (match_operand:SWI48 0 "register_operand" "")
11528                    (ctz:SWI48 (match_dup 1)))])
11529    (set (match_dup 0) (if_then_else:SWI48
11530                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
11531                         (match_dup 2)
11532                         (match_dup 0)))
11533    (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11534               (clobber (reg:CC FLAGS_REG))])]
11535   ""
11536 {
11537   if (<MODE>mode == SImode && !TARGET_CMOVE)
11538     {
11539       emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
11540       DONE;
11541     }
11542   operands[2] = gen_reg_rtx (<MODE>mode);
11543 })
11544
11545 (define_insn_and_split "ffssi2_no_cmove"
11546   [(set (match_operand:SI 0 "register_operand" "=r")
11547         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
11548    (clobber (match_scratch:SI 2 "=&q"))
11549    (clobber (reg:CC FLAGS_REG))]
11550   "!TARGET_CMOVE"
11551   "#"
11552   "&& reload_completed"
11553   [(parallel [(set (reg:CCZ FLAGS_REG)
11554                    (compare:CCZ (match_dup 1) (const_int 0)))
11555               (set (match_dup 0) (ctz:SI (match_dup 1)))])
11556    (set (strict_low_part (match_dup 3))
11557         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
11558    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
11559               (clobber (reg:CC FLAGS_REG))])
11560    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
11561               (clobber (reg:CC FLAGS_REG))])
11562    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
11563               (clobber (reg:CC FLAGS_REG))])]
11564 {
11565   operands[3] = gen_lowpart (QImode, operands[2]);
11566   ix86_expand_clear (operands[2]);
11567 })
11568
11569 (define_insn "*ffs<mode>_1"
11570   [(set (reg:CCZ FLAGS_REG)
11571         (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11572                      (const_int 0)))
11573    (set (match_operand:SWI48 0 "register_operand" "=r")
11574         (ctz:SWI48 (match_dup 1)))]
11575   ""
11576   "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
11577   [(set_attr "type" "alu1")
11578    (set_attr "prefix_0f" "1")
11579    (set_attr "mode" "<MODE>")])
11580
11581 (define_insn "ctz<mode>2"
11582   [(set (match_operand:SWI48 0 "register_operand" "=r")
11583         (ctz:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
11584    (clobber (reg:CC FLAGS_REG))]
11585   ""
11586   "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
11587   [(set_attr "type" "alu1")
11588    (set_attr "prefix_0f" "1")
11589    (set_attr "mode" "<MODE>")])
11590
11591 (define_expand "clz<mode>2"
11592   [(parallel
11593      [(set (match_operand:SWI248 0 "register_operand" "")
11594            (minus:SWI248
11595              (match_dup 2)
11596              (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
11597       (clobber (reg:CC FLAGS_REG))])
11598    (parallel
11599      [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
11600       (clobber (reg:CC FLAGS_REG))])]
11601   ""
11602 {
11603   if (TARGET_ABM)
11604     {
11605       emit_insn (gen_clz<mode>2_abm (operands[0], operands[1]));
11606       DONE;
11607     }
11608   operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
11609 })
11610
11611 (define_insn "clz<mode>2_abm"
11612   [(set (match_operand:SWI248 0 "register_operand" "=r")
11613         (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11614    (clobber (reg:CC FLAGS_REG))]
11615   "TARGET_ABM"
11616   "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
11617   [(set_attr "prefix_rep" "1")
11618    (set_attr "type" "bitmanip")
11619    (set_attr "mode" "<MODE>")])
11620
11621 (define_insn "bsr_rex64"
11622   [(set (match_operand:DI 0 "register_operand" "=r")
11623         (minus:DI (const_int 63)
11624                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
11625    (clobber (reg:CC FLAGS_REG))]
11626   "TARGET_64BIT"
11627   "bsr{q}\t{%1, %0|%0, %1}"
11628   [(set_attr "type" "alu1")
11629    (set_attr "prefix_0f" "1")
11630    (set_attr "mode" "DI")])
11631
11632 (define_insn "bsr"
11633   [(set (match_operand:SI 0 "register_operand" "=r")
11634         (minus:SI (const_int 31)
11635                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
11636    (clobber (reg:CC FLAGS_REG))]
11637   ""
11638   "bsr{l}\t{%1, %0|%0, %1}"
11639   [(set_attr "type" "alu1")
11640    (set_attr "prefix_0f" "1")
11641    (set_attr "mode" "SI")])
11642
11643 (define_insn "*bsrhi"
11644   [(set (match_operand:HI 0 "register_operand" "=r")
11645         (minus:HI (const_int 15)
11646                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
11647    (clobber (reg:CC FLAGS_REG))]
11648   ""
11649   "bsr{w}\t{%1, %0|%0, %1}"
11650   [(set_attr "type" "alu1")
11651    (set_attr "prefix_0f" "1")
11652    (set_attr "mode" "HI")])
11653
11654 (define_insn "popcount<mode>2"
11655   [(set (match_operand:SWI248 0 "register_operand" "=r")
11656         (popcount:SWI248
11657           (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11658    (clobber (reg:CC FLAGS_REG))]
11659   "TARGET_POPCNT"
11660 {
11661 #if TARGET_MACHO
11662   return "popcnt\t{%1, %0|%0, %1}";
11663 #else
11664   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
11665 #endif
11666 }
11667   [(set_attr "prefix_rep" "1")
11668    (set_attr "type" "bitmanip")
11669    (set_attr "mode" "<MODE>")])
11670
11671 (define_insn "*popcount<mode>2_cmp"
11672   [(set (reg FLAGS_REG)
11673         (compare
11674           (popcount:SWI248
11675             (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
11676           (const_int 0)))
11677    (set (match_operand:SWI248 0 "register_operand" "=r")
11678         (popcount:SWI248 (match_dup 1)))]
11679   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
11680 {
11681 #if TARGET_MACHO
11682   return "popcnt\t{%1, %0|%0, %1}";
11683 #else
11684   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
11685 #endif
11686 }
11687   [(set_attr "prefix_rep" "1")
11688    (set_attr "type" "bitmanip")
11689    (set_attr "mode" "<MODE>")])
11690
11691 (define_insn "*popcountsi2_cmp_zext"
11692   [(set (reg FLAGS_REG)
11693         (compare
11694           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
11695           (const_int 0)))
11696    (set (match_operand:DI 0 "register_operand" "=r")
11697         (zero_extend:DI(popcount:SI (match_dup 1))))]
11698   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
11699 {
11700 #if TARGET_MACHO
11701   return "popcnt\t{%1, %0|%0, %1}";
11702 #else
11703   return "popcnt{l}\t{%1, %0|%0, %1}";
11704 #endif
11705 }
11706   [(set_attr "prefix_rep" "1")
11707    (set_attr "type" "bitmanip")
11708    (set_attr "mode" "SI")])
11709
11710 (define_expand "bswap<mode>2"
11711   [(set (match_operand:SWI48 0 "register_operand" "")
11712         (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
11713   ""
11714 {
11715   if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
11716     {
11717       rtx x = operands[0];
11718
11719       emit_move_insn (x, operands[1]);
11720       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
11721       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
11722       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
11723       DONE;
11724     }
11725 })
11726
11727 (define_insn "*bswap<mode>2_movbe"
11728   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
11729         (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
11730   "TARGET_MOVBE
11731    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
11732   "@
11733     bswap\t%0
11734     movbe\t{%1, %0|%0, %1}
11735     movbe\t{%1, %0|%0, %1}"
11736   [(set_attr "type" "bitmanip,imov,imov")
11737    (set_attr "modrm" "0,1,1")
11738    (set_attr "prefix_0f" "*,1,1")
11739    (set_attr "prefix_extra" "*,1,1")
11740    (set_attr "mode" "<MODE>")])
11741
11742 (define_insn "*bswap<mode>2_1"
11743   [(set (match_operand:SWI48 0 "register_operand" "=r")
11744         (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
11745   "TARGET_BSWAP"
11746   "bswap\t%0"
11747   [(set_attr "type" "bitmanip")
11748    (set_attr "modrm" "0")
11749    (set_attr "mode" "<MODE>")])
11750
11751 (define_insn "*bswaphi_lowpart_1"
11752   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
11753         (bswap:HI (match_dup 0)))
11754    (clobber (reg:CC FLAGS_REG))]
11755   "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
11756   "@
11757     xchg{b}\t{%h0, %b0|%b0, %h0}
11758     rol{w}\t{$8, %0|%0, 8}"
11759   [(set_attr "length" "2,4")
11760    (set_attr "mode" "QI,HI")])
11761
11762 (define_insn "bswaphi_lowpart"
11763   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
11764         (bswap:HI (match_dup 0)))
11765    (clobber (reg:CC FLAGS_REG))]
11766   ""
11767   "rol{w}\t{$8, %0|%0, 8}"
11768   [(set_attr "length" "4")
11769    (set_attr "mode" "HI")])
11770
11771 (define_expand "paritydi2"
11772   [(set (match_operand:DI 0 "register_operand" "")
11773         (parity:DI (match_operand:DI 1 "register_operand" "")))]
11774   "! TARGET_POPCNT"
11775 {
11776   rtx scratch = gen_reg_rtx (QImode);
11777   rtx cond;
11778
11779   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
11780                                 NULL_RTX, operands[1]));
11781
11782   cond = gen_rtx_fmt_ee (ORDERED, QImode,
11783                          gen_rtx_REG (CCmode, FLAGS_REG),
11784                          const0_rtx);
11785   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
11786
11787   if (TARGET_64BIT)
11788     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
11789   else
11790     {
11791       rtx tmp = gen_reg_rtx (SImode);
11792
11793       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
11794       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
11795     }
11796   DONE;
11797 })
11798
11799 (define_expand "paritysi2"
11800   [(set (match_operand:SI 0 "register_operand" "")
11801         (parity:SI (match_operand:SI 1 "register_operand" "")))]
11802   "! TARGET_POPCNT"
11803 {
11804   rtx scratch = gen_reg_rtx (QImode);
11805   rtx cond;
11806
11807   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
11808
11809   cond = gen_rtx_fmt_ee (ORDERED, QImode,
11810                          gen_rtx_REG (CCmode, FLAGS_REG),
11811                          const0_rtx);
11812   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
11813
11814   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
11815   DONE;
11816 })
11817
11818 (define_insn_and_split "paritydi2_cmp"
11819   [(set (reg:CC FLAGS_REG)
11820         (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
11821                    UNSPEC_PARITY))
11822    (clobber (match_scratch:DI 0 "=r"))
11823    (clobber (match_scratch:SI 1 "=&r"))
11824    (clobber (match_scratch:HI 2 "=Q"))]
11825   "! TARGET_POPCNT"
11826   "#"
11827   "&& reload_completed"
11828   [(parallel
11829      [(set (match_dup 1)
11830            (xor:SI (match_dup 1) (match_dup 4)))
11831       (clobber (reg:CC FLAGS_REG))])
11832    (parallel
11833      [(set (reg:CC FLAGS_REG)
11834            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
11835       (clobber (match_dup 1))
11836       (clobber (match_dup 2))])]
11837 {
11838   operands[4] = gen_lowpart (SImode, operands[3]);
11839
11840   if (TARGET_64BIT)
11841     {
11842       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
11843       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
11844     }
11845   else
11846     operands[1] = gen_highpart (SImode, operands[3]);
11847 })
11848
11849 (define_insn_and_split "paritysi2_cmp"
11850   [(set (reg:CC FLAGS_REG)
11851         (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
11852                    UNSPEC_PARITY))
11853    (clobber (match_scratch:SI 0 "=r"))
11854    (clobber (match_scratch:HI 1 "=&Q"))]
11855   "! TARGET_POPCNT"
11856   "#"
11857   "&& reload_completed"
11858   [(parallel
11859      [(set (match_dup 1)
11860            (xor:HI (match_dup 1) (match_dup 3)))
11861       (clobber (reg:CC FLAGS_REG))])
11862    (parallel
11863      [(set (reg:CC FLAGS_REG)
11864            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
11865       (clobber (match_dup 1))])]
11866 {
11867   operands[3] = gen_lowpart (HImode, operands[2]);
11868
11869   emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
11870   emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
11871 })
11872
11873 (define_insn "*parityhi2_cmp"
11874   [(set (reg:CC FLAGS_REG)
11875         (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
11876                    UNSPEC_PARITY))
11877    (clobber (match_scratch:HI 0 "=Q"))]
11878   "! TARGET_POPCNT"
11879   "xor{b}\t{%h0, %b0|%b0, %h0}"
11880   [(set_attr "length" "2")
11881    (set_attr "mode" "HI")])
11882 \f
11883 ;; Thread-local storage patterns for ELF.
11884 ;;
11885 ;; Note that these code sequences must appear exactly as shown
11886 ;; in order to allow linker relaxation.
11887
11888 (define_insn "*tls_global_dynamic_32_gnu"
11889   [(set (match_operand:SI 0 "register_operand" "=a")
11890         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
11891                     (match_operand:SI 2 "tls_symbolic_operand" "")
11892                     (match_operand:SI 3 "call_insn_operand" "")]
11893                     UNSPEC_TLS_GD))
11894    (clobber (match_scratch:SI 4 "=d"))
11895    (clobber (match_scratch:SI 5 "=c"))
11896    (clobber (reg:CC FLAGS_REG))]
11897   "!TARGET_64BIT && TARGET_GNU_TLS"
11898   "lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}\;call\t%P3"
11899   [(set_attr "type" "multi")
11900    (set_attr "length" "12")])
11901
11902 (define_expand "tls_global_dynamic_32"
11903   [(parallel [(set (match_operand:SI 0 "register_operand" "")
11904                    (unspec:SI
11905                     [(match_dup 2)
11906                      (match_operand:SI 1 "tls_symbolic_operand" "")
11907                      (match_dup 3)]
11908                     UNSPEC_TLS_GD))
11909               (clobber (match_scratch:SI 4 ""))
11910               (clobber (match_scratch:SI 5 ""))
11911               (clobber (reg:CC FLAGS_REG))])]
11912   ""
11913 {
11914   if (flag_pic)
11915     operands[2] = pic_offset_table_rtx;
11916   else
11917     {
11918       operands[2] = gen_reg_rtx (Pmode);
11919       emit_insn (gen_set_got (operands[2]));
11920     }
11921   if (TARGET_GNU2_TLS)
11922     {
11923        emit_insn (gen_tls_dynamic_gnu2_32
11924                   (operands[0], operands[1], operands[2]));
11925        DONE;
11926     }
11927   operands[3] = ix86_tls_get_addr ();
11928 })
11929
11930 (define_insn "*tls_global_dynamic_64"
11931   [(set (match_operand:DI 0 "register_operand" "=a")
11932         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
11933                  (match_operand:DI 3 "" "")))
11934    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
11935               UNSPEC_TLS_GD)]
11936   "TARGET_64BIT"
11937   { 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"; }
11938   [(set_attr "type" "multi")
11939    (set_attr "length" "16")])
11940
11941 (define_expand "tls_global_dynamic_64"
11942   [(parallel [(set (match_operand:DI 0 "register_operand" "")
11943                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
11944               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
11945                          UNSPEC_TLS_GD)])]
11946   ""
11947 {
11948   if (TARGET_GNU2_TLS)
11949     {
11950        emit_insn (gen_tls_dynamic_gnu2_64
11951                   (operands[0], operands[1]));
11952        DONE;
11953     }
11954   operands[2] = ix86_tls_get_addr ();
11955 })
11956
11957 (define_insn "*tls_local_dynamic_base_32_gnu"
11958   [(set (match_operand:SI 0 "register_operand" "=a")
11959         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
11960                     (match_operand:SI 2 "call_insn_operand" "")]
11961                    UNSPEC_TLS_LD_BASE))
11962    (clobber (match_scratch:SI 3 "=d"))
11963    (clobber (match_scratch:SI 4 "=c"))
11964    (clobber (reg:CC FLAGS_REG))]
11965   "!TARGET_64BIT && TARGET_GNU_TLS"
11966   "lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}\;call\t%P2"
11967   [(set_attr "type" "multi")
11968    (set_attr "length" "11")])
11969
11970 (define_expand "tls_local_dynamic_base_32"
11971   [(parallel [(set (match_operand:SI 0 "register_operand" "")
11972                    (unspec:SI [(match_dup 1) (match_dup 2)]
11973                               UNSPEC_TLS_LD_BASE))
11974               (clobber (match_scratch:SI 3 ""))
11975               (clobber (match_scratch:SI 4 ""))
11976               (clobber (reg:CC FLAGS_REG))])]
11977   ""
11978 {
11979   if (flag_pic)
11980     operands[1] = pic_offset_table_rtx;
11981   else
11982     {
11983       operands[1] = gen_reg_rtx (Pmode);
11984       emit_insn (gen_set_got (operands[1]));
11985     }
11986   if (TARGET_GNU2_TLS)
11987     {
11988        emit_insn (gen_tls_dynamic_gnu2_32
11989                   (operands[0], ix86_tls_module_base (), operands[1]));
11990        DONE;
11991     }
11992   operands[2] = ix86_tls_get_addr ();
11993 })
11994
11995 (define_insn "*tls_local_dynamic_base_64"
11996   [(set (match_operand:DI 0 "register_operand" "=a")
11997         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
11998                  (match_operand:DI 2 "" "")))
11999    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12000   "TARGET_64BIT"
12001   "lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}\;call\t%P1"
12002   [(set_attr "type" "multi")
12003    (set_attr "length" "12")])
12004
12005 (define_expand "tls_local_dynamic_base_64"
12006   [(parallel [(set (match_operand:DI 0 "register_operand" "")
12007                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
12008               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
12009   ""
12010 {
12011   if (TARGET_GNU2_TLS)
12012     {
12013        emit_insn (gen_tls_dynamic_gnu2_64
12014                   (operands[0], ix86_tls_module_base ()));
12015        DONE;
12016     }
12017   operands[1] = ix86_tls_get_addr ();
12018 })
12019
12020 ;; Local dynamic of a single variable is a lose.  Show combine how
12021 ;; to convert that back to global dynamic.
12022
12023 (define_insn_and_split "*tls_local_dynamic_32_once"
12024   [(set (match_operand:SI 0 "register_operand" "=a")
12025         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12026                              (match_operand:SI 2 "call_insn_operand" "")]
12027                             UNSPEC_TLS_LD_BASE)
12028                  (const:SI (unspec:SI
12029                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
12030                             UNSPEC_DTPOFF))))
12031    (clobber (match_scratch:SI 4 "=d"))
12032    (clobber (match_scratch:SI 5 "=c"))
12033    (clobber (reg:CC FLAGS_REG))]
12034   ""
12035   "#"
12036   ""
12037   [(parallel [(set (match_dup 0)
12038                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12039                               UNSPEC_TLS_GD))
12040               (clobber (match_dup 4))
12041               (clobber (match_dup 5))
12042               (clobber (reg:CC FLAGS_REG))])]
12043   "")
12044
12045 ;; Load and add the thread base pointer from %gs:0.
12046
12047 (define_insn "*load_tp_si"
12048   [(set (match_operand:SI 0 "register_operand" "=r")
12049         (unspec:SI [(const_int 0)] UNSPEC_TP))]
12050   "!TARGET_64BIT"
12051   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
12052   [(set_attr "type" "imov")
12053    (set_attr "modrm" "0")
12054    (set_attr "length" "7")
12055    (set_attr "memory" "load")
12056    (set_attr "imm_disp" "false")])
12057
12058 (define_insn "*add_tp_si"
12059   [(set (match_operand:SI 0 "register_operand" "=r")
12060         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12061                  (match_operand:SI 1 "register_operand" "0")))
12062    (clobber (reg:CC FLAGS_REG))]
12063   "!TARGET_64BIT"
12064   "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
12065   [(set_attr "type" "alu")
12066    (set_attr "modrm" "0")
12067    (set_attr "length" "7")
12068    (set_attr "memory" "load")
12069    (set_attr "imm_disp" "false")])
12070
12071 (define_insn "*load_tp_di"
12072   [(set (match_operand:DI 0 "register_operand" "=r")
12073         (unspec:DI [(const_int 0)] UNSPEC_TP))]
12074   "TARGET_64BIT"
12075   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
12076   [(set_attr "type" "imov")
12077    (set_attr "modrm" "0")
12078    (set_attr "length" "7")
12079    (set_attr "memory" "load")
12080    (set_attr "imm_disp" "false")])
12081
12082 (define_insn "*add_tp_di"
12083   [(set (match_operand:DI 0 "register_operand" "=r")
12084         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
12085                  (match_operand:DI 1 "register_operand" "0")))
12086    (clobber (reg:CC FLAGS_REG))]
12087   "TARGET_64BIT"
12088   "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
12089   [(set_attr "type" "alu")
12090    (set_attr "modrm" "0")
12091    (set_attr "length" "7")
12092    (set_attr "memory" "load")
12093    (set_attr "imm_disp" "false")])
12094
12095 ;; GNU2 TLS patterns can be split.
12096
12097 (define_expand "tls_dynamic_gnu2_32"
12098   [(set (match_dup 3)
12099         (plus:SI (match_operand:SI 2 "register_operand" "")
12100                  (const:SI
12101                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12102                              UNSPEC_TLSDESC))))
12103    (parallel
12104     [(set (match_operand:SI 0 "register_operand" "")
12105           (unspec:SI [(match_dup 1) (match_dup 3)
12106                       (match_dup 2) (reg:SI SP_REG)]
12107                       UNSPEC_TLSDESC))
12108      (clobber (reg:CC FLAGS_REG))])]
12109   "!TARGET_64BIT && TARGET_GNU2_TLS"
12110 {
12111   operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12112   ix86_tls_descriptor_calls_expanded_in_cfun = true;
12113 })
12114
12115 (define_insn "*tls_dynamic_lea_32"
12116   [(set (match_operand:SI 0 "register_operand" "=r")
12117         (plus:SI (match_operand:SI 1 "register_operand" "b")
12118                  (const:SI
12119                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12120                               UNSPEC_TLSDESC))))]
12121   "!TARGET_64BIT && TARGET_GNU2_TLS"
12122   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
12123   [(set_attr "type" "lea")
12124    (set_attr "mode" "SI")
12125    (set_attr "length" "6")
12126    (set_attr "length_address" "4")])
12127
12128 (define_insn "*tls_dynamic_call_32"
12129   [(set (match_operand:SI 0 "register_operand" "=a")
12130         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12131                     (match_operand:SI 2 "register_operand" "0")
12132                     ;; we have to make sure %ebx still points to the GOT
12133                     (match_operand:SI 3 "register_operand" "b")
12134                     (reg:SI SP_REG)]
12135                    UNSPEC_TLSDESC))
12136    (clobber (reg:CC FLAGS_REG))]
12137   "!TARGET_64BIT && TARGET_GNU2_TLS"
12138   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12139   [(set_attr "type" "call")
12140    (set_attr "length" "2")
12141    (set_attr "length_address" "0")])
12142
12143 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12144   [(set (match_operand:SI 0 "register_operand" "=&a")
12145         (plus:SI
12146          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12147                      (match_operand:SI 4 "" "")
12148                      (match_operand:SI 2 "register_operand" "b")
12149                      (reg:SI SP_REG)]
12150                     UNSPEC_TLSDESC)
12151          (const:SI (unspec:SI
12152                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
12153                     UNSPEC_DTPOFF))))
12154    (clobber (reg:CC FLAGS_REG))]
12155   "!TARGET_64BIT && TARGET_GNU2_TLS"
12156   "#"
12157   ""
12158   [(set (match_dup 0) (match_dup 5))]
12159 {
12160   operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12161   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12162 })
12163
12164 (define_expand "tls_dynamic_gnu2_64"
12165   [(set (match_dup 2)
12166         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12167                    UNSPEC_TLSDESC))
12168    (parallel
12169     [(set (match_operand:DI 0 "register_operand" "")
12170           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12171                      UNSPEC_TLSDESC))
12172      (clobber (reg:CC FLAGS_REG))])]
12173   "TARGET_64BIT && TARGET_GNU2_TLS"
12174 {
12175   operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12176   ix86_tls_descriptor_calls_expanded_in_cfun = true;
12177 })
12178
12179 (define_insn "*tls_dynamic_lea_64"
12180   [(set (match_operand:DI 0 "register_operand" "=r")
12181         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12182                    UNSPEC_TLSDESC))]
12183   "TARGET_64BIT && TARGET_GNU2_TLS"
12184   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
12185   [(set_attr "type" "lea")
12186    (set_attr "mode" "DI")
12187    (set_attr "length" "7")
12188    (set_attr "length_address" "4")])
12189
12190 (define_insn "*tls_dynamic_call_64"
12191   [(set (match_operand:DI 0 "register_operand" "=a")
12192         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
12193                     (match_operand:DI 2 "register_operand" "0")
12194                     (reg:DI SP_REG)]
12195                    UNSPEC_TLSDESC))
12196    (clobber (reg:CC FLAGS_REG))]
12197   "TARGET_64BIT && TARGET_GNU2_TLS"
12198   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12199   [(set_attr "type" "call")
12200    (set_attr "length" "2")
12201    (set_attr "length_address" "0")])
12202
12203 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12204   [(set (match_operand:DI 0 "register_operand" "=&a")
12205         (plus:DI
12206          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12207                      (match_operand:DI 3 "" "")
12208                      (reg:DI SP_REG)]
12209                     UNSPEC_TLSDESC)
12210          (const:DI (unspec:DI
12211                     [(match_operand:DI 1 "tls_symbolic_operand" "")]
12212                     UNSPEC_DTPOFF))))
12213    (clobber (reg:CC FLAGS_REG))]
12214   "TARGET_64BIT && TARGET_GNU2_TLS"
12215   "#"
12216   ""
12217   [(set (match_dup 0) (match_dup 4))]
12218 {
12219   operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12220   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12221 })
12222
12223 ;;
12224 \f
12225 ;; These patterns match the binary 387 instructions for addM3, subM3,
12226 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
12227 ;; SFmode.  The first is the normal insn, the second the same insn but
12228 ;; with one operand a conversion, and the third the same insn but with
12229 ;; the other operand a conversion.  The conversion may be SFmode or
12230 ;; SImode if the target mode DFmode, but only SImode if the target mode
12231 ;; is SFmode.
12232
12233 ;; Gcc is slightly more smart about handling normal two address instructions
12234 ;; so use special patterns for add and mull.
12235
12236 (define_insn "*fop_<mode>_comm_mixed_avx"
12237   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
12238         (match_operator:MODEF 3 "binary_fp_operator"
12239           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
12240            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
12241   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12242    && COMMUTATIVE_ARITH_P (operands[3])
12243    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12244   "* return output_387_binary_op (insn, operands);"
12245   [(set (attr "type")
12246         (if_then_else (eq_attr "alternative" "1")
12247            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12248               (const_string "ssemul")
12249               (const_string "sseadd"))
12250            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12251               (const_string "fmul")
12252               (const_string "fop"))))
12253    (set_attr "prefix" "orig,maybe_vex")
12254    (set_attr "mode" "<MODE>")])
12255
12256 (define_insn "*fop_<mode>_comm_mixed"
12257   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
12258         (match_operator:MODEF 3 "binary_fp_operator"
12259           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
12260            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
12261   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12262    && COMMUTATIVE_ARITH_P (operands[3])
12263    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12264   "* return output_387_binary_op (insn, operands);"
12265   [(set (attr "type")
12266         (if_then_else (eq_attr "alternative" "1")
12267            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12268               (const_string "ssemul")
12269               (const_string "sseadd"))
12270            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12271               (const_string "fmul")
12272               (const_string "fop"))))
12273    (set_attr "mode" "<MODE>")])
12274
12275 (define_insn "*fop_<mode>_comm_avx"
12276   [(set (match_operand:MODEF 0 "register_operand" "=x")
12277         (match_operator:MODEF 3 "binary_fp_operator"
12278           [(match_operand:MODEF 1 "nonimmediate_operand" "%x")
12279            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12280   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12281    && COMMUTATIVE_ARITH_P (operands[3])
12282    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12283   "* return output_387_binary_op (insn, operands);"
12284   [(set (attr "type")
12285         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12286            (const_string "ssemul")
12287            (const_string "sseadd")))
12288    (set_attr "prefix" "vex")
12289    (set_attr "mode" "<MODE>")])
12290
12291 (define_insn "*fop_<mode>_comm_sse"
12292   [(set (match_operand:MODEF 0 "register_operand" "=x")
12293         (match_operator:MODEF 3 "binary_fp_operator"
12294           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12295            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12296   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12297    && COMMUTATIVE_ARITH_P (operands[3])
12298    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12299   "* return output_387_binary_op (insn, operands);"
12300   [(set (attr "type")
12301         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12302            (const_string "ssemul")
12303            (const_string "sseadd")))
12304    (set_attr "mode" "<MODE>")])
12305
12306 (define_insn "*fop_<mode>_comm_i387"
12307   [(set (match_operand:MODEF 0 "register_operand" "=f")
12308         (match_operator:MODEF 3 "binary_fp_operator"
12309           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12310            (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
12311   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12312    && COMMUTATIVE_ARITH_P (operands[3])
12313    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12314   "* return output_387_binary_op (insn, operands);"
12315   [(set (attr "type")
12316         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12317            (const_string "fmul")
12318            (const_string "fop")))
12319    (set_attr "mode" "<MODE>")])
12320
12321 (define_insn "*fop_<mode>_1_mixed_avx"
12322   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
12323         (match_operator:MODEF 3 "binary_fp_operator"
12324           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,x")
12325            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
12326   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12327    && !COMMUTATIVE_ARITH_P (operands[3])
12328    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12329   "* return output_387_binary_op (insn, operands);"
12330   [(set (attr "type")
12331         (cond [(and (eq_attr "alternative" "2")
12332                     (match_operand:MODEF 3 "mult_operator" ""))
12333                  (const_string "ssemul")
12334                (and (eq_attr "alternative" "2")
12335                     (match_operand:MODEF 3 "div_operator" ""))
12336                  (const_string "ssediv")
12337                (eq_attr "alternative" "2")
12338                  (const_string "sseadd")
12339                (match_operand:MODEF 3 "mult_operator" "")
12340                  (const_string "fmul")
12341                (match_operand:MODEF 3 "div_operator" "")
12342                  (const_string "fdiv")
12343               ]
12344               (const_string "fop")))
12345    (set_attr "prefix" "orig,orig,maybe_vex")
12346    (set_attr "mode" "<MODE>")])
12347
12348 (define_insn "*fop_<mode>_1_mixed"
12349   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
12350         (match_operator:MODEF 3 "binary_fp_operator"
12351           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
12352            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
12353   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12354    && !COMMUTATIVE_ARITH_P (operands[3])
12355    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12356   "* return output_387_binary_op (insn, operands);"
12357   [(set (attr "type")
12358         (cond [(and (eq_attr "alternative" "2")
12359                     (match_operand:MODEF 3 "mult_operator" ""))
12360                  (const_string "ssemul")
12361                (and (eq_attr "alternative" "2")
12362                     (match_operand:MODEF 3 "div_operator" ""))
12363                  (const_string "ssediv")
12364                (eq_attr "alternative" "2")
12365                  (const_string "sseadd")
12366                (match_operand:MODEF 3 "mult_operator" "")
12367                  (const_string "fmul")
12368                (match_operand:MODEF 3 "div_operator" "")
12369                  (const_string "fdiv")
12370               ]
12371               (const_string "fop")))
12372    (set_attr "mode" "<MODE>")])
12373
12374 (define_insn "*rcpsf2_sse"
12375   [(set (match_operand:SF 0 "register_operand" "=x")
12376         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
12377                    UNSPEC_RCP))]
12378   "TARGET_SSE_MATH"
12379   "%vrcpss\t{%1, %d0|%d0, %1}"
12380   [(set_attr "type" "sse")
12381    (set_attr "atom_sse_attr" "rcp")
12382    (set_attr "prefix" "maybe_vex")
12383    (set_attr "mode" "SF")])
12384
12385 (define_insn "*fop_<mode>_1_avx"
12386   [(set (match_operand:MODEF 0 "register_operand" "=x")
12387         (match_operator:MODEF 3 "binary_fp_operator"
12388           [(match_operand:MODEF 1 "register_operand" "x")
12389            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12390   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12391    && !COMMUTATIVE_ARITH_P (operands[3])"
12392   "* return output_387_binary_op (insn, operands);"
12393   [(set (attr "type")
12394         (cond [(match_operand:MODEF 3 "mult_operator" "")
12395                  (const_string "ssemul")
12396                (match_operand:MODEF 3 "div_operator" "")
12397                  (const_string "ssediv")
12398               ]
12399               (const_string "sseadd")))
12400    (set_attr "prefix" "vex")
12401    (set_attr "mode" "<MODE>")])
12402
12403 (define_insn "*fop_<mode>_1_sse"
12404   [(set (match_operand:MODEF 0 "register_operand" "=x")
12405         (match_operator:MODEF 3 "binary_fp_operator"
12406           [(match_operand:MODEF 1 "register_operand" "0")
12407            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12408   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12409    && !COMMUTATIVE_ARITH_P (operands[3])"
12410   "* return output_387_binary_op (insn, operands);"
12411   [(set (attr "type")
12412         (cond [(match_operand:MODEF 3 "mult_operator" "")
12413                  (const_string "ssemul")
12414                (match_operand:MODEF 3 "div_operator" "")
12415                  (const_string "ssediv")
12416               ]
12417               (const_string "sseadd")))
12418    (set_attr "mode" "<MODE>")])
12419
12420 ;; This pattern is not fully shadowed by the pattern above.
12421 (define_insn "*fop_<mode>_1_i387"
12422   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12423         (match_operator:MODEF 3 "binary_fp_operator"
12424           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
12425            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
12426   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12427    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
12428    && !COMMUTATIVE_ARITH_P (operands[3])
12429    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12430   "* return output_387_binary_op (insn, operands);"
12431   [(set (attr "type")
12432         (cond [(match_operand:MODEF 3 "mult_operator" "")
12433                  (const_string "fmul")
12434                (match_operand:MODEF 3 "div_operator" "")
12435                  (const_string "fdiv")
12436               ]
12437               (const_string "fop")))
12438    (set_attr "mode" "<MODE>")])
12439
12440 ;; ??? Add SSE splitters for these!
12441 (define_insn "*fop_<MODEF:mode>_2_i387"
12442   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12443         (match_operator:MODEF 3 "binary_fp_operator"
12444           [(float:MODEF
12445              (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
12446            (match_operand:MODEF 2 "register_operand" "0,0")]))]
12447   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
12448    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12449    && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12450   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12451   [(set (attr "type")
12452         (cond [(match_operand:MODEF 3 "mult_operator" "")
12453                  (const_string "fmul")
12454                (match_operand:MODEF 3 "div_operator" "")
12455                  (const_string "fdiv")
12456               ]
12457               (const_string "fop")))
12458    (set_attr "fp_int_src" "true")
12459    (set_attr "mode" "<X87MODEI12:MODE>")])
12460
12461 (define_insn "*fop_<MODEF:mode>_3_i387"
12462   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12463         (match_operator:MODEF 3 "binary_fp_operator"
12464           [(match_operand:MODEF 1 "register_operand" "0,0")
12465            (float:MODEF
12466              (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
12467   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
12468    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12469    && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12470   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12471   [(set (attr "type")
12472         (cond [(match_operand:MODEF 3 "mult_operator" "")
12473                  (const_string "fmul")
12474                (match_operand:MODEF 3 "div_operator" "")
12475                  (const_string "fdiv")
12476               ]
12477               (const_string "fop")))
12478    (set_attr "fp_int_src" "true")
12479    (set_attr "mode" "<MODE>")])
12480
12481 (define_insn "*fop_df_4_i387"
12482   [(set (match_operand:DF 0 "register_operand" "=f,f")
12483         (match_operator:DF 3 "binary_fp_operator"
12484            [(float_extend:DF
12485              (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
12486             (match_operand:DF 2 "register_operand" "0,f")]))]
12487   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12488    && !(TARGET_SSE2 && TARGET_SSE_MATH)
12489    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12490   "* return output_387_binary_op (insn, operands);"
12491   [(set (attr "type")
12492         (cond [(match_operand:DF 3 "mult_operator" "")
12493                  (const_string "fmul")
12494                (match_operand:DF 3 "div_operator" "")
12495                  (const_string "fdiv")
12496               ]
12497               (const_string "fop")))
12498    (set_attr "mode" "SF")])
12499
12500 (define_insn "*fop_df_5_i387"
12501   [(set (match_operand:DF 0 "register_operand" "=f,f")
12502         (match_operator:DF 3 "binary_fp_operator"
12503           [(match_operand:DF 1 "register_operand" "0,f")
12504            (float_extend:DF
12505             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12506   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12507    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12508   "* return output_387_binary_op (insn, operands);"
12509   [(set (attr "type")
12510         (cond [(match_operand:DF 3 "mult_operator" "")
12511                  (const_string "fmul")
12512                (match_operand:DF 3 "div_operator" "")
12513                  (const_string "fdiv")
12514               ]
12515               (const_string "fop")))
12516    (set_attr "mode" "SF")])
12517
12518 (define_insn "*fop_df_6_i387"
12519   [(set (match_operand:DF 0 "register_operand" "=f,f")
12520         (match_operator:DF 3 "binary_fp_operator"
12521           [(float_extend:DF
12522             (match_operand:SF 1 "register_operand" "0,f"))
12523            (float_extend:DF
12524             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12525   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12526    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12527   "* return output_387_binary_op (insn, operands);"
12528   [(set (attr "type")
12529         (cond [(match_operand:DF 3 "mult_operator" "")
12530                  (const_string "fmul")
12531                (match_operand:DF 3 "div_operator" "")
12532                  (const_string "fdiv")
12533               ]
12534               (const_string "fop")))
12535    (set_attr "mode" "SF")])
12536
12537 (define_insn "*fop_xf_comm_i387"
12538   [(set (match_operand:XF 0 "register_operand" "=f")
12539         (match_operator:XF 3 "binary_fp_operator"
12540                         [(match_operand:XF 1 "register_operand" "%0")
12541                          (match_operand:XF 2 "register_operand" "f")]))]
12542   "TARGET_80387
12543    && COMMUTATIVE_ARITH_P (operands[3])"
12544   "* return output_387_binary_op (insn, operands);"
12545   [(set (attr "type")
12546         (if_then_else (match_operand:XF 3 "mult_operator" "")
12547            (const_string "fmul")
12548            (const_string "fop")))
12549    (set_attr "mode" "XF")])
12550
12551 (define_insn "*fop_xf_1_i387"
12552   [(set (match_operand:XF 0 "register_operand" "=f,f")
12553         (match_operator:XF 3 "binary_fp_operator"
12554                         [(match_operand:XF 1 "register_operand" "0,f")
12555                          (match_operand:XF 2 "register_operand" "f,0")]))]
12556   "TARGET_80387
12557    && !COMMUTATIVE_ARITH_P (operands[3])"
12558   "* return output_387_binary_op (insn, operands);"
12559   [(set (attr "type")
12560         (cond [(match_operand:XF 3 "mult_operator" "")
12561                  (const_string "fmul")
12562                (match_operand:XF 3 "div_operator" "")
12563                  (const_string "fdiv")
12564               ]
12565               (const_string "fop")))
12566    (set_attr "mode" "XF")])
12567
12568 (define_insn "*fop_xf_2_i387"
12569   [(set (match_operand:XF 0 "register_operand" "=f,f")
12570         (match_operator:XF 3 "binary_fp_operator"
12571           [(float:XF
12572              (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
12573            (match_operand:XF 2 "register_operand" "0,0")]))]
12574   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12575   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12576   [(set (attr "type")
12577         (cond [(match_operand:XF 3 "mult_operator" "")
12578                  (const_string "fmul")
12579                (match_operand:XF 3 "div_operator" "")
12580                  (const_string "fdiv")
12581               ]
12582               (const_string "fop")))
12583    (set_attr "fp_int_src" "true")
12584    (set_attr "mode" "<MODE>")])
12585
12586 (define_insn "*fop_xf_3_i387"
12587   [(set (match_operand:XF 0 "register_operand" "=f,f")
12588         (match_operator:XF 3 "binary_fp_operator"
12589           [(match_operand:XF 1 "register_operand" "0,0")
12590            (float:XF
12591              (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
12592   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12593   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12594   [(set (attr "type")
12595         (cond [(match_operand:XF 3 "mult_operator" "")
12596                  (const_string "fmul")
12597                (match_operand:XF 3 "div_operator" "")
12598                  (const_string "fdiv")
12599               ]
12600               (const_string "fop")))
12601    (set_attr "fp_int_src" "true")
12602    (set_attr "mode" "<MODE>")])
12603
12604 (define_insn "*fop_xf_4_i387"
12605   [(set (match_operand:XF 0 "register_operand" "=f,f")
12606         (match_operator:XF 3 "binary_fp_operator"
12607            [(float_extend:XF
12608               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
12609             (match_operand:XF 2 "register_operand" "0,f")]))]
12610   "TARGET_80387"
12611   "* return output_387_binary_op (insn, operands);"
12612   [(set (attr "type")
12613         (cond [(match_operand:XF 3 "mult_operator" "")
12614                  (const_string "fmul")
12615                (match_operand:XF 3 "div_operator" "")
12616                  (const_string "fdiv")
12617               ]
12618               (const_string "fop")))
12619    (set_attr "mode" "<MODE>")])
12620
12621 (define_insn "*fop_xf_5_i387"
12622   [(set (match_operand:XF 0 "register_operand" "=f,f")
12623         (match_operator:XF 3 "binary_fp_operator"
12624           [(match_operand:XF 1 "register_operand" "0,f")
12625            (float_extend:XF
12626              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
12627   "TARGET_80387"
12628   "* return output_387_binary_op (insn, operands);"
12629   [(set (attr "type")
12630         (cond [(match_operand:XF 3 "mult_operator" "")
12631                  (const_string "fmul")
12632                (match_operand:XF 3 "div_operator" "")
12633                  (const_string "fdiv")
12634               ]
12635               (const_string "fop")))
12636    (set_attr "mode" "<MODE>")])
12637
12638 (define_insn "*fop_xf_6_i387"
12639   [(set (match_operand:XF 0 "register_operand" "=f,f")
12640         (match_operator:XF 3 "binary_fp_operator"
12641           [(float_extend:XF
12642              (match_operand:MODEF 1 "register_operand" "0,f"))
12643            (float_extend:XF
12644              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
12645   "TARGET_80387"
12646   "* return output_387_binary_op (insn, operands);"
12647   [(set (attr "type")
12648         (cond [(match_operand:XF 3 "mult_operator" "")
12649                  (const_string "fmul")
12650                (match_operand:XF 3 "div_operator" "")
12651                  (const_string "fdiv")
12652               ]
12653               (const_string "fop")))
12654    (set_attr "mode" "<MODE>")])
12655
12656 (define_split
12657   [(set (match_operand 0 "register_operand" "")
12658         (match_operator 3 "binary_fp_operator"
12659            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
12660             (match_operand 2 "register_operand" "")]))]
12661   "reload_completed
12662    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
12663    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
12664   [(const_int 0)]
12665 {
12666   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
12667   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
12668   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
12669                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
12670                                           GET_MODE (operands[3]),
12671                                           operands[4],
12672                                           operands[2])));
12673   ix86_free_from_memory (GET_MODE (operands[1]));
12674   DONE;
12675 })
12676
12677 (define_split
12678   [(set (match_operand 0 "register_operand" "")
12679         (match_operator 3 "binary_fp_operator"
12680            [(match_operand 1 "register_operand" "")
12681             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
12682   "reload_completed
12683    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
12684    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
12685   [(const_int 0)]
12686 {
12687   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
12688   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
12689   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
12690                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
12691                                           GET_MODE (operands[3]),
12692                                           operands[1],
12693                                           operands[4])));
12694   ix86_free_from_memory (GET_MODE (operands[2]));
12695   DONE;
12696 })
12697 \f
12698 ;; FPU special functions.
12699
12700 ;; This pattern implements a no-op XFmode truncation for
12701 ;; all fancy i386 XFmode math functions.
12702
12703 (define_insn "truncxf<mode>2_i387_noop_unspec"
12704   [(set (match_operand:MODEF 0 "register_operand" "=f")
12705         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
12706         UNSPEC_TRUNC_NOOP))]
12707   "TARGET_USE_FANCY_MATH_387"
12708   "* return output_387_reg_move (insn, operands);"
12709   [(set_attr "type" "fmov")
12710    (set_attr "mode" "<MODE>")])
12711
12712 (define_insn "sqrtxf2"
12713   [(set (match_operand:XF 0 "register_operand" "=f")
12714         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
12715   "TARGET_USE_FANCY_MATH_387"
12716   "fsqrt"
12717   [(set_attr "type" "fpspc")
12718    (set_attr "mode" "XF")
12719    (set_attr "athlon_decode" "direct")
12720    (set_attr "amdfam10_decode" "direct")])
12721
12722 (define_insn "sqrt_extend<mode>xf2_i387"
12723   [(set (match_operand:XF 0 "register_operand" "=f")
12724         (sqrt:XF
12725           (float_extend:XF
12726             (match_operand:MODEF 1 "register_operand" "0"))))]
12727   "TARGET_USE_FANCY_MATH_387"
12728   "fsqrt"
12729   [(set_attr "type" "fpspc")
12730    (set_attr "mode" "XF")
12731    (set_attr "athlon_decode" "direct")
12732    (set_attr "amdfam10_decode" "direct")])
12733
12734 (define_insn "*rsqrtsf2_sse"
12735   [(set (match_operand:SF 0 "register_operand" "=x")
12736         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
12737                    UNSPEC_RSQRT))]
12738   "TARGET_SSE_MATH"
12739   "%vrsqrtss\t{%1, %d0|%d0, %1}"
12740   [(set_attr "type" "sse")
12741    (set_attr "atom_sse_attr" "rcp")
12742    (set_attr "prefix" "maybe_vex")
12743    (set_attr "mode" "SF")])
12744
12745 (define_expand "rsqrtsf2"
12746   [(set (match_operand:SF 0 "register_operand" "")
12747         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
12748                    UNSPEC_RSQRT))]
12749   "TARGET_SSE_MATH"
12750 {
12751   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
12752   DONE;
12753 })
12754
12755 (define_insn "*sqrt<mode>2_sse"
12756   [(set (match_operand:MODEF 0 "register_operand" "=x")
12757         (sqrt:MODEF
12758           (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
12759   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
12760   "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}"
12761   [(set_attr "type" "sse")
12762    (set_attr "atom_sse_attr" "sqrt")
12763    (set_attr "prefix" "maybe_vex")
12764    (set_attr "mode" "<MODE>")
12765    (set_attr "athlon_decode" "*")
12766    (set_attr "amdfam10_decode" "*")])
12767
12768 (define_expand "sqrt<mode>2"
12769   [(set (match_operand:MODEF 0 "register_operand" "")
12770         (sqrt:MODEF
12771           (match_operand:MODEF 1 "nonimmediate_operand" "")))]
12772   "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
12773    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
12774 {
12775   if (<MODE>mode == SFmode
12776       && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
12777       && flag_finite_math_only && !flag_trapping_math
12778       && flag_unsafe_math_optimizations)
12779     {
12780       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
12781       DONE;
12782     }
12783
12784   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
12785     {
12786       rtx op0 = gen_reg_rtx (XFmode);
12787       rtx op1 = force_reg (<MODE>mode, operands[1]);
12788
12789       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
12790       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
12791       DONE;
12792    }
12793 })
12794
12795 (define_insn "fpremxf4_i387"
12796   [(set (match_operand:XF 0 "register_operand" "=f")
12797         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
12798                     (match_operand:XF 3 "register_operand" "1")]
12799                    UNSPEC_FPREM_F))
12800    (set (match_operand:XF 1 "register_operand" "=u")
12801         (unspec:XF [(match_dup 2) (match_dup 3)]
12802                    UNSPEC_FPREM_U))
12803    (set (reg:CCFP FPSR_REG)
12804         (unspec:CCFP [(match_dup 2) (match_dup 3)]
12805                      UNSPEC_C2_FLAG))]
12806   "TARGET_USE_FANCY_MATH_387"
12807   "fprem"
12808   [(set_attr "type" "fpspc")
12809    (set_attr "mode" "XF")])
12810
12811 (define_expand "fmodxf3"
12812   [(use (match_operand:XF 0 "register_operand" ""))
12813    (use (match_operand:XF 1 "general_operand" ""))
12814    (use (match_operand:XF 2 "general_operand" ""))]
12815   "TARGET_USE_FANCY_MATH_387"
12816 {
12817   rtx label = gen_label_rtx ();
12818
12819   rtx op1 = gen_reg_rtx (XFmode);
12820   rtx op2 = gen_reg_rtx (XFmode);
12821
12822   emit_move_insn (op2, operands[2]);
12823   emit_move_insn (op1, operands[1]);
12824
12825   emit_label (label);
12826   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
12827   ix86_emit_fp_unordered_jump (label);
12828   LABEL_NUSES (label) = 1;
12829
12830   emit_move_insn (operands[0], op1);
12831   DONE;
12832 })
12833
12834 (define_expand "fmod<mode>3"
12835   [(use (match_operand:MODEF 0 "register_operand" ""))
12836    (use (match_operand:MODEF 1 "general_operand" ""))
12837    (use (match_operand:MODEF 2 "general_operand" ""))]
12838   "TARGET_USE_FANCY_MATH_387"
12839 {
12840   rtx (*gen_truncxf) (rtx, rtx);
12841
12842   rtx label = gen_label_rtx ();
12843
12844   rtx op1 = gen_reg_rtx (XFmode);
12845   rtx op2 = gen_reg_rtx (XFmode);
12846
12847   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
12848   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
12849
12850   emit_label (label);
12851   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
12852   ix86_emit_fp_unordered_jump (label);
12853   LABEL_NUSES (label) = 1;
12854
12855   /* Truncate the result properly for strict SSE math.  */
12856   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12857       && !TARGET_MIX_SSE_I387)
12858     gen_truncxf = gen_truncxf<mode>2;
12859   else
12860     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
12861
12862   emit_insn (gen_truncxf (operands[0], op1));
12863   DONE;
12864 })
12865
12866 (define_insn "fprem1xf4_i387"
12867   [(set (match_operand:XF 0 "register_operand" "=f")
12868         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
12869                     (match_operand:XF 3 "register_operand" "1")]
12870                    UNSPEC_FPREM1_F))
12871    (set (match_operand:XF 1 "register_operand" "=u")
12872         (unspec:XF [(match_dup 2) (match_dup 3)]
12873                    UNSPEC_FPREM1_U))
12874    (set (reg:CCFP FPSR_REG)
12875         (unspec:CCFP [(match_dup 2) (match_dup 3)]
12876                      UNSPEC_C2_FLAG))]
12877   "TARGET_USE_FANCY_MATH_387"
12878   "fprem1"
12879   [(set_attr "type" "fpspc")
12880    (set_attr "mode" "XF")])
12881
12882 (define_expand "remainderxf3"
12883   [(use (match_operand:XF 0 "register_operand" ""))
12884    (use (match_operand:XF 1 "general_operand" ""))
12885    (use (match_operand:XF 2 "general_operand" ""))]
12886   "TARGET_USE_FANCY_MATH_387"
12887 {
12888   rtx label = gen_label_rtx ();
12889
12890   rtx op1 = gen_reg_rtx (XFmode);
12891   rtx op2 = gen_reg_rtx (XFmode);
12892
12893   emit_move_insn (op2, operands[2]);
12894   emit_move_insn (op1, operands[1]);
12895
12896   emit_label (label);
12897   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
12898   ix86_emit_fp_unordered_jump (label);
12899   LABEL_NUSES (label) = 1;
12900
12901   emit_move_insn (operands[0], op1);
12902   DONE;
12903 })
12904
12905 (define_expand "remainder<mode>3"
12906   [(use (match_operand:MODEF 0 "register_operand" ""))
12907    (use (match_operand:MODEF 1 "general_operand" ""))
12908    (use (match_operand:MODEF 2 "general_operand" ""))]
12909   "TARGET_USE_FANCY_MATH_387"
12910 {
12911   rtx (*gen_truncxf) (rtx, rtx);
12912
12913   rtx label = gen_label_rtx ();
12914
12915   rtx op1 = gen_reg_rtx (XFmode);
12916   rtx op2 = gen_reg_rtx (XFmode);
12917
12918   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
12919   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
12920
12921   emit_label (label);
12922
12923   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
12924   ix86_emit_fp_unordered_jump (label);
12925   LABEL_NUSES (label) = 1;
12926
12927   /* Truncate the result properly for strict SSE math.  */
12928   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12929       && !TARGET_MIX_SSE_I387)
12930     gen_truncxf = gen_truncxf<mode>2;
12931   else
12932     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
12933
12934   emit_insn (gen_truncxf (operands[0], op1));
12935   DONE;
12936 })
12937
12938 (define_insn "*sinxf2_i387"
12939   [(set (match_operand:XF 0 "register_operand" "=f")
12940         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
12941   "TARGET_USE_FANCY_MATH_387
12942    && flag_unsafe_math_optimizations"
12943   "fsin"
12944   [(set_attr "type" "fpspc")
12945    (set_attr "mode" "XF")])
12946
12947 (define_insn "*sin_extend<mode>xf2_i387"
12948   [(set (match_operand:XF 0 "register_operand" "=f")
12949         (unspec:XF [(float_extend:XF
12950                       (match_operand:MODEF 1 "register_operand" "0"))]
12951                    UNSPEC_SIN))]
12952   "TARGET_USE_FANCY_MATH_387
12953    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
12954        || TARGET_MIX_SSE_I387)
12955    && flag_unsafe_math_optimizations"
12956   "fsin"
12957   [(set_attr "type" "fpspc")
12958    (set_attr "mode" "XF")])
12959
12960 (define_insn "*cosxf2_i387"
12961   [(set (match_operand:XF 0 "register_operand" "=f")
12962         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
12963   "TARGET_USE_FANCY_MATH_387
12964    && flag_unsafe_math_optimizations"
12965   "fcos"
12966   [(set_attr "type" "fpspc")
12967    (set_attr "mode" "XF")])
12968
12969 (define_insn "*cos_extend<mode>xf2_i387"
12970   [(set (match_operand:XF 0 "register_operand" "=f")
12971         (unspec:XF [(float_extend:XF
12972                       (match_operand:MODEF 1 "register_operand" "0"))]
12973                    UNSPEC_COS))]
12974   "TARGET_USE_FANCY_MATH_387
12975    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
12976        || TARGET_MIX_SSE_I387)
12977    && flag_unsafe_math_optimizations"
12978   "fcos"
12979   [(set_attr "type" "fpspc")
12980    (set_attr "mode" "XF")])
12981
12982 ;; When sincos pattern is defined, sin and cos builtin functions will be
12983 ;; expanded to sincos pattern with one of its outputs left unused.
12984 ;; CSE pass will figure out if two sincos patterns can be combined,
12985 ;; otherwise sincos pattern will be split back to sin or cos pattern,
12986 ;; depending on the unused output.
12987
12988 (define_insn "sincosxf3"
12989   [(set (match_operand:XF 0 "register_operand" "=f")
12990         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
12991                    UNSPEC_SINCOS_COS))
12992    (set (match_operand:XF 1 "register_operand" "=u")
12993         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
12994   "TARGET_USE_FANCY_MATH_387
12995    && flag_unsafe_math_optimizations"
12996   "fsincos"
12997   [(set_attr "type" "fpspc")
12998    (set_attr "mode" "XF")])
12999
13000 (define_split
13001   [(set (match_operand:XF 0 "register_operand" "")
13002         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13003                    UNSPEC_SINCOS_COS))
13004    (set (match_operand:XF 1 "register_operand" "")
13005         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13006   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13007    && !(reload_completed || reload_in_progress)"
13008   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13009
13010 (define_split
13011   [(set (match_operand:XF 0 "register_operand" "")
13012         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13013                    UNSPEC_SINCOS_COS))
13014    (set (match_operand:XF 1 "register_operand" "")
13015         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13016   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13017    && !(reload_completed || reload_in_progress)"
13018   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13019
13020 (define_insn "sincos_extend<mode>xf3_i387"
13021   [(set (match_operand:XF 0 "register_operand" "=f")
13022         (unspec:XF [(float_extend:XF
13023                       (match_operand:MODEF 2 "register_operand" "0"))]
13024                    UNSPEC_SINCOS_COS))
13025    (set (match_operand:XF 1 "register_operand" "=u")
13026         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13027   "TARGET_USE_FANCY_MATH_387
13028    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13029        || TARGET_MIX_SSE_I387)
13030    && flag_unsafe_math_optimizations"
13031   "fsincos"
13032   [(set_attr "type" "fpspc")
13033    (set_attr "mode" "XF")])
13034
13035 (define_split
13036   [(set (match_operand:XF 0 "register_operand" "")
13037         (unspec:XF [(float_extend:XF
13038                       (match_operand:MODEF 2 "register_operand" ""))]
13039                    UNSPEC_SINCOS_COS))
13040    (set (match_operand:XF 1 "register_operand" "")
13041         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13042   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13043    && !(reload_completed || reload_in_progress)"
13044   [(set (match_dup 1)
13045         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13046
13047 (define_split
13048   [(set (match_operand:XF 0 "register_operand" "")
13049         (unspec:XF [(float_extend:XF
13050                       (match_operand:MODEF 2 "register_operand" ""))]
13051                    UNSPEC_SINCOS_COS))
13052    (set (match_operand:XF 1 "register_operand" "")
13053         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13054   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13055    && !(reload_completed || reload_in_progress)"
13056   [(set (match_dup 0)
13057         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13058
13059 (define_expand "sincos<mode>3"
13060   [(use (match_operand:MODEF 0 "register_operand" ""))
13061    (use (match_operand:MODEF 1 "register_operand" ""))
13062    (use (match_operand:MODEF 2 "register_operand" ""))]
13063   "TARGET_USE_FANCY_MATH_387
13064    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13065        || TARGET_MIX_SSE_I387)
13066    && flag_unsafe_math_optimizations"
13067 {
13068   rtx op0 = gen_reg_rtx (XFmode);
13069   rtx op1 = gen_reg_rtx (XFmode);
13070
13071   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13072   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13073   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13074   DONE;
13075 })
13076
13077 (define_insn "fptanxf4_i387"
13078   [(set (match_operand:XF 0 "register_operand" "=f")
13079         (match_operand:XF 3 "const_double_operand" "F"))
13080    (set (match_operand:XF 1 "register_operand" "=u")
13081         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13082                    UNSPEC_TAN))]
13083   "TARGET_USE_FANCY_MATH_387
13084    && flag_unsafe_math_optimizations
13085    && standard_80387_constant_p (operands[3]) == 2"
13086   "fptan"
13087   [(set_attr "type" "fpspc")
13088    (set_attr "mode" "XF")])
13089
13090 (define_insn "fptan_extend<mode>xf4_i387"
13091   [(set (match_operand:MODEF 0 "register_operand" "=f")
13092         (match_operand:MODEF 3 "const_double_operand" "F"))
13093    (set (match_operand:XF 1 "register_operand" "=u")
13094         (unspec:XF [(float_extend:XF
13095                       (match_operand:MODEF 2 "register_operand" "0"))]
13096                    UNSPEC_TAN))]
13097   "TARGET_USE_FANCY_MATH_387
13098    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13099        || TARGET_MIX_SSE_I387)
13100    && flag_unsafe_math_optimizations
13101    && standard_80387_constant_p (operands[3]) == 2"
13102   "fptan"
13103   [(set_attr "type" "fpspc")
13104    (set_attr "mode" "XF")])
13105
13106 (define_expand "tanxf2"
13107   [(use (match_operand:XF 0 "register_operand" ""))
13108    (use (match_operand:XF 1 "register_operand" ""))]
13109   "TARGET_USE_FANCY_MATH_387
13110    && flag_unsafe_math_optimizations"
13111 {
13112   rtx one = gen_reg_rtx (XFmode);
13113   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13114
13115   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13116   DONE;
13117 })
13118
13119 (define_expand "tan<mode>2"
13120   [(use (match_operand:MODEF 0 "register_operand" ""))
13121    (use (match_operand:MODEF 1 "register_operand" ""))]
13122   "TARGET_USE_FANCY_MATH_387
13123    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13124        || TARGET_MIX_SSE_I387)
13125    && flag_unsafe_math_optimizations"
13126 {
13127   rtx op0 = gen_reg_rtx (XFmode);
13128
13129   rtx one = gen_reg_rtx (<MODE>mode);
13130   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13131
13132   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13133                                              operands[1], op2));
13134   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13135   DONE;
13136 })
13137
13138 (define_insn "*fpatanxf3_i387"
13139   [(set (match_operand:XF 0 "register_operand" "=f")
13140         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13141                     (match_operand:XF 2 "register_operand" "u")]
13142                    UNSPEC_FPATAN))
13143    (clobber (match_scratch:XF 3 "=2"))]
13144   "TARGET_USE_FANCY_MATH_387
13145    && flag_unsafe_math_optimizations"
13146   "fpatan"
13147   [(set_attr "type" "fpspc")
13148    (set_attr "mode" "XF")])
13149
13150 (define_insn "fpatan_extend<mode>xf3_i387"
13151   [(set (match_operand:XF 0 "register_operand" "=f")
13152         (unspec:XF [(float_extend:XF
13153                       (match_operand:MODEF 1 "register_operand" "0"))
13154                     (float_extend:XF
13155                       (match_operand:MODEF 2 "register_operand" "u"))]
13156                    UNSPEC_FPATAN))
13157    (clobber (match_scratch:XF 3 "=2"))]
13158   "TARGET_USE_FANCY_MATH_387
13159    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13160        || TARGET_MIX_SSE_I387)
13161    && flag_unsafe_math_optimizations"
13162   "fpatan"
13163   [(set_attr "type" "fpspc")
13164    (set_attr "mode" "XF")])
13165
13166 (define_expand "atan2xf3"
13167   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13168                    (unspec:XF [(match_operand:XF 2 "register_operand" "")
13169                                (match_operand:XF 1 "register_operand" "")]
13170                               UNSPEC_FPATAN))
13171               (clobber (match_scratch:XF 3 ""))])]
13172   "TARGET_USE_FANCY_MATH_387
13173    && flag_unsafe_math_optimizations"
13174   "")
13175
13176 (define_expand "atan2<mode>3"
13177   [(use (match_operand:MODEF 0 "register_operand" ""))
13178    (use (match_operand:MODEF 1 "register_operand" ""))
13179    (use (match_operand:MODEF 2 "register_operand" ""))]
13180   "TARGET_USE_FANCY_MATH_387
13181    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13182        || TARGET_MIX_SSE_I387)
13183    && flag_unsafe_math_optimizations"
13184 {
13185   rtx op0 = gen_reg_rtx (XFmode);
13186
13187   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13188   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13189   DONE;
13190 })
13191
13192 (define_expand "atanxf2"
13193   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13194                    (unspec:XF [(match_dup 2)
13195                                (match_operand:XF 1 "register_operand" "")]
13196                               UNSPEC_FPATAN))
13197               (clobber (match_scratch:XF 3 ""))])]
13198   "TARGET_USE_FANCY_MATH_387
13199    && flag_unsafe_math_optimizations"
13200 {
13201   operands[2] = gen_reg_rtx (XFmode);
13202   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
13203 })
13204
13205 (define_expand "atan<mode>2"
13206   [(use (match_operand:MODEF 0 "register_operand" ""))
13207    (use (match_operand:MODEF 1 "register_operand" ""))]
13208   "TARGET_USE_FANCY_MATH_387
13209    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13210        || TARGET_MIX_SSE_I387)
13211    && flag_unsafe_math_optimizations"
13212 {
13213   rtx op0 = gen_reg_rtx (XFmode);
13214
13215   rtx op2 = gen_reg_rtx (<MODE>mode);
13216   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
13217
13218   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13219   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13220   DONE;
13221 })
13222
13223 (define_expand "asinxf2"
13224   [(set (match_dup 2)
13225         (mult:XF (match_operand:XF 1 "register_operand" "")
13226                  (match_dup 1)))
13227    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13228    (set (match_dup 5) (sqrt:XF (match_dup 4)))
13229    (parallel [(set (match_operand:XF 0 "register_operand" "")
13230                    (unspec:XF [(match_dup 5) (match_dup 1)]
13231                               UNSPEC_FPATAN))
13232               (clobber (match_scratch:XF 6 ""))])]
13233   "TARGET_USE_FANCY_MATH_387
13234    && flag_unsafe_math_optimizations"
13235 {
13236   int i;
13237
13238   if (optimize_insn_for_size_p ())
13239     FAIL;
13240
13241   for (i = 2; i < 6; i++)
13242     operands[i] = gen_reg_rtx (XFmode);
13243
13244   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
13245 })
13246
13247 (define_expand "asin<mode>2"
13248   [(use (match_operand:MODEF 0 "register_operand" ""))
13249    (use (match_operand:MODEF 1 "general_operand" ""))]
13250  "TARGET_USE_FANCY_MATH_387
13251    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13252        || TARGET_MIX_SSE_I387)
13253    && flag_unsafe_math_optimizations"
13254 {
13255   rtx op0 = gen_reg_rtx (XFmode);
13256   rtx op1 = gen_reg_rtx (XFmode);
13257
13258   if (optimize_insn_for_size_p ())
13259     FAIL;
13260
13261   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13262   emit_insn (gen_asinxf2 (op0, op1));
13263   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13264   DONE;
13265 })
13266
13267 (define_expand "acosxf2"
13268   [(set (match_dup 2)
13269         (mult:XF (match_operand:XF 1 "register_operand" "")
13270                  (match_dup 1)))
13271    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13272    (set (match_dup 5) (sqrt:XF (match_dup 4)))
13273    (parallel [(set (match_operand:XF 0 "register_operand" "")
13274                    (unspec:XF [(match_dup 1) (match_dup 5)]
13275                               UNSPEC_FPATAN))
13276               (clobber (match_scratch:XF 6 ""))])]
13277   "TARGET_USE_FANCY_MATH_387
13278    && flag_unsafe_math_optimizations"
13279 {
13280   int i;
13281
13282   if (optimize_insn_for_size_p ())
13283     FAIL;
13284
13285   for (i = 2; i < 6; i++)
13286     operands[i] = gen_reg_rtx (XFmode);
13287
13288   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
13289 })
13290
13291 (define_expand "acos<mode>2"
13292   [(use (match_operand:MODEF 0 "register_operand" ""))
13293    (use (match_operand:MODEF 1 "general_operand" ""))]
13294  "TARGET_USE_FANCY_MATH_387
13295    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13296        || TARGET_MIX_SSE_I387)
13297    && flag_unsafe_math_optimizations"
13298 {
13299   rtx op0 = gen_reg_rtx (XFmode);
13300   rtx op1 = gen_reg_rtx (XFmode);
13301
13302   if (optimize_insn_for_size_p ())
13303     FAIL;
13304
13305   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13306   emit_insn (gen_acosxf2 (op0, op1));
13307   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13308   DONE;
13309 })
13310
13311 (define_insn "fyl2xxf3_i387"
13312   [(set (match_operand:XF 0 "register_operand" "=f")
13313         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13314                     (match_operand:XF 2 "register_operand" "u")]
13315                    UNSPEC_FYL2X))
13316    (clobber (match_scratch:XF 3 "=2"))]
13317   "TARGET_USE_FANCY_MATH_387
13318    && flag_unsafe_math_optimizations"
13319   "fyl2x"
13320   [(set_attr "type" "fpspc")
13321    (set_attr "mode" "XF")])
13322
13323 (define_insn "fyl2x_extend<mode>xf3_i387"
13324   [(set (match_operand:XF 0 "register_operand" "=f")
13325         (unspec:XF [(float_extend:XF
13326                       (match_operand:MODEF 1 "register_operand" "0"))
13327                     (match_operand:XF 2 "register_operand" "u")]
13328                    UNSPEC_FYL2X))
13329    (clobber (match_scratch:XF 3 "=2"))]
13330   "TARGET_USE_FANCY_MATH_387
13331    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13332        || TARGET_MIX_SSE_I387)
13333    && flag_unsafe_math_optimizations"
13334   "fyl2x"
13335   [(set_attr "type" "fpspc")
13336    (set_attr "mode" "XF")])
13337
13338 (define_expand "logxf2"
13339   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13340                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
13341                                (match_dup 2)] UNSPEC_FYL2X))
13342               (clobber (match_scratch:XF 3 ""))])]
13343   "TARGET_USE_FANCY_MATH_387
13344    && flag_unsafe_math_optimizations"
13345 {
13346   operands[2] = gen_reg_rtx (XFmode);
13347   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
13348 })
13349
13350 (define_expand "log<mode>2"
13351   [(use (match_operand:MODEF 0 "register_operand" ""))
13352    (use (match_operand:MODEF 1 "register_operand" ""))]
13353   "TARGET_USE_FANCY_MATH_387
13354    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13355        || TARGET_MIX_SSE_I387)
13356    && flag_unsafe_math_optimizations"
13357 {
13358   rtx op0 = gen_reg_rtx (XFmode);
13359
13360   rtx op2 = gen_reg_rtx (XFmode);
13361   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
13362
13363   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13364   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13365   DONE;
13366 })
13367
13368 (define_expand "log10xf2"
13369   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13370                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
13371                                (match_dup 2)] UNSPEC_FYL2X))
13372               (clobber (match_scratch:XF 3 ""))])]
13373   "TARGET_USE_FANCY_MATH_387
13374    && flag_unsafe_math_optimizations"
13375 {
13376   operands[2] = gen_reg_rtx (XFmode);
13377   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
13378 })
13379
13380 (define_expand "log10<mode>2"
13381   [(use (match_operand:MODEF 0 "register_operand" ""))
13382    (use (match_operand:MODEF 1 "register_operand" ""))]
13383   "TARGET_USE_FANCY_MATH_387
13384    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13385        || TARGET_MIX_SSE_I387)
13386    && flag_unsafe_math_optimizations"
13387 {
13388   rtx op0 = gen_reg_rtx (XFmode);
13389
13390   rtx op2 = gen_reg_rtx (XFmode);
13391   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
13392
13393   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13394   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13395   DONE;
13396 })
13397
13398 (define_expand "log2xf2"
13399   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13400                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
13401                                (match_dup 2)] UNSPEC_FYL2X))
13402               (clobber (match_scratch:XF 3 ""))])]
13403   "TARGET_USE_FANCY_MATH_387
13404    && flag_unsafe_math_optimizations"
13405 {
13406   operands[2] = gen_reg_rtx (XFmode);
13407   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13408 })
13409
13410 (define_expand "log2<mode>2"
13411   [(use (match_operand:MODEF 0 "register_operand" ""))
13412    (use (match_operand:MODEF 1 "register_operand" ""))]
13413   "TARGET_USE_FANCY_MATH_387
13414    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13415        || TARGET_MIX_SSE_I387)
13416    && flag_unsafe_math_optimizations"
13417 {
13418   rtx op0 = gen_reg_rtx (XFmode);
13419
13420   rtx op2 = gen_reg_rtx (XFmode);
13421   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
13422
13423   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13424   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13425   DONE;
13426 })
13427
13428 (define_insn "fyl2xp1xf3_i387"
13429   [(set (match_operand:XF 0 "register_operand" "=f")
13430         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13431                     (match_operand:XF 2 "register_operand" "u")]
13432                    UNSPEC_FYL2XP1))
13433    (clobber (match_scratch:XF 3 "=2"))]
13434   "TARGET_USE_FANCY_MATH_387
13435    && flag_unsafe_math_optimizations"
13436   "fyl2xp1"
13437   [(set_attr "type" "fpspc")
13438    (set_attr "mode" "XF")])
13439
13440 (define_insn "fyl2xp1_extend<mode>xf3_i387"
13441   [(set (match_operand:XF 0 "register_operand" "=f")
13442         (unspec:XF [(float_extend:XF
13443                       (match_operand:MODEF 1 "register_operand" "0"))
13444                     (match_operand:XF 2 "register_operand" "u")]
13445                    UNSPEC_FYL2XP1))
13446    (clobber (match_scratch:XF 3 "=2"))]
13447   "TARGET_USE_FANCY_MATH_387
13448    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13449        || TARGET_MIX_SSE_I387)
13450    && flag_unsafe_math_optimizations"
13451   "fyl2xp1"
13452   [(set_attr "type" "fpspc")
13453    (set_attr "mode" "XF")])
13454
13455 (define_expand "log1pxf2"
13456   [(use (match_operand:XF 0 "register_operand" ""))
13457    (use (match_operand:XF 1 "register_operand" ""))]
13458   "TARGET_USE_FANCY_MATH_387
13459    && flag_unsafe_math_optimizations"
13460 {
13461   if (optimize_insn_for_size_p ())
13462     FAIL;
13463
13464   ix86_emit_i387_log1p (operands[0], operands[1]);
13465   DONE;
13466 })
13467
13468 (define_expand "log1p<mode>2"
13469   [(use (match_operand:MODEF 0 "register_operand" ""))
13470    (use (match_operand:MODEF 1 "register_operand" ""))]
13471   "TARGET_USE_FANCY_MATH_387
13472    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13473        || TARGET_MIX_SSE_I387)
13474    && flag_unsafe_math_optimizations"
13475 {
13476   rtx op0;
13477
13478   if (optimize_insn_for_size_p ())
13479     FAIL;
13480
13481   op0 = gen_reg_rtx (XFmode);
13482
13483   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
13484
13485   ix86_emit_i387_log1p (op0, operands[1]);
13486   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13487   DONE;
13488 })
13489
13490 (define_insn "fxtractxf3_i387"
13491   [(set (match_operand:XF 0 "register_operand" "=f")
13492         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13493                    UNSPEC_XTRACT_FRACT))
13494    (set (match_operand:XF 1 "register_operand" "=u")
13495         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
13496   "TARGET_USE_FANCY_MATH_387
13497    && flag_unsafe_math_optimizations"
13498   "fxtract"
13499   [(set_attr "type" "fpspc")
13500    (set_attr "mode" "XF")])
13501
13502 (define_insn "fxtract_extend<mode>xf3_i387"
13503   [(set (match_operand:XF 0 "register_operand" "=f")
13504         (unspec:XF [(float_extend:XF
13505                       (match_operand:MODEF 2 "register_operand" "0"))]
13506                    UNSPEC_XTRACT_FRACT))
13507    (set (match_operand:XF 1 "register_operand" "=u")
13508         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
13509   "TARGET_USE_FANCY_MATH_387
13510    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13511        || TARGET_MIX_SSE_I387)
13512    && flag_unsafe_math_optimizations"
13513   "fxtract"
13514   [(set_attr "type" "fpspc")
13515    (set_attr "mode" "XF")])
13516
13517 (define_expand "logbxf2"
13518   [(parallel [(set (match_dup 2)
13519                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
13520                               UNSPEC_XTRACT_FRACT))
13521               (set (match_operand:XF 0 "register_operand" "")
13522                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
13523   "TARGET_USE_FANCY_MATH_387
13524    && flag_unsafe_math_optimizations"
13525 {
13526   operands[2] = gen_reg_rtx (XFmode);
13527 })
13528
13529 (define_expand "logb<mode>2"
13530   [(use (match_operand:MODEF 0 "register_operand" ""))
13531    (use (match_operand:MODEF 1 "register_operand" ""))]
13532   "TARGET_USE_FANCY_MATH_387
13533    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13534        || TARGET_MIX_SSE_I387)
13535    && flag_unsafe_math_optimizations"
13536 {
13537   rtx op0 = gen_reg_rtx (XFmode);
13538   rtx op1 = gen_reg_rtx (XFmode);
13539
13540   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13541   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
13542   DONE;
13543 })
13544
13545 (define_expand "ilogbxf2"
13546   [(use (match_operand:SI 0 "register_operand" ""))
13547    (use (match_operand:XF 1 "register_operand" ""))]
13548   "TARGET_USE_FANCY_MATH_387
13549    && flag_unsafe_math_optimizations"
13550 {
13551   rtx op0, op1;
13552
13553   if (optimize_insn_for_size_p ())
13554     FAIL;
13555
13556   op0 = gen_reg_rtx (XFmode);
13557   op1 = gen_reg_rtx (XFmode);
13558
13559   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
13560   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13561   DONE;
13562 })
13563
13564 (define_expand "ilogb<mode>2"
13565   [(use (match_operand:SI 0 "register_operand" ""))
13566    (use (match_operand:MODEF 1 "register_operand" ""))]
13567   "TARGET_USE_FANCY_MATH_387
13568    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13569        || TARGET_MIX_SSE_I387)
13570    && flag_unsafe_math_optimizations"
13571 {
13572   rtx op0, op1;
13573
13574   if (optimize_insn_for_size_p ())
13575     FAIL;
13576
13577   op0 = gen_reg_rtx (XFmode);
13578   op1 = gen_reg_rtx (XFmode);
13579
13580   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13581   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13582   DONE;
13583 })
13584
13585 (define_insn "*f2xm1xf2_i387"
13586   [(set (match_operand:XF 0 "register_operand" "=f")
13587         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13588                    UNSPEC_F2XM1))]
13589   "TARGET_USE_FANCY_MATH_387
13590    && flag_unsafe_math_optimizations"
13591   "f2xm1"
13592   [(set_attr "type" "fpspc")
13593    (set_attr "mode" "XF")])
13594
13595 (define_insn "*fscalexf4_i387"
13596   [(set (match_operand:XF 0 "register_operand" "=f")
13597         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13598                     (match_operand:XF 3 "register_operand" "1")]
13599                    UNSPEC_FSCALE_FRACT))
13600    (set (match_operand:XF 1 "register_operand" "=u")
13601         (unspec:XF [(match_dup 2) (match_dup 3)]
13602                    UNSPEC_FSCALE_EXP))]
13603   "TARGET_USE_FANCY_MATH_387
13604    && flag_unsafe_math_optimizations"
13605   "fscale"
13606   [(set_attr "type" "fpspc")
13607    (set_attr "mode" "XF")])
13608
13609 (define_expand "expNcorexf3"
13610   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
13611                                (match_operand:XF 2 "register_operand" "")))
13612    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
13613    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
13614    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
13615    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
13616    (parallel [(set (match_operand:XF 0 "register_operand" "")
13617                    (unspec:XF [(match_dup 8) (match_dup 4)]
13618                               UNSPEC_FSCALE_FRACT))
13619               (set (match_dup 9)
13620                    (unspec:XF [(match_dup 8) (match_dup 4)]
13621                               UNSPEC_FSCALE_EXP))])]
13622   "TARGET_USE_FANCY_MATH_387
13623    && flag_unsafe_math_optimizations"
13624 {
13625   int i;
13626
13627   if (optimize_insn_for_size_p ())
13628     FAIL;
13629
13630   for (i = 3; i < 10; i++)
13631     operands[i] = gen_reg_rtx (XFmode);
13632
13633   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
13634 })
13635
13636 (define_expand "expxf2"
13637   [(use (match_operand:XF 0 "register_operand" ""))
13638    (use (match_operand:XF 1 "register_operand" ""))]
13639   "TARGET_USE_FANCY_MATH_387
13640    && flag_unsafe_math_optimizations"
13641 {
13642   rtx op2;
13643
13644   if (optimize_insn_for_size_p ())
13645     FAIL;
13646
13647   op2 = gen_reg_rtx (XFmode);
13648   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
13649
13650   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
13651   DONE;
13652 })
13653
13654 (define_expand "exp<mode>2"
13655   [(use (match_operand:MODEF 0 "register_operand" ""))
13656    (use (match_operand:MODEF 1 "general_operand" ""))]
13657  "TARGET_USE_FANCY_MATH_387
13658    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13659        || TARGET_MIX_SSE_I387)
13660    && flag_unsafe_math_optimizations"
13661 {
13662   rtx op0, op1;
13663
13664   if (optimize_insn_for_size_p ())
13665     FAIL;
13666
13667   op0 = gen_reg_rtx (XFmode);
13668   op1 = gen_reg_rtx (XFmode);
13669
13670   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13671   emit_insn (gen_expxf2 (op0, op1));
13672   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13673   DONE;
13674 })
13675
13676 (define_expand "exp10xf2"
13677   [(use (match_operand:XF 0 "register_operand" ""))
13678    (use (match_operand:XF 1 "register_operand" ""))]
13679   "TARGET_USE_FANCY_MATH_387
13680    && flag_unsafe_math_optimizations"
13681 {
13682   rtx op2;
13683
13684   if (optimize_insn_for_size_p ())
13685     FAIL;
13686
13687   op2 = gen_reg_rtx (XFmode);
13688   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
13689
13690   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
13691   DONE;
13692 })
13693
13694 (define_expand "exp10<mode>2"
13695   [(use (match_operand:MODEF 0 "register_operand" ""))
13696    (use (match_operand:MODEF 1 "general_operand" ""))]
13697  "TARGET_USE_FANCY_MATH_387
13698    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13699        || TARGET_MIX_SSE_I387)
13700    && flag_unsafe_math_optimizations"
13701 {
13702   rtx op0, op1;
13703
13704   if (optimize_insn_for_size_p ())
13705     FAIL;
13706
13707   op0 = gen_reg_rtx (XFmode);
13708   op1 = gen_reg_rtx (XFmode);
13709
13710   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13711   emit_insn (gen_exp10xf2 (op0, op1));
13712   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13713   DONE;
13714 })
13715
13716 (define_expand "exp2xf2"
13717   [(use (match_operand:XF 0 "register_operand" ""))
13718    (use (match_operand:XF 1 "register_operand" ""))]
13719   "TARGET_USE_FANCY_MATH_387
13720    && flag_unsafe_math_optimizations"
13721 {
13722   rtx op2;
13723
13724   if (optimize_insn_for_size_p ())
13725     FAIL;
13726
13727   op2 = gen_reg_rtx (XFmode);
13728   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
13729
13730   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
13731   DONE;
13732 })
13733
13734 (define_expand "exp2<mode>2"
13735   [(use (match_operand:MODEF 0 "register_operand" ""))
13736    (use (match_operand:MODEF 1 "general_operand" ""))]
13737  "TARGET_USE_FANCY_MATH_387
13738    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13739        || TARGET_MIX_SSE_I387)
13740    && flag_unsafe_math_optimizations"
13741 {
13742   rtx op0, op1;
13743
13744   if (optimize_insn_for_size_p ())
13745     FAIL;
13746
13747   op0 = gen_reg_rtx (XFmode);
13748   op1 = gen_reg_rtx (XFmode);
13749
13750   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13751   emit_insn (gen_exp2xf2 (op0, op1));
13752   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13753   DONE;
13754 })
13755
13756 (define_expand "expm1xf2"
13757   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
13758                                (match_dup 2)))
13759    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
13760    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
13761    (set (match_dup 9) (float_extend:XF (match_dup 13)))
13762    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
13763    (parallel [(set (match_dup 7)
13764                    (unspec:XF [(match_dup 6) (match_dup 4)]
13765                               UNSPEC_FSCALE_FRACT))
13766               (set (match_dup 8)
13767                    (unspec:XF [(match_dup 6) (match_dup 4)]
13768                               UNSPEC_FSCALE_EXP))])
13769    (parallel [(set (match_dup 10)
13770                    (unspec:XF [(match_dup 9) (match_dup 8)]
13771                               UNSPEC_FSCALE_FRACT))
13772               (set (match_dup 11)
13773                    (unspec:XF [(match_dup 9) (match_dup 8)]
13774                               UNSPEC_FSCALE_EXP))])
13775    (set (match_dup 12) (minus:XF (match_dup 10)
13776                                  (float_extend:XF (match_dup 13))))
13777    (set (match_operand:XF 0 "register_operand" "")
13778         (plus:XF (match_dup 12) (match_dup 7)))]
13779   "TARGET_USE_FANCY_MATH_387
13780    && flag_unsafe_math_optimizations"
13781 {
13782   int i;
13783
13784   if (optimize_insn_for_size_p ())
13785     FAIL;
13786
13787   for (i = 2; i < 13; i++)
13788     operands[i] = gen_reg_rtx (XFmode);
13789
13790   operands[13]
13791     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
13792
13793   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
13794 })
13795
13796 (define_expand "expm1<mode>2"
13797   [(use (match_operand:MODEF 0 "register_operand" ""))
13798    (use (match_operand:MODEF 1 "general_operand" ""))]
13799  "TARGET_USE_FANCY_MATH_387
13800    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13801        || TARGET_MIX_SSE_I387)
13802    && flag_unsafe_math_optimizations"
13803 {
13804   rtx op0, op1;
13805
13806   if (optimize_insn_for_size_p ())
13807     FAIL;
13808
13809   op0 = gen_reg_rtx (XFmode);
13810   op1 = gen_reg_rtx (XFmode);
13811
13812   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13813   emit_insn (gen_expm1xf2 (op0, op1));
13814   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13815   DONE;
13816 })
13817
13818 (define_expand "ldexpxf3"
13819   [(set (match_dup 3)
13820         (float:XF (match_operand:SI 2 "register_operand" "")))
13821    (parallel [(set (match_operand:XF 0 " register_operand" "")
13822                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
13823                                (match_dup 3)]
13824                               UNSPEC_FSCALE_FRACT))
13825               (set (match_dup 4)
13826                    (unspec:XF [(match_dup 1) (match_dup 3)]
13827                               UNSPEC_FSCALE_EXP))])]
13828   "TARGET_USE_FANCY_MATH_387
13829    && flag_unsafe_math_optimizations"
13830 {
13831   if (optimize_insn_for_size_p ())
13832     FAIL;
13833
13834   operands[3] = gen_reg_rtx (XFmode);
13835   operands[4] = gen_reg_rtx (XFmode);
13836 })
13837
13838 (define_expand "ldexp<mode>3"
13839   [(use (match_operand:MODEF 0 "register_operand" ""))
13840    (use (match_operand:MODEF 1 "general_operand" ""))
13841    (use (match_operand:SI 2 "register_operand" ""))]
13842  "TARGET_USE_FANCY_MATH_387
13843    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13844        || TARGET_MIX_SSE_I387)
13845    && flag_unsafe_math_optimizations"
13846 {
13847   rtx op0, op1;
13848
13849   if (optimize_insn_for_size_p ())
13850     FAIL;
13851
13852   op0 = gen_reg_rtx (XFmode);
13853   op1 = gen_reg_rtx (XFmode);
13854
13855   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13856   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
13857   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13858   DONE;
13859 })
13860
13861 (define_expand "scalbxf3"
13862   [(parallel [(set (match_operand:XF 0 " register_operand" "")
13863                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
13864                                (match_operand:XF 2 "register_operand" "")]
13865                               UNSPEC_FSCALE_FRACT))
13866               (set (match_dup 3)
13867                    (unspec:XF [(match_dup 1) (match_dup 2)]
13868                               UNSPEC_FSCALE_EXP))])]
13869   "TARGET_USE_FANCY_MATH_387
13870    && flag_unsafe_math_optimizations"
13871 {
13872   if (optimize_insn_for_size_p ())
13873     FAIL;
13874
13875   operands[3] = gen_reg_rtx (XFmode);
13876 })
13877
13878 (define_expand "scalb<mode>3"
13879   [(use (match_operand:MODEF 0 "register_operand" ""))
13880    (use (match_operand:MODEF 1 "general_operand" ""))
13881    (use (match_operand:MODEF 2 "general_operand" ""))]
13882  "TARGET_USE_FANCY_MATH_387
13883    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13884        || TARGET_MIX_SSE_I387)
13885    && flag_unsafe_math_optimizations"
13886 {
13887   rtx op0, op1, op2;
13888
13889   if (optimize_insn_for_size_p ())
13890     FAIL;
13891
13892   op0 = gen_reg_rtx (XFmode);
13893   op1 = gen_reg_rtx (XFmode);
13894   op2 = gen_reg_rtx (XFmode);
13895
13896   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13897   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13898   emit_insn (gen_scalbxf3 (op0, op1, op2));
13899   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13900   DONE;
13901 })
13902
13903 (define_expand "significandxf2"
13904   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13905                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
13906                               UNSPEC_XTRACT_FRACT))
13907               (set (match_dup 2)
13908                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
13909   "TARGET_USE_FANCY_MATH_387
13910    && flag_unsafe_math_optimizations"
13911 {
13912   operands[2] = gen_reg_rtx (XFmode);
13913 })
13914
13915 (define_expand "significand<mode>2"
13916   [(use (match_operand:MODEF 0 "register_operand" ""))
13917    (use (match_operand:MODEF 1 "register_operand" ""))]
13918   "TARGET_USE_FANCY_MATH_387
13919    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13920        || TARGET_MIX_SSE_I387)
13921    && flag_unsafe_math_optimizations"
13922 {
13923   rtx op0 = gen_reg_rtx (XFmode);
13924   rtx op1 = gen_reg_rtx (XFmode);
13925
13926   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13927   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13928   DONE;
13929 })
13930 \f
13931
13932 (define_insn "sse4_1_round<mode>2"
13933   [(set (match_operand:MODEF 0 "register_operand" "=x")
13934         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
13935                        (match_operand:SI 2 "const_0_to_15_operand" "n")]
13936                       UNSPEC_ROUND))]
13937   "TARGET_ROUND"
13938   "%vrounds<ssemodefsuffix>\t{%2, %1, %d0|%d0, %1, %2}"
13939   [(set_attr "type" "ssecvt")
13940    (set_attr "prefix_extra" "1")
13941    (set_attr "prefix" "maybe_vex")
13942    (set_attr "mode" "<MODE>")])
13943
13944 (define_insn "rintxf2"
13945   [(set (match_operand:XF 0 "register_operand" "=f")
13946         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13947                    UNSPEC_FRNDINT))]
13948   "TARGET_USE_FANCY_MATH_387
13949    && flag_unsafe_math_optimizations"
13950   "frndint"
13951   [(set_attr "type" "fpspc")
13952    (set_attr "mode" "XF")])
13953
13954 (define_expand "rint<mode>2"
13955   [(use (match_operand:MODEF 0 "register_operand" ""))
13956    (use (match_operand:MODEF 1 "register_operand" ""))]
13957   "(TARGET_USE_FANCY_MATH_387
13958     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13959         || TARGET_MIX_SSE_I387)
13960     && flag_unsafe_math_optimizations)
13961    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13962        && !flag_trapping_math)"
13963 {
13964   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13965       && !flag_trapping_math)
13966     {
13967       if (!TARGET_ROUND && optimize_insn_for_size_p ())
13968         FAIL;
13969       if (TARGET_ROUND)
13970         emit_insn (gen_sse4_1_round<mode>2
13971                    (operands[0], operands[1], GEN_INT (0x04)));
13972       else
13973         ix86_expand_rint (operand0, operand1);
13974     }
13975   else
13976     {
13977       rtx op0 = gen_reg_rtx (XFmode);
13978       rtx op1 = gen_reg_rtx (XFmode);
13979
13980       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13981       emit_insn (gen_rintxf2 (op0, op1));
13982
13983       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13984     }
13985   DONE;
13986 })
13987
13988 (define_expand "round<mode>2"
13989   [(match_operand:MODEF 0 "register_operand" "")
13990    (match_operand:MODEF 1 "nonimmediate_operand" "")]
13991   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13992    && !flag_trapping_math && !flag_rounding_math"
13993 {
13994   if (optimize_insn_for_size_p ())
13995     FAIL;
13996   if (TARGET_64BIT || (<MODE>mode != DFmode))
13997     ix86_expand_round (operand0, operand1);
13998   else
13999     ix86_expand_rounddf_32 (operand0, operand1);
14000   DONE;
14001 })
14002
14003 (define_insn_and_split "*fistdi2_1"
14004   [(set (match_operand:DI 0 "nonimmediate_operand" "")
14005         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14006                    UNSPEC_FIST))]
14007   "TARGET_USE_FANCY_MATH_387
14008    && can_create_pseudo_p ()"
14009   "#"
14010   "&& 1"
14011   [(const_int 0)]
14012 {
14013   if (memory_operand (operands[0], VOIDmode))
14014     emit_insn (gen_fistdi2 (operands[0], operands[1]));
14015   else
14016     {
14017       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14018       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14019                                          operands[2]));
14020     }
14021   DONE;
14022 }
14023   [(set_attr "type" "fpspc")
14024    (set_attr "mode" "DI")])
14025
14026 (define_insn "fistdi2"
14027   [(set (match_operand:DI 0 "memory_operand" "=m")
14028         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14029                    UNSPEC_FIST))
14030    (clobber (match_scratch:XF 2 "=&1f"))]
14031   "TARGET_USE_FANCY_MATH_387"
14032   "* return output_fix_trunc (insn, operands, 0);"
14033   [(set_attr "type" "fpspc")
14034    (set_attr "mode" "DI")])
14035
14036 (define_insn "fistdi2_with_temp"
14037   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14038         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14039                    UNSPEC_FIST))
14040    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14041    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14042   "TARGET_USE_FANCY_MATH_387"
14043   "#"
14044   [(set_attr "type" "fpspc")
14045    (set_attr "mode" "DI")])
14046
14047 (define_split
14048   [(set (match_operand:DI 0 "register_operand" "")
14049         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14050                    UNSPEC_FIST))
14051    (clobber (match_operand:DI 2 "memory_operand" ""))
14052    (clobber (match_scratch 3 ""))]
14053   "reload_completed"
14054   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14055               (clobber (match_dup 3))])
14056    (set (match_dup 0) (match_dup 2))])
14057
14058 (define_split
14059   [(set (match_operand:DI 0 "memory_operand" "")
14060         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14061                    UNSPEC_FIST))
14062    (clobber (match_operand:DI 2 "memory_operand" ""))
14063    (clobber (match_scratch 3 ""))]
14064   "reload_completed"
14065   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14066               (clobber (match_dup 3))])])
14067
14068 (define_insn_and_split "*fist<mode>2_1"
14069   [(set (match_operand:X87MODEI12 0 "register_operand" "")
14070         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14071                            UNSPEC_FIST))]
14072   "TARGET_USE_FANCY_MATH_387
14073    && can_create_pseudo_p ()"
14074   "#"
14075   "&& 1"
14076   [(const_int 0)]
14077 {
14078   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14079   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14080                                         operands[2]));
14081   DONE;
14082 }
14083   [(set_attr "type" "fpspc")
14084    (set_attr "mode" "<MODE>")])
14085
14086 (define_insn "fist<mode>2"
14087   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14088         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14089                            UNSPEC_FIST))]
14090   "TARGET_USE_FANCY_MATH_387"
14091   "* return output_fix_trunc (insn, operands, 0);"
14092   [(set_attr "type" "fpspc")
14093    (set_attr "mode" "<MODE>")])
14094
14095 (define_insn "fist<mode>2_with_temp"
14096   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
14097         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14098                            UNSPEC_FIST))
14099    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
14100   "TARGET_USE_FANCY_MATH_387"
14101   "#"
14102   [(set_attr "type" "fpspc")
14103    (set_attr "mode" "<MODE>")])
14104
14105 (define_split
14106   [(set (match_operand:X87MODEI12 0 "register_operand" "")
14107         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14108                            UNSPEC_FIST))
14109    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14110   "reload_completed"
14111   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
14112    (set (match_dup 0) (match_dup 2))])
14113
14114 (define_split
14115   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14116         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14117                            UNSPEC_FIST))
14118    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14119   "reload_completed"
14120   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))])
14121
14122 (define_expand "lrintxf<mode>2"
14123   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14124      (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14125                       UNSPEC_FIST))]
14126   "TARGET_USE_FANCY_MATH_387"
14127   "")
14128
14129 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
14130   [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14131      (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
14132                         UNSPEC_FIX_NOTRUNC))]
14133   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14134    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
14135   "")
14136
14137 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
14138   [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14139    (match_operand:MODEF 1 "register_operand" "")]
14140   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14141    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
14142    && !flag_trapping_math && !flag_rounding_math"
14143 {
14144   if (optimize_insn_for_size_p ())
14145     FAIL;
14146   ix86_expand_lround (operand0, operand1);
14147   DONE;
14148 })
14149
14150 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14151 (define_insn_and_split "frndintxf2_floor"
14152   [(set (match_operand:XF 0 "register_operand" "")
14153         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14154          UNSPEC_FRNDINT_FLOOR))
14155    (clobber (reg:CC FLAGS_REG))]
14156   "TARGET_USE_FANCY_MATH_387
14157    && flag_unsafe_math_optimizations
14158    && can_create_pseudo_p ()"
14159   "#"
14160   "&& 1"
14161   [(const_int 0)]
14162 {
14163   ix86_optimize_mode_switching[I387_FLOOR] = 1;
14164
14165   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14166   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14167
14168   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14169                                         operands[2], operands[3]));
14170   DONE;
14171 }
14172   [(set_attr "type" "frndint")
14173    (set_attr "i387_cw" "floor")
14174    (set_attr "mode" "XF")])
14175
14176 (define_insn "frndintxf2_floor_i387"
14177   [(set (match_operand:XF 0 "register_operand" "=f")
14178         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14179          UNSPEC_FRNDINT_FLOOR))
14180    (use (match_operand:HI 2 "memory_operand" "m"))
14181    (use (match_operand:HI 3 "memory_operand" "m"))]
14182   "TARGET_USE_FANCY_MATH_387
14183    && flag_unsafe_math_optimizations"
14184   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14185   [(set_attr "type" "frndint")
14186    (set_attr "i387_cw" "floor")
14187    (set_attr "mode" "XF")])
14188
14189 (define_expand "floorxf2"
14190   [(use (match_operand:XF 0 "register_operand" ""))
14191    (use (match_operand:XF 1 "register_operand" ""))]
14192   "TARGET_USE_FANCY_MATH_387
14193    && flag_unsafe_math_optimizations"
14194 {
14195   if (optimize_insn_for_size_p ())
14196     FAIL;
14197   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14198   DONE;
14199 })
14200
14201 (define_expand "floor<mode>2"
14202   [(use (match_operand:MODEF 0 "register_operand" ""))
14203    (use (match_operand:MODEF 1 "register_operand" ""))]
14204   "(TARGET_USE_FANCY_MATH_387
14205     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14206         || TARGET_MIX_SSE_I387)
14207     && flag_unsafe_math_optimizations)
14208    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14209        && !flag_trapping_math)"
14210 {
14211   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14212       && !flag_trapping_math
14213       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14214     {
14215       if (!TARGET_ROUND && optimize_insn_for_size_p ())
14216         FAIL;
14217       if (TARGET_ROUND)
14218         emit_insn (gen_sse4_1_round<mode>2
14219                    (operands[0], operands[1], GEN_INT (0x01)));
14220       else if (TARGET_64BIT || (<MODE>mode != DFmode))
14221         ix86_expand_floorceil (operand0, operand1, true);
14222       else
14223         ix86_expand_floorceildf_32 (operand0, operand1, true);
14224     }
14225   else
14226     {
14227       rtx op0, op1;
14228
14229       if (optimize_insn_for_size_p ())
14230         FAIL;
14231
14232       op0 = gen_reg_rtx (XFmode);
14233       op1 = gen_reg_rtx (XFmode);
14234       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14235       emit_insn (gen_frndintxf2_floor (op0, op1));
14236
14237       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14238     }
14239   DONE;
14240 })
14241
14242 (define_insn_and_split "*fist<mode>2_floor_1"
14243   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14244         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14245          UNSPEC_FIST_FLOOR))
14246    (clobber (reg:CC FLAGS_REG))]
14247   "TARGET_USE_FANCY_MATH_387
14248    && flag_unsafe_math_optimizations
14249    && can_create_pseudo_p ()"
14250   "#"
14251   "&& 1"
14252   [(const_int 0)]
14253 {
14254   ix86_optimize_mode_switching[I387_FLOOR] = 1;
14255
14256   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14257   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14258   if (memory_operand (operands[0], VOIDmode))
14259     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14260                                       operands[2], operands[3]));
14261   else
14262     {
14263       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14264       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14265                                                   operands[2], operands[3],
14266                                                   operands[4]));
14267     }
14268   DONE;
14269 }
14270   [(set_attr "type" "fistp")
14271    (set_attr "i387_cw" "floor")
14272    (set_attr "mode" "<MODE>")])
14273
14274 (define_insn "fistdi2_floor"
14275   [(set (match_operand:DI 0 "memory_operand" "=m")
14276         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14277          UNSPEC_FIST_FLOOR))
14278    (use (match_operand:HI 2 "memory_operand" "m"))
14279    (use (match_operand:HI 3 "memory_operand" "m"))
14280    (clobber (match_scratch:XF 4 "=&1f"))]
14281   "TARGET_USE_FANCY_MATH_387
14282    && flag_unsafe_math_optimizations"
14283   "* return output_fix_trunc (insn, operands, 0);"
14284   [(set_attr "type" "fistp")
14285    (set_attr "i387_cw" "floor")
14286    (set_attr "mode" "DI")])
14287
14288 (define_insn "fistdi2_floor_with_temp"
14289   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14290         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14291          UNSPEC_FIST_FLOOR))
14292    (use (match_operand:HI 2 "memory_operand" "m,m"))
14293    (use (match_operand:HI 3 "memory_operand" "m,m"))
14294    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14295    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14296   "TARGET_USE_FANCY_MATH_387
14297    && flag_unsafe_math_optimizations"
14298   "#"
14299   [(set_attr "type" "fistp")
14300    (set_attr "i387_cw" "floor")
14301    (set_attr "mode" "DI")])
14302
14303 (define_split
14304   [(set (match_operand:DI 0 "register_operand" "")
14305         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14306          UNSPEC_FIST_FLOOR))
14307    (use (match_operand:HI 2 "memory_operand" ""))
14308    (use (match_operand:HI 3 "memory_operand" ""))
14309    (clobber (match_operand:DI 4 "memory_operand" ""))
14310    (clobber (match_scratch 5 ""))]
14311   "reload_completed"
14312   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14313               (use (match_dup 2))
14314               (use (match_dup 3))
14315               (clobber (match_dup 5))])
14316    (set (match_dup 0) (match_dup 4))])
14317
14318 (define_split
14319   [(set (match_operand:DI 0 "memory_operand" "")
14320         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14321          UNSPEC_FIST_FLOOR))
14322    (use (match_operand:HI 2 "memory_operand" ""))
14323    (use (match_operand:HI 3 "memory_operand" ""))
14324    (clobber (match_operand:DI 4 "memory_operand" ""))
14325    (clobber (match_scratch 5 ""))]
14326   "reload_completed"
14327   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14328               (use (match_dup 2))
14329               (use (match_dup 3))
14330               (clobber (match_dup 5))])])
14331
14332 (define_insn "fist<mode>2_floor"
14333   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14334         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14335          UNSPEC_FIST_FLOOR))
14336    (use (match_operand:HI 2 "memory_operand" "m"))
14337    (use (match_operand:HI 3 "memory_operand" "m"))]
14338   "TARGET_USE_FANCY_MATH_387
14339    && flag_unsafe_math_optimizations"
14340   "* return output_fix_trunc (insn, operands, 0);"
14341   [(set_attr "type" "fistp")
14342    (set_attr "i387_cw" "floor")
14343    (set_attr "mode" "<MODE>")])
14344
14345 (define_insn "fist<mode>2_floor_with_temp"
14346   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
14347         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
14348          UNSPEC_FIST_FLOOR))
14349    (use (match_operand:HI 2 "memory_operand" "m,m"))
14350    (use (match_operand:HI 3 "memory_operand" "m,m"))
14351    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
14352   "TARGET_USE_FANCY_MATH_387
14353    && flag_unsafe_math_optimizations"
14354   "#"
14355   [(set_attr "type" "fistp")
14356    (set_attr "i387_cw" "floor")
14357    (set_attr "mode" "<MODE>")])
14358
14359 (define_split
14360   [(set (match_operand:X87MODEI12 0 "register_operand" "")
14361         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14362          UNSPEC_FIST_FLOOR))
14363    (use (match_operand:HI 2 "memory_operand" ""))
14364    (use (match_operand:HI 3 "memory_operand" ""))
14365    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14366   "reload_completed"
14367   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
14368                                   UNSPEC_FIST_FLOOR))
14369               (use (match_dup 2))
14370               (use (match_dup 3))])
14371    (set (match_dup 0) (match_dup 4))])
14372
14373 (define_split
14374   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14375         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14376          UNSPEC_FIST_FLOOR))
14377    (use (match_operand:HI 2 "memory_operand" ""))
14378    (use (match_operand:HI 3 "memory_operand" ""))
14379    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14380   "reload_completed"
14381   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
14382                                   UNSPEC_FIST_FLOOR))
14383               (use (match_dup 2))
14384               (use (match_dup 3))])])
14385
14386 (define_expand "lfloorxf<mode>2"
14387   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14388                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14389                     UNSPEC_FIST_FLOOR))
14390               (clobber (reg:CC FLAGS_REG))])]
14391   "TARGET_USE_FANCY_MATH_387
14392    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14393    && flag_unsafe_math_optimizations"
14394   "")
14395
14396 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
14397   [(match_operand:SWI48 0 "nonimmediate_operand" "")
14398    (match_operand:MODEF 1 "register_operand" "")]
14399   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14400    && !flag_trapping_math"
14401 {
14402   if (TARGET_64BIT && optimize_insn_for_size_p ())
14403     FAIL;
14404   ix86_expand_lfloorceil (operand0, operand1, true);
14405   DONE;
14406 })
14407
14408 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14409 (define_insn_and_split "frndintxf2_ceil"
14410   [(set (match_operand:XF 0 "register_operand" "")
14411         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14412          UNSPEC_FRNDINT_CEIL))
14413    (clobber (reg:CC FLAGS_REG))]
14414   "TARGET_USE_FANCY_MATH_387
14415    && flag_unsafe_math_optimizations
14416    && can_create_pseudo_p ()"
14417   "#"
14418   "&& 1"
14419   [(const_int 0)]
14420 {
14421   ix86_optimize_mode_switching[I387_CEIL] = 1;
14422
14423   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14424   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14425
14426   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
14427                                        operands[2], operands[3]));
14428   DONE;
14429 }
14430   [(set_attr "type" "frndint")
14431    (set_attr "i387_cw" "ceil")
14432    (set_attr "mode" "XF")])
14433
14434 (define_insn "frndintxf2_ceil_i387"
14435   [(set (match_operand:XF 0 "register_operand" "=f")
14436         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14437          UNSPEC_FRNDINT_CEIL))
14438    (use (match_operand:HI 2 "memory_operand" "m"))
14439    (use (match_operand:HI 3 "memory_operand" "m"))]
14440   "TARGET_USE_FANCY_MATH_387
14441    && flag_unsafe_math_optimizations"
14442   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14443   [(set_attr "type" "frndint")
14444    (set_attr "i387_cw" "ceil")
14445    (set_attr "mode" "XF")])
14446
14447 (define_expand "ceilxf2"
14448   [(use (match_operand:XF 0 "register_operand" ""))
14449    (use (match_operand:XF 1 "register_operand" ""))]
14450   "TARGET_USE_FANCY_MATH_387
14451    && flag_unsafe_math_optimizations"
14452 {
14453   if (optimize_insn_for_size_p ())
14454     FAIL;
14455   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
14456   DONE;
14457 })
14458
14459 (define_expand "ceil<mode>2"
14460   [(use (match_operand:MODEF 0 "register_operand" ""))
14461    (use (match_operand:MODEF 1 "register_operand" ""))]
14462   "(TARGET_USE_FANCY_MATH_387
14463     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14464         || TARGET_MIX_SSE_I387)
14465     && flag_unsafe_math_optimizations)
14466    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14467        && !flag_trapping_math)"
14468 {
14469   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14470       && !flag_trapping_math
14471       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14472     {
14473       if (TARGET_ROUND)
14474         emit_insn (gen_sse4_1_round<mode>2
14475                    (operands[0], operands[1], GEN_INT (0x02)));
14476       else if (optimize_insn_for_size_p ())
14477         FAIL;
14478       else if (TARGET_64BIT || (<MODE>mode != DFmode))
14479         ix86_expand_floorceil (operand0, operand1, false);
14480       else
14481         ix86_expand_floorceildf_32 (operand0, operand1, false);
14482     }
14483   else
14484     {
14485       rtx op0, op1;
14486
14487       if (optimize_insn_for_size_p ())
14488         FAIL;
14489
14490       op0 = gen_reg_rtx (XFmode);
14491       op1 = gen_reg_rtx (XFmode);
14492       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14493       emit_insn (gen_frndintxf2_ceil (op0, op1));
14494
14495       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14496     }
14497   DONE;
14498 })
14499
14500 (define_insn_and_split "*fist<mode>2_ceil_1"
14501   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14502         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14503          UNSPEC_FIST_CEIL))
14504    (clobber (reg:CC FLAGS_REG))]
14505   "TARGET_USE_FANCY_MATH_387
14506    && flag_unsafe_math_optimizations
14507    && can_create_pseudo_p ()"
14508   "#"
14509   "&& 1"
14510   [(const_int 0)]
14511 {
14512   ix86_optimize_mode_switching[I387_CEIL] = 1;
14513
14514   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14515   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14516   if (memory_operand (operands[0], VOIDmode))
14517     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
14518                                      operands[2], operands[3]));
14519   else
14520     {
14521       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14522       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
14523                                                  operands[2], operands[3],
14524                                                  operands[4]));
14525     }
14526   DONE;
14527 }
14528   [(set_attr "type" "fistp")
14529    (set_attr "i387_cw" "ceil")
14530    (set_attr "mode" "<MODE>")])
14531
14532 (define_insn "fistdi2_ceil"
14533   [(set (match_operand:DI 0 "memory_operand" "=m")
14534         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14535          UNSPEC_FIST_CEIL))
14536    (use (match_operand:HI 2 "memory_operand" "m"))
14537    (use (match_operand:HI 3 "memory_operand" "m"))
14538    (clobber (match_scratch:XF 4 "=&1f"))]
14539   "TARGET_USE_FANCY_MATH_387
14540    && flag_unsafe_math_optimizations"
14541   "* return output_fix_trunc (insn, operands, 0);"
14542   [(set_attr "type" "fistp")
14543    (set_attr "i387_cw" "ceil")
14544    (set_attr "mode" "DI")])
14545
14546 (define_insn "fistdi2_ceil_with_temp"
14547   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14548         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14549          UNSPEC_FIST_CEIL))
14550    (use (match_operand:HI 2 "memory_operand" "m,m"))
14551    (use (match_operand:HI 3 "memory_operand" "m,m"))
14552    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14553    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14554   "TARGET_USE_FANCY_MATH_387
14555    && flag_unsafe_math_optimizations"
14556   "#"
14557   [(set_attr "type" "fistp")
14558    (set_attr "i387_cw" "ceil")
14559    (set_attr "mode" "DI")])
14560
14561 (define_split
14562   [(set (match_operand:DI 0 "register_operand" "")
14563         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14564          UNSPEC_FIST_CEIL))
14565    (use (match_operand:HI 2 "memory_operand" ""))
14566    (use (match_operand:HI 3 "memory_operand" ""))
14567    (clobber (match_operand:DI 4 "memory_operand" ""))
14568    (clobber (match_scratch 5 ""))]
14569   "reload_completed"
14570   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
14571               (use (match_dup 2))
14572               (use (match_dup 3))
14573               (clobber (match_dup 5))])
14574    (set (match_dup 0) (match_dup 4))])
14575
14576 (define_split
14577   [(set (match_operand:DI 0 "memory_operand" "")
14578         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14579          UNSPEC_FIST_CEIL))
14580    (use (match_operand:HI 2 "memory_operand" ""))
14581    (use (match_operand:HI 3 "memory_operand" ""))
14582    (clobber (match_operand:DI 4 "memory_operand" ""))
14583    (clobber (match_scratch 5 ""))]
14584   "reload_completed"
14585   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
14586               (use (match_dup 2))
14587               (use (match_dup 3))
14588               (clobber (match_dup 5))])])
14589
14590 (define_insn "fist<mode>2_ceil"
14591   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14592         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14593          UNSPEC_FIST_CEIL))
14594    (use (match_operand:HI 2 "memory_operand" "m"))
14595    (use (match_operand:HI 3 "memory_operand" "m"))]
14596   "TARGET_USE_FANCY_MATH_387
14597    && flag_unsafe_math_optimizations"
14598   "* return output_fix_trunc (insn, operands, 0);"
14599   [(set_attr "type" "fistp")
14600    (set_attr "i387_cw" "ceil")
14601    (set_attr "mode" "<MODE>")])
14602
14603 (define_insn "fist<mode>2_ceil_with_temp"
14604   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
14605         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
14606          UNSPEC_FIST_CEIL))
14607    (use (match_operand:HI 2 "memory_operand" "m,m"))
14608    (use (match_operand:HI 3 "memory_operand" "m,m"))
14609    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
14610   "TARGET_USE_FANCY_MATH_387
14611    && flag_unsafe_math_optimizations"
14612   "#"
14613   [(set_attr "type" "fistp")
14614    (set_attr "i387_cw" "ceil")
14615    (set_attr "mode" "<MODE>")])
14616
14617 (define_split
14618   [(set (match_operand:X87MODEI12 0 "register_operand" "")
14619         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14620          UNSPEC_FIST_CEIL))
14621    (use (match_operand:HI 2 "memory_operand" ""))
14622    (use (match_operand:HI 3 "memory_operand" ""))
14623    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14624   "reload_completed"
14625   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
14626                                   UNSPEC_FIST_CEIL))
14627               (use (match_dup 2))
14628               (use (match_dup 3))])
14629    (set (match_dup 0) (match_dup 4))])
14630
14631 (define_split
14632   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14633         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14634          UNSPEC_FIST_CEIL))
14635    (use (match_operand:HI 2 "memory_operand" ""))
14636    (use (match_operand:HI 3 "memory_operand" ""))
14637    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14638   "reload_completed"
14639   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
14640                                   UNSPEC_FIST_CEIL))
14641               (use (match_dup 2))
14642               (use (match_dup 3))])])
14643
14644 (define_expand "lceilxf<mode>2"
14645   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14646                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14647                     UNSPEC_FIST_CEIL))
14648               (clobber (reg:CC FLAGS_REG))])]
14649   "TARGET_USE_FANCY_MATH_387
14650    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14651    && flag_unsafe_math_optimizations"
14652   "")
14653
14654 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
14655   [(match_operand:SWI48 0 "nonimmediate_operand" "")
14656    (match_operand:MODEF 1 "register_operand" "")]
14657   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14658    && !flag_trapping_math"
14659 {
14660   ix86_expand_lfloorceil (operand0, operand1, false);
14661   DONE;
14662 })
14663
14664 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14665 (define_insn_and_split "frndintxf2_trunc"
14666   [(set (match_operand:XF 0 "register_operand" "")
14667         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14668          UNSPEC_FRNDINT_TRUNC))
14669    (clobber (reg:CC FLAGS_REG))]
14670   "TARGET_USE_FANCY_MATH_387
14671    && flag_unsafe_math_optimizations
14672    && can_create_pseudo_p ()"
14673   "#"
14674   "&& 1"
14675   [(const_int 0)]
14676 {
14677   ix86_optimize_mode_switching[I387_TRUNC] = 1;
14678
14679   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14680   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
14681
14682   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
14683                                         operands[2], operands[3]));
14684   DONE;
14685 }
14686   [(set_attr "type" "frndint")
14687    (set_attr "i387_cw" "trunc")
14688    (set_attr "mode" "XF")])
14689
14690 (define_insn "frndintxf2_trunc_i387"
14691   [(set (match_operand:XF 0 "register_operand" "=f")
14692         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14693          UNSPEC_FRNDINT_TRUNC))
14694    (use (match_operand:HI 2 "memory_operand" "m"))
14695    (use (match_operand:HI 3 "memory_operand" "m"))]
14696   "TARGET_USE_FANCY_MATH_387
14697    && flag_unsafe_math_optimizations"
14698   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14699   [(set_attr "type" "frndint")
14700    (set_attr "i387_cw" "trunc")
14701    (set_attr "mode" "XF")])
14702
14703 (define_expand "btruncxf2"
14704   [(use (match_operand:XF 0 "register_operand" ""))
14705    (use (match_operand:XF 1 "register_operand" ""))]
14706   "TARGET_USE_FANCY_MATH_387
14707    && flag_unsafe_math_optimizations"
14708 {
14709   if (optimize_insn_for_size_p ())
14710     FAIL;
14711   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
14712   DONE;
14713 })
14714
14715 (define_expand "btrunc<mode>2"
14716   [(use (match_operand:MODEF 0 "register_operand" ""))
14717    (use (match_operand:MODEF 1 "register_operand" ""))]
14718   "(TARGET_USE_FANCY_MATH_387
14719     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14720         || TARGET_MIX_SSE_I387)
14721     && flag_unsafe_math_optimizations)
14722    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14723        && !flag_trapping_math)"
14724 {
14725   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14726       && !flag_trapping_math
14727       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14728     {
14729       if (TARGET_ROUND)
14730         emit_insn (gen_sse4_1_round<mode>2
14731                    (operands[0], operands[1], GEN_INT (0x03)));
14732       else if (optimize_insn_for_size_p ())
14733         FAIL;
14734       else if (TARGET_64BIT || (<MODE>mode != DFmode))
14735         ix86_expand_trunc (operand0, operand1);
14736       else
14737         ix86_expand_truncdf_32 (operand0, operand1);
14738     }
14739   else
14740     {
14741       rtx op0, op1;
14742
14743       if (optimize_insn_for_size_p ())
14744         FAIL;
14745
14746       op0 = gen_reg_rtx (XFmode);
14747       op1 = gen_reg_rtx (XFmode);
14748       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14749       emit_insn (gen_frndintxf2_trunc (op0, op1));
14750
14751       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14752     }
14753   DONE;
14754 })
14755
14756 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14757 (define_insn_and_split "frndintxf2_mask_pm"
14758   [(set (match_operand:XF 0 "register_operand" "")
14759         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14760          UNSPEC_FRNDINT_MASK_PM))
14761    (clobber (reg:CC FLAGS_REG))]
14762   "TARGET_USE_FANCY_MATH_387
14763    && flag_unsafe_math_optimizations
14764    && can_create_pseudo_p ()"
14765   "#"
14766   "&& 1"
14767   [(const_int 0)]
14768 {
14769   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
14770
14771   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14772   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
14773
14774   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
14775                                           operands[2], operands[3]));
14776   DONE;
14777 }
14778   [(set_attr "type" "frndint")
14779    (set_attr "i387_cw" "mask_pm")
14780    (set_attr "mode" "XF")])
14781
14782 (define_insn "frndintxf2_mask_pm_i387"
14783   [(set (match_operand:XF 0 "register_operand" "=f")
14784         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14785          UNSPEC_FRNDINT_MASK_PM))
14786    (use (match_operand:HI 2 "memory_operand" "m"))
14787    (use (match_operand:HI 3 "memory_operand" "m"))]
14788   "TARGET_USE_FANCY_MATH_387
14789    && flag_unsafe_math_optimizations"
14790   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
14791   [(set_attr "type" "frndint")
14792    (set_attr "i387_cw" "mask_pm")
14793    (set_attr "mode" "XF")])
14794
14795 (define_expand "nearbyintxf2"
14796   [(use (match_operand:XF 0 "register_operand" ""))
14797    (use (match_operand:XF 1 "register_operand" ""))]
14798   "TARGET_USE_FANCY_MATH_387
14799    && flag_unsafe_math_optimizations"
14800 {
14801   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
14802
14803   DONE;
14804 })
14805
14806 (define_expand "nearbyint<mode>2"
14807   [(use (match_operand:MODEF 0 "register_operand" ""))
14808    (use (match_operand:MODEF 1 "register_operand" ""))]
14809   "TARGET_USE_FANCY_MATH_387
14810    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14811        || TARGET_MIX_SSE_I387)
14812    && flag_unsafe_math_optimizations"
14813 {
14814   rtx op0 = gen_reg_rtx (XFmode);
14815   rtx op1 = gen_reg_rtx (XFmode);
14816
14817   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14818   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
14819
14820   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14821   DONE;
14822 })
14823
14824 (define_insn "fxam<mode>2_i387"
14825   [(set (match_operand:HI 0 "register_operand" "=a")
14826         (unspec:HI
14827           [(match_operand:X87MODEF 1 "register_operand" "f")]
14828           UNSPEC_FXAM))]
14829   "TARGET_USE_FANCY_MATH_387"
14830   "fxam\n\tfnstsw\t%0"
14831   [(set_attr "type" "multi")
14832    (set_attr "length" "4")
14833    (set_attr "unit" "i387")
14834    (set_attr "mode" "<MODE>")])
14835
14836 (define_insn_and_split "fxam<mode>2_i387_with_temp"
14837   [(set (match_operand:HI 0 "register_operand" "")
14838         (unspec:HI
14839           [(match_operand:MODEF 1 "memory_operand" "")]
14840           UNSPEC_FXAM_MEM))]
14841   "TARGET_USE_FANCY_MATH_387
14842    && can_create_pseudo_p ()"
14843   "#"
14844   "&& 1"
14845   [(set (match_dup 2)(match_dup 1))
14846    (set (match_dup 0)
14847         (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
14848 {
14849   operands[2] = gen_reg_rtx (<MODE>mode);
14850
14851   MEM_VOLATILE_P (operands[1]) = 1;
14852 }
14853   [(set_attr "type" "multi")
14854    (set_attr "unit" "i387")
14855    (set_attr "mode" "<MODE>")])
14856
14857 (define_expand "isinfxf2"
14858   [(use (match_operand:SI 0 "register_operand" ""))
14859    (use (match_operand:XF 1 "register_operand" ""))]
14860   "TARGET_USE_FANCY_MATH_387
14861    && TARGET_C99_FUNCTIONS"
14862 {
14863   rtx mask = GEN_INT (0x45);
14864   rtx val = GEN_INT (0x05);
14865
14866   rtx cond;
14867
14868   rtx scratch = gen_reg_rtx (HImode);
14869   rtx res = gen_reg_rtx (QImode);
14870
14871   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
14872
14873   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
14874   emit_insn (gen_cmpqi_ext_3 (scratch, val));
14875   cond = gen_rtx_fmt_ee (EQ, QImode,
14876                          gen_rtx_REG (CCmode, FLAGS_REG),
14877                          const0_rtx);
14878   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
14879   emit_insn (gen_zero_extendqisi2 (operands[0], res));
14880   DONE;
14881 })
14882
14883 (define_expand "isinf<mode>2"
14884   [(use (match_operand:SI 0 "register_operand" ""))
14885    (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
14886   "TARGET_USE_FANCY_MATH_387
14887    && TARGET_C99_FUNCTIONS
14888    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
14889 {
14890   rtx mask = GEN_INT (0x45);
14891   rtx val = GEN_INT (0x05);
14892
14893   rtx cond;
14894
14895   rtx scratch = gen_reg_rtx (HImode);
14896   rtx res = gen_reg_rtx (QImode);
14897
14898   /* Remove excess precision by forcing value through memory. */
14899   if (memory_operand (operands[1], VOIDmode))
14900     emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
14901   else
14902     {
14903       enum ix86_stack_slot slot = (virtuals_instantiated
14904                                    ? SLOT_TEMP
14905                                    : SLOT_VIRTUAL);
14906       rtx temp = assign_386_stack_local (<MODE>mode, slot);
14907
14908       emit_move_insn (temp, operands[1]);
14909       emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
14910     }
14911
14912   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
14913   emit_insn (gen_cmpqi_ext_3 (scratch, val));
14914   cond = gen_rtx_fmt_ee (EQ, QImode,
14915                          gen_rtx_REG (CCmode, FLAGS_REG),
14916                          const0_rtx);
14917   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
14918   emit_insn (gen_zero_extendqisi2 (operands[0], res));
14919   DONE;
14920 })
14921
14922 (define_expand "signbit<mode>2"
14923   [(use (match_operand:SI 0 "register_operand" ""))
14924    (use (match_operand:X87MODEF 1 "register_operand" ""))]
14925   "TARGET_USE_FANCY_MATH_387
14926    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
14927 {
14928   rtx mask = GEN_INT (0x0200);
14929
14930   rtx scratch = gen_reg_rtx (HImode);
14931
14932   emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
14933   emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
14934   DONE;
14935 })
14936 \f
14937 ;; Block operation instructions
14938
14939 (define_insn "cld"
14940   [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
14941   ""
14942   "cld"
14943   [(set_attr "length" "1")
14944    (set_attr "length_immediate" "0")
14945    (set_attr "modrm" "0")])
14946
14947 (define_expand "movmemsi"
14948   [(use (match_operand:BLK 0 "memory_operand" ""))
14949    (use (match_operand:BLK 1 "memory_operand" ""))
14950    (use (match_operand:SI 2 "nonmemory_operand" ""))
14951    (use (match_operand:SI 3 "const_int_operand" ""))
14952    (use (match_operand:SI 4 "const_int_operand" ""))
14953    (use (match_operand:SI 5 "const_int_operand" ""))]
14954   ""
14955 {
14956  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
14957                          operands[4], operands[5]))
14958    DONE;
14959  else
14960    FAIL;
14961 })
14962
14963 (define_expand "movmemdi"
14964   [(use (match_operand:BLK 0 "memory_operand" ""))
14965    (use (match_operand:BLK 1 "memory_operand" ""))
14966    (use (match_operand:DI 2 "nonmemory_operand" ""))
14967    (use (match_operand:DI 3 "const_int_operand" ""))
14968    (use (match_operand:SI 4 "const_int_operand" ""))
14969    (use (match_operand:SI 5 "const_int_operand" ""))]
14970   "TARGET_64BIT"
14971 {
14972  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
14973                          operands[4], operands[5]))
14974    DONE;
14975  else
14976    FAIL;
14977 })
14978
14979 ;; Most CPUs don't like single string operations
14980 ;; Handle this case here to simplify previous expander.
14981
14982 (define_expand "strmov"
14983   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
14984    (set (match_operand 1 "memory_operand" "") (match_dup 4))
14985    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
14986               (clobber (reg:CC FLAGS_REG))])
14987    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
14988               (clobber (reg:CC FLAGS_REG))])]
14989   ""
14990 {
14991   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
14992
14993   /* If .md ever supports :P for Pmode, these can be directly
14994      in the pattern above.  */
14995   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
14996   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
14997
14998   /* Can't use this if the user has appropriated esi or edi.  */
14999   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15000       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15001     {
15002       emit_insn (gen_strmov_singleop (operands[0], operands[1],
15003                                       operands[2], operands[3],
15004                                       operands[5], operands[6]));
15005       DONE;
15006     }
15007
15008   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15009 })
15010
15011 (define_expand "strmov_singleop"
15012   [(parallel [(set (match_operand 1 "memory_operand" "")
15013                    (match_operand 3 "memory_operand" ""))
15014               (set (match_operand 0 "register_operand" "")
15015                    (match_operand 4 "" ""))
15016               (set (match_operand 2 "register_operand" "")
15017                    (match_operand 5 "" ""))])]
15018   ""
15019   "ix86_current_function_needs_cld = 1;")
15020
15021 (define_insn "*strmovdi_rex_1"
15022   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15023         (mem:DI (match_operand:DI 3 "register_operand" "1")))
15024    (set (match_operand:DI 0 "register_operand" "=D")
15025         (plus:DI (match_dup 2)
15026                  (const_int 8)))
15027    (set (match_operand:DI 1 "register_operand" "=S")
15028         (plus:DI (match_dup 3)
15029                  (const_int 8)))]
15030   "TARGET_64BIT"
15031   "movsq"
15032   [(set_attr "type" "str")
15033    (set_attr "mode" "DI")
15034    (set_attr "memory" "both")])
15035
15036 (define_insn "*strmovsi_1"
15037   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
15038         (mem:SI (match_operand:SI 3 "register_operand" "1")))
15039    (set (match_operand:SI 0 "register_operand" "=D")
15040         (plus:SI (match_dup 2)
15041                  (const_int 4)))
15042    (set (match_operand:SI 1 "register_operand" "=S")
15043         (plus:SI (match_dup 3)
15044                  (const_int 4)))]
15045   "!TARGET_64BIT"
15046   "movs{l|d}"
15047   [(set_attr "type" "str")
15048    (set_attr "mode" "SI")
15049    (set_attr "memory" "both")])
15050
15051 (define_insn "*strmovsi_rex_1"
15052   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
15053         (mem:SI (match_operand:DI 3 "register_operand" "1")))
15054    (set (match_operand:DI 0 "register_operand" "=D")
15055         (plus:DI (match_dup 2)
15056                  (const_int 4)))
15057    (set (match_operand:DI 1 "register_operand" "=S")
15058         (plus:DI (match_dup 3)
15059                  (const_int 4)))]
15060   "TARGET_64BIT"
15061   "movs{l|d}"
15062   [(set_attr "type" "str")
15063    (set_attr "mode" "SI")
15064    (set_attr "memory" "both")])
15065
15066 (define_insn "*strmovhi_1"
15067   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
15068         (mem:HI (match_operand:SI 3 "register_operand" "1")))
15069    (set (match_operand:SI 0 "register_operand" "=D")
15070         (plus:SI (match_dup 2)
15071                  (const_int 2)))
15072    (set (match_operand:SI 1 "register_operand" "=S")
15073         (plus:SI (match_dup 3)
15074                  (const_int 2)))]
15075   "!TARGET_64BIT"
15076   "movsw"
15077   [(set_attr "type" "str")
15078    (set_attr "memory" "both")
15079    (set_attr "mode" "HI")])
15080
15081 (define_insn "*strmovhi_rex_1"
15082   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
15083         (mem:HI (match_operand:DI 3 "register_operand" "1")))
15084    (set (match_operand:DI 0 "register_operand" "=D")
15085         (plus:DI (match_dup 2)
15086                  (const_int 2)))
15087    (set (match_operand:DI 1 "register_operand" "=S")
15088         (plus:DI (match_dup 3)
15089                  (const_int 2)))]
15090   "TARGET_64BIT"
15091   "movsw"
15092   [(set_attr "type" "str")
15093    (set_attr "memory" "both")
15094    (set_attr "mode" "HI")])
15095
15096 (define_insn "*strmovqi_1"
15097   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
15098         (mem:QI (match_operand:SI 3 "register_operand" "1")))
15099    (set (match_operand:SI 0 "register_operand" "=D")
15100         (plus:SI (match_dup 2)
15101                  (const_int 1)))
15102    (set (match_operand:SI 1 "register_operand" "=S")
15103         (plus:SI (match_dup 3)
15104                  (const_int 1)))]
15105   "!TARGET_64BIT"
15106   "movsb"
15107   [(set_attr "type" "str")
15108    (set_attr "memory" "both")
15109    (set_attr "mode" "QI")])
15110
15111 (define_insn "*strmovqi_rex_1"
15112   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
15113         (mem:QI (match_operand:DI 3 "register_operand" "1")))
15114    (set (match_operand:DI 0 "register_operand" "=D")
15115         (plus:DI (match_dup 2)
15116                  (const_int 1)))
15117    (set (match_operand:DI 1 "register_operand" "=S")
15118         (plus:DI (match_dup 3)
15119                  (const_int 1)))]
15120   "TARGET_64BIT"
15121   "movsb"
15122   [(set_attr "type" "str")
15123    (set_attr "memory" "both")
15124    (set_attr "prefix_rex" "0")
15125    (set_attr "mode" "QI")])
15126
15127 (define_expand "rep_mov"
15128   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15129               (set (match_operand 0 "register_operand" "")
15130                    (match_operand 5 "" ""))
15131               (set (match_operand 2 "register_operand" "")
15132                    (match_operand 6 "" ""))
15133               (set (match_operand 1 "memory_operand" "")
15134                    (match_operand 3 "memory_operand" ""))
15135               (use (match_dup 4))])]
15136   ""
15137   "ix86_current_function_needs_cld = 1;")
15138
15139 (define_insn "*rep_movdi_rex64"
15140   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15141    (set (match_operand:DI 0 "register_operand" "=D")
15142         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15143                             (const_int 3))
15144                  (match_operand:DI 3 "register_operand" "0")))
15145    (set (match_operand:DI 1 "register_operand" "=S")
15146         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15147                  (match_operand:DI 4 "register_operand" "1")))
15148    (set (mem:BLK (match_dup 3))
15149         (mem:BLK (match_dup 4)))
15150    (use (match_dup 5))]
15151   "TARGET_64BIT"
15152   "rep{%;} movsq"
15153   [(set_attr "type" "str")
15154    (set_attr "prefix_rep" "1")
15155    (set_attr "memory" "both")
15156    (set_attr "mode" "DI")])
15157
15158 (define_insn "*rep_movsi"
15159   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
15160    (set (match_operand:SI 0 "register_operand" "=D")
15161         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
15162                             (const_int 2))
15163                  (match_operand:SI 3 "register_operand" "0")))
15164    (set (match_operand:SI 1 "register_operand" "=S")
15165         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
15166                  (match_operand:SI 4 "register_operand" "1")))
15167    (set (mem:BLK (match_dup 3))
15168         (mem:BLK (match_dup 4)))
15169    (use (match_dup 5))]
15170   "!TARGET_64BIT"
15171   "rep{%;} movs{l|d}"
15172   [(set_attr "type" "str")
15173    (set_attr "prefix_rep" "1")
15174    (set_attr "memory" "both")
15175    (set_attr "mode" "SI")])
15176
15177 (define_insn "*rep_movsi_rex64"
15178   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15179    (set (match_operand:DI 0 "register_operand" "=D")
15180         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15181                             (const_int 2))
15182                  (match_operand:DI 3 "register_operand" "0")))
15183    (set (match_operand:DI 1 "register_operand" "=S")
15184         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
15185                  (match_operand:DI 4 "register_operand" "1")))
15186    (set (mem:BLK (match_dup 3))
15187         (mem:BLK (match_dup 4)))
15188    (use (match_dup 5))]
15189   "TARGET_64BIT"
15190   "rep{%;} movs{l|d}"
15191   [(set_attr "type" "str")
15192    (set_attr "prefix_rep" "1")
15193    (set_attr "memory" "both")
15194    (set_attr "mode" "SI")])
15195
15196 (define_insn "*rep_movqi"
15197   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
15198    (set (match_operand:SI 0 "register_operand" "=D")
15199         (plus:SI (match_operand:SI 3 "register_operand" "0")
15200                  (match_operand:SI 5 "register_operand" "2")))
15201    (set (match_operand:SI 1 "register_operand" "=S")
15202         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
15203    (set (mem:BLK (match_dup 3))
15204         (mem:BLK (match_dup 4)))
15205    (use (match_dup 5))]
15206   "!TARGET_64BIT"
15207   "rep{%;} movsb"
15208   [(set_attr "type" "str")
15209    (set_attr "prefix_rep" "1")
15210    (set_attr "memory" "both")
15211    (set_attr "mode" "SI")])
15212
15213 (define_insn "*rep_movqi_rex64"
15214   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15215    (set (match_operand:DI 0 "register_operand" "=D")
15216         (plus:DI (match_operand:DI 3 "register_operand" "0")
15217                  (match_operand:DI 5 "register_operand" "2")))
15218    (set (match_operand:DI 1 "register_operand" "=S")
15219         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
15220    (set (mem:BLK (match_dup 3))
15221         (mem:BLK (match_dup 4)))
15222    (use (match_dup 5))]
15223   "TARGET_64BIT"
15224   "rep{%;} movsb"
15225   [(set_attr "type" "str")
15226    (set_attr "prefix_rep" "1")
15227    (set_attr "memory" "both")
15228    (set_attr "mode" "SI")])
15229
15230 (define_expand "setmemsi"
15231    [(use (match_operand:BLK 0 "memory_operand" ""))
15232     (use (match_operand:SI 1 "nonmemory_operand" ""))
15233     (use (match_operand 2 "const_int_operand" ""))
15234     (use (match_operand 3 "const_int_operand" ""))
15235     (use (match_operand:SI 4 "const_int_operand" ""))
15236     (use (match_operand:SI 5 "const_int_operand" ""))]
15237   ""
15238 {
15239  if (ix86_expand_setmem (operands[0], operands[1],
15240                          operands[2], operands[3],
15241                          operands[4], operands[5]))
15242    DONE;
15243  else
15244    FAIL;
15245 })
15246
15247 (define_expand "setmemdi"
15248    [(use (match_operand:BLK 0 "memory_operand" ""))
15249     (use (match_operand:DI 1 "nonmemory_operand" ""))
15250     (use (match_operand 2 "const_int_operand" ""))
15251     (use (match_operand 3 "const_int_operand" ""))
15252     (use (match_operand 4 "const_int_operand" ""))
15253     (use (match_operand 5 "const_int_operand" ""))]
15254   "TARGET_64BIT"
15255 {
15256  if (ix86_expand_setmem (operands[0], operands[1],
15257                          operands[2], operands[3],
15258                          operands[4], operands[5]))
15259    DONE;
15260  else
15261    FAIL;
15262 })
15263
15264 ;; Most CPUs don't like single string operations
15265 ;; Handle this case here to simplify previous expander.
15266
15267 (define_expand "strset"
15268   [(set (match_operand 1 "memory_operand" "")
15269         (match_operand 2 "register_operand" ""))
15270    (parallel [(set (match_operand 0 "register_operand" "")
15271                    (match_dup 3))
15272               (clobber (reg:CC FLAGS_REG))])]
15273   ""
15274 {
15275   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15276     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15277
15278   /* If .md ever supports :P for Pmode, this can be directly
15279      in the pattern above.  */
15280   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15281                               GEN_INT (GET_MODE_SIZE (GET_MODE
15282                                                       (operands[2]))));
15283   if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15284     {
15285       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15286                                       operands[3]));
15287       DONE;
15288     }
15289 })
15290
15291 (define_expand "strset_singleop"
15292   [(parallel [(set (match_operand 1 "memory_operand" "")
15293                    (match_operand 2 "register_operand" ""))
15294               (set (match_operand 0 "register_operand" "")
15295                    (match_operand 3 "" ""))])]
15296   ""
15297   "ix86_current_function_needs_cld = 1;")
15298
15299 (define_insn "*strsetdi_rex_1"
15300   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
15301         (match_operand:DI 2 "register_operand" "a"))
15302    (set (match_operand:DI 0 "register_operand" "=D")
15303         (plus:DI (match_dup 1)
15304                  (const_int 8)))]
15305   "TARGET_64BIT"
15306   "stosq"
15307   [(set_attr "type" "str")
15308    (set_attr "memory" "store")
15309    (set_attr "mode" "DI")])
15310
15311 (define_insn "*strsetsi_1"
15312   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
15313         (match_operand:SI 2 "register_operand" "a"))
15314    (set (match_operand:SI 0 "register_operand" "=D")
15315         (plus:SI (match_dup 1)
15316                  (const_int 4)))]
15317   "!TARGET_64BIT"
15318   "stos{l|d}"
15319   [(set_attr "type" "str")
15320    (set_attr "memory" "store")
15321    (set_attr "mode" "SI")])
15322
15323 (define_insn "*strsetsi_rex_1"
15324   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
15325         (match_operand:SI 2 "register_operand" "a"))
15326    (set (match_operand:DI 0 "register_operand" "=D")
15327         (plus:DI (match_dup 1)
15328                  (const_int 4)))]
15329   "TARGET_64BIT"
15330   "stos{l|d}"
15331   [(set_attr "type" "str")
15332    (set_attr "memory" "store")
15333    (set_attr "mode" "SI")])
15334
15335 (define_insn "*strsethi_1"
15336   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
15337         (match_operand:HI 2 "register_operand" "a"))
15338    (set (match_operand:SI 0 "register_operand" "=D")
15339         (plus:SI (match_dup 1)
15340                  (const_int 2)))]
15341   "!TARGET_64BIT"
15342   "stosw"
15343   [(set_attr "type" "str")
15344    (set_attr "memory" "store")
15345    (set_attr "mode" "HI")])
15346
15347 (define_insn "*strsethi_rex_1"
15348   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
15349         (match_operand:HI 2 "register_operand" "a"))
15350    (set (match_operand:DI 0 "register_operand" "=D")
15351         (plus:DI (match_dup 1)
15352                  (const_int 2)))]
15353   "TARGET_64BIT"
15354   "stosw"
15355   [(set_attr "type" "str")
15356    (set_attr "memory" "store")
15357    (set_attr "mode" "HI")])
15358
15359 (define_insn "*strsetqi_1"
15360   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
15361         (match_operand:QI 2 "register_operand" "a"))
15362    (set (match_operand:SI 0 "register_operand" "=D")
15363         (plus:SI (match_dup 1)
15364                  (const_int 1)))]
15365   "!TARGET_64BIT"
15366   "stosb"
15367   [(set_attr "type" "str")
15368    (set_attr "memory" "store")
15369    (set_attr "mode" "QI")])
15370
15371 (define_insn "*strsetqi_rex_1"
15372   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
15373         (match_operand:QI 2 "register_operand" "a"))
15374    (set (match_operand:DI 0 "register_operand" "=D")
15375         (plus:DI (match_dup 1)
15376                  (const_int 1)))]
15377   "TARGET_64BIT"
15378   "stosb"
15379   [(set_attr "type" "str")
15380    (set_attr "memory" "store")
15381    (set_attr "prefix_rex" "0")
15382    (set_attr "mode" "QI")])
15383
15384 (define_expand "rep_stos"
15385   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15386               (set (match_operand 0 "register_operand" "")
15387                    (match_operand 4 "" ""))
15388               (set (match_operand 2 "memory_operand" "") (const_int 0))
15389               (use (match_operand 3 "register_operand" ""))
15390               (use (match_dup 1))])]
15391   ""
15392   "ix86_current_function_needs_cld = 1;")
15393
15394 (define_insn "*rep_stosdi_rex64"
15395   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15396    (set (match_operand:DI 0 "register_operand" "=D")
15397         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15398                             (const_int 3))
15399                  (match_operand:DI 3 "register_operand" "0")))
15400    (set (mem:BLK (match_dup 3))
15401         (const_int 0))
15402    (use (match_operand:DI 2 "register_operand" "a"))
15403    (use (match_dup 4))]
15404   "TARGET_64BIT"
15405   "rep{%;} stosq"
15406   [(set_attr "type" "str")
15407    (set_attr "prefix_rep" "1")
15408    (set_attr "memory" "store")
15409    (set_attr "mode" "DI")])
15410
15411 (define_insn "*rep_stossi"
15412   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
15413    (set (match_operand:SI 0 "register_operand" "=D")
15414         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
15415                             (const_int 2))
15416                  (match_operand:SI 3 "register_operand" "0")))
15417    (set (mem:BLK (match_dup 3))
15418         (const_int 0))
15419    (use (match_operand:SI 2 "register_operand" "a"))
15420    (use (match_dup 4))]
15421   "!TARGET_64BIT"
15422   "rep{%;} stos{l|d}"
15423   [(set_attr "type" "str")
15424    (set_attr "prefix_rep" "1")
15425    (set_attr "memory" "store")
15426    (set_attr "mode" "SI")])
15427
15428 (define_insn "*rep_stossi_rex64"
15429   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15430    (set (match_operand:DI 0 "register_operand" "=D")
15431         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15432                             (const_int 2))
15433                  (match_operand:DI 3 "register_operand" "0")))
15434    (set (mem:BLK (match_dup 3))
15435         (const_int 0))
15436    (use (match_operand:SI 2 "register_operand" "a"))
15437    (use (match_dup 4))]
15438   "TARGET_64BIT"
15439   "rep{%;} stos{l|d}"
15440   [(set_attr "type" "str")
15441    (set_attr "prefix_rep" "1")
15442    (set_attr "memory" "store")
15443    (set_attr "mode" "SI")])
15444
15445 (define_insn "*rep_stosqi"
15446   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
15447    (set (match_operand:SI 0 "register_operand" "=D")
15448         (plus:SI (match_operand:SI 3 "register_operand" "0")
15449                  (match_operand:SI 4 "register_operand" "1")))
15450    (set (mem:BLK (match_dup 3))
15451         (const_int 0))
15452    (use (match_operand:QI 2 "register_operand" "a"))
15453    (use (match_dup 4))]
15454   "!TARGET_64BIT"
15455   "rep{%;} stosb"
15456   [(set_attr "type" "str")
15457    (set_attr "prefix_rep" "1")
15458    (set_attr "memory" "store")
15459    (set_attr "mode" "QI")])
15460
15461 (define_insn "*rep_stosqi_rex64"
15462   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15463    (set (match_operand:DI 0 "register_operand" "=D")
15464         (plus:DI (match_operand:DI 3 "register_operand" "0")
15465                  (match_operand:DI 4 "register_operand" "1")))
15466    (set (mem:BLK (match_dup 3))
15467         (const_int 0))
15468    (use (match_operand:QI 2 "register_operand" "a"))
15469    (use (match_dup 4))]
15470   "TARGET_64BIT"
15471   "rep{%;} stosb"
15472   [(set_attr "type" "str")
15473    (set_attr "prefix_rep" "1")
15474    (set_attr "memory" "store")
15475    (set_attr "prefix_rex" "0")
15476    (set_attr "mode" "QI")])
15477
15478 (define_expand "cmpstrnsi"
15479   [(set (match_operand:SI 0 "register_operand" "")
15480         (compare:SI (match_operand:BLK 1 "general_operand" "")
15481                     (match_operand:BLK 2 "general_operand" "")))
15482    (use (match_operand 3 "general_operand" ""))
15483    (use (match_operand 4 "immediate_operand" ""))]
15484   ""
15485 {
15486   rtx addr1, addr2, out, outlow, count, countreg, align;
15487
15488   if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
15489     FAIL;
15490
15491   /* Can't use this if the user has appropriated esi or edi.  */
15492   if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
15493     FAIL;
15494
15495   out = operands[0];
15496   if (!REG_P (out))
15497     out = gen_reg_rtx (SImode);
15498
15499   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
15500   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
15501   if (addr1 != XEXP (operands[1], 0))
15502     operands[1] = replace_equiv_address_nv (operands[1], addr1);
15503   if (addr2 != XEXP (operands[2], 0))
15504     operands[2] = replace_equiv_address_nv (operands[2], addr2);
15505
15506   count = operands[3];
15507   countreg = ix86_zero_extend_to_Pmode (count);
15508
15509   /* %%% Iff we are testing strict equality, we can use known alignment
15510      to good advantage.  This may be possible with combine, particularly
15511      once cc0 is dead.  */
15512   align = operands[4];
15513
15514   if (CONST_INT_P (count))
15515     {
15516       if (INTVAL (count) == 0)
15517         {
15518           emit_move_insn (operands[0], const0_rtx);
15519           DONE;
15520         }
15521       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
15522                                      operands[1], operands[2]));
15523     }
15524   else
15525     {
15526       rtx (*gen_cmp) (rtx, rtx);
15527
15528       gen_cmp = (TARGET_64BIT
15529                  ? gen_cmpdi_1 : gen_cmpsi_1);
15530
15531       emit_insn (gen_cmp (countreg, countreg));
15532       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
15533                                   operands[1], operands[2]));
15534     }
15535
15536   outlow = gen_lowpart (QImode, out);
15537   emit_insn (gen_cmpintqi (outlow));
15538   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
15539
15540   if (operands[0] != out)
15541     emit_move_insn (operands[0], out);
15542
15543   DONE;
15544 })
15545
15546 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
15547
15548 (define_expand "cmpintqi"
15549   [(set (match_dup 1)
15550         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15551    (set (match_dup 2)
15552         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15553    (parallel [(set (match_operand:QI 0 "register_operand" "")
15554                    (minus:QI (match_dup 1)
15555                              (match_dup 2)))
15556               (clobber (reg:CC FLAGS_REG))])]
15557   ""
15558   "operands[1] = gen_reg_rtx (QImode);
15559    operands[2] = gen_reg_rtx (QImode);")
15560
15561 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
15562 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
15563
15564 (define_expand "cmpstrnqi_nz_1"
15565   [(parallel [(set (reg:CC FLAGS_REG)
15566                    (compare:CC (match_operand 4 "memory_operand" "")
15567                                (match_operand 5 "memory_operand" "")))
15568               (use (match_operand 2 "register_operand" ""))
15569               (use (match_operand:SI 3 "immediate_operand" ""))
15570               (clobber (match_operand 0 "register_operand" ""))
15571               (clobber (match_operand 1 "register_operand" ""))
15572               (clobber (match_dup 2))])]
15573   ""
15574   "ix86_current_function_needs_cld = 1;")
15575
15576 (define_insn "*cmpstrnqi_nz_1"
15577   [(set (reg:CC FLAGS_REG)
15578         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
15579                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
15580    (use (match_operand:SI 6 "register_operand" "2"))
15581    (use (match_operand:SI 3 "immediate_operand" "i"))
15582    (clobber (match_operand:SI 0 "register_operand" "=S"))
15583    (clobber (match_operand:SI 1 "register_operand" "=D"))
15584    (clobber (match_operand:SI 2 "register_operand" "=c"))]
15585   "!TARGET_64BIT"
15586   "repz{%;} cmpsb"
15587   [(set_attr "type" "str")
15588    (set_attr "mode" "QI")
15589    (set_attr "prefix_rep" "1")])
15590
15591 (define_insn "*cmpstrnqi_nz_rex_1"
15592   [(set (reg:CC FLAGS_REG)
15593         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
15594                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
15595    (use (match_operand:DI 6 "register_operand" "2"))
15596    (use (match_operand:SI 3 "immediate_operand" "i"))
15597    (clobber (match_operand:DI 0 "register_operand" "=S"))
15598    (clobber (match_operand:DI 1 "register_operand" "=D"))
15599    (clobber (match_operand:DI 2 "register_operand" "=c"))]
15600   "TARGET_64BIT"
15601   "repz{%;} cmpsb"
15602   [(set_attr "type" "str")
15603    (set_attr "mode" "QI")
15604    (set_attr "prefix_rex" "0")
15605    (set_attr "prefix_rep" "1")])
15606
15607 ;; The same, but the count is not known to not be zero.
15608
15609 (define_expand "cmpstrnqi_1"
15610   [(parallel [(set (reg:CC FLAGS_REG)
15611                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
15612                                      (const_int 0))
15613                   (compare:CC (match_operand 4 "memory_operand" "")
15614                               (match_operand 5 "memory_operand" ""))
15615                   (const_int 0)))
15616               (use (match_operand:SI 3 "immediate_operand" ""))
15617               (use (reg:CC FLAGS_REG))
15618               (clobber (match_operand 0 "register_operand" ""))
15619               (clobber (match_operand 1 "register_operand" ""))
15620               (clobber (match_dup 2))])]
15621   ""
15622   "ix86_current_function_needs_cld = 1;")
15623
15624 (define_insn "*cmpstrnqi_1"
15625   [(set (reg:CC FLAGS_REG)
15626         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
15627                              (const_int 0))
15628           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
15629                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
15630           (const_int 0)))
15631    (use (match_operand:SI 3 "immediate_operand" "i"))
15632    (use (reg:CC FLAGS_REG))
15633    (clobber (match_operand:SI 0 "register_operand" "=S"))
15634    (clobber (match_operand:SI 1 "register_operand" "=D"))
15635    (clobber (match_operand:SI 2 "register_operand" "=c"))]
15636   "!TARGET_64BIT"
15637   "repz{%;} cmpsb"
15638   [(set_attr "type" "str")
15639    (set_attr "mode" "QI")
15640    (set_attr "prefix_rep" "1")])
15641
15642 (define_insn "*cmpstrnqi_rex_1"
15643   [(set (reg:CC FLAGS_REG)
15644         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
15645                              (const_int 0))
15646           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
15647                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
15648           (const_int 0)))
15649    (use (match_operand:SI 3 "immediate_operand" "i"))
15650    (use (reg:CC FLAGS_REG))
15651    (clobber (match_operand:DI 0 "register_operand" "=S"))
15652    (clobber (match_operand:DI 1 "register_operand" "=D"))
15653    (clobber (match_operand:DI 2 "register_operand" "=c"))]
15654   "TARGET_64BIT"
15655   "repz{%;} cmpsb"
15656   [(set_attr "type" "str")
15657    (set_attr "mode" "QI")
15658    (set_attr "prefix_rex" "0")
15659    (set_attr "prefix_rep" "1")])
15660
15661 (define_expand "strlensi"
15662   [(set (match_operand:SI 0 "register_operand" "")
15663         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
15664                     (match_operand:QI 2 "immediate_operand" "")
15665                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
15666   ""
15667 {
15668  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
15669    DONE;
15670  else
15671    FAIL;
15672 })
15673
15674 (define_expand "strlendi"
15675   [(set (match_operand:DI 0 "register_operand" "")
15676         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
15677                     (match_operand:QI 2 "immediate_operand" "")
15678                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
15679   ""
15680 {
15681  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
15682    DONE;
15683  else
15684    FAIL;
15685 })
15686
15687 (define_expand "strlenqi_1"
15688   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
15689               (clobber (match_operand 1 "register_operand" ""))
15690               (clobber (reg:CC FLAGS_REG))])]
15691   ""
15692   "ix86_current_function_needs_cld = 1;")
15693
15694 (define_insn "*strlenqi_1"
15695   [(set (match_operand:SI 0 "register_operand" "=&c")
15696         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
15697                     (match_operand:QI 2 "register_operand" "a")
15698                     (match_operand:SI 3 "immediate_operand" "i")
15699                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
15700    (clobber (match_operand:SI 1 "register_operand" "=D"))
15701    (clobber (reg:CC FLAGS_REG))]
15702   "!TARGET_64BIT"
15703   "repnz{%;} scasb"
15704   [(set_attr "type" "str")
15705    (set_attr "mode" "QI")
15706    (set_attr "prefix_rep" "1")])
15707
15708 (define_insn "*strlenqi_rex_1"
15709   [(set (match_operand:DI 0 "register_operand" "=&c")
15710         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
15711                     (match_operand:QI 2 "register_operand" "a")
15712                     (match_operand:DI 3 "immediate_operand" "i")
15713                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
15714    (clobber (match_operand:DI 1 "register_operand" "=D"))
15715    (clobber (reg:CC FLAGS_REG))]
15716   "TARGET_64BIT"
15717   "repnz{%;} scasb"
15718   [(set_attr "type" "str")
15719    (set_attr "mode" "QI")
15720    (set_attr "prefix_rex" "0")
15721    (set_attr "prefix_rep" "1")])
15722
15723 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
15724 ;; handled in combine, but it is not currently up to the task.
15725 ;; When used for their truth value, the cmpstrn* expanders generate
15726 ;; code like this:
15727 ;;
15728 ;;   repz cmpsb
15729 ;;   seta       %al
15730 ;;   setb       %dl
15731 ;;   cmpb       %al, %dl
15732 ;;   jcc        label
15733 ;;
15734 ;; The intermediate three instructions are unnecessary.
15735
15736 ;; This one handles cmpstrn*_nz_1...
15737 (define_peephole2
15738   [(parallel[
15739      (set (reg:CC FLAGS_REG)
15740           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15741                       (mem:BLK (match_operand 5 "register_operand" ""))))
15742      (use (match_operand 6 "register_operand" ""))
15743      (use (match_operand:SI 3 "immediate_operand" ""))
15744      (clobber (match_operand 0 "register_operand" ""))
15745      (clobber (match_operand 1 "register_operand" ""))
15746      (clobber (match_operand 2 "register_operand" ""))])
15747    (set (match_operand:QI 7 "register_operand" "")
15748         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15749    (set (match_operand:QI 8 "register_operand" "")
15750         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15751    (set (reg FLAGS_REG)
15752         (compare (match_dup 7) (match_dup 8)))
15753   ]
15754   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15755   [(parallel[
15756      (set (reg:CC FLAGS_REG)
15757           (compare:CC (mem:BLK (match_dup 4))
15758                       (mem:BLK (match_dup 5))))
15759      (use (match_dup 6))
15760      (use (match_dup 3))
15761      (clobber (match_dup 0))
15762      (clobber (match_dup 1))
15763      (clobber (match_dup 2))])])
15764
15765 ;; ...and this one handles cmpstrn*_1.
15766 (define_peephole2
15767   [(parallel[
15768      (set (reg:CC FLAGS_REG)
15769           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
15770                                (const_int 0))
15771             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15772                         (mem:BLK (match_operand 5 "register_operand" "")))
15773             (const_int 0)))
15774      (use (match_operand:SI 3 "immediate_operand" ""))
15775      (use (reg:CC FLAGS_REG))
15776      (clobber (match_operand 0 "register_operand" ""))
15777      (clobber (match_operand 1 "register_operand" ""))
15778      (clobber (match_operand 2 "register_operand" ""))])
15779    (set (match_operand:QI 7 "register_operand" "")
15780         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15781    (set (match_operand:QI 8 "register_operand" "")
15782         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15783    (set (reg FLAGS_REG)
15784         (compare (match_dup 7) (match_dup 8)))
15785   ]
15786   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15787   [(parallel[
15788      (set (reg:CC FLAGS_REG)
15789           (if_then_else:CC (ne (match_dup 6)
15790                                (const_int 0))
15791             (compare:CC (mem:BLK (match_dup 4))
15792                         (mem:BLK (match_dup 5)))
15793             (const_int 0)))
15794      (use (match_dup 3))
15795      (use (reg:CC FLAGS_REG))
15796      (clobber (match_dup 0))
15797      (clobber (match_dup 1))
15798      (clobber (match_dup 2))])])
15799 \f
15800 ;; Conditional move instructions.
15801
15802 (define_expand "mov<mode>cc"
15803   [(set (match_operand:SWIM 0 "register_operand" "")
15804         (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator" "")
15805                            (match_operand:SWIM 2 "general_operand" "")
15806                            (match_operand:SWIM 3 "general_operand" "")))]
15807   ""
15808   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
15809
15810 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
15811 ;; the register first winds up with `sbbl $0,reg', which is also weird.
15812 ;; So just document what we're doing explicitly.
15813
15814 (define_expand "x86_mov<mode>cc_0_m1"
15815   [(parallel
15816     [(set (match_operand:SWI48 0 "register_operand" "")
15817           (if_then_else:SWI48
15818             (match_operator:SWI48 2 "ix86_carry_flag_operator"
15819              [(match_operand 1 "flags_reg_operand" "")
15820               (const_int 0)])
15821             (const_int -1)
15822             (const_int 0)))
15823      (clobber (reg:CC FLAGS_REG))])]
15824   ""
15825   "")
15826
15827 (define_insn "*x86_mov<mode>cc_0_m1"
15828   [(set (match_operand:SWI48 0 "register_operand" "=r")
15829         (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
15830                              [(reg FLAGS_REG) (const_int 0)])
15831           (const_int -1)
15832           (const_int 0)))
15833    (clobber (reg:CC FLAGS_REG))]
15834   ""
15835   "sbb{<imodesuffix>}\t%0, %0"
15836   ; Since we don't have the proper number of operands for an alu insn,
15837   ; fill in all the blanks.
15838   [(set_attr "type" "alu")
15839    (set_attr "use_carry" "1")
15840    (set_attr "pent_pair" "pu")
15841    (set_attr "memory" "none")
15842    (set_attr "imm_disp" "false")
15843    (set_attr "mode" "<MODE>")
15844    (set_attr "length_immediate" "0")])
15845
15846 (define_insn "*x86_mov<mode>cc_0_m1_se"
15847   [(set (match_operand:SWI48 0 "register_operand" "=r")
15848         (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
15849                              [(reg FLAGS_REG) (const_int 0)])
15850                             (const_int 1)
15851                             (const_int 0)))
15852    (clobber (reg:CC FLAGS_REG))]
15853   ""
15854   "sbb{<imodesuffix>}\t%0, %0"
15855   [(set_attr "type" "alu")
15856    (set_attr "use_carry" "1")
15857    (set_attr "pent_pair" "pu")
15858    (set_attr "memory" "none")
15859    (set_attr "imm_disp" "false")
15860    (set_attr "mode" "<MODE>")
15861    (set_attr "length_immediate" "0")])
15862
15863 (define_insn "*x86_mov<mode>cc_0_m1_neg"
15864   [(set (match_operand:SWI48 0 "register_operand" "=r")
15865         (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
15866                     [(reg FLAGS_REG) (const_int 0)])))]
15867   ""
15868   "sbb{<imodesuffix>}\t%0, %0"
15869   [(set_attr "type" "alu")
15870    (set_attr "use_carry" "1")
15871    (set_attr "pent_pair" "pu")
15872    (set_attr "memory" "none")
15873    (set_attr "imm_disp" "false")
15874    (set_attr "mode" "<MODE>")
15875    (set_attr "length_immediate" "0")])
15876
15877 (define_insn "*mov<mode>cc_noc"
15878   [(set (match_operand:SWI248 0 "register_operand" "=r,r")
15879         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
15880                                [(reg FLAGS_REG) (const_int 0)])
15881           (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
15882           (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
15883   "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
15884   "@
15885    cmov%O2%C1\t{%2, %0|%0, %2}
15886    cmov%O2%c1\t{%3, %0|%0, %3}"
15887   [(set_attr "type" "icmov")
15888    (set_attr "mode" "<MODE>")])
15889
15890 (define_insn_and_split "*movqicc_noc"
15891   [(set (match_operand:QI 0 "register_operand" "=r,r")
15892         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
15893                            [(match_operand 4 "flags_reg_operand" "")
15894                             (const_int 0)])
15895                       (match_operand:QI 2 "register_operand" "r,0")
15896                       (match_operand:QI 3 "register_operand" "0,r")))]
15897   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
15898   "#"
15899   "&& reload_completed"
15900   [(set (match_dup 0)
15901         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
15902                       (match_dup 2)
15903                       (match_dup 3)))]
15904   "operands[0] = gen_lowpart (SImode, operands[0]);
15905    operands[2] = gen_lowpart (SImode, operands[2]);
15906    operands[3] = gen_lowpart (SImode, operands[3]);"
15907   [(set_attr "type" "icmov")
15908    (set_attr "mode" "SI")])
15909
15910 (define_expand "mov<mode>cc"
15911   [(set (match_operand:X87MODEF 0 "register_operand" "")
15912         (if_then_else:X87MODEF
15913           (match_operand 1 "ix86_fp_comparison_operator" "")
15914           (match_operand:X87MODEF 2 "register_operand" "")
15915           (match_operand:X87MODEF 3 "register_operand" "")))]
15916   "(TARGET_80387 && TARGET_CMOVE)
15917    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15918   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
15919
15920 (define_insn "*movsfcc_1_387"
15921   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
15922         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
15923                                 [(reg FLAGS_REG) (const_int 0)])
15924                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
15925                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
15926   "TARGET_80387 && TARGET_CMOVE
15927    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
15928   "@
15929    fcmov%F1\t{%2, %0|%0, %2}
15930    fcmov%f1\t{%3, %0|%0, %3}
15931    cmov%O2%C1\t{%2, %0|%0, %2}
15932    cmov%O2%c1\t{%3, %0|%0, %3}"
15933   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
15934    (set_attr "mode" "SF,SF,SI,SI")])
15935
15936 (define_insn "*movdfcc_1"
15937   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
15938         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
15939                                 [(reg FLAGS_REG) (const_int 0)])
15940                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
15941                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
15942   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
15943    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
15944   "@
15945    fcmov%F1\t{%2, %0|%0, %2}
15946    fcmov%f1\t{%3, %0|%0, %3}
15947    #
15948    #"
15949   [(set_attr "type" "fcmov,fcmov,multi,multi")
15950    (set_attr "mode" "DF")])
15951
15952 (define_insn "*movdfcc_1_rex64"
15953   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
15954         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
15955                                 [(reg FLAGS_REG) (const_int 0)])
15956                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
15957                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
15958   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
15959    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
15960   "@
15961    fcmov%F1\t{%2, %0|%0, %2}
15962    fcmov%f1\t{%3, %0|%0, %3}
15963    cmov%O2%C1\t{%2, %0|%0, %2}
15964    cmov%O2%c1\t{%3, %0|%0, %3}"
15965   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
15966    (set_attr "mode" "DF")])
15967
15968 (define_split
15969   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
15970         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
15971                                 [(match_operand 4 "flags_reg_operand" "")
15972                                  (const_int 0)])
15973                       (match_operand:DF 2 "nonimmediate_operand" "")
15974                       (match_operand:DF 3 "nonimmediate_operand" "")))]
15975   "!TARGET_64BIT && reload_completed"
15976   [(set (match_dup 2)
15977         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
15978                       (match_dup 5)
15979                       (match_dup 6)))
15980    (set (match_dup 3)
15981         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
15982                       (match_dup 7)
15983                       (match_dup 8)))]
15984 {
15985   split_di (&operands[2], 2, &operands[5], &operands[7]);
15986   split_di (&operands[0], 1, &operands[2], &operands[3]);
15987 })
15988
15989 (define_insn "*movxfcc_1"
15990   [(set (match_operand:XF 0 "register_operand" "=f,f")
15991         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
15992                                 [(reg FLAGS_REG) (const_int 0)])
15993                       (match_operand:XF 2 "register_operand" "f,0")
15994                       (match_operand:XF 3 "register_operand" "0,f")))]
15995   "TARGET_80387 && TARGET_CMOVE"
15996   "@
15997    fcmov%F1\t{%2, %0|%0, %2}
15998    fcmov%f1\t{%3, %0|%0, %3}"
15999   [(set_attr "type" "fcmov")
16000    (set_attr "mode" "XF")])
16001
16002 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16003 ;; the scalar versions to have only XMM registers as operands.
16004
16005 ;; XOP conditional move
16006 (define_insn "*xop_pcmov_<mode>"
16007   [(set (match_operand:MODEF 0 "register_operand" "=x")
16008         (if_then_else:MODEF
16009           (match_operand:MODEF 1 "register_operand" "x")
16010           (match_operand:MODEF 2 "register_operand" "x")
16011           (match_operand:MODEF 3 "register_operand" "x")))]
16012   "TARGET_XOP"
16013   "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16014   [(set_attr "type" "sse4arg")])
16015
16016 ;; These versions of the min/max patterns are intentionally ignorant of
16017 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16018 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16019 ;; are undefined in this condition, we're certain this is correct.
16020
16021 (define_insn "*avx_<code><mode>3"
16022   [(set (match_operand:MODEF 0 "register_operand" "=x")
16023         (smaxmin:MODEF
16024           (match_operand:MODEF 1 "nonimmediate_operand" "%x")
16025           (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
16026   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16027   "v<maxmin_float>s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16028   [(set_attr "type" "sseadd")
16029    (set_attr "prefix" "vex")
16030    (set_attr "mode" "<MODE>")])
16031
16032 (define_insn "<code><mode>3"
16033   [(set (match_operand:MODEF 0 "register_operand" "=x")
16034         (smaxmin:MODEF
16035           (match_operand:MODEF 1 "nonimmediate_operand" "%0")
16036           (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
16037   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16038   "<maxmin_float>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
16039   [(set_attr "type" "sseadd")
16040    (set_attr "mode" "<MODE>")])
16041
16042 ;; These versions of the min/max patterns implement exactly the operations
16043 ;;   min = (op1 < op2 ? op1 : op2)
16044 ;;   max = (!(op1 < op2) ? op1 : op2)
16045 ;; Their operands are not commutative, and thus they may be used in the
16046 ;; presence of -0.0 and NaN.
16047
16048 (define_insn "*avx_ieee_smin<mode>3"
16049   [(set (match_operand:MODEF 0 "register_operand" "=x")
16050         (unspec:MODEF
16051           [(match_operand:MODEF 1 "register_operand" "x")
16052            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16053          UNSPEC_IEEE_MIN))]
16054   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16055   "vmins<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16056   [(set_attr "type" "sseadd")
16057    (set_attr "prefix" "vex")
16058    (set_attr "mode" "<MODE>")])
16059
16060 (define_insn "*ieee_smin<mode>3"
16061   [(set (match_operand:MODEF 0 "register_operand" "=x")
16062         (unspec:MODEF
16063           [(match_operand:MODEF 1 "register_operand" "0")
16064            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16065          UNSPEC_IEEE_MIN))]
16066   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16067   "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
16068   [(set_attr "type" "sseadd")
16069    (set_attr "mode" "<MODE>")])
16070
16071 (define_insn "*avx_ieee_smax<mode>3"
16072   [(set (match_operand:MODEF 0 "register_operand" "=x")
16073         (unspec:MODEF
16074           [(match_operand:MODEF 1 "register_operand" "0")
16075            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16076          UNSPEC_IEEE_MAX))]
16077   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16078   "vmaxs<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16079   [(set_attr "type" "sseadd")
16080    (set_attr "prefix" "vex")
16081    (set_attr "mode" "<MODE>")])
16082
16083 (define_insn "*ieee_smax<mode>3"
16084   [(set (match_operand:MODEF 0 "register_operand" "=x")
16085         (unspec:MODEF
16086           [(match_operand:MODEF 1 "register_operand" "0")
16087            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16088          UNSPEC_IEEE_MAX))]
16089   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16090   "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
16091   [(set_attr "type" "sseadd")
16092    (set_attr "mode" "<MODE>")])
16093
16094 ;; Make two stack loads independent:
16095 ;;   fld aa              fld aa
16096 ;;   fld %st(0)     ->   fld bb
16097 ;;   fmul bb             fmul %st(1), %st
16098 ;;
16099 ;; Actually we only match the last two instructions for simplicity.
16100 (define_peephole2
16101   [(set (match_operand 0 "fp_register_operand" "")
16102         (match_operand 1 "fp_register_operand" ""))
16103    (set (match_dup 0)
16104         (match_operator 2 "binary_fp_operator"
16105            [(match_dup 0)
16106             (match_operand 3 "memory_operand" "")]))]
16107   "REGNO (operands[0]) != REGNO (operands[1])"
16108   [(set (match_dup 0) (match_dup 3))
16109    (set (match_dup 0) (match_dup 4))]
16110
16111   ;; The % modifier is not operational anymore in peephole2's, so we have to
16112   ;; swap the operands manually in the case of addition and multiplication.
16113   "if (COMMUTATIVE_ARITH_P (operands[2]))
16114      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16115                                    GET_MODE (operands[2]),
16116                                    operands[0], operands[1]);
16117    else
16118      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16119                                    GET_MODE (operands[2]),
16120                                    operands[1], operands[0]);")
16121
16122 ;; Conditional addition patterns
16123 (define_expand "add<mode>cc"
16124   [(match_operand:SWI 0 "register_operand" "")
16125    (match_operand 1 "ordered_comparison_operator" "")
16126    (match_operand:SWI 2 "register_operand" "")
16127    (match_operand:SWI 3 "const_int_operand" "")]
16128   ""
16129   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16130 \f
16131 ;; Misc patterns (?)
16132
16133 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16134 ;; Otherwise there will be nothing to keep
16135 ;;
16136 ;; [(set (reg ebp) (reg esp))]
16137 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16138 ;;  (clobber (eflags)]
16139 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16140 ;;
16141 ;; in proper program order.
16142
16143 (define_insn "pro_epilogue_adjust_stack_<mode>_1"
16144   [(set (match_operand:P 0 "register_operand" "=r,r")
16145         (plus:P (match_operand:P 1 "register_operand" "0,r")
16146                 (match_operand:P 2 "<immediate_operand>" "<i>,<i>")))
16147    (clobber (reg:CC FLAGS_REG))
16148    (clobber (mem:BLK (scratch)))]
16149   ""
16150 {
16151   switch (get_attr_type (insn))
16152     {
16153     case TYPE_IMOV:
16154       return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16155
16156     case TYPE_ALU:
16157       gcc_assert (rtx_equal_p (operands[0], operands[1]));
16158       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16159         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16160
16161       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16162
16163     default:
16164       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16165       return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
16166     }
16167 }
16168   [(set (attr "type")
16169         (cond [(and (eq_attr "alternative" "0")
16170                     (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
16171                  (const_string "alu")
16172                (match_operand:<MODE> 2 "const0_operand" "")
16173                  (const_string "imov")
16174               ]
16175               (const_string "lea")))
16176    (set (attr "length_immediate")
16177         (cond [(eq_attr "type" "imov")
16178                  (const_string "0")
16179                (and (eq_attr "type" "alu")
16180                     (match_operand 2 "const128_operand" ""))
16181                  (const_string "1")
16182               ]
16183               (const_string "*")))
16184    (set_attr "mode" "<MODE>")])
16185
16186 (define_insn "pro_epilogue_adjust_stack_di_2"
16187   [(set (match_operand:DI 0 "register_operand" "=r,r")
16188         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
16189                  (match_operand:DI 3 "immediate_operand" "i,i")))
16190    (use (match_operand:DI 2 "register_operand" "r,l"))
16191    (clobber (reg:CC FLAGS_REG))
16192    (clobber (mem:BLK (scratch)))]
16193   "TARGET_64BIT"
16194 {
16195   switch (get_attr_type (insn))
16196     {
16197     case TYPE_ALU:
16198       return "add{q}\t{%2, %0|%0, %2}";
16199
16200     case TYPE_LEA:
16201       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
16202       return "lea{q}\t{%a2, %0|%0, %a2}";
16203
16204     default:
16205       gcc_unreachable ();
16206     }
16207 }
16208   [(set_attr "type" "alu,lea")
16209    (set_attr "mode" "DI")])
16210
16211 (define_insn "allocate_stack_worker_32"
16212   [(set (match_operand:SI 0 "register_operand" "=a")
16213         (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")]
16214                             UNSPECV_STACK_PROBE))
16215    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 1)))
16216    (clobber (reg:CC FLAGS_REG))]
16217   "!TARGET_64BIT && ix86_target_stack_probe ()"
16218   "call\t___chkstk"
16219   [(set_attr "type" "multi")
16220    (set_attr "length" "5")])
16221
16222 (define_insn "allocate_stack_worker_64"
16223   [(set (match_operand:DI 0 "register_operand" "=a")
16224         (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "0")]
16225                             UNSPECV_STACK_PROBE))
16226    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 1)))
16227    (clobber (reg:DI R10_REG))
16228    (clobber (reg:DI R11_REG))
16229    (clobber (reg:CC FLAGS_REG))]
16230   "TARGET_64BIT && ix86_target_stack_probe ()"
16231   "call\t___chkstk"
16232   [(set_attr "type" "multi")
16233    (set_attr "length" "5")])
16234
16235 (define_expand "allocate_stack"
16236   [(match_operand 0 "register_operand" "")
16237    (match_operand 1 "general_operand" "")]
16238   "ix86_target_stack_probe ()"
16239 {
16240   rtx x;
16241
16242 #ifndef CHECK_STACK_LIMIT
16243 #define CHECK_STACK_LIMIT 0
16244 #endif
16245
16246   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16247       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16248     {
16249       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16250                                stack_pointer_rtx, 0, OPTAB_DIRECT);
16251       if (x != stack_pointer_rtx)
16252         emit_move_insn (stack_pointer_rtx, x);
16253     }
16254   else
16255     {
16256       rtx (*gen_allocate_stack_worker) (rtx, rtx);
16257
16258       if (TARGET_64BIT)
16259         gen_allocate_stack_worker = gen_allocate_stack_worker_64;
16260       else
16261         gen_allocate_stack_worker = gen_allocate_stack_worker_32;
16262
16263       x = copy_to_mode_reg (Pmode, operands[1]);
16264       emit_insn (gen_allocate_stack_worker (x, x));
16265     }
16266
16267   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16268   DONE;
16269 })
16270
16271 ;; Use IOR for stack probes, this is shorter.
16272 (define_expand "probe_stack"
16273   [(match_operand 0 "memory_operand" "")]
16274   ""
16275 {
16276   rtx (*gen_ior3) (rtx, rtx, rtx);
16277
16278   gen_ior3 = (GET_MODE (operands[0]) == DImode
16279               ? gen_iordi3 : gen_iorsi3);
16280
16281   emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16282   DONE;
16283 })
16284
16285 (define_insn "adjust_stack_and_probe<mode>"
16286   [(set (match_operand:P 0 "register_operand" "=r")
16287         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16288                             UNSPECV_PROBE_STACK_RANGE))
16289    (set (reg:P SP_REG)
16290         (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16291    (clobber (reg:CC FLAGS_REG))
16292    (clobber (mem:BLK (scratch)))]
16293   ""
16294   "* return output_adjust_stack_and_probe (operands[0]);"
16295   [(set_attr "type" "multi")])
16296
16297 (define_insn "probe_stack_range<mode>"
16298   [(set (match_operand:P 0 "register_operand" "=r")
16299         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16300                             (match_operand:P 2 "const_int_operand" "n")]
16301                             UNSPECV_PROBE_STACK_RANGE))
16302    (clobber (reg:CC FLAGS_REG))]
16303   ""
16304   "* return output_probe_stack_range (operands[0], operands[2]);"
16305   [(set_attr "type" "multi")])
16306
16307 (define_expand "builtin_setjmp_receiver"
16308   [(label_ref (match_operand 0 "" ""))]
16309   "!TARGET_64BIT && flag_pic"
16310 {
16311 #if TARGET_MACHO
16312   if (TARGET_MACHO)
16313     {
16314       rtx xops[3];
16315       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16316       rtx label_rtx = gen_label_rtx ();
16317       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16318       xops[0] = xops[1] = picreg;
16319       xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16320       ix86_expand_binary_operator (MINUS, SImode, xops);
16321     }
16322   else
16323 #endif
16324     emit_insn (gen_set_got (pic_offset_table_rtx));
16325   DONE;
16326 })
16327 \f
16328 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16329
16330 (define_split
16331   [(set (match_operand 0 "register_operand" "")
16332         (match_operator 3 "promotable_binary_operator"
16333            [(match_operand 1 "register_operand" "")
16334             (match_operand 2 "aligned_operand" "")]))
16335    (clobber (reg:CC FLAGS_REG))]
16336   "! TARGET_PARTIAL_REG_STALL && reload_completed
16337    && ((GET_MODE (operands[0]) == HImode
16338         && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16339             /* ??? next two lines just !satisfies_constraint_K (...) */
16340             || !CONST_INT_P (operands[2])
16341             || satisfies_constraint_K (operands[2])))
16342        || (GET_MODE (operands[0]) == QImode
16343            && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16344   [(parallel [(set (match_dup 0)
16345                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16346               (clobber (reg:CC FLAGS_REG))])]
16347   "operands[0] = gen_lowpart (SImode, operands[0]);
16348    operands[1] = gen_lowpart (SImode, operands[1]);
16349    if (GET_CODE (operands[3]) != ASHIFT)
16350      operands[2] = gen_lowpart (SImode, operands[2]);
16351    PUT_MODE (operands[3], SImode);")
16352
16353 ; Promote the QImode tests, as i386 has encoding of the AND
16354 ; instruction with 32-bit sign-extended immediate and thus the
16355 ; instruction size is unchanged, except in the %eax case for
16356 ; which it is increased by one byte, hence the ! optimize_size.
16357 (define_split
16358   [(set (match_operand 0 "flags_reg_operand" "")
16359         (match_operator 2 "compare_operator"
16360           [(and (match_operand 3 "aligned_operand" "")
16361                 (match_operand 4 "const_int_operand" ""))
16362            (const_int 0)]))
16363    (set (match_operand 1 "register_operand" "")
16364         (and (match_dup 3) (match_dup 4)))]
16365   "! TARGET_PARTIAL_REG_STALL && reload_completed
16366    && optimize_insn_for_speed_p ()
16367    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16368        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16369    /* Ensure that the operand will remain sign-extended immediate.  */
16370    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16371   [(parallel [(set (match_dup 0)
16372                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16373                                     (const_int 0)]))
16374               (set (match_dup 1)
16375                    (and:SI (match_dup 3) (match_dup 4)))])]
16376 {
16377   operands[4]
16378     = gen_int_mode (INTVAL (operands[4])
16379                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16380   operands[1] = gen_lowpart (SImode, operands[1]);
16381   operands[3] = gen_lowpart (SImode, operands[3]);
16382 })
16383
16384 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16385 ; the TEST instruction with 32-bit sign-extended immediate and thus
16386 ; the instruction size would at least double, which is not what we
16387 ; want even with ! optimize_size.
16388 (define_split
16389   [(set (match_operand 0 "flags_reg_operand" "")
16390         (match_operator 1 "compare_operator"
16391           [(and (match_operand:HI 2 "aligned_operand" "")
16392                 (match_operand:HI 3 "const_int_operand" ""))
16393            (const_int 0)]))]
16394   "! TARGET_PARTIAL_REG_STALL && reload_completed
16395    && ! TARGET_FAST_PREFIX
16396    && optimize_insn_for_speed_p ()
16397    /* Ensure that the operand will remain sign-extended immediate.  */
16398    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16399   [(set (match_dup 0)
16400         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16401                          (const_int 0)]))]
16402 {
16403   operands[3]
16404     = gen_int_mode (INTVAL (operands[3])
16405                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16406   operands[2] = gen_lowpart (SImode, operands[2]);
16407 })
16408
16409 (define_split
16410   [(set (match_operand 0 "register_operand" "")
16411         (neg (match_operand 1 "register_operand" "")))
16412    (clobber (reg:CC FLAGS_REG))]
16413   "! TARGET_PARTIAL_REG_STALL && reload_completed
16414    && (GET_MODE (operands[0]) == HImode
16415        || (GET_MODE (operands[0]) == QImode
16416            && (TARGET_PROMOTE_QImode
16417                || optimize_insn_for_size_p ())))"
16418   [(parallel [(set (match_dup 0)
16419                    (neg:SI (match_dup 1)))
16420               (clobber (reg:CC FLAGS_REG))])]
16421   "operands[0] = gen_lowpart (SImode, operands[0]);
16422    operands[1] = gen_lowpart (SImode, operands[1]);")
16423
16424 (define_split
16425   [(set (match_operand 0 "register_operand" "")
16426         (not (match_operand 1 "register_operand" "")))]
16427   "! TARGET_PARTIAL_REG_STALL && reload_completed
16428    && (GET_MODE (operands[0]) == HImode
16429        || (GET_MODE (operands[0]) == QImode
16430            && (TARGET_PROMOTE_QImode
16431                || optimize_insn_for_size_p ())))"
16432   [(set (match_dup 0)
16433         (not:SI (match_dup 1)))]
16434   "operands[0] = gen_lowpart (SImode, operands[0]);
16435    operands[1] = gen_lowpart (SImode, operands[1]);")
16436
16437 (define_split
16438   [(set (match_operand 0 "register_operand" "")
16439         (if_then_else (match_operator 1 "ordered_comparison_operator"
16440                                 [(reg FLAGS_REG) (const_int 0)])
16441                       (match_operand 2 "register_operand" "")
16442                       (match_operand 3 "register_operand" "")))]
16443   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
16444    && (GET_MODE (operands[0]) == HImode
16445        || (GET_MODE (operands[0]) == QImode
16446            && (TARGET_PROMOTE_QImode
16447                || optimize_insn_for_size_p ())))"
16448   [(set (match_dup 0)
16449         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16450   "operands[0] = gen_lowpart (SImode, operands[0]);
16451    operands[2] = gen_lowpart (SImode, operands[2]);
16452    operands[3] = gen_lowpart (SImode, operands[3]);")
16453 \f
16454 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
16455 ;; transform a complex memory operation into two memory to register operations.
16456
16457 ;; Don't push memory operands
16458 (define_peephole2
16459   [(set (match_operand:SWI 0 "push_operand" "")
16460         (match_operand:SWI 1 "memory_operand" ""))
16461    (match_scratch:SWI 2 "<r>")]
16462   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16463    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16464   [(set (match_dup 2) (match_dup 1))
16465    (set (match_dup 0) (match_dup 2))])
16466
16467 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16468 ;; SImode pushes.
16469 (define_peephole2
16470   [(set (match_operand:SF 0 "push_operand" "")
16471         (match_operand:SF 1 "memory_operand" ""))
16472    (match_scratch:SF 2 "r")]
16473   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16474    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16475   [(set (match_dup 2) (match_dup 1))
16476    (set (match_dup 0) (match_dup 2))])
16477
16478 ;; Don't move an immediate directly to memory when the instruction
16479 ;; gets too big.
16480 (define_peephole2
16481   [(match_scratch:SWI124 1 "<r>")
16482    (set (match_operand:SWI124 0 "memory_operand" "")
16483         (const_int 0))]
16484   "optimize_insn_for_speed_p ()
16485    && !TARGET_USE_MOV0
16486    && TARGET_SPLIT_LONG_MOVES
16487    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16488    && peep2_regno_dead_p (0, FLAGS_REG)"
16489   [(parallel [(set (match_dup 2) (const_int 0))
16490               (clobber (reg:CC FLAGS_REG))])
16491    (set (match_dup 0) (match_dup 1))]
16492   "operands[2] = gen_lowpart (SImode, operands[1]);")
16493
16494 (define_peephole2
16495   [(match_scratch:SWI124 2 "<r>")
16496    (set (match_operand:SWI124 0 "memory_operand" "")
16497         (match_operand:SWI124 1 "immediate_operand" ""))]
16498   "optimize_insn_for_speed_p ()
16499    && TARGET_SPLIT_LONG_MOVES
16500    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16501   [(set (match_dup 2) (match_dup 1))
16502    (set (match_dup 0) (match_dup 2))])
16503
16504 ;; Don't compare memory with zero, load and use a test instead.
16505 (define_peephole2
16506   [(set (match_operand 0 "flags_reg_operand" "")
16507         (match_operator 1 "compare_operator"
16508           [(match_operand:SI 2 "memory_operand" "")
16509            (const_int 0)]))
16510    (match_scratch:SI 3 "r")]
16511   "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16512   [(set (match_dup 3) (match_dup 2))
16513    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16514
16515 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16516 ;; Don't split NOTs with a displacement operand, because resulting XOR
16517 ;; will not be pairable anyway.
16518 ;;
16519 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16520 ;; represented using a modRM byte.  The XOR replacement is long decoded,
16521 ;; so this split helps here as well.
16522 ;;
16523 ;; Note: Can't do this as a regular split because we can't get proper
16524 ;; lifetime information then.
16525
16526 (define_peephole2
16527   [(set (match_operand:SWI124 0 "nonimmediate_operand" "")
16528         (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand" "")))]
16529   "optimize_insn_for_speed_p ()
16530    && ((TARGET_NOT_UNPAIRABLE
16531         && (!MEM_P (operands[0])
16532             || !memory_displacement_operand (operands[0], <MODE>mode)))
16533        || (TARGET_NOT_VECTORMODE
16534            && long_memory_operand (operands[0], <MODE>mode)))
16535    && peep2_regno_dead_p (0, FLAGS_REG)"
16536   [(parallel [(set (match_dup 0)
16537                    (xor:SWI124 (match_dup 1) (const_int -1)))
16538               (clobber (reg:CC FLAGS_REG))])])
16539
16540 ;; Non pairable "test imm, reg" instructions can be translated to
16541 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
16542 ;; byte opcode instead of two, have a short form for byte operands),
16543 ;; so do it for other CPUs as well.  Given that the value was dead,
16544 ;; this should not create any new dependencies.  Pass on the sub-word
16545 ;; versions if we're concerned about partial register stalls.
16546
16547 (define_peephole2
16548   [(set (match_operand 0 "flags_reg_operand" "")
16549         (match_operator 1 "compare_operator"
16550           [(and:SI (match_operand:SI 2 "register_operand" "")
16551                    (match_operand:SI 3 "immediate_operand" ""))
16552            (const_int 0)]))]
16553   "ix86_match_ccmode (insn, CCNOmode)
16554    && (true_regnum (operands[2]) != AX_REG
16555        || satisfies_constraint_K (operands[3]))
16556    && peep2_reg_dead_p (1, operands[2])"
16557   [(parallel
16558      [(set (match_dup 0)
16559            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16560                             (const_int 0)]))
16561       (set (match_dup 2)
16562            (and:SI (match_dup 2) (match_dup 3)))])])
16563
16564 ;; We don't need to handle HImode case, because it will be promoted to SImode
16565 ;; on ! TARGET_PARTIAL_REG_STALL
16566
16567 (define_peephole2
16568   [(set (match_operand 0 "flags_reg_operand" "")
16569         (match_operator 1 "compare_operator"
16570           [(and:QI (match_operand:QI 2 "register_operand" "")
16571                    (match_operand:QI 3 "immediate_operand" ""))
16572            (const_int 0)]))]
16573   "! TARGET_PARTIAL_REG_STALL
16574    && ix86_match_ccmode (insn, CCNOmode)
16575    && true_regnum (operands[2]) != AX_REG
16576    && peep2_reg_dead_p (1, operands[2])"
16577   [(parallel
16578      [(set (match_dup 0)
16579            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
16580                             (const_int 0)]))
16581       (set (match_dup 2)
16582            (and:QI (match_dup 2) (match_dup 3)))])])
16583
16584 (define_peephole2
16585   [(set (match_operand 0 "flags_reg_operand" "")
16586         (match_operator 1 "compare_operator"
16587           [(and:SI
16588              (zero_extract:SI
16589                (match_operand 2 "ext_register_operand" "")
16590                (const_int 8)
16591                (const_int 8))
16592              (match_operand 3 "const_int_operand" ""))
16593            (const_int 0)]))]
16594   "! TARGET_PARTIAL_REG_STALL
16595    && ix86_match_ccmode (insn, CCNOmode)
16596    && true_regnum (operands[2]) != AX_REG
16597    && peep2_reg_dead_p (1, operands[2])"
16598   [(parallel [(set (match_dup 0)
16599                    (match_op_dup 1
16600                      [(and:SI
16601                         (zero_extract:SI
16602                           (match_dup 2)
16603                           (const_int 8)
16604                           (const_int 8))
16605                         (match_dup 3))
16606                       (const_int 0)]))
16607               (set (zero_extract:SI (match_dup 2)
16608                                     (const_int 8)
16609                                     (const_int 8))
16610                    (and:SI
16611                      (zero_extract:SI
16612                        (match_dup 2)
16613                        (const_int 8)
16614                        (const_int 8))
16615                      (match_dup 3)))])])
16616
16617 ;; Don't do logical operations with memory inputs.
16618 (define_peephole2
16619   [(match_scratch:SI 2 "r")
16620    (parallel [(set (match_operand:SI 0 "register_operand" "")
16621                    (match_operator:SI 3 "arith_or_logical_operator"
16622                      [(match_dup 0)
16623                       (match_operand:SI 1 "memory_operand" "")]))
16624               (clobber (reg:CC FLAGS_REG))])]
16625   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
16626   [(set (match_dup 2) (match_dup 1))
16627    (parallel [(set (match_dup 0)
16628                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
16629               (clobber (reg:CC FLAGS_REG))])])
16630
16631 (define_peephole2
16632   [(match_scratch:SI 2 "r")
16633    (parallel [(set (match_operand:SI 0 "register_operand" "")
16634                    (match_operator:SI 3 "arith_or_logical_operator"
16635                      [(match_operand:SI 1 "memory_operand" "")
16636                       (match_dup 0)]))
16637               (clobber (reg:CC FLAGS_REG))])]
16638   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
16639   [(set (match_dup 2) (match_dup 1))
16640    (parallel [(set (match_dup 0)
16641                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
16642               (clobber (reg:CC FLAGS_REG))])])
16643
16644 ;; Prefer Load+RegOp to Mov+MemOp.  Watch out for cases when the memory address
16645 ;; refers to the destination of the load!
16646
16647 (define_peephole2
16648   [(set (match_operand:SI 0 "register_operand" "")
16649         (match_operand:SI 1 "register_operand" ""))
16650    (parallel [(set (match_dup 0)
16651                    (match_operator:SI 3 "commutative_operator"
16652                      [(match_dup 0)
16653                       (match_operand:SI 2 "memory_operand" "")]))
16654               (clobber (reg:CC FLAGS_REG))])]
16655   "REGNO (operands[0]) != REGNO (operands[1])
16656    && GENERAL_REGNO_P (REGNO (operands[0]))
16657    && GENERAL_REGNO_P (REGNO (operands[1]))"
16658   [(set (match_dup 0) (match_dup 4))
16659    (parallel [(set (match_dup 0)
16660                    (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
16661               (clobber (reg:CC FLAGS_REG))])]
16662   "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
16663
16664 (define_peephole2
16665   [(set (match_operand 0 "register_operand" "")
16666         (match_operand 1 "register_operand" ""))
16667    (set (match_dup 0)
16668                    (match_operator 3 "commutative_operator"
16669                      [(match_dup 0)
16670                       (match_operand 2 "memory_operand" "")]))]
16671   "REGNO (operands[0]) != REGNO (operands[1])
16672    && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1])) 
16673        || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
16674   [(set (match_dup 0) (match_dup 2))
16675    (set (match_dup 0)
16676         (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
16677
16678 ; Don't do logical operations with memory outputs
16679 ;
16680 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
16681 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
16682 ; the same decoder scheduling characteristics as the original.
16683
16684 (define_peephole2
16685   [(match_scratch:SI 2 "r")
16686    (parallel [(set (match_operand:SI 0 "memory_operand" "")
16687                    (match_operator:SI 3 "arith_or_logical_operator"
16688                      [(match_dup 0)
16689                       (match_operand:SI 1 "nonmemory_operand" "")]))
16690               (clobber (reg:CC FLAGS_REG))])]
16691   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
16692    /* Do not split stack checking probes.  */
16693    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
16694   [(set (match_dup 2) (match_dup 0))
16695    (parallel [(set (match_dup 2)
16696                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
16697               (clobber (reg:CC FLAGS_REG))])
16698    (set (match_dup 0) (match_dup 2))])
16699
16700 (define_peephole2
16701   [(match_scratch:SI 2 "r")
16702    (parallel [(set (match_operand:SI 0 "memory_operand" "")
16703                    (match_operator:SI 3 "arith_or_logical_operator"
16704                      [(match_operand:SI 1 "nonmemory_operand" "")
16705                       (match_dup 0)]))
16706               (clobber (reg:CC FLAGS_REG))])]
16707   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
16708    /* Do not split stack checking probes.  */
16709    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
16710   [(set (match_dup 2) (match_dup 0))
16711    (parallel [(set (match_dup 2)
16712                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16713               (clobber (reg:CC FLAGS_REG))])
16714    (set (match_dup 0) (match_dup 2))])
16715
16716 ;; Attempt to always use XOR for zeroing registers.
16717 (define_peephole2
16718   [(set (match_operand 0 "register_operand" "")
16719         (match_operand 1 "const0_operand" ""))]
16720   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
16721    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
16722    && GENERAL_REG_P (operands[0])
16723    && peep2_regno_dead_p (0, FLAGS_REG)"
16724   [(parallel [(set (match_dup 0) (const_int 0))
16725               (clobber (reg:CC FLAGS_REG))])]
16726   "operands[0] = gen_lowpart (word_mode, operands[0]);")
16727
16728 (define_peephole2
16729   [(set (strict_low_part (match_operand 0 "register_operand" ""))
16730         (const_int 0))]
16731   "(GET_MODE (operands[0]) == QImode
16732     || GET_MODE (operands[0]) == HImode)
16733    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
16734    && peep2_regno_dead_p (0, FLAGS_REG)"
16735   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
16736               (clobber (reg:CC FLAGS_REG))])])
16737
16738 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
16739 (define_peephole2
16740   [(set (match_operand:SWI248 0 "register_operand" "")
16741         (const_int -1))]
16742   "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
16743    && peep2_regno_dead_p (0, FLAGS_REG)"
16744   [(parallel [(set (match_dup 0) (const_int -1))
16745               (clobber (reg:CC FLAGS_REG))])]
16746 {
16747   if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
16748     operands[0] = gen_lowpart (SImode, operands[0]);
16749 })
16750
16751 ;; Attempt to convert simple lea to add/shift.
16752 ;; These can be created by move expanders.
16753
16754 (define_peephole2
16755   [(set (match_operand:SWI48 0 "register_operand" "")
16756         (plus:SWI48 (match_dup 0)
16757                     (match_operand:SWI48 1 "<nonmemory_operand>" "")))]
16758   "peep2_regno_dead_p (0, FLAGS_REG)"
16759   [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
16760               (clobber (reg:CC FLAGS_REG))])])
16761
16762 (define_peephole2
16763   [(set (match_operand:SI 0 "register_operand" "")
16764         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
16765                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
16766   "TARGET_64BIT
16767    && peep2_regno_dead_p (0, FLAGS_REG)
16768    && REGNO (operands[0]) == REGNO (operands[1])"
16769   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
16770               (clobber (reg:CC FLAGS_REG))])]
16771   "operands[2] = gen_lowpart (SImode, operands[2]);")
16772
16773 (define_peephole2
16774   [(set (match_operand:SWI48 0 "register_operand" "")
16775         (mult:SWI48 (match_dup 0)
16776                     (match_operand:SWI48 1 "const_int_operand" "")))]
16777   "exact_log2 (INTVAL (operands[1])) >= 0
16778    && peep2_regno_dead_p (0, FLAGS_REG)"
16779   [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
16780               (clobber (reg:CC FLAGS_REG))])]
16781   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
16782
16783 (define_peephole2
16784   [(set (match_operand:SI 0 "register_operand" "")
16785         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
16786                    (match_operand:DI 2 "const_int_operand" "")) 0))]
16787   "TARGET_64BIT
16788    && exact_log2 (INTVAL (operands[2])) >= 0
16789    && REGNO (operands[0]) == REGNO (operands[1])
16790    && peep2_regno_dead_p (0, FLAGS_REG)"
16791   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
16792               (clobber (reg:CC FLAGS_REG))])]
16793   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
16794
16795 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
16796 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
16797 ;; On many CPUs it is also faster, since special hardware to avoid esp
16798 ;; dependencies is present.
16799
16800 ;; While some of these conversions may be done using splitters, we use
16801 ;; peepholes in order to allow combine_stack_adjustments pass to see
16802 ;; nonobfuscated RTL.
16803
16804 ;; Convert prologue esp subtractions to push.
16805 ;; We need register to push.  In order to keep verify_flow_info happy we have
16806 ;; two choices
16807 ;; - use scratch and clobber it in order to avoid dependencies
16808 ;; - use already live register
16809 ;; We can't use the second way right now, since there is no reliable way how to
16810 ;; verify that given register is live.  First choice will also most likely in
16811 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
16812 ;; call clobbered registers are dead.  We may want to use base pointer as an
16813 ;; alternative when no register is available later.
16814
16815 (define_peephole2
16816   [(match_scratch:P 1 "r")
16817    (parallel [(set (reg:P SP_REG)
16818                    (plus:P (reg:P SP_REG)
16819                            (match_operand:P 0 "const_int_operand" "")))
16820               (clobber (reg:CC FLAGS_REG))
16821               (clobber (mem:BLK (scratch)))])]
16822   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
16823    && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
16824   [(clobber (match_dup 1))
16825    (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16826               (clobber (mem:BLK (scratch)))])])
16827
16828 (define_peephole2
16829   [(match_scratch:P 1 "r")
16830    (parallel [(set (reg:P SP_REG)
16831                    (plus:P (reg:P SP_REG)
16832                            (match_operand:P 0 "const_int_operand" "")))
16833               (clobber (reg:CC FLAGS_REG))
16834               (clobber (mem:BLK (scratch)))])]
16835   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
16836    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
16837   [(clobber (match_dup 1))
16838    (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16839    (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16840               (clobber (mem:BLK (scratch)))])])
16841
16842 ;; Convert esp subtractions to push.
16843 (define_peephole2
16844   [(match_scratch:P 1 "r")
16845    (parallel [(set (reg:P SP_REG)
16846                    (plus:P (reg:P SP_REG)
16847                            (match_operand:P 0 "const_int_operand" "")))
16848               (clobber (reg:CC FLAGS_REG))])]
16849   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
16850    && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
16851   [(clobber (match_dup 1))
16852    (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
16853
16854 (define_peephole2
16855   [(match_scratch:P 1 "r")
16856    (parallel [(set (reg:P SP_REG)
16857                    (plus:P (reg:P SP_REG)
16858                            (match_operand:P 0 "const_int_operand" "")))
16859               (clobber (reg:CC FLAGS_REG))])]
16860   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
16861    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
16862   [(clobber (match_dup 1))
16863    (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16864    (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
16865
16866 ;; Convert epilogue deallocator to pop.
16867 (define_peephole2
16868   [(match_scratch:P 1 "r")
16869    (parallel [(set (reg:P SP_REG)
16870                    (plus:P (reg:P SP_REG)
16871                            (match_operand:P 0 "const_int_operand" "")))
16872               (clobber (reg:CC FLAGS_REG))
16873               (clobber (mem:BLK (scratch)))])]
16874   "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
16875    && INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
16876   [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
16877               (clobber (mem:BLK (scratch)))])])
16878
16879 ;; Two pops case is tricky, since pop causes dependency
16880 ;; on destination register.  We use two registers if available.
16881 (define_peephole2
16882   [(match_scratch:P 1 "r")
16883    (match_scratch:P 2 "r")
16884    (parallel [(set (reg:P SP_REG)
16885                    (plus:P (reg:P SP_REG)
16886                            (match_operand:P 0 "const_int_operand" "")))
16887               (clobber (reg:CC FLAGS_REG))
16888               (clobber (mem:BLK (scratch)))])]
16889   "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
16890    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
16891   [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
16892               (clobber (mem:BLK (scratch)))])
16893    (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
16894
16895 (define_peephole2
16896   [(match_scratch:P 1 "r")
16897    (parallel [(set (reg:P SP_REG)
16898                    (plus:P (reg:P SP_REG)
16899                            (match_operand:P 0 "const_int_operand" "")))
16900               (clobber (reg:CC FLAGS_REG))
16901               (clobber (mem:BLK (scratch)))])]
16902   "optimize_insn_for_size_p ()
16903    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
16904   [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
16905               (clobber (mem:BLK (scratch)))])
16906    (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
16907
16908 ;; Convert esp additions to pop.
16909 (define_peephole2
16910   [(match_scratch:P 1 "r")
16911    (parallel [(set (reg:P SP_REG)
16912                    (plus:P (reg:P SP_REG)
16913                            (match_operand:P 0 "const_int_operand" "")))
16914               (clobber (reg:CC FLAGS_REG))])]
16915   "INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
16916   [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
16917
16918 ;; Two pops case is tricky, since pop causes dependency
16919 ;; on destination register.  We use two registers if available.
16920 (define_peephole2
16921   [(match_scratch:P 1 "r")
16922    (match_scratch:P 2 "r")
16923    (parallel [(set (reg:P SP_REG)
16924                    (plus:P (reg:P SP_REG)
16925                            (match_operand:P 0 "const_int_operand" "")))
16926               (clobber (reg:CC FLAGS_REG))])]
16927   "INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
16928   [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
16929    (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
16930
16931 (define_peephole2
16932   [(match_scratch:P 1 "r")
16933    (parallel [(set (reg:P SP_REG)
16934                    (plus:P (reg:P SP_REG)
16935                            (match_operand:P 0 "const_int_operand" "")))
16936               (clobber (reg:CC FLAGS_REG))])]
16937   "optimize_insn_for_size_p ()
16938    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
16939   [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
16940    (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
16941 \f
16942 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
16943 ;; required and register dies.  Similarly for 128 to -128.
16944 (define_peephole2
16945   [(set (match_operand 0 "flags_reg_operand" "")
16946         (match_operator 1 "compare_operator"
16947           [(match_operand 2 "register_operand" "")
16948            (match_operand 3 "const_int_operand" "")]))]
16949   "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
16950      && incdec_operand (operands[3], GET_MODE (operands[3])))
16951     || (!TARGET_FUSE_CMP_AND_BRANCH
16952         && INTVAL (operands[3]) == 128))
16953    && ix86_match_ccmode (insn, CCGCmode)
16954    && peep2_reg_dead_p (1, operands[2])"
16955   [(parallel [(set (match_dup 0)
16956                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
16957               (clobber (match_dup 2))])])
16958 \f
16959 ;; Convert imul by three, five and nine into lea
16960 (define_peephole2
16961   [(parallel
16962     [(set (match_operand:SWI48 0 "register_operand" "")
16963           (mult:SWI48 (match_operand:SWI48 1 "register_operand" "")
16964                       (match_operand:SWI48 2 "const_int_operand" "")))
16965      (clobber (reg:CC FLAGS_REG))])]
16966   "INTVAL (operands[2]) == 3
16967    || INTVAL (operands[2]) == 5
16968    || INTVAL (operands[2]) == 9"
16969   [(set (match_dup 0)
16970         (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
16971                     (match_dup 1)))]
16972   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
16973
16974 (define_peephole2
16975   [(parallel
16976     [(set (match_operand:SWI48 0 "register_operand" "")
16977           (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
16978                       (match_operand:SWI48 2 "const_int_operand" "")))
16979      (clobber (reg:CC FLAGS_REG))])]
16980   "optimize_insn_for_speed_p ()
16981    && (INTVAL (operands[2]) == 3
16982        || INTVAL (operands[2]) == 5
16983        || INTVAL (operands[2]) == 9)"
16984   [(set (match_dup 0) (match_dup 1))
16985    (set (match_dup 0)
16986         (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
16987                     (match_dup 0)))]
16988   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
16989
16990 ;; imul $32bit_imm, mem, reg is vector decoded, while
16991 ;; imul $32bit_imm, reg, reg is direct decoded.
16992 (define_peephole2
16993   [(match_scratch:SWI48 3 "r")
16994    (parallel [(set (match_operand:SWI48 0 "register_operand" "")
16995                    (mult:SWI48 (match_operand:SWI48 1 "memory_operand" "")
16996                                (match_operand:SWI48 2 "immediate_operand" "")))
16997               (clobber (reg:CC FLAGS_REG))])]
16998   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
16999    && !satisfies_constraint_K (operands[2])"
17000   [(set (match_dup 3) (match_dup 1))
17001    (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17002               (clobber (reg:CC FLAGS_REG))])])
17003
17004 (define_peephole2
17005   [(match_scratch:SI 3 "r")
17006    (parallel [(set (match_operand:DI 0 "register_operand" "")
17007                    (zero_extend:DI
17008                      (mult:SI (match_operand:SI 1 "memory_operand" "")
17009                               (match_operand:SI 2 "immediate_operand" ""))))
17010               (clobber (reg:CC FLAGS_REG))])]
17011   "TARGET_64BIT
17012    && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17013    && !satisfies_constraint_K (operands[2])"
17014   [(set (match_dup 3) (match_dup 1))
17015    (parallel [(set (match_dup 0)
17016                    (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17017               (clobber (reg:CC FLAGS_REG))])])
17018
17019 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17020 ;; Convert it into imul reg, reg
17021 ;; It would be better to force assembler to encode instruction using long
17022 ;; immediate, but there is apparently no way to do so.
17023 (define_peephole2
17024   [(parallel [(set (match_operand:SWI248 0 "register_operand" "")
17025                    (mult:SWI248
17026                     (match_operand:SWI248 1 "nonimmediate_operand" "")
17027                     (match_operand:SWI248 2 "const_int_operand" "")))
17028               (clobber (reg:CC FLAGS_REG))])
17029    (match_scratch:SWI248 3 "r")]
17030   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17031    && satisfies_constraint_K (operands[2])"
17032   [(set (match_dup 3) (match_dup 2))
17033    (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17034               (clobber (reg:CC FLAGS_REG))])]
17035 {
17036   if (!rtx_equal_p (operands[0], operands[1]))
17037     emit_move_insn (operands[0], operands[1]);
17038 })
17039
17040 ;; After splitting up read-modify operations, array accesses with memory
17041 ;; operands might end up in form:
17042 ;;  sall    $2, %eax
17043 ;;  movl    4(%esp), %edx
17044 ;;  addl    %edx, %eax
17045 ;; instead of pre-splitting:
17046 ;;  sall    $2, %eax
17047 ;;  addl    4(%esp), %eax
17048 ;; Turn it into:
17049 ;;  movl    4(%esp), %edx
17050 ;;  leal    (%edx,%eax,4), %eax
17051
17052 (define_peephole2
17053   [(match_scratch:P 5 "r")
17054    (parallel [(set (match_operand 0 "register_operand" "")
17055                    (ashift (match_operand 1 "register_operand" "")
17056                            (match_operand 2 "const_int_operand" "")))
17057                (clobber (reg:CC FLAGS_REG))])
17058    (parallel [(set (match_operand 3 "register_operand" "")
17059                    (plus (match_dup 0)
17060                          (match_operand 4 "x86_64_general_operand" "")))
17061                    (clobber (reg:CC FLAGS_REG))])]
17062   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
17063    /* Validate MODE for lea.  */
17064    && ((!TARGET_PARTIAL_REG_STALL
17065         && (GET_MODE (operands[0]) == QImode
17066             || GET_MODE (operands[0]) == HImode))
17067        || GET_MODE (operands[0]) == SImode
17068        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17069    && (rtx_equal_p (operands[0], operands[3])
17070        || peep2_reg_dead_p (2, operands[0]))
17071    /* We reorder load and the shift.  */
17072    && !reg_overlap_mentioned_p (operands[0], operands[4])"
17073   [(set (match_dup 5) (match_dup 4))
17074    (set (match_dup 0) (match_dup 1))]
17075 {
17076   enum machine_mode mode = GET_MODE (operands[1]) == DImode ? DImode : SImode;
17077   int scale = 1 << INTVAL (operands[2]);
17078   rtx index = gen_lowpart (Pmode, operands[1]);
17079   rtx base = gen_lowpart (Pmode, operands[5]);
17080   rtx dest = gen_lowpart (mode, operands[3]);
17081
17082   operands[1] = gen_rtx_PLUS (Pmode, base,
17083                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
17084   operands[5] = base;
17085   if (mode != Pmode)
17086     {
17087       operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17088       operands[5] = gen_rtx_SUBREG (mode, operands[5], 0);
17089     }
17090   operands[0] = dest;
17091 })
17092 \f
17093 ;; Call-value patterns last so that the wildcard operand does not
17094 ;; disrupt insn-recog's switch tables.
17095
17096 (define_insn "*call_value_pop_0"
17097   [(set (match_operand 0 "" "")
17098         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17099               (match_operand:SI 2 "" "")))
17100    (set (reg:SI SP_REG)
17101         (plus:SI (reg:SI SP_REG)
17102                  (match_operand:SI 3 "immediate_operand" "")))]
17103   "!TARGET_64BIT"
17104 {
17105   if (SIBLING_CALL_P (insn))
17106     return "jmp\t%P1";
17107   else
17108     return "call\t%P1";
17109 }
17110   [(set_attr "type" "callv")])
17111
17112 (define_insn "*call_value_pop_1"
17113   [(set (match_operand 0 "" "")
17114         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17115               (match_operand:SI 2 "" "")))
17116    (set (reg:SI SP_REG)
17117         (plus:SI (reg:SI SP_REG)
17118                  (match_operand:SI 3 "immediate_operand" "i")))]
17119   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17120 {
17121   if (constant_call_address_operand (operands[1], Pmode))
17122     return "call\t%P1";
17123   return "call\t%A1";
17124 }
17125   [(set_attr "type" "callv")])
17126
17127 (define_insn "*sibcall_value_pop_1"
17128   [(set (match_operand 0 "" "")
17129         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17130               (match_operand:SI 2 "" "")))
17131    (set (reg:SI SP_REG)
17132         (plus:SI (reg:SI SP_REG)
17133                  (match_operand:SI 3 "immediate_operand" "i,i")))]
17134   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17135   "@
17136    jmp\t%P1
17137    jmp\t%A1"
17138   [(set_attr "type" "callv")])
17139
17140 (define_insn "*call_value_0"
17141   [(set (match_operand 0 "" "")
17142         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17143               (match_operand:SI 2 "" "")))]
17144   "!TARGET_64BIT"
17145 {
17146   if (SIBLING_CALL_P (insn))
17147     return "jmp\t%P1";
17148   else
17149     return "call\t%P1";
17150 }
17151   [(set_attr "type" "callv")])
17152
17153 (define_insn "*call_value_0_rex64"
17154   [(set (match_operand 0 "" "")
17155         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17156               (match_operand:DI 2 "const_int_operand" "")))]
17157   "TARGET_64BIT"
17158 {
17159   if (SIBLING_CALL_P (insn))
17160     return "jmp\t%P1";
17161   else
17162     return "call\t%P1";
17163 }
17164   [(set_attr "type" "callv")])
17165
17166 (define_insn "*call_value_0_rex64_ms_sysv"
17167   [(set (match_operand 0 "" "")
17168         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17169               (match_operand:DI 2 "const_int_operand" "")))
17170    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17171    (clobber (reg:TI XMM6_REG))
17172    (clobber (reg:TI XMM7_REG))
17173    (clobber (reg:TI XMM8_REG))
17174    (clobber (reg:TI XMM9_REG))
17175    (clobber (reg:TI XMM10_REG))
17176    (clobber (reg:TI XMM11_REG))
17177    (clobber (reg:TI XMM12_REG))
17178    (clobber (reg:TI XMM13_REG))
17179    (clobber (reg:TI XMM14_REG))
17180    (clobber (reg:TI XMM15_REG))
17181    (clobber (reg:DI SI_REG))
17182    (clobber (reg:DI DI_REG))]
17183   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17184 {
17185   if (SIBLING_CALL_P (insn))
17186     return "jmp\t%P1";
17187   else
17188     return "call\t%P1";
17189 }
17190   [(set_attr "type" "callv")])
17191
17192 (define_insn "*call_value_1"
17193   [(set (match_operand 0 "" "")
17194         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17195               (match_operand:SI 2 "" "")))]
17196   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17197 {
17198   if (constant_call_address_operand (operands[1], Pmode))
17199     return "call\t%P1";
17200   return "call\t%A1";
17201 }
17202   [(set_attr "type" "callv")])
17203
17204 (define_insn "*sibcall_value_1"
17205   [(set (match_operand 0 "" "")
17206         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17207               (match_operand:SI 2 "" "")))]
17208   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17209   "@
17210    jmp\t%P1
17211    jmp\t%A1"
17212   [(set_attr "type" "callv")])
17213
17214 (define_insn "*call_value_1_rex64"
17215   [(set (match_operand 0 "" "")
17216         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17217               (match_operand:DI 2 "" "")))]
17218   "TARGET_64BIT && !SIBLING_CALL_P (insn)
17219    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
17220 {
17221   if (constant_call_address_operand (operands[1], Pmode))
17222     return "call\t%P1";
17223   return "call\t%A1";
17224 }
17225   [(set_attr "type" "callv")])
17226
17227 (define_insn "*call_value_1_rex64_ms_sysv"
17228   [(set (match_operand 0 "" "")
17229         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17230               (match_operand:DI 2 "" "")))
17231    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17232    (clobber (reg:TI XMM6_REG))
17233    (clobber (reg:TI XMM7_REG))
17234    (clobber (reg:TI XMM8_REG))
17235    (clobber (reg:TI XMM9_REG))
17236    (clobber (reg:TI XMM10_REG))
17237    (clobber (reg:TI XMM11_REG))
17238    (clobber (reg:TI XMM12_REG))
17239    (clobber (reg:TI XMM13_REG))
17240    (clobber (reg:TI XMM14_REG))
17241    (clobber (reg:TI XMM15_REG))
17242    (clobber (reg:DI SI_REG))
17243    (clobber (reg:DI DI_REG))]
17244   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17245 {
17246   if (constant_call_address_operand (operands[1], Pmode))
17247     return "call\t%P1";
17248   return "call\t%A1";
17249 }
17250   [(set_attr "type" "callv")])
17251
17252 (define_insn "*call_value_1_rex64_large"
17253   [(set (match_operand 0 "" "")
17254         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
17255               (match_operand:DI 2 "" "")))]
17256   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17257   "call\t%A1"
17258   [(set_attr "type" "callv")])
17259
17260 (define_insn "*sibcall_value_1_rex64"
17261   [(set (match_operand 0 "" "")
17262         (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
17263               (match_operand:DI 2 "" "")))]
17264   "TARGET_64BIT && SIBLING_CALL_P (insn)"
17265   "@
17266    jmp\t%P1
17267    jmp\t%A1"
17268   [(set_attr "type" "callv")])
17269 \f
17270 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17271 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17272 ;; caught for use by garbage collectors and the like.  Using an insn that
17273 ;; maps to SIGILL makes it more likely the program will rightfully die.
17274 ;; Keeping with tradition, "6" is in honor of #UD.
17275 (define_insn "trap"
17276   [(trap_if (const_int 1) (const_int 6))]
17277   ""
17278   { return ASM_SHORT "0x0b0f"; }
17279   [(set_attr "length" "2")])
17280
17281 (define_expand "prefetch"
17282   [(prefetch (match_operand 0 "address_operand" "")
17283              (match_operand:SI 1 "const_int_operand" "")
17284              (match_operand:SI 2 "const_int_operand" ""))]
17285   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17286 {
17287   int rw = INTVAL (operands[1]);
17288   int locality = INTVAL (operands[2]);
17289
17290   gcc_assert (rw == 0 || rw == 1);
17291   gcc_assert (locality >= 0 && locality <= 3);
17292   gcc_assert (GET_MODE (operands[0]) == Pmode
17293               || GET_MODE (operands[0]) == VOIDmode);
17294
17295   /* Use 3dNOW prefetch in case we are asking for write prefetch not
17296      supported by SSE counterpart or the SSE prefetch is not available
17297      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
17298      of locality.  */
17299   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17300     operands[2] = GEN_INT (3);
17301   else
17302     operands[1] = const0_rtx;
17303 })
17304
17305 (define_insn "*prefetch_sse_<mode>"
17306   [(prefetch (match_operand:P 0 "address_operand" "p")
17307              (const_int 0)
17308              (match_operand:SI 1 "const_int_operand" ""))]
17309   "TARGET_PREFETCH_SSE"
17310 {
17311   static const char * const patterns[4] = {
17312    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17313   };
17314
17315   int locality = INTVAL (operands[1]);
17316   gcc_assert (locality >= 0 && locality <= 3);
17317
17318   return patterns[locality];
17319 }
17320   [(set_attr "type" "sse")
17321    (set_attr "atom_sse_attr" "prefetch")
17322    (set (attr "length_address")
17323         (symbol_ref "memory_address_length (operands[0])"))
17324    (set_attr "memory" "none")])
17325
17326 (define_insn "*prefetch_3dnow_<mode>"
17327   [(prefetch (match_operand:P 0 "address_operand" "p")
17328              (match_operand:SI 1 "const_int_operand" "n")
17329              (const_int 3))]
17330   "TARGET_3DNOW"
17331 {
17332   if (INTVAL (operands[1]) == 0)
17333     return "prefetch\t%a0";
17334   else
17335     return "prefetchw\t%a0";
17336 }
17337   [(set_attr "type" "mmx")
17338    (set (attr "length_address")
17339         (symbol_ref "memory_address_length (operands[0])"))
17340    (set_attr "memory" "none")])
17341
17342 (define_expand "stack_protect_set"
17343   [(match_operand 0 "memory_operand" "")
17344    (match_operand 1 "memory_operand" "")]
17345   ""
17346 {
17347 #ifdef TARGET_THREAD_SSP_OFFSET
17348   if (TARGET_64BIT)
17349     emit_insn (gen_stack_tls_protect_set_di (operands[0],
17350                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
17351   else
17352     emit_insn (gen_stack_tls_protect_set_si (operands[0],
17353                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
17354 #else
17355   if (TARGET_64BIT)
17356     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
17357   else
17358     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
17359 #endif
17360   DONE;
17361 })
17362
17363 (define_insn "stack_protect_set_si"
17364   [(set (match_operand:SI 0 "memory_operand" "=m")
17365         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
17366    (set (match_scratch:SI 2 "=&r") (const_int 0))
17367    (clobber (reg:CC FLAGS_REG))]
17368   ""
17369   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
17370   [(set_attr "type" "multi")])
17371
17372 (define_insn "stack_protect_set_di"
17373   [(set (match_operand:DI 0 "memory_operand" "=m")
17374         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
17375    (set (match_scratch:DI 2 "=&r") (const_int 0))
17376    (clobber (reg:CC FLAGS_REG))]
17377   "TARGET_64BIT"
17378   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17379   [(set_attr "type" "multi")])
17380
17381 (define_insn "stack_tls_protect_set_si"
17382   [(set (match_operand:SI 0 "memory_operand" "=m")
17383         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")]
17384                    UNSPEC_SP_TLS_SET))
17385    (set (match_scratch:SI 2 "=&r") (const_int 0))
17386    (clobber (reg:CC FLAGS_REG))]
17387   ""
17388   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
17389   [(set_attr "type" "multi")])
17390
17391 (define_insn "stack_tls_protect_set_di"
17392   [(set (match_operand:DI 0 "memory_operand" "=m")
17393         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")]
17394                    UNSPEC_SP_TLS_SET))
17395    (set (match_scratch:DI 2 "=&r") (const_int 0))
17396    (clobber (reg:CC FLAGS_REG))]
17397   "TARGET_64BIT"
17398   {
17399      /* The kernel uses a different segment register for performance reasons; a
17400         system call would not have to trash the userspace segment register,
17401         which would be expensive */
17402      if (ix86_cmodel != CM_KERNEL)
17403         return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
17404      else
17405         return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
17406   }
17407   [(set_attr "type" "multi")])
17408
17409 (define_expand "stack_protect_test"
17410   [(match_operand 0 "memory_operand" "")
17411    (match_operand 1 "memory_operand" "")
17412    (match_operand 2 "" "")]
17413   ""
17414 {
17415   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17416
17417 #ifdef TARGET_THREAD_SSP_OFFSET
17418   if (TARGET_64BIT)
17419     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
17420                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
17421   else
17422     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
17423                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
17424 #else
17425   if (TARGET_64BIT)
17426     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
17427   else
17428     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
17429 #endif
17430
17431   emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17432                                   flags, const0_rtx, operands[2]));
17433   DONE;
17434 })
17435
17436 (define_insn "stack_protect_test_si"
17437   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17438         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
17439                      (match_operand:SI 2 "memory_operand" "m")]
17440                     UNSPEC_SP_TEST))
17441    (clobber (match_scratch:SI 3 "=&r"))]
17442   ""
17443   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
17444   [(set_attr "type" "multi")])
17445
17446 (define_insn "stack_protect_test_di"
17447   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17448         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
17449                      (match_operand:DI 2 "memory_operand" "m")]
17450                     UNSPEC_SP_TEST))
17451    (clobber (match_scratch:DI 3 "=&r"))]
17452   "TARGET_64BIT"
17453   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
17454   [(set_attr "type" "multi")])
17455
17456 (define_insn "stack_tls_protect_test_si"
17457   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17458         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
17459                      (match_operand:SI 2 "const_int_operand" "i")]
17460                     UNSPEC_SP_TLS_TEST))
17461    (clobber (match_scratch:SI 3 "=r"))]
17462   ""
17463   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
17464   [(set_attr "type" "multi")])
17465
17466 (define_insn "stack_tls_protect_test_di"
17467   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17468         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
17469                      (match_operand:DI 2 "const_int_operand" "i")]
17470                     UNSPEC_SP_TLS_TEST))
17471    (clobber (match_scratch:DI 3 "=r"))]
17472   "TARGET_64BIT"
17473   {
17474      /* The kernel uses a different segment register for performance reasons; a
17475         system call would not have to trash the userspace segment register,
17476         which would be expensive */
17477      if (ix86_cmodel != CM_KERNEL)
17478         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
17479      else
17480         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
17481   }
17482   [(set_attr "type" "multi")])
17483
17484 (define_insn "sse4_2_crc32<mode>"
17485   [(set (match_operand:SI 0 "register_operand" "=r")
17486         (unspec:SI
17487           [(match_operand:SI 1 "register_operand" "0")
17488            (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17489           UNSPEC_CRC32))]
17490   "TARGET_SSE4_2 || TARGET_CRC32"
17491   "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17492   [(set_attr "type" "sselog1")
17493    (set_attr "prefix_rep" "1")
17494    (set_attr "prefix_extra" "1")
17495    (set (attr "prefix_data16")
17496      (if_then_else (match_operand:HI 2 "" "")
17497        (const_string "1")
17498        (const_string "*")))
17499    (set (attr "prefix_rex")
17500      (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
17501        (const_string "1")
17502        (const_string "*")))
17503    (set_attr "mode" "SI")])
17504
17505 (define_insn "sse4_2_crc32di"
17506   [(set (match_operand:DI 0 "register_operand" "=r")
17507         (unspec:DI
17508           [(match_operand:DI 1 "register_operand" "0")
17509            (match_operand:DI 2 "nonimmediate_operand" "rm")]
17510           UNSPEC_CRC32))]
17511   "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17512   "crc32{q}\t{%2, %0|%0, %2}"
17513   [(set_attr "type" "sselog1")
17514    (set_attr "prefix_rep" "1")
17515    (set_attr "prefix_extra" "1")
17516    (set_attr "mode" "DI")])
17517
17518 (define_expand "rdpmc"
17519   [(match_operand:DI 0 "register_operand" "")
17520    (match_operand:SI 1 "register_operand" "")]
17521   ""
17522 {
17523   rtx reg = gen_reg_rtx (DImode);
17524   rtx si;
17525
17526   /* Force operand 1 into ECX.  */
17527   rtx ecx = gen_rtx_REG (SImode, CX_REG);
17528   emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
17529   si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
17530                                 UNSPECV_RDPMC);
17531
17532   if (TARGET_64BIT)
17533     {
17534       rtvec vec = rtvec_alloc (2);
17535       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17536       rtx upper = gen_reg_rtx (DImode);
17537       rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17538                                         gen_rtvec (1, const0_rtx),
17539                                         UNSPECV_RDPMC);
17540       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
17541       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17542       emit_insn (load);
17543       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17544                                    NULL, 1, OPTAB_DIRECT);
17545       reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17546                                  OPTAB_DIRECT);
17547     }
17548   else
17549     emit_insn (gen_rtx_SET (VOIDmode, reg, si));
17550   emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17551   DONE;
17552 })
17553
17554 (define_insn "*rdpmc"
17555   [(set (match_operand:DI 0 "register_operand" "=A")
17556         (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17557                             UNSPECV_RDPMC))]
17558   "!TARGET_64BIT"
17559   "rdpmc"
17560   [(set_attr "type" "other")
17561    (set_attr "length" "2")])
17562
17563 (define_insn "*rdpmc_rex64"
17564   [(set (match_operand:DI 0 "register_operand" "=a")
17565         (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17566                             UNSPECV_RDPMC))
17567   (set (match_operand:DI 1 "register_operand" "=d")
17568        (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
17569   "TARGET_64BIT"
17570   "rdpmc"
17571   [(set_attr "type" "other")
17572    (set_attr "length" "2")])
17573
17574 (define_expand "rdtsc"
17575   [(set (match_operand:DI 0 "register_operand" "")
17576         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17577   ""
17578 {
17579   if (TARGET_64BIT)
17580     {
17581       rtvec vec = rtvec_alloc (2);
17582       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17583       rtx upper = gen_reg_rtx (DImode);
17584       rtx lower = gen_reg_rtx (DImode);
17585       rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
17586                                          gen_rtvec (1, const0_rtx),
17587                                          UNSPECV_RDTSC);
17588       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
17589       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
17590       emit_insn (load);
17591       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17592                                    NULL, 1, OPTAB_DIRECT);
17593       lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
17594                                    OPTAB_DIRECT);
17595       emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
17596       DONE;
17597     }
17598 })
17599
17600 (define_insn "*rdtsc"
17601   [(set (match_operand:DI 0 "register_operand" "=A")
17602         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17603   "!TARGET_64BIT"
17604   "rdtsc"
17605   [(set_attr "type" "other")
17606    (set_attr "length" "2")])
17607
17608 (define_insn "*rdtsc_rex64"
17609   [(set (match_operand:DI 0 "register_operand" "=a")
17610         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17611    (set (match_operand:DI 1 "register_operand" "=d")
17612         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17613   "TARGET_64BIT"
17614   "rdtsc"
17615   [(set_attr "type" "other")
17616    (set_attr "length" "2")])
17617
17618 (define_expand "rdtscp"
17619   [(match_operand:DI 0 "register_operand" "")
17620    (match_operand:SI 1 "memory_operand" "")]
17621   ""
17622 {
17623   rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17624                                     gen_rtvec (1, const0_rtx),
17625                                     UNSPECV_RDTSCP);
17626   rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
17627                                     gen_rtvec (1, const0_rtx),
17628                                     UNSPECV_RDTSCP);
17629   rtx reg = gen_reg_rtx (DImode);
17630   rtx tmp = gen_reg_rtx (SImode);
17631
17632   if (TARGET_64BIT)
17633     {
17634       rtvec vec = rtvec_alloc (3);
17635       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17636       rtx upper = gen_reg_rtx (DImode);
17637       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17638       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17639       RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
17640       emit_insn (load);
17641       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17642                                    NULL, 1, OPTAB_DIRECT);
17643       reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17644                                  OPTAB_DIRECT);
17645     }
17646   else
17647     {
17648       rtvec vec = rtvec_alloc (2);
17649       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17650       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17651       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
17652       emit_insn (load);
17653     }
17654   emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17655   emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
17656   DONE;
17657 })
17658
17659 (define_insn "*rdtscp"
17660   [(set (match_operand:DI 0 "register_operand" "=A")
17661         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17662    (set (match_operand:SI 1 "register_operand" "=c")
17663         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17664   "!TARGET_64BIT"
17665   "rdtscp"
17666   [(set_attr "type" "other")
17667    (set_attr "length" "3")])
17668
17669 (define_insn "*rdtscp_rex64"
17670   [(set (match_operand:DI 0 "register_operand" "=a")
17671         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17672    (set (match_operand:DI 1 "register_operand" "=d")
17673         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17674    (set (match_operand:SI 2 "register_operand" "=c")
17675         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17676   "TARGET_64BIT"
17677   "rdtscp"
17678   [(set_attr "type" "other")
17679    (set_attr "length" "3")])
17680
17681 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17682 ;;
17683 ;; LWP instructions
17684 ;;
17685 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17686
17687 (define_expand "lwp_llwpcb"
17688   [(unspec_volatile [(match_operand 0 "register_operand" "r")]
17689                     UNSPECV_LLWP_INTRINSIC)]
17690   "TARGET_LWP"
17691   "")
17692
17693 (define_insn "*lwp_llwpcb<mode>1"
17694   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
17695                     UNSPECV_LLWP_INTRINSIC)]
17696   "TARGET_LWP"
17697   "llwpcb\t%0"
17698   [(set_attr "type" "lwp")
17699    (set_attr "mode" "<MODE>")
17700    (set_attr "length" "5")])
17701
17702 (define_expand "lwp_slwpcb"
17703   [(set (match_operand 0 "register_operand" "=r")
17704         (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
17705   "TARGET_LWP"
17706   {
17707     if (TARGET_64BIT)
17708       emit_insn (gen_lwp_slwpcbdi (operands[0]));
17709     else
17710       emit_insn (gen_lwp_slwpcbsi (operands[0]));
17711     DONE;
17712   })
17713
17714 (define_insn "lwp_slwpcb<mode>"
17715   [(set (match_operand:P 0 "register_operand" "=r")
17716         (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
17717   "TARGET_LWP"
17718   "slwpcb\t%0"
17719   [(set_attr "type" "lwp")
17720    (set_attr "mode" "<MODE>")
17721    (set_attr "length" "5")])
17722
17723 (define_expand "lwp_lwpval<mode>3"
17724   [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
17725                      (match_operand:SI 2 "nonimmediate_operand" "rm")
17726                      (match_operand:SI 3 "const_int_operand" "i")]
17727                     UNSPECV_LWPVAL_INTRINSIC)]
17728   "TARGET_LWP"
17729   "/* Avoid unused variable warning.  */
17730    (void) operand0;")
17731
17732 (define_insn "*lwp_lwpval<mode>3_1"
17733   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
17734                      (match_operand:SI 1 "nonimmediate_operand" "rm")
17735                      (match_operand:SI 2 "const_int_operand" "i")]
17736                     UNSPECV_LWPVAL_INTRINSIC)]
17737   "TARGET_LWP"
17738   "lwpval\t{%2, %1, %0|%0, %1, %2}"
17739   [(set_attr "type" "lwp")
17740    (set_attr "mode" "<MODE>")
17741    (set (attr "length")
17742         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
17743
17744 (define_expand "lwp_lwpins<mode>3"
17745   [(set (reg:CCC FLAGS_REG)
17746         (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
17747                               (match_operand:SI 2 "nonimmediate_operand" "rm")
17748                               (match_operand:SI 3 "const_int_operand" "i")]
17749                              UNSPECV_LWPINS_INTRINSIC))
17750    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
17751         (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
17752   "TARGET_LWP"
17753   "")
17754
17755 (define_insn "*lwp_lwpins<mode>3_1"
17756   [(set (reg:CCC FLAGS_REG)
17757         (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
17758                               (match_operand:SI 1 "nonimmediate_operand" "rm")
17759                               (match_operand:SI 2 "const_int_operand" "i")]
17760                              UNSPECV_LWPINS_INTRINSIC))]
17761   "TARGET_LWP"
17762   "lwpins\t{%2, %1, %0|%0, %1, %2}"
17763   [(set_attr "type" "lwp")
17764    (set_attr "mode" "<MODE>")
17765    (set (attr "length")
17766         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
17767
17768 (define_insn "rdfsbase<mode>"
17769   [(set (match_operand:SWI48 0 "register_operand" "=r")
17770         (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDFSBASE))]
17771   "TARGET_64BIT && TARGET_FSGSBASE"
17772   "rdfsbase %0"
17773   [(set_attr "type" "other")
17774    (set_attr "prefix_extra" "2")])
17775
17776 (define_insn "rdgsbase<mode>"
17777   [(set (match_operand:SWI48 0 "register_operand" "=r")
17778         (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDGSBASE))]
17779   "TARGET_64BIT && TARGET_FSGSBASE"
17780   "rdgsbase %0"
17781   [(set_attr "type" "other")
17782    (set_attr "prefix_extra" "2")])
17783
17784 (define_insn "wrfsbase<mode>"
17785   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
17786                     UNSPECV_WRFSBASE)]
17787   "TARGET_64BIT && TARGET_FSGSBASE"
17788   "wrfsbase %0"
17789   [(set_attr "type" "other")
17790    (set_attr "prefix_extra" "2")])
17791
17792 (define_insn "wrgsbase<mode>"
17793   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
17794                     UNSPECV_WRGSBASE)]
17795   "TARGET_64BIT && TARGET_FSGSBASE"
17796   "wrgsbase %0"
17797   [(set_attr "type" "other")
17798    (set_attr "prefix_extra" "2")])
17799
17800 (define_expand "rdrand<mode>"
17801   [(set (match_operand:SWI248 0 "register_operand" "=r")
17802         (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))]
17803   "TARGET_RDRND"
17804 {
17805   rtx retry_label, insn, ccc;
17806
17807   retry_label = gen_label_rtx ();
17808
17809   emit_label (retry_label);
17810
17811   /* Generate rdrand.  */
17812   emit_insn (gen_rdrand<mode>_1 (operands[0]));
17813
17814   /* Retry if the carry flag isn't valid.  */
17815   ccc = gen_rtx_REG (CCCmode, FLAGS_REG);
17816   ccc = gen_rtx_EQ (VOIDmode, ccc, const0_rtx);
17817   ccc = gen_rtx_IF_THEN_ELSE (VOIDmode, ccc, pc_rtx,
17818                               gen_rtx_LABEL_REF (VOIDmode, retry_label));
17819   insn = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, ccc));
17820   JUMP_LABEL (insn) = retry_label;
17821
17822   DONE;
17823 })
17824
17825 (define_insn "rdrand<mode>_1"
17826   [(set (match_operand:SWI248 0 "register_operand" "=r")
17827         (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))]
17828   "TARGET_RDRND"
17829   "rdrand %0"
17830   [(set_attr "type" "other")
17831    (set_attr "prefix_extra" "1")])
17832
17833 (include "mmx.md")
17834 (include "sse.md")
17835 (include "sync.md")