OSDN Git Service

* config/i386/i386.md: Remove empty prepartion statements
[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 64BIT abi 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 "general_operand" ""))]
2592   "TARGET_SSE2 && reload_completed
2593    && !SSE_REG_P (operands[1])"
2594   [(const_int 0)]
2595   "ix86_split_long_move (operands); DONE;")
2596
2597 (define_split
2598   [(set (match_operand:TF 0 "push_operand" "")
2599         (match_operand:TF 1 "any_fp_register_operand" ""))]
2600   "TARGET_SSE2"
2601   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2602    (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
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 "any_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    && !ANY_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.  So just
3974 ;; emit moves.
3975
3976 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3977 (define_insn "*dummy_extendsfdf2"
3978   [(set (match_operand:DF 0 "push_operand" "=<")
3979         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY2")))]
3980   "0"
3981   "#")
3982
3983 (define_split
3984   [(set (match_operand:DF 0 "push_operand" "")
3985         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3986   ""
3987   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3988    (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3989
3990 (define_insn "*dummy_extendsfxf2"
3991   [(set (match_operand:XF 0 "push_operand" "=<")
3992         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3993   "0"
3994   "#")
3995
3996 (define_split
3997   [(set (match_operand:XF 0 "push_operand" "")
3998         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3999   ""
4000   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4001    (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4002   "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
4003
4004 (define_split
4005   [(set (match_operand:XF 0 "push_operand" "")
4006         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
4007   ""
4008   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4009    (set (mem:DF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4010   "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
4011
4012 (define_expand "extendsfdf2"
4013   [(set (match_operand:DF 0 "nonimmediate_operand" "")
4014         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
4015   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4016 {
4017   /* ??? Needed for compress_float_constant since all fp constants
4018      are LEGITIMATE_CONSTANT_P.  */
4019   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4020     {
4021       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4022           && standard_80387_constant_p (operands[1]) > 0)
4023         {
4024           operands[1] = simplify_const_unary_operation
4025             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4026           emit_move_insn_1 (operands[0], operands[1]);
4027           DONE;
4028         }
4029       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4030     }
4031 })
4032
4033 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4034    cvtss2sd:
4035       unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4036       cvtps2pd xmm2,xmm1
4037    We do the conversion post reload to avoid producing of 128bit spills
4038    that might lead to ICE on 32bit target.  The sequence unlikely combine
4039    anyway.  */
4040 (define_split
4041   [(set (match_operand:DF 0 "register_operand" "")
4042         (float_extend:DF
4043           (match_operand:SF 1 "nonimmediate_operand" "")))]
4044   "TARGET_USE_VECTOR_FP_CONVERTS
4045    && optimize_insn_for_speed_p ()
4046    && reload_completed && SSE_REG_P (operands[0])"
4047    [(set (match_dup 2)
4048          (float_extend:V2DF
4049            (vec_select:V2SF
4050              (match_dup 3)
4051              (parallel [(const_int 0) (const_int 1)]))))]
4052 {
4053   operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4054   operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4055   /* Use movss for loading from memory, unpcklps reg, reg for registers.
4056      Try to avoid move when unpacking can be done in source.  */
4057   if (REG_P (operands[1]))
4058     {
4059       /* If it is unsafe to overwrite upper half of source, we need
4060          to move to destination and unpack there.  */
4061       if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4062            || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4063           && true_regnum (operands[0]) != true_regnum (operands[1]))
4064         {
4065           rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4066           emit_move_insn (tmp, operands[1]);
4067         }
4068       else
4069         operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4070       emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4071                                              operands[3]));
4072     }
4073   else
4074     emit_insn (gen_vec_setv4sf_0 (operands[3],
4075                                   CONST0_RTX (V4SFmode), operands[1]));
4076 })
4077
4078 (define_insn "*extendsfdf2_mixed"
4079   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4080         (float_extend:DF
4081           (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4082   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4083 {
4084   switch (which_alternative)
4085     {
4086     case 0:
4087     case 1:
4088       return output_387_reg_move (insn, operands);
4089
4090     case 2:
4091       return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4092
4093     default:
4094       gcc_unreachable ();
4095     }
4096 }
4097   [(set_attr "type" "fmov,fmov,ssecvt")
4098    (set_attr "prefix" "orig,orig,maybe_vex")
4099    (set_attr "mode" "SF,XF,DF")])
4100
4101 (define_insn "*extendsfdf2_sse"
4102   [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4103         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4104   "TARGET_SSE2 && TARGET_SSE_MATH"
4105   "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4106   [(set_attr "type" "ssecvt")
4107    (set_attr "prefix" "maybe_vex")
4108    (set_attr "mode" "DF")])
4109
4110 (define_insn "*extendsfdf2_i387"
4111   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4112         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4113   "TARGET_80387"
4114   "* return output_387_reg_move (insn, operands);"
4115   [(set_attr "type" "fmov")
4116    (set_attr "mode" "SF,XF")])
4117
4118 (define_expand "extend<mode>xf2"
4119   [(set (match_operand:XF 0 "nonimmediate_operand" "")
4120         (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4121   "TARGET_80387"
4122 {
4123   /* ??? Needed for compress_float_constant since all fp constants
4124      are LEGITIMATE_CONSTANT_P.  */
4125   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4126     {
4127       if (standard_80387_constant_p (operands[1]) > 0)
4128         {
4129           operands[1] = simplify_const_unary_operation
4130             (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4131           emit_move_insn_1 (operands[0], operands[1]);
4132           DONE;
4133         }
4134       operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4135     }
4136 })
4137
4138 (define_insn "*extend<mode>xf2_i387"
4139   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4140         (float_extend:XF
4141           (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4142   "TARGET_80387"
4143   "* return output_387_reg_move (insn, operands);"
4144   [(set_attr "type" "fmov")
4145    (set_attr "mode" "<MODE>,XF")])
4146
4147 ;; %%% This seems bad bad news.
4148 ;; This cannot output into an f-reg because there is no way to be sure
4149 ;; of truncating in that case.  Otherwise this is just like a simple move
4150 ;; insn.  So we pretend we can output to a reg in order to get better
4151 ;; register preferencing, but we really use a stack slot.
4152
4153 ;; Conversion from DFmode to SFmode.
4154
4155 (define_expand "truncdfsf2"
4156   [(set (match_operand:SF 0 "nonimmediate_operand" "")
4157         (float_truncate:SF
4158           (match_operand:DF 1 "nonimmediate_operand" "")))]
4159   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4160 {
4161   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4162     ;
4163   else if (flag_unsafe_math_optimizations)
4164     ;
4165   else
4166     {
4167       enum ix86_stack_slot slot = (virtuals_instantiated
4168                                    ? SLOT_TEMP
4169                                    : SLOT_VIRTUAL);
4170       rtx temp = assign_386_stack_local (SFmode, slot);
4171       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4172       DONE;
4173     }
4174 })
4175
4176 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4177    cvtsd2ss:
4178       unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4179       cvtpd2ps xmm2,xmm1
4180    We do the conversion post reload to avoid producing of 128bit spills
4181    that might lead to ICE on 32bit target.  The sequence unlikely combine
4182    anyway.  */
4183 (define_split
4184   [(set (match_operand:SF 0 "register_operand" "")
4185         (float_truncate:SF
4186           (match_operand:DF 1 "nonimmediate_operand" "")))]
4187   "TARGET_USE_VECTOR_FP_CONVERTS
4188    && optimize_insn_for_speed_p ()
4189    && reload_completed && SSE_REG_P (operands[0])"
4190    [(set (match_dup 2)
4191          (vec_concat:V4SF
4192            (float_truncate:V2SF
4193              (match_dup 4))
4194            (match_dup 3)))]
4195 {
4196   operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4197   operands[3] = CONST0_RTX (V2SFmode);
4198   operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4199   /* Use movsd for loading from memory, unpcklpd for registers.
4200      Try to avoid move when unpacking can be done in source, or SSE3
4201      movddup is available.  */
4202   if (REG_P (operands[1]))
4203     {
4204       if (!TARGET_SSE3
4205           && true_regnum (operands[0]) != true_regnum (operands[1])
4206           && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4207               || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4208         {
4209           rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4210           emit_move_insn (tmp, operands[1]);
4211           operands[1] = tmp;
4212         }
4213       else if (!TARGET_SSE3)
4214         operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4215       emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4216     }
4217   else
4218     emit_insn (gen_sse2_loadlpd (operands[4],
4219                                  CONST0_RTX (V2DFmode), operands[1]));
4220 })
4221
4222 (define_expand "truncdfsf2_with_temp"
4223   [(parallel [(set (match_operand:SF 0 "" "")
4224                    (float_truncate:SF (match_operand:DF 1 "" "")))
4225               (clobber (match_operand:SF 2 "" ""))])]
4226   "")
4227
4228 (define_insn "*truncdfsf_fast_mixed"
4229   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm,x")
4230         (float_truncate:SF
4231           (match_operand:DF 1 "nonimmediate_operand" "f  ,xm")))]
4232   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4233 {
4234   switch (which_alternative)
4235     {
4236     case 0:
4237       return output_387_reg_move (insn, operands);
4238     case 1:
4239       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4240     default:
4241       gcc_unreachable ();
4242     }
4243 }
4244   [(set_attr "type" "fmov,ssecvt")
4245    (set_attr "prefix" "orig,maybe_vex")
4246    (set_attr "mode" "SF")])
4247
4248 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4249 ;; because nothing we do here is unsafe.
4250 (define_insn "*truncdfsf_fast_sse"
4251   [(set (match_operand:SF 0 "nonimmediate_operand"   "=x")
4252         (float_truncate:SF
4253           (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4254   "TARGET_SSE2 && TARGET_SSE_MATH"
4255   "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4256   [(set_attr "type" "ssecvt")
4257    (set_attr "prefix" "maybe_vex")
4258    (set_attr "mode" "SF")])
4259
4260 (define_insn "*truncdfsf_fast_i387"
4261   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
4262         (float_truncate:SF
4263           (match_operand:DF 1 "nonimmediate_operand" "f")))]
4264   "TARGET_80387 && flag_unsafe_math_optimizations"
4265   "* return output_387_reg_move (insn, operands);"
4266   [(set_attr "type" "fmov")
4267    (set_attr "mode" "SF")])
4268
4269 (define_insn "*truncdfsf_mixed"
4270   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,Y2 ,?f,?x,?*r")
4271         (float_truncate:SF
4272           (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4273    (clobber (match_operand:SF 2 "memory_operand"     "=X,X  ,m ,m ,m"))]
4274   "TARGET_MIX_SSE_I387"
4275 {
4276   switch (which_alternative)
4277     {
4278     case 0:
4279       return output_387_reg_move (insn, operands);
4280     case 1:
4281       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4282
4283     default:
4284       return "#";
4285     }
4286 }
4287   [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4288    (set_attr "unit" "*,*,i387,i387,i387")
4289    (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4290    (set_attr "mode" "SF")])
4291
4292 (define_insn "*truncdfsf_i387"
4293   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?f,?x,?*r")
4294         (float_truncate:SF
4295           (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4296    (clobber (match_operand:SF 2 "memory_operand"     "=X,m ,m ,m"))]
4297   "TARGET_80387"
4298 {
4299   switch (which_alternative)
4300     {
4301     case 0:
4302       return output_387_reg_move (insn, operands);
4303
4304     default:
4305       return "#";
4306     }
4307 }
4308   [(set_attr "type" "fmov,multi,multi,multi")
4309    (set_attr "unit" "*,i387,i387,i387")
4310    (set_attr "mode" "SF")])
4311
4312 (define_insn "*truncdfsf2_i387_1"
4313   [(set (match_operand:SF 0 "memory_operand" "=m")
4314         (float_truncate:SF
4315           (match_operand:DF 1 "register_operand" "f")))]
4316   "TARGET_80387
4317    && !(TARGET_SSE2 && TARGET_SSE_MATH)
4318    && !TARGET_MIX_SSE_I387"
4319   "* return output_387_reg_move (insn, operands);"
4320   [(set_attr "type" "fmov")
4321    (set_attr "mode" "SF")])
4322
4323 (define_split
4324   [(set (match_operand:SF 0 "register_operand" "")
4325         (float_truncate:SF
4326          (match_operand:DF 1 "fp_register_operand" "")))
4327    (clobber (match_operand 2 "" ""))]
4328   "reload_completed"
4329   [(set (match_dup 2) (match_dup 1))
4330    (set (match_dup 0) (match_dup 2))]
4331   "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4332
4333 ;; Conversion from XFmode to {SF,DF}mode
4334
4335 (define_expand "truncxf<mode>2"
4336   [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4337                    (float_truncate:MODEF
4338                      (match_operand:XF 1 "register_operand" "")))
4339               (clobber (match_dup 2))])]
4340   "TARGET_80387"
4341 {
4342   if (flag_unsafe_math_optimizations)
4343     {
4344       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4345       emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4346       if (reg != operands[0])
4347         emit_move_insn (operands[0], reg);
4348       DONE;
4349     }
4350   else
4351     {
4352      enum ix86_stack_slot slot = (virtuals_instantiated
4353                                   ? SLOT_TEMP
4354                                   : SLOT_VIRTUAL);
4355       operands[2] = assign_386_stack_local (<MODE>mode, slot);
4356     }
4357 })
4358
4359 (define_insn "*truncxfsf2_mixed"
4360   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4361         (float_truncate:SF
4362           (match_operand:XF 1 "register_operand"   "f ,f ,f ,f")))
4363    (clobber (match_operand:SF 2 "memory_operand"   "=X,m ,m ,m"))]
4364   "TARGET_80387"
4365 {
4366   gcc_assert (!which_alternative);
4367   return output_387_reg_move (insn, operands);
4368 }
4369   [(set_attr "type" "fmov,multi,multi,multi")
4370    (set_attr "unit" "*,i387,i387,i387")
4371    (set_attr "mode" "SF")])
4372
4373 (define_insn "*truncxfdf2_mixed"
4374   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4375         (float_truncate:DF
4376           (match_operand:XF 1 "register_operand"   "f ,f ,f  ,f")))
4377    (clobber (match_operand:DF 2 "memory_operand"   "=X,m ,m  ,m"))]
4378   "TARGET_80387"
4379 {
4380   gcc_assert (!which_alternative);
4381   return output_387_reg_move (insn, operands);
4382 }
4383   [(set_attr "type" "fmov,multi,multi,multi")
4384    (set_attr "unit" "*,i387,i387,i387")
4385    (set_attr "mode" "DF")])
4386
4387 (define_insn "truncxf<mode>2_i387_noop"
4388   [(set (match_operand:MODEF 0 "register_operand" "=f")
4389         (float_truncate:MODEF
4390           (match_operand:XF 1 "register_operand" "f")))]
4391   "TARGET_80387 && flag_unsafe_math_optimizations"
4392   "* return output_387_reg_move (insn, operands);"
4393   [(set_attr "type" "fmov")
4394    (set_attr "mode" "<MODE>")])
4395
4396 (define_insn "*truncxf<mode>2_i387"
4397   [(set (match_operand:MODEF 0 "memory_operand" "=m")
4398         (float_truncate:MODEF
4399           (match_operand:XF 1 "register_operand" "f")))]
4400   "TARGET_80387"
4401   "* return output_387_reg_move (insn, operands);"
4402   [(set_attr "type" "fmov")
4403    (set_attr "mode" "<MODE>")])
4404
4405 (define_split
4406   [(set (match_operand:MODEF 0 "register_operand" "")
4407         (float_truncate:MODEF
4408           (match_operand:XF 1 "register_operand" "")))
4409    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4410   "TARGET_80387 && reload_completed"
4411   [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4412    (set (match_dup 0) (match_dup 2))])
4413
4414 (define_split
4415   [(set (match_operand:MODEF 0 "memory_operand" "")
4416         (float_truncate:MODEF
4417           (match_operand:XF 1 "register_operand" "")))
4418    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4419   "TARGET_80387"
4420   [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4421 \f
4422 ;; Signed conversion to DImode.
4423
4424 (define_expand "fix_truncxfdi2"
4425   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4426                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4427               (clobber (reg:CC FLAGS_REG))])]
4428   "TARGET_80387"
4429 {
4430   if (TARGET_FISTTP)
4431    {
4432      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4433      DONE;
4434    }
4435 })
4436
4437 (define_expand "fix_trunc<mode>di2"
4438   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4439                    (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4440               (clobber (reg:CC FLAGS_REG))])]
4441   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4442 {
4443   if (TARGET_FISTTP
4444       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4445    {
4446      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4447      DONE;
4448    }
4449   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4450    {
4451      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4452      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4453      if (out != operands[0])
4454         emit_move_insn (operands[0], out);
4455      DONE;
4456    }
4457 })
4458
4459 ;; Signed conversion to SImode.
4460
4461 (define_expand "fix_truncxfsi2"
4462   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4463                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4464               (clobber (reg:CC FLAGS_REG))])]
4465   "TARGET_80387"
4466 {
4467   if (TARGET_FISTTP)
4468    {
4469      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4470      DONE;
4471    }
4472 })
4473
4474 (define_expand "fix_trunc<mode>si2"
4475   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4476                    (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4477               (clobber (reg:CC FLAGS_REG))])]
4478   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4479 {
4480   if (TARGET_FISTTP
4481       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4482    {
4483      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4484      DONE;
4485    }
4486   if (SSE_FLOAT_MODE_P (<MODE>mode))
4487    {
4488      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4489      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4490      if (out != operands[0])
4491         emit_move_insn (operands[0], out);
4492      DONE;
4493    }
4494 })
4495
4496 ;; Signed conversion to HImode.
4497
4498 (define_expand "fix_trunc<mode>hi2"
4499   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4500                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4501               (clobber (reg:CC FLAGS_REG))])]
4502   "TARGET_80387
4503    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4504 {
4505   if (TARGET_FISTTP)
4506    {
4507      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4508      DONE;
4509    }
4510 })
4511
4512 ;; Unsigned conversion to SImode.
4513
4514 (define_expand "fixuns_trunc<mode>si2"
4515   [(parallel
4516     [(set (match_operand:SI 0 "register_operand" "")
4517           (unsigned_fix:SI
4518             (match_operand:MODEF 1 "nonimmediate_operand" "")))
4519      (use (match_dup 2))
4520      (clobber (match_scratch:<ssevecmode> 3 ""))
4521      (clobber (match_scratch:<ssevecmode> 4 ""))])]
4522   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4523 {
4524   enum machine_mode mode = <MODE>mode;
4525   enum machine_mode vecmode = <ssevecmode>mode;
4526   REAL_VALUE_TYPE TWO31r;
4527   rtx two31;
4528
4529   if (optimize_insn_for_size_p ())
4530     FAIL;
4531
4532   real_ldexp (&TWO31r, &dconst1, 31);
4533   two31 = const_double_from_real_value (TWO31r, mode);
4534   two31 = ix86_build_const_vector (mode, true, two31);
4535   operands[2] = force_reg (vecmode, two31);
4536 })
4537
4538 (define_insn_and_split "*fixuns_trunc<mode>_1"
4539   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4540         (unsigned_fix:SI
4541           (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4542    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
4543    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4544    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4545   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4546    && optimize_function_for_speed_p (cfun)"
4547   "#"
4548   "&& reload_completed"
4549   [(const_int 0)]
4550 {
4551   ix86_split_convert_uns_si_sse (operands);
4552   DONE;
4553 })
4554
4555 ;; Unsigned conversion to HImode.
4556 ;; Without these patterns, we'll try the unsigned SI conversion which
4557 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4558
4559 (define_expand "fixuns_trunc<mode>hi2"
4560   [(set (match_dup 2)
4561         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4562    (set (match_operand:HI 0 "nonimmediate_operand" "")
4563         (subreg:HI (match_dup 2) 0))]
4564   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4565   "operands[2] = gen_reg_rtx (SImode);")
4566
4567 ;; When SSE is available, it is always faster to use it!
4568 (define_insn "fix_trunc<mode>di_sse"
4569   [(set (match_operand:DI 0 "register_operand" "=r,r")
4570         (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4571   "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4572    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4573   "%vcvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4574   [(set_attr "type" "sseicvt")
4575    (set_attr "prefix" "maybe_vex")
4576    (set_attr "prefix_rex" "1")
4577    (set_attr "mode" "<MODE>")
4578    (set_attr "athlon_decode" "double,vector")
4579    (set_attr "amdfam10_decode" "double,double")])
4580
4581 (define_insn "fix_trunc<mode>si_sse"
4582   [(set (match_operand:SI 0 "register_operand" "=r,r")
4583         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4584   "SSE_FLOAT_MODE_P (<MODE>mode)
4585    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4586   "%vcvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4587   [(set_attr "type" "sseicvt")
4588    (set_attr "prefix" "maybe_vex")
4589    (set_attr "mode" "<MODE>")
4590    (set_attr "athlon_decode" "double,vector")
4591    (set_attr "amdfam10_decode" "double,double")])
4592
4593 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4594 (define_peephole2
4595   [(set (match_operand:MODEF 0 "register_operand" "")
4596         (match_operand:MODEF 1 "memory_operand" ""))
4597    (set (match_operand:SSEMODEI24 2 "register_operand" "")
4598         (fix:SSEMODEI24 (match_dup 0)))]
4599   "TARGET_SHORTEN_X87_SSE
4600    && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4601    && peep2_reg_dead_p (2, operands[0])"
4602   [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))])
4603
4604 ;; Avoid vector decoded forms of the instruction.
4605 (define_peephole2
4606   [(match_scratch:DF 2 "Y2")
4607    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4608         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4609   "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4610   [(set (match_dup 2) (match_dup 1))
4611    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))])
4612
4613 (define_peephole2
4614   [(match_scratch:SF 2 "x")
4615    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4616         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4617   "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4618   [(set (match_dup 2) (match_dup 1))
4619    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))])
4620
4621 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4622   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4623         (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4624   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4625    && TARGET_FISTTP
4626    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4627          && (TARGET_64BIT || <MODE>mode != DImode))
4628         && TARGET_SSE_MATH)
4629    && can_create_pseudo_p ()"
4630   "#"
4631   "&& 1"
4632   [(const_int 0)]
4633 {
4634   if (memory_operand (operands[0], VOIDmode))
4635     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4636   else
4637     {
4638       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4639       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4640                                                             operands[1],
4641                                                             operands[2]));
4642     }
4643   DONE;
4644 }
4645   [(set_attr "type" "fisttp")
4646    (set_attr "mode" "<MODE>")])
4647
4648 (define_insn "fix_trunc<mode>_i387_fisttp"
4649   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4650         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4651    (clobber (match_scratch:XF 2 "=&1f"))]
4652   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4653    && TARGET_FISTTP
4654    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4655          && (TARGET_64BIT || <MODE>mode != DImode))
4656         && TARGET_SSE_MATH)"
4657   "* return output_fix_trunc (insn, operands, 1);"
4658   [(set_attr "type" "fisttp")
4659    (set_attr "mode" "<MODE>")])
4660
4661 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4662   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4663         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4664    (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
4665    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4666   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4667    && TARGET_FISTTP
4668    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4669         && (TARGET_64BIT || <MODE>mode != DImode))
4670         && TARGET_SSE_MATH)"
4671   "#"
4672   [(set_attr "type" "fisttp")
4673    (set_attr "mode" "<MODE>")])
4674
4675 (define_split
4676   [(set (match_operand:X87MODEI 0 "register_operand" "")
4677         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4678    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4679    (clobber (match_scratch 3 ""))]
4680   "reload_completed"
4681   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4682               (clobber (match_dup 3))])
4683    (set (match_dup 0) (match_dup 2))])
4684
4685 (define_split
4686   [(set (match_operand:X87MODEI 0 "memory_operand" "")
4687         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4688    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4689    (clobber (match_scratch 3 ""))]
4690   "reload_completed"
4691   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4692               (clobber (match_dup 3))])])
4693
4694 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4695 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4696 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4697 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4698 ;; function in i386.c.
4699 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4700   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4701         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4702    (clobber (reg:CC FLAGS_REG))]
4703   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4704    && !TARGET_FISTTP
4705    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4706          && (TARGET_64BIT || <MODE>mode != DImode))
4707    && can_create_pseudo_p ()"
4708   "#"
4709   "&& 1"
4710   [(const_int 0)]
4711 {
4712   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4713
4714   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4715   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4716   if (memory_operand (operands[0], VOIDmode))
4717     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4718                                          operands[2], operands[3]));
4719   else
4720     {
4721       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4722       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4723                                                      operands[2], operands[3],
4724                                                      operands[4]));
4725     }
4726   DONE;
4727 }
4728   [(set_attr "type" "fistp")
4729    (set_attr "i387_cw" "trunc")
4730    (set_attr "mode" "<MODE>")])
4731
4732 (define_insn "fix_truncdi_i387"
4733   [(set (match_operand:DI 0 "memory_operand" "=m")
4734         (fix:DI (match_operand 1 "register_operand" "f")))
4735    (use (match_operand:HI 2 "memory_operand" "m"))
4736    (use (match_operand:HI 3 "memory_operand" "m"))
4737    (clobber (match_scratch:XF 4 "=&1f"))]
4738   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4739    && !TARGET_FISTTP
4740    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4741   "* return output_fix_trunc (insn, operands, 0);"
4742   [(set_attr "type" "fistp")
4743    (set_attr "i387_cw" "trunc")
4744    (set_attr "mode" "DI")])
4745
4746 (define_insn "fix_truncdi_i387_with_temp"
4747   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4748         (fix:DI (match_operand 1 "register_operand" "f,f")))
4749    (use (match_operand:HI 2 "memory_operand" "m,m"))
4750    (use (match_operand:HI 3 "memory_operand" "m,m"))
4751    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4752    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4753   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4754    && !TARGET_FISTTP
4755    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4756   "#"
4757   [(set_attr "type" "fistp")
4758    (set_attr "i387_cw" "trunc")
4759    (set_attr "mode" "DI")])
4760
4761 (define_split
4762   [(set (match_operand:DI 0 "register_operand" "")
4763         (fix:DI (match_operand 1 "register_operand" "")))
4764    (use (match_operand:HI 2 "memory_operand" ""))
4765    (use (match_operand:HI 3 "memory_operand" ""))
4766    (clobber (match_operand:DI 4 "memory_operand" ""))
4767    (clobber (match_scratch 5 ""))]
4768   "reload_completed"
4769   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4770               (use (match_dup 2))
4771               (use (match_dup 3))
4772               (clobber (match_dup 5))])
4773    (set (match_dup 0) (match_dup 4))])
4774
4775 (define_split
4776   [(set (match_operand:DI 0 "memory_operand" "")
4777         (fix:DI (match_operand 1 "register_operand" "")))
4778    (use (match_operand:HI 2 "memory_operand" ""))
4779    (use (match_operand:HI 3 "memory_operand" ""))
4780    (clobber (match_operand:DI 4 "memory_operand" ""))
4781    (clobber (match_scratch 5 ""))]
4782   "reload_completed"
4783   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4784               (use (match_dup 2))
4785               (use (match_dup 3))
4786               (clobber (match_dup 5))])])
4787
4788 (define_insn "fix_trunc<mode>_i387"
4789   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4790         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4791    (use (match_operand:HI 2 "memory_operand" "m"))
4792    (use (match_operand:HI 3 "memory_operand" "m"))]
4793   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4794    && !TARGET_FISTTP
4795    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4796   "* return output_fix_trunc (insn, operands, 0);"
4797   [(set_attr "type" "fistp")
4798    (set_attr "i387_cw" "trunc")
4799    (set_attr "mode" "<MODE>")])
4800
4801 (define_insn "fix_trunc<mode>_i387_with_temp"
4802   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4803         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4804    (use (match_operand:HI 2 "memory_operand" "m,m"))
4805    (use (match_operand:HI 3 "memory_operand" "m,m"))
4806    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
4807   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4808    && !TARGET_FISTTP
4809    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4810   "#"
4811   [(set_attr "type" "fistp")
4812    (set_attr "i387_cw" "trunc")
4813    (set_attr "mode" "<MODE>")])
4814
4815 (define_split
4816   [(set (match_operand:X87MODEI12 0 "register_operand" "")
4817         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4818    (use (match_operand:HI 2 "memory_operand" ""))
4819    (use (match_operand:HI 3 "memory_operand" ""))
4820    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4821   "reload_completed"
4822   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4823               (use (match_dup 2))
4824               (use (match_dup 3))])
4825    (set (match_dup 0) (match_dup 4))])
4826
4827 (define_split
4828   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4829         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4830    (use (match_operand:HI 2 "memory_operand" ""))
4831    (use (match_operand:HI 3 "memory_operand" ""))
4832    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4833   "reload_completed"
4834   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4835               (use (match_dup 2))
4836               (use (match_dup 3))])])
4837
4838 (define_insn "x86_fnstcw_1"
4839   [(set (match_operand:HI 0 "memory_operand" "=m")
4840         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4841   "TARGET_80387"
4842   "fnstcw\t%0"
4843   [(set (attr "length")
4844         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4845    (set_attr "mode" "HI")
4846    (set_attr "unit" "i387")])
4847
4848 (define_insn "x86_fldcw_1"
4849   [(set (reg:HI FPCR_REG)
4850         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4851   "TARGET_80387"
4852   "fldcw\t%0"
4853   [(set (attr "length")
4854         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4855    (set_attr "mode" "HI")
4856    (set_attr "unit" "i387")
4857    (set_attr "athlon_decode" "vector")
4858    (set_attr "amdfam10_decode" "vector")])
4859 \f
4860 ;; Conversion between fixed point and floating point.
4861
4862 ;; Even though we only accept memory inputs, the backend _really_
4863 ;; wants to be able to do this between registers.
4864
4865 (define_expand "floathi<mode>2"
4866   [(set (match_operand:X87MODEF 0 "register_operand" "")
4867         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4868   "TARGET_80387
4869    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4870        || TARGET_MIX_SSE_I387)"
4871   "")
4872
4873 ;; Pre-reload splitter to add memory clobber to the pattern.
4874 (define_insn_and_split "*floathi<mode>2_1"
4875   [(set (match_operand:X87MODEF 0 "register_operand" "")
4876         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4877   "TARGET_80387
4878    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4879        || TARGET_MIX_SSE_I387)
4880    && can_create_pseudo_p ()"
4881   "#"
4882   "&& 1"
4883   [(parallel [(set (match_dup 0)
4884               (float:X87MODEF (match_dup 1)))
4885    (clobber (match_dup 2))])]
4886   "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4887
4888 (define_insn "*floathi<mode>2_i387_with_temp"
4889   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4890         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4891   (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
4892   "TARGET_80387
4893    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4894        || TARGET_MIX_SSE_I387)"
4895   "#"
4896   [(set_attr "type" "fmov,multi")
4897    (set_attr "mode" "<MODE>")
4898    (set_attr "unit" "*,i387")
4899    (set_attr "fp_int_src" "true")])
4900
4901 (define_insn "*floathi<mode>2_i387"
4902   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4903         (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4904   "TARGET_80387
4905    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4906        || TARGET_MIX_SSE_I387)"
4907   "fild%Z1\t%1"
4908   [(set_attr "type" "fmov")
4909    (set_attr "mode" "<MODE>")
4910    (set_attr "fp_int_src" "true")])
4911
4912 (define_split
4913   [(set (match_operand:X87MODEF 0 "register_operand" "")
4914         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4915    (clobber (match_operand:HI 2 "memory_operand" ""))]
4916   "TARGET_80387
4917    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4918        || TARGET_MIX_SSE_I387)
4919    && reload_completed"
4920   [(set (match_dup 2) (match_dup 1))
4921    (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4922
4923 (define_split
4924   [(set (match_operand:X87MODEF 0 "register_operand" "")
4925         (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
4926    (clobber (match_operand:HI 2 "memory_operand" ""))]
4927    "TARGET_80387
4928     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4929         || TARGET_MIX_SSE_I387)
4930     && reload_completed"
4931   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4932
4933 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
4934   [(set (match_operand:X87MODEF 0 "register_operand" "")
4935         (float:X87MODEF
4936           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
4937   "TARGET_80387
4938    || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4939        && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4940 {
4941   if (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4942         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4943       && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode))
4944     {
4945       rtx reg = gen_reg_rtx (XFmode);
4946       rtx insn;
4947
4948       emit_insn (gen_float<SSEMODEI24:mode>xf2 (reg, operands[1]));
4949
4950       if (<X87MODEF:MODE>mode == SFmode)
4951         insn = gen_truncxfsf2 (operands[0], reg);
4952       else if (<X87MODEF:MODE>mode == DFmode)
4953         insn = gen_truncxfdf2 (operands[0], reg);
4954       else
4955         gcc_unreachable ();
4956
4957       emit_insn (insn);
4958       DONE;
4959     }
4960 })
4961
4962 ;; Pre-reload splitter to add memory clobber to the pattern.
4963 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
4964   [(set (match_operand:X87MODEF 0 "register_operand" "")
4965         (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
4966   "((TARGET_80387
4967      && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
4968      && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4969            && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4970          || TARGET_MIX_SSE_I387))
4971     || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4972         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4973         && ((<SSEMODEI24:MODE>mode == SImode
4974              && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4975              && optimize_function_for_speed_p (cfun)
4976              && flag_trapping_math)
4977             || !(TARGET_INTER_UNIT_CONVERSIONS
4978                  || optimize_function_for_size_p (cfun)))))
4979    && can_create_pseudo_p ()"
4980   "#"
4981   "&& 1"
4982   [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4983               (clobber (match_dup 2))])]
4984 {
4985   operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
4986
4987   /* Avoid store forwarding (partial memory) stall penalty
4988      by passing DImode value through XMM registers.  */
4989   if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
4990       && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4991       && optimize_function_for_speed_p (cfun))
4992     {
4993       emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4994                                                             operands[1],
4995                                                             operands[2]));
4996       DONE;
4997     }
4998 })
4999
5000 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
5001   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
5002         (float:MODEF
5003           (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
5004    (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
5005   "TARGET_SSE2 && TARGET_MIX_SSE_I387
5006    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5007   "#"
5008   [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
5009    (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
5010    (set_attr "unit" "*,i387,*,*,*")
5011    (set_attr "athlon_decode" "*,*,double,direct,double")
5012    (set_attr "amdfam10_decode" "*,*,vector,double,double")
5013    (set_attr "fp_int_src" "true")])
5014
5015 (define_insn "*floatsi<mode>2_vector_mixed"
5016   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5017         (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
5018   "TARGET_SSE2 && TARGET_MIX_SSE_I387
5019    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5020   "@
5021    fild%Z1\t%1
5022    #"
5023   [(set_attr "type" "fmov,sseicvt")
5024    (set_attr "mode" "<MODE>,<ssevecmode>")
5025    (set_attr "unit" "i387,*")
5026    (set_attr "athlon_decode" "*,direct")
5027    (set_attr "amdfam10_decode" "*,double")
5028    (set_attr "fp_int_src" "true")])
5029
5030 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
5031   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
5032         (float:MODEF
5033           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
5034   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
5035   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5036    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
5037   "#"
5038   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5039    (set_attr "mode" "<MODEF:MODE>")
5040    (set_attr "unit" "*,i387,*,*")
5041    (set_attr "athlon_decode" "*,*,double,direct")
5042    (set_attr "amdfam10_decode" "*,*,vector,double")
5043    (set_attr "fp_int_src" "true")])
5044
5045 (define_split
5046   [(set (match_operand:MODEF 0 "register_operand" "")
5047         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5048    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5049   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5050    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5051    && TARGET_INTER_UNIT_CONVERSIONS
5052    && reload_completed
5053    && (SSE_REG_P (operands[0])
5054        || (GET_CODE (operands[0]) == SUBREG
5055            && SSE_REG_P (operands[0])))"
5056   [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5057
5058 (define_split
5059   [(set (match_operand:MODEF 0 "register_operand" "")
5060         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5061    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5062   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5063    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5064    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5065    && reload_completed
5066    && (SSE_REG_P (operands[0])
5067        || (GET_CODE (operands[0]) == SUBREG
5068            && SSE_REG_P (operands[0])))"
5069   [(set (match_dup 2) (match_dup 1))
5070    (set (match_dup 0) (float:MODEF (match_dup 2)))])
5071
5072 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5073   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5074         (float:MODEF
5075           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
5076   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5077    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5078    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5079   "@
5080    fild%Z1\t%1
5081    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
5082    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5083   [(set_attr "type" "fmov,sseicvt,sseicvt")
5084    (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5085    (set_attr "mode" "<MODEF:MODE>")
5086    (set (attr "prefix_rex")
5087      (if_then_else
5088        (and (eq_attr "prefix" "maybe_vex")
5089             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5090        (const_string "1")
5091        (const_string "*")))
5092    (set_attr "unit" "i387,*,*")
5093    (set_attr "athlon_decode" "*,double,direct")
5094    (set_attr "amdfam10_decode" "*,vector,double")
5095    (set_attr "fp_int_src" "true")])
5096
5097 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5098   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5099         (float:MODEF
5100           (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5101   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5102    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5103    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5104   "@
5105    fild%Z1\t%1
5106    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5107   [(set_attr "type" "fmov,sseicvt")
5108    (set_attr "prefix" "orig,maybe_vex")
5109    (set_attr "mode" "<MODEF:MODE>")
5110    (set (attr "prefix_rex")
5111      (if_then_else
5112        (and (eq_attr "prefix" "maybe_vex")
5113             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5114        (const_string "1")
5115        (const_string "*")))
5116    (set_attr "athlon_decode" "*,direct")
5117    (set_attr "amdfam10_decode" "*,double")
5118    (set_attr "fp_int_src" "true")])
5119
5120 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5121   [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5122         (float:MODEF
5123           (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5124    (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5125   "TARGET_SSE2 && TARGET_SSE_MATH
5126    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5127   "#"
5128   [(set_attr "type" "sseicvt")
5129    (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5130    (set_attr "athlon_decode" "double,direct,double")
5131    (set_attr "amdfam10_decode" "vector,double,double")
5132    (set_attr "fp_int_src" "true")])
5133
5134 (define_insn "*floatsi<mode>2_vector_sse"
5135   [(set (match_operand:MODEF 0 "register_operand" "=x")
5136         (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5137   "TARGET_SSE2 && TARGET_SSE_MATH
5138    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5139   "#"
5140   [(set_attr "type" "sseicvt")
5141    (set_attr "mode" "<MODE>")
5142    (set_attr "athlon_decode" "direct")
5143    (set_attr "amdfam10_decode" "double")
5144    (set_attr "fp_int_src" "true")])
5145
5146 (define_split
5147   [(set (match_operand:MODEF 0 "register_operand" "")
5148         (float:MODEF (match_operand:SI 1 "register_operand" "")))
5149    (clobber (match_operand:SI 2 "memory_operand" ""))]
5150   "TARGET_SSE2 && TARGET_SSE_MATH
5151    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5152    && reload_completed
5153    && (SSE_REG_P (operands[0])
5154        || (GET_CODE (operands[0]) == SUBREG
5155            && SSE_REG_P (operands[0])))"
5156   [(const_int 0)]
5157 {
5158   rtx op1 = operands[1];
5159
5160   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5161                                      <MODE>mode, 0);
5162   if (GET_CODE (op1) == SUBREG)
5163     op1 = SUBREG_REG (op1);
5164
5165   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5166     {
5167       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5168       emit_insn (gen_sse2_loadld (operands[4],
5169                                   CONST0_RTX (V4SImode), operands[1]));
5170     }
5171   /* We can ignore possible trapping value in the
5172      high part of SSE register for non-trapping math. */
5173   else if (SSE_REG_P (op1) && !flag_trapping_math)
5174     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5175   else
5176     {
5177       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5178       emit_move_insn (operands[2], operands[1]);
5179       emit_insn (gen_sse2_loadld (operands[4],
5180                                   CONST0_RTX (V4SImode), operands[2]));
5181     }
5182   emit_insn
5183     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5184   DONE;
5185 })
5186
5187 (define_split
5188   [(set (match_operand:MODEF 0 "register_operand" "")
5189         (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5190    (clobber (match_operand:SI 2 "memory_operand" ""))]
5191   "TARGET_SSE2 && TARGET_SSE_MATH
5192    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5193    && reload_completed
5194    && (SSE_REG_P (operands[0])
5195        || (GET_CODE (operands[0]) == SUBREG
5196            && SSE_REG_P (operands[0])))"
5197   [(const_int 0)]
5198 {
5199   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5200                                      <MODE>mode, 0);
5201   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5202
5203   emit_insn (gen_sse2_loadld (operands[4],
5204                               CONST0_RTX (V4SImode), operands[1]));
5205   emit_insn
5206     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5207   DONE;
5208 })
5209
5210 (define_split
5211   [(set (match_operand:MODEF 0 "register_operand" "")
5212         (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5213   "TARGET_SSE2 && TARGET_SSE_MATH
5214    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5215    && reload_completed
5216    && (SSE_REG_P (operands[0])
5217        || (GET_CODE (operands[0]) == SUBREG
5218            && SSE_REG_P (operands[0])))"
5219   [(const_int 0)]
5220 {
5221   rtx op1 = operands[1];
5222
5223   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5224                                      <MODE>mode, 0);
5225   if (GET_CODE (op1) == SUBREG)
5226     op1 = SUBREG_REG (op1);
5227
5228   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5229     {
5230       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5231       emit_insn (gen_sse2_loadld (operands[4],
5232                                   CONST0_RTX (V4SImode), operands[1]));
5233     }
5234   /* We can ignore possible trapping value in the
5235      high part of SSE register for non-trapping math. */
5236   else if (SSE_REG_P (op1) && !flag_trapping_math)
5237     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5238   else
5239     gcc_unreachable ();
5240   emit_insn
5241     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5242   DONE;
5243 })
5244
5245 (define_split
5246   [(set (match_operand:MODEF 0 "register_operand" "")
5247         (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5248   "TARGET_SSE2 && TARGET_SSE_MATH
5249    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5250    && reload_completed
5251    && (SSE_REG_P (operands[0])
5252        || (GET_CODE (operands[0]) == SUBREG
5253            && SSE_REG_P (operands[0])))"
5254   [(const_int 0)]
5255 {
5256   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5257                                      <MODE>mode, 0);
5258   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5259
5260   emit_insn (gen_sse2_loadld (operands[4],
5261                               CONST0_RTX (V4SImode), operands[1]));
5262   emit_insn
5263     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5264   DONE;
5265 })
5266
5267 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5268   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5269         (float:MODEF
5270           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5271   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5272   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5273    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5274   "#"
5275   [(set_attr "type" "sseicvt")
5276    (set_attr "mode" "<MODEF:MODE>")
5277    (set_attr "athlon_decode" "double,direct")
5278    (set_attr "amdfam10_decode" "vector,double")
5279    (set_attr "fp_int_src" "true")])
5280
5281 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5282   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5283         (float:MODEF
5284           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5285   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5286    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5287    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5288   "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5289   [(set_attr "type" "sseicvt")
5290    (set_attr "prefix" "maybe_vex")
5291    (set_attr "mode" "<MODEF:MODE>")
5292    (set (attr "prefix_rex")
5293      (if_then_else
5294        (and (eq_attr "prefix" "maybe_vex")
5295             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5296        (const_string "1")
5297        (const_string "*")))
5298    (set_attr "athlon_decode" "double,direct")
5299    (set_attr "amdfam10_decode" "vector,double")
5300    (set_attr "fp_int_src" "true")])
5301
5302 (define_split
5303   [(set (match_operand:MODEF 0 "register_operand" "")
5304         (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5305    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5306   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5307    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5308    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5309    && reload_completed
5310    && (SSE_REG_P (operands[0])
5311        || (GET_CODE (operands[0]) == SUBREG
5312            && SSE_REG_P (operands[0])))"
5313   [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5314
5315 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5316   [(set (match_operand:MODEF 0 "register_operand" "=x")
5317         (float:MODEF
5318           (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5319   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5320    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5321    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5322   "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5323   [(set_attr "type" "sseicvt")
5324    (set_attr "prefix" "maybe_vex")
5325    (set_attr "mode" "<MODEF:MODE>")
5326    (set (attr "prefix_rex")
5327      (if_then_else
5328        (and (eq_attr "prefix" "maybe_vex")
5329             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5330        (const_string "1")
5331        (const_string "*")))
5332    (set_attr "athlon_decode" "direct")
5333    (set_attr "amdfam10_decode" "double")
5334    (set_attr "fp_int_src" "true")])
5335
5336 (define_split
5337   [(set (match_operand:MODEF 0 "register_operand" "")
5338         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5339    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5340   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5341    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5342    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5343    && reload_completed
5344    && (SSE_REG_P (operands[0])
5345        || (GET_CODE (operands[0]) == SUBREG
5346            && SSE_REG_P (operands[0])))"
5347   [(set (match_dup 2) (match_dup 1))
5348    (set (match_dup 0) (float:MODEF (match_dup 2)))])
5349
5350 (define_split
5351   [(set (match_operand:MODEF 0 "register_operand" "")
5352         (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5353    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5354   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5355    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5356    && reload_completed
5357    && (SSE_REG_P (operands[0])
5358        || (GET_CODE (operands[0]) == SUBREG
5359            && SSE_REG_P (operands[0])))"
5360   [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5361
5362 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5363   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5364         (float:X87MODEF
5365           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5366   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5367   "TARGET_80387
5368    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5369   "@
5370    fild%Z1\t%1
5371    #"
5372   [(set_attr "type" "fmov,multi")
5373    (set_attr "mode" "<X87MODEF:MODE>")
5374    (set_attr "unit" "*,i387")
5375    (set_attr "fp_int_src" "true")])
5376
5377 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5378   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5379         (float:X87MODEF
5380           (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5381   "TARGET_80387
5382    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5383   "fild%Z1\t%1"
5384   [(set_attr "type" "fmov")
5385    (set_attr "mode" "<X87MODEF:MODE>")
5386    (set_attr "fp_int_src" "true")])
5387
5388 (define_split
5389   [(set (match_operand:X87MODEF 0 "register_operand" "")
5390         (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5391    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5392   "TARGET_80387
5393    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5394    && reload_completed
5395    && FP_REG_P (operands[0])"
5396   [(set (match_dup 2) (match_dup 1))
5397    (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5398
5399 (define_split
5400   [(set (match_operand:X87MODEF 0 "register_operand" "")
5401         (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5402    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5403   "TARGET_80387
5404    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5405    && reload_completed
5406    && FP_REG_P (operands[0])"
5407   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5408
5409 ;; Avoid store forwarding (partial memory) stall penalty
5410 ;; by passing DImode value through XMM registers.  */
5411
5412 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5413   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5414         (float:X87MODEF
5415           (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5416    (clobber (match_scratch:V4SI 3 "=X,x"))
5417    (clobber (match_scratch:V4SI 4 "=X,x"))
5418    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5419   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5420    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5421    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5422   "#"
5423   [(set_attr "type" "multi")
5424    (set_attr "mode" "<X87MODEF:MODE>")
5425    (set_attr "unit" "i387")
5426    (set_attr "fp_int_src" "true")])
5427
5428 (define_split
5429   [(set (match_operand:X87MODEF 0 "register_operand" "")
5430         (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5431    (clobber (match_scratch:V4SI 3 ""))
5432    (clobber (match_scratch:V4SI 4 ""))
5433    (clobber (match_operand:DI 2 "memory_operand" ""))]
5434   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5435    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5436    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5437    && reload_completed
5438    && FP_REG_P (operands[0])"
5439   [(set (match_dup 2) (match_dup 3))
5440    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5441 {
5442   /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5443      Assemble the 64-bit DImode value in an xmm register.  */
5444   emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5445                               gen_rtx_SUBREG (SImode, operands[1], 0)));
5446   emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5447                               gen_rtx_SUBREG (SImode, operands[1], 4)));
5448   emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5449                                          operands[4]));
5450
5451   operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5452 })
5453
5454 (define_split
5455   [(set (match_operand:X87MODEF 0 "register_operand" "")
5456         (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5457    (clobber (match_scratch:V4SI 3 ""))
5458    (clobber (match_scratch:V4SI 4 ""))
5459    (clobber (match_operand:DI 2 "memory_operand" ""))]
5460   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5461    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5462    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5463    && reload_completed
5464    && FP_REG_P (operands[0])"
5465   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5466
5467 ;; Avoid store forwarding (partial memory) stall penalty by extending
5468 ;; SImode value to DImode through XMM register instead of pushing two
5469 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5470 ;; targets benefit from this optimization. Also note that fild
5471 ;; loads from memory only.
5472
5473 (define_insn "*floatunssi<mode>2_1"
5474   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5475         (unsigned_float:X87MODEF
5476           (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5477    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5478    (clobber (match_scratch:SI 3 "=X,x"))]
5479   "!TARGET_64BIT
5480    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5481    && TARGET_SSE"
5482   "#"
5483   [(set_attr "type" "multi")
5484    (set_attr "mode" "<MODE>")])
5485
5486 (define_split
5487   [(set (match_operand:X87MODEF 0 "register_operand" "")
5488         (unsigned_float:X87MODEF
5489           (match_operand:SI 1 "register_operand" "")))
5490    (clobber (match_operand:DI 2 "memory_operand" ""))
5491    (clobber (match_scratch:SI 3 ""))]
5492   "!TARGET_64BIT
5493    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5494    && TARGET_SSE
5495    && reload_completed"
5496   [(set (match_dup 2) (match_dup 1))
5497    (set (match_dup 0)
5498         (float:X87MODEF (match_dup 2)))]
5499   "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5500
5501 (define_split
5502   [(set (match_operand:X87MODEF 0 "register_operand" "")
5503         (unsigned_float:X87MODEF
5504           (match_operand:SI 1 "memory_operand" "")))
5505    (clobber (match_operand:DI 2 "memory_operand" ""))
5506    (clobber (match_scratch:SI 3 ""))]
5507   "!TARGET_64BIT
5508    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5509    && TARGET_SSE
5510    && reload_completed"
5511   [(set (match_dup 2) (match_dup 3))
5512    (set (match_dup 0)
5513         (float:X87MODEF (match_dup 2)))]
5514 {
5515   emit_move_insn (operands[3], operands[1]);
5516   operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5517 })
5518
5519 (define_expand "floatunssi<mode>2"
5520   [(parallel
5521      [(set (match_operand:X87MODEF 0 "register_operand" "")
5522            (unsigned_float:X87MODEF
5523              (match_operand:SI 1 "nonimmediate_operand" "")))
5524       (clobber (match_dup 2))
5525       (clobber (match_scratch:SI 3 ""))])]
5526   "!TARGET_64BIT
5527    && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5528         && TARGET_SSE)
5529        || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5530 {
5531   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5532     {
5533       ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5534       DONE;
5535     }
5536   else
5537     {
5538       enum ix86_stack_slot slot = (virtuals_instantiated
5539                                    ? SLOT_TEMP
5540                                    : SLOT_VIRTUAL);
5541       operands[2] = assign_386_stack_local (DImode, slot);
5542     }
5543 })
5544
5545 (define_expand "floatunsdisf2"
5546   [(use (match_operand:SF 0 "register_operand" ""))
5547    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5548   "TARGET_64BIT && TARGET_SSE_MATH"
5549   "x86_emit_floatuns (operands); DONE;")
5550
5551 (define_expand "floatunsdidf2"
5552   [(use (match_operand:DF 0 "register_operand" ""))
5553    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5554   "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5555    && TARGET_SSE2 && TARGET_SSE_MATH"
5556 {
5557   if (TARGET_64BIT)
5558     x86_emit_floatuns (operands);
5559   else
5560     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5561   DONE;
5562 })
5563 \f
5564 ;; Add instructions
5565
5566 (define_expand "add<mode>3"
5567   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5568         (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5569                     (match_operand:SDWIM 2 "<general_operand>" "")))]
5570   ""
5571   "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5572
5573 (define_insn_and_split "*add<dwi>3_doubleword"
5574   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5575         (plus:<DWI>
5576           (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5577           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5578    (clobber (reg:CC FLAGS_REG))]
5579   "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5580   "#"
5581   "reload_completed"
5582   [(parallel [(set (reg:CC FLAGS_REG)
5583                    (unspec:CC [(match_dup 1) (match_dup 2)]
5584                               UNSPEC_ADD_CARRY))
5585               (set (match_dup 0)
5586                    (plus:DWIH (match_dup 1) (match_dup 2)))])
5587    (parallel [(set (match_dup 3)
5588                    (plus:DWIH
5589                      (match_dup 4)
5590                      (plus:DWIH
5591                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5592                        (match_dup 5))))
5593               (clobber (reg:CC FLAGS_REG))])]
5594   "split_<dwi> (&operands[0], 3, &operands[0], &operands[3]);")
5595
5596 (define_insn "*add<mode>3_cc"
5597   [(set (reg:CC FLAGS_REG)
5598         (unspec:CC
5599           [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5600            (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5601           UNSPEC_ADD_CARRY))
5602    (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5603         (plus:SWI48 (match_dup 1) (match_dup 2)))]
5604   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5605   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5606   [(set_attr "type" "alu")
5607    (set_attr "mode" "<MODE>")])
5608
5609 (define_insn "addqi3_cc"
5610   [(set (reg:CC FLAGS_REG)
5611         (unspec:CC
5612           [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5613            (match_operand:QI 2 "general_operand" "qn,qm")]
5614           UNSPEC_ADD_CARRY))
5615    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5616         (plus:QI (match_dup 1) (match_dup 2)))]
5617   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5618   "add{b}\t{%2, %0|%0, %2}"
5619   [(set_attr "type" "alu")
5620    (set_attr "mode" "QI")])
5621
5622 (define_insn "*lea_1"
5623   [(set (match_operand:P 0 "register_operand" "=r")
5624         (match_operand:P 1 "no_seg_address_operand" "p"))]
5625   ""
5626   "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
5627   [(set_attr "type" "lea")
5628    (set_attr "mode" "<MODE>")])
5629
5630 (define_insn "*lea_2"
5631   [(set (match_operand:SI 0 "register_operand" "=r")
5632         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5633   "TARGET_64BIT"
5634   "lea{l}\t{%a1, %0|%0, %a1}"
5635   [(set_attr "type" "lea")
5636    (set_attr "mode" "SI")])
5637
5638 (define_insn "*lea_2_zext"
5639   [(set (match_operand:DI 0 "register_operand" "=r")
5640         (zero_extend:DI
5641           (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5642   "TARGET_64BIT"
5643   "lea{l}\t{%a1, %k0|%k0, %a1}"
5644   [(set_attr "type" "lea")
5645    (set_attr "mode" "SI")])
5646
5647 (define_insn "*add<mode>_1"
5648   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5649         (plus:SWI48
5650           (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5651           (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,0,l<i>")))
5652    (clobber (reg:CC FLAGS_REG))]
5653   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5654 {
5655   switch (get_attr_type (insn))
5656     {
5657     case TYPE_LEA:
5658       return "#";
5659
5660     case TYPE_INCDEC:
5661       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5662       if (operands[2] == const1_rtx)
5663         return "inc{<imodesuffix>}\t%0";
5664       else
5665         {
5666           gcc_assert (operands[2] == constm1_rtx);
5667           return "dec{<imodesuffix>}\t%0";
5668         }
5669
5670     default:
5671       /* For most processors, ADD is faster than LEA.  This alternative
5672          was added to use ADD as much as possible.  */
5673       if (which_alternative == 2)
5674         {
5675           rtx tmp;
5676           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5677         }
5678         
5679       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5680       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5681         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5682
5683       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5684     }
5685 }
5686   [(set (attr "type")
5687      (cond [(eq_attr "alternative" "3")
5688               (const_string "lea")
5689             (match_operand:SWI48 2 "incdec_operand" "")
5690               (const_string "incdec")
5691            ]
5692            (const_string "alu")))
5693    (set (attr "length_immediate")
5694       (if_then_else
5695         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5696         (const_string "1")
5697         (const_string "*")))
5698    (set_attr "mode" "<MODE>")])
5699
5700 ;; It may seem that nonimmediate operand is proper one for operand 1.
5701 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5702 ;; we take care in ix86_binary_operator_ok to not allow two memory
5703 ;; operands so proper swapping will be done in reload.  This allow
5704 ;; patterns constructed from addsi_1 to match.
5705
5706 (define_insn "*addsi_1_zext"
5707   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5708         (zero_extend:DI
5709           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5710                    (match_operand:SI 2 "general_operand" "g,0,li"))))
5711    (clobber (reg:CC FLAGS_REG))]
5712   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5713 {
5714   switch (get_attr_type (insn))
5715     {
5716     case TYPE_LEA:
5717       return "#";
5718
5719     case TYPE_INCDEC:
5720       if (operands[2] == const1_rtx)
5721         return "inc{l}\t%k0";
5722       else
5723         {
5724           gcc_assert (operands[2] == constm1_rtx);
5725           return "dec{l}\t%k0";
5726         }
5727
5728     default:
5729       /* For most processors, ADD is faster than LEA.  This alternative
5730          was added to use ADD as much as possible.  */
5731       if (which_alternative == 1)
5732         {
5733           rtx tmp;
5734           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5735         }
5736
5737       if (x86_maybe_negate_const_int (&operands[2], SImode))
5738         return "sub{l}\t{%2, %k0|%k0, %2}";
5739
5740       return "add{l}\t{%2, %k0|%k0, %2}";
5741     }
5742 }
5743   [(set (attr "type")
5744      (cond [(eq_attr "alternative" "2")
5745               (const_string "lea")
5746             (match_operand:SI 2 "incdec_operand" "")
5747               (const_string "incdec")
5748            ]
5749            (const_string "alu")))
5750    (set (attr "length_immediate")
5751       (if_then_else
5752         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5753         (const_string "1")
5754         (const_string "*")))
5755    (set_attr "mode" "SI")])
5756
5757 (define_insn "*addhi_1"
5758   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5759         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5760                  (match_operand:HI 2 "general_operand" "rn,rm")))
5761    (clobber (reg:CC FLAGS_REG))]
5762   "TARGET_PARTIAL_REG_STALL
5763    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5764 {
5765   switch (get_attr_type (insn))
5766     {
5767     case TYPE_INCDEC:
5768       if (operands[2] == const1_rtx)
5769         return "inc{w}\t%0";
5770       else
5771         {
5772           gcc_assert (operands[2] == constm1_rtx);
5773           return "dec{w}\t%0";
5774         }
5775
5776     default:
5777       if (x86_maybe_negate_const_int (&operands[2], HImode))
5778         return "sub{w}\t{%2, %0|%0, %2}";
5779
5780       return "add{w}\t{%2, %0|%0, %2}";
5781     }
5782 }
5783   [(set (attr "type")
5784      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5785         (const_string "incdec")
5786         (const_string "alu")))
5787    (set (attr "length_immediate")
5788       (if_then_else
5789         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5790         (const_string "1")
5791         (const_string "*")))
5792    (set_attr "mode" "HI")])
5793
5794 (define_insn "*addhi_1_lea"
5795   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm,r,r")
5796         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,r")
5797                  (match_operand:HI 2 "general_operand" "rmn,rn,0,ln")))
5798    (clobber (reg:CC FLAGS_REG))]
5799   "!TARGET_PARTIAL_REG_STALL
5800    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5801 {
5802   switch (get_attr_type (insn))
5803     {
5804     case TYPE_LEA:
5805       return "#";
5806
5807     case TYPE_INCDEC:
5808       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5809       if (operands[2] == const1_rtx)
5810         return "inc{w}\t%0";
5811       else
5812         {
5813           gcc_assert (operands[2] == constm1_rtx);
5814           return "dec{w}\t%0";
5815         }
5816
5817     default:
5818       /* For most processors, ADD is faster than LEA.  This alternative
5819          was added to use ADD as much as possible.  */
5820       if (which_alternative == 2)
5821         {
5822           rtx tmp;
5823           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5824         }
5825
5826       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5827       if (x86_maybe_negate_const_int (&operands[2], HImode))
5828         return "sub{w}\t{%2, %0|%0, %2}";
5829
5830       return "add{w}\t{%2, %0|%0, %2}";
5831     }
5832 }
5833   [(set (attr "type")
5834      (cond [(eq_attr "alternative" "3")
5835               (const_string "lea")
5836             (match_operand:HI 2 "incdec_operand" "")
5837               (const_string "incdec")
5838            ]
5839            (const_string "alu")))
5840    (set (attr "length_immediate")
5841       (if_then_else
5842         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5843         (const_string "1")
5844         (const_string "*")))
5845    (set_attr "mode" "HI,HI,HI,SI")])
5846
5847 ;; %%% Potential partial reg stall on alternative 2.  What to do?
5848 (define_insn "*addqi_1"
5849   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
5850         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
5851                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
5852    (clobber (reg:CC FLAGS_REG))]
5853   "TARGET_PARTIAL_REG_STALL
5854    && ix86_binary_operator_ok (PLUS, QImode, operands)"
5855 {
5856   int widen = (which_alternative == 2);
5857   switch (get_attr_type (insn))
5858     {
5859     case TYPE_INCDEC:
5860       if (operands[2] == const1_rtx)
5861         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5862       else
5863         {
5864           gcc_assert (operands[2] == constm1_rtx);
5865           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5866         }
5867
5868     default:
5869       if (x86_maybe_negate_const_int (&operands[2], QImode))
5870         {
5871           if (widen)
5872             return "sub{l}\t{%2, %k0|%k0, %2}";
5873           else
5874             return "sub{b}\t{%2, %0|%0, %2}";
5875         }
5876       if (widen)
5877         return "add{l}\t{%k2, %k0|%k0, %k2}";
5878       else
5879         return "add{b}\t{%2, %0|%0, %2}";
5880     }
5881 }
5882   [(set (attr "type")
5883      (if_then_else (match_operand:QI 2 "incdec_operand" "")
5884         (const_string "incdec")
5885         (const_string "alu")))
5886    (set (attr "length_immediate")
5887       (if_then_else
5888         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5889         (const_string "1")
5890         (const_string "*")))
5891    (set_attr "mode" "QI,QI,SI")])
5892
5893 ;; %%% Potential partial reg stall on alternatives 3 and 4.  What to do?
5894 (define_insn "*addqi_1_lea"
5895   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,q,r,r,r")
5896         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,r")
5897                  (match_operand:QI 2 "general_operand" "qmn,qn,0,rn,0,ln")))
5898    (clobber (reg:CC FLAGS_REG))]
5899   "!TARGET_PARTIAL_REG_STALL
5900    && ix86_binary_operator_ok (PLUS, QImode, operands)"
5901 {
5902   int widen = (which_alternative == 3 || which_alternative == 4);
5903
5904   switch (get_attr_type (insn))
5905     {
5906     case TYPE_LEA:
5907       return "#";
5908
5909     case TYPE_INCDEC:
5910       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5911       if (operands[2] == const1_rtx)
5912         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5913       else
5914         {
5915           gcc_assert (operands[2] == constm1_rtx);
5916           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5917         }
5918
5919     default:
5920       /* For most processors, ADD is faster than LEA.  These alternatives
5921          were added to use ADD as much as possible.  */
5922       if (which_alternative == 2 || which_alternative == 4)
5923         {
5924           rtx tmp;
5925           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5926         }
5927
5928       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5929       if (x86_maybe_negate_const_int (&operands[2], QImode))
5930         {
5931           if (widen)
5932             return "sub{l}\t{%2, %k0|%k0, %2}";
5933           else
5934             return "sub{b}\t{%2, %0|%0, %2}";
5935         }
5936       if (widen)
5937         return "add{l}\t{%k2, %k0|%k0, %k2}";
5938       else
5939         return "add{b}\t{%2, %0|%0, %2}";
5940     }
5941 }
5942   [(set (attr "type")
5943      (cond [(eq_attr "alternative" "5")
5944               (const_string "lea")
5945             (match_operand:QI 2 "incdec_operand" "")
5946               (const_string "incdec")
5947            ]
5948            (const_string "alu")))
5949    (set (attr "length_immediate")
5950       (if_then_else
5951         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5952         (const_string "1")
5953         (const_string "*")))
5954    (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5955
5956 (define_insn "*addqi_1_slp"
5957   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5958         (plus:QI (match_dup 0)
5959                  (match_operand:QI 1 "general_operand" "qn,qnm")))
5960    (clobber (reg:CC FLAGS_REG))]
5961   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5962    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5963 {
5964   switch (get_attr_type (insn))
5965     {
5966     case TYPE_INCDEC:
5967       if (operands[1] == const1_rtx)
5968         return "inc{b}\t%0";
5969       else
5970         {
5971           gcc_assert (operands[1] == constm1_rtx);
5972           return "dec{b}\t%0";
5973         }
5974
5975     default:
5976       if (x86_maybe_negate_const_int (&operands[1], QImode))
5977         return "sub{b}\t{%1, %0|%0, %1}";
5978
5979       return "add{b}\t{%1, %0|%0, %1}";
5980     }
5981 }
5982   [(set (attr "type")
5983      (if_then_else (match_operand:QI 1 "incdec_operand" "")
5984         (const_string "incdec")
5985         (const_string "alu1")))
5986    (set (attr "memory")
5987      (if_then_else (match_operand 1 "memory_operand" "")
5988         (const_string "load")
5989         (const_string "none")))
5990    (set_attr "mode" "QI")])
5991
5992 ;; Convert lea to the lea pattern to avoid flags dependency.
5993 (define_split
5994   [(set (match_operand 0 "register_operand" "")
5995         (plus (match_operand 1 "register_operand" "")
5996               (match_operand 2 "nonmemory_operand" "")))
5997    (clobber (reg:CC FLAGS_REG))]
5998   "reload_completed && ix86_lea_for_add_ok (insn, operands)" 
5999   [(const_int 0)]
6000 {
6001   rtx pat;
6002   enum machine_mode mode = GET_MODE (operands[0]);
6003
6004   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
6005      may confuse gen_lowpart.  */
6006   if (mode != Pmode)
6007     {
6008       operands[1] = gen_lowpart (Pmode, operands[1]);
6009       operands[2] = gen_lowpart (Pmode, operands[2]);
6010     }
6011
6012   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
6013
6014   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6015     operands[0] = gen_lowpart (SImode, operands[0]);
6016
6017   if (TARGET_64BIT && mode != Pmode)
6018     pat = gen_rtx_SUBREG (SImode, pat, 0);
6019
6020   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6021   DONE;
6022 })
6023
6024 ;; Convert lea to the lea pattern to avoid flags dependency.
6025 ;; ??? This pattern handles immediate operands that do not satisfy immediate
6026 ;; operand predicate (LEGITIMATE_CONSTANT_P) in the previous pattern.
6027 (define_split
6028   [(set (match_operand:DI 0 "register_operand" "")
6029         (plus:DI (match_operand:DI 1 "register_operand" "")
6030                  (match_operand:DI 2 "x86_64_immediate_operand" "")))
6031    (clobber (reg:CC FLAGS_REG))]
6032   "TARGET_64BIT && reload_completed 
6033    && true_regnum (operands[0]) != true_regnum (operands[1])"
6034   [(set (match_dup 0)
6035         (plus:DI (match_dup 1) (match_dup 2)))])
6036
6037 ;; Convert lea to the lea pattern to avoid flags dependency.
6038 (define_split
6039   [(set (match_operand:DI 0 "register_operand" "")
6040         (zero_extend:DI
6041           (plus:SI (match_operand:SI 1 "register_operand" "")
6042                    (match_operand:SI 2 "nonmemory_operand" ""))))
6043    (clobber (reg:CC FLAGS_REG))]
6044   "TARGET_64BIT && reload_completed
6045    && ix86_lea_for_add_ok (insn, operands)"
6046   [(set (match_dup 0)
6047         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
6048 {
6049   operands[1] = gen_lowpart (DImode, operands[1]);
6050   operands[2] = gen_lowpart (DImode, operands[2]);
6051 })
6052
6053 (define_insn "*add<mode>_2"
6054   [(set (reg FLAGS_REG)
6055         (compare
6056           (plus:SWI
6057             (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6058             (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
6059           (const_int 0)))
6060    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
6061         (plus:SWI (match_dup 1) (match_dup 2)))]
6062   "ix86_match_ccmode (insn, CCGOCmode)
6063    && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6064 {
6065   switch (get_attr_type (insn))
6066     {
6067     case TYPE_INCDEC:
6068       if (operands[2] == const1_rtx)
6069         return "inc{<imodesuffix>}\t%0";
6070       else
6071         {
6072           gcc_assert (operands[2] == constm1_rtx);
6073           return "dec{<imodesuffix>}\t%0";
6074         }
6075
6076     default:
6077       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6078         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6079
6080       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6081     }
6082 }
6083   [(set (attr "type")
6084      (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6085         (const_string "incdec")
6086         (const_string "alu")))
6087    (set (attr "length_immediate")
6088       (if_then_else
6089         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6090         (const_string "1")
6091         (const_string "*")))
6092    (set_attr "mode" "<MODE>")])
6093
6094 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6095 (define_insn "*addsi_2_zext"
6096   [(set (reg FLAGS_REG)
6097         (compare
6098           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6099                    (match_operand:SI 2 "general_operand" "g"))
6100           (const_int 0)))
6101    (set (match_operand:DI 0 "register_operand" "=r")
6102         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6103   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6104    && ix86_binary_operator_ok (PLUS, SImode, operands)"
6105 {
6106   switch (get_attr_type (insn))
6107     {
6108     case TYPE_INCDEC:
6109       if (operands[2] == const1_rtx)
6110         return "inc{l}\t%k0";
6111       else
6112         {
6113           gcc_assert (operands[2] == constm1_rtx);
6114           return "dec{l}\t%k0";
6115         }
6116
6117     default:
6118       if (x86_maybe_negate_const_int (&operands[2], SImode))
6119         return "sub{l}\t{%2, %k0|%k0, %2}";
6120
6121       return "add{l}\t{%2, %k0|%k0, %2}";
6122     }
6123 }
6124   [(set (attr "type")
6125      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6126         (const_string "incdec")
6127         (const_string "alu")))
6128    (set (attr "length_immediate")
6129       (if_then_else
6130         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6131         (const_string "1")
6132         (const_string "*")))
6133    (set_attr "mode" "SI")])
6134
6135 (define_insn "*add<mode>_3"
6136   [(set (reg FLAGS_REG)
6137         (compare
6138           (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>"))
6139           (match_operand:SWI 1 "nonimmediate_operand" "%0")))
6140    (clobber (match_scratch:SWI 0 "=<r>"))]
6141   "ix86_match_ccmode (insn, CCZmode)
6142    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6143 {
6144   switch (get_attr_type (insn))
6145     {
6146     case TYPE_INCDEC:
6147       if (operands[2] == const1_rtx)
6148         return "inc{<imodesuffix>}\t%0";
6149       else
6150         {
6151           gcc_assert (operands[2] == constm1_rtx);
6152           return "dec{<imodesuffix>}\t%0";
6153         }
6154
6155     default:
6156       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6157         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6158
6159       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6160     }
6161 }
6162   [(set (attr "type")
6163      (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6164         (const_string "incdec")
6165         (const_string "alu")))
6166    (set (attr "length_immediate")
6167       (if_then_else
6168         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6169         (const_string "1")
6170         (const_string "*")))
6171    (set_attr "mode" "<MODE>")])
6172
6173 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6174 (define_insn "*addsi_3_zext"
6175   [(set (reg FLAGS_REG)
6176         (compare
6177           (neg:SI (match_operand:SI 2 "general_operand" "g"))
6178           (match_operand:SI 1 "nonimmediate_operand" "%0")))
6179    (set (match_operand:DI 0 "register_operand" "=r")
6180         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6181   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6182    && ix86_binary_operator_ok (PLUS, SImode, operands)"
6183 {
6184   switch (get_attr_type (insn))
6185     {
6186     case TYPE_INCDEC:
6187       if (operands[2] == const1_rtx)
6188         return "inc{l}\t%k0";
6189       else
6190         {
6191           gcc_assert (operands[2] == constm1_rtx);
6192           return "dec{l}\t%k0";
6193         }
6194
6195     default:
6196       if (x86_maybe_negate_const_int (&operands[2], SImode))
6197         return "sub{l}\t{%2, %k0|%k0, %2}";
6198
6199       return "add{l}\t{%2, %k0|%k0, %2}";
6200     }
6201 }
6202   [(set (attr "type")
6203      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6204         (const_string "incdec")
6205         (const_string "alu")))
6206    (set (attr "length_immediate")
6207       (if_then_else
6208         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6209         (const_string "1")
6210         (const_string "*")))
6211    (set_attr "mode" "SI")])
6212
6213 ; For comparisons against 1, -1 and 128, we may generate better code
6214 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6215 ; is matched then.  We can't accept general immediate, because for
6216 ; case of overflows,  the result is messed up.
6217 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6218 ; only for comparisons not depending on it.
6219
6220 (define_insn "*adddi_4"
6221   [(set (reg FLAGS_REG)
6222         (compare
6223           (match_operand:DI 1 "nonimmediate_operand" "0")
6224           (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6225    (clobber (match_scratch:DI 0 "=rm"))]
6226   "TARGET_64BIT
6227    && ix86_match_ccmode (insn, CCGCmode)"
6228 {
6229   switch (get_attr_type (insn))
6230     {
6231     case TYPE_INCDEC:
6232       if (operands[2] == constm1_rtx)
6233         return "inc{q}\t%0";
6234       else
6235         {
6236           gcc_assert (operands[2] == const1_rtx);
6237           return "dec{q}\t%0";
6238         }
6239
6240     default:
6241       if (x86_maybe_negate_const_int (&operands[2], DImode))
6242         return "add{q}\t{%2, %0|%0, %2}";
6243
6244       return "sub{q}\t{%2, %0|%0, %2}";
6245     }
6246 }
6247   [(set (attr "type")
6248      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6249         (const_string "incdec")
6250         (const_string "alu")))
6251    (set (attr "length_immediate")
6252       (if_then_else
6253         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6254         (const_string "1")
6255         (const_string "*")))
6256    (set_attr "mode" "DI")])
6257
6258 ; For comparisons against 1, -1 and 128, we may generate better code
6259 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6260 ; is matched then.  We can't accept general immediate, because for
6261 ; case of overflows,  the result is messed up.
6262 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6263 ; only for comparisons not depending on it.
6264
6265 (define_insn "*add<mode>_4"
6266   [(set (reg FLAGS_REG)
6267         (compare
6268           (match_operand:SWI124 1 "nonimmediate_operand" "0")
6269           (match_operand:SWI124 2 "const_int_operand" "n")))
6270    (clobber (match_scratch:SWI124 0 "=<r>m"))]
6271   "ix86_match_ccmode (insn, CCGCmode)"
6272 {
6273   switch (get_attr_type (insn))
6274     {
6275     case TYPE_INCDEC:
6276       if (operands[2] == constm1_rtx)
6277         return "inc{<imodesuffix>}\t%0";
6278       else
6279         {
6280           gcc_assert (operands[2] == const1_rtx);
6281           return "dec{<imodesuffix>}\t%0";
6282         }
6283
6284     default:
6285       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6286         return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6287
6288       return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6289     }
6290 }
6291   [(set (attr "type")
6292      (if_then_else (match_operand:<MODE> 2 "incdec_operand" "")
6293         (const_string "incdec")
6294         (const_string "alu")))
6295    (set (attr "length_immediate")
6296       (if_then_else
6297         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6298         (const_string "1")
6299         (const_string "*")))
6300    (set_attr "mode" "<MODE>")])
6301
6302 (define_insn "*add<mode>_5"
6303   [(set (reg FLAGS_REG)
6304         (compare
6305           (plus:SWI
6306             (match_operand:SWI 1 "nonimmediate_operand" "%0")
6307             (match_operand:SWI 2 "<general_operand>" "<g>"))
6308           (const_int 0)))
6309    (clobber (match_scratch:SWI 0 "=<r>"))]
6310   "ix86_match_ccmode (insn, CCGOCmode)
6311    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6312 {
6313   switch (get_attr_type (insn))
6314     {
6315     case TYPE_INCDEC:
6316       if (operands[2] == const1_rtx)
6317         return "inc{<imodesuffix>}\t%0";
6318       else
6319         {
6320           gcc_assert (operands[2] == constm1_rtx);
6321           return "dec{<imodesuffix>}\t%0";
6322         }
6323
6324     default:
6325       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6326         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6327
6328       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6329     }
6330 }
6331   [(set (attr "type")
6332      (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6333         (const_string "incdec")
6334         (const_string "alu")))
6335    (set (attr "length_immediate")
6336       (if_then_else
6337         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6338         (const_string "1")
6339         (const_string "*")))
6340    (set_attr "mode" "<MODE>")])
6341
6342 (define_insn "*addqi_ext_1_rex64"
6343   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6344                          (const_int 8)
6345                          (const_int 8))
6346         (plus:SI
6347           (zero_extract:SI
6348             (match_operand 1 "ext_register_operand" "0")
6349             (const_int 8)
6350             (const_int 8))
6351           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6352    (clobber (reg:CC FLAGS_REG))]
6353   "TARGET_64BIT"
6354 {
6355   switch (get_attr_type (insn))
6356     {
6357     case TYPE_INCDEC:
6358       if (operands[2] == const1_rtx)
6359         return "inc{b}\t%h0";
6360       else
6361         {
6362           gcc_assert (operands[2] == constm1_rtx);
6363           return "dec{b}\t%h0";
6364         }
6365
6366     default:
6367       return "add{b}\t{%2, %h0|%h0, %2}";
6368     }
6369 }
6370   [(set (attr "type")
6371      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6372         (const_string "incdec")
6373         (const_string "alu")))
6374    (set_attr "modrm" "1")
6375    (set_attr "mode" "QI")])
6376
6377 (define_insn "addqi_ext_1"
6378   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6379                          (const_int 8)
6380                          (const_int 8))
6381         (plus:SI
6382           (zero_extract:SI
6383             (match_operand 1 "ext_register_operand" "0")
6384             (const_int 8)
6385             (const_int 8))
6386           (match_operand:QI 2 "general_operand" "Qmn")))
6387    (clobber (reg:CC FLAGS_REG))]
6388   "!TARGET_64BIT"
6389 {
6390   switch (get_attr_type (insn))
6391     {
6392     case TYPE_INCDEC:
6393       if (operands[2] == const1_rtx)
6394         return "inc{b}\t%h0";
6395       else
6396         {
6397           gcc_assert (operands[2] == constm1_rtx);
6398           return "dec{b}\t%h0";
6399         }
6400
6401     default:
6402       return "add{b}\t{%2, %h0|%h0, %2}";
6403     }
6404 }
6405   [(set (attr "type")
6406      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6407         (const_string "incdec")
6408         (const_string "alu")))
6409    (set_attr "modrm" "1")
6410    (set_attr "mode" "QI")])
6411
6412 (define_insn "*addqi_ext_2"
6413   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6414                          (const_int 8)
6415                          (const_int 8))
6416         (plus:SI
6417           (zero_extract:SI
6418             (match_operand 1 "ext_register_operand" "%0")
6419             (const_int 8)
6420             (const_int 8))
6421           (zero_extract:SI
6422             (match_operand 2 "ext_register_operand" "Q")
6423             (const_int 8)
6424             (const_int 8))))
6425    (clobber (reg:CC FLAGS_REG))]
6426   ""
6427   "add{b}\t{%h2, %h0|%h0, %h2}"
6428   [(set_attr "type" "alu")
6429    (set_attr "mode" "QI")])
6430
6431 ;; The lea patterns for non-Pmodes needs to be matched by
6432 ;; several insns converted to real lea by splitters.
6433
6434 (define_insn_and_split "*lea_general_1"
6435   [(set (match_operand 0 "register_operand" "=r")
6436         (plus (plus (match_operand 1 "index_register_operand" "l")
6437                     (match_operand 2 "register_operand" "r"))
6438               (match_operand 3 "immediate_operand" "i")))]
6439   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6440     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6441    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6442    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6443    && GET_MODE (operands[0]) == GET_MODE (operands[2])
6444    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6445        || GET_MODE (operands[3]) == VOIDmode)"
6446   "#"
6447   "&& reload_completed"
6448   [(const_int 0)]
6449 {
6450   rtx pat;
6451   operands[0] = gen_lowpart (SImode, operands[0]);
6452   operands[1] = gen_lowpart (Pmode, operands[1]);
6453   operands[2] = gen_lowpart (Pmode, operands[2]);
6454   operands[3] = gen_lowpart (Pmode, operands[3]);
6455   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
6456                       operands[3]);
6457   if (Pmode != SImode)
6458     pat = gen_rtx_SUBREG (SImode, pat, 0);
6459   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6460   DONE;
6461 }
6462   [(set_attr "type" "lea")
6463    (set_attr "mode" "SI")])
6464
6465 (define_insn_and_split "*lea_general_1_zext"
6466   [(set (match_operand:DI 0 "register_operand" "=r")
6467         (zero_extend:DI
6468           (plus:SI (plus:SI
6469                      (match_operand:SI 1 "index_register_operand" "l")
6470                      (match_operand:SI 2 "register_operand" "r"))
6471                    (match_operand:SI 3 "immediate_operand" "i"))))]
6472   "TARGET_64BIT"
6473   "#"
6474   "&& reload_completed"
6475   [(set (match_dup 0)
6476         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
6477                                                      (match_dup 2))
6478                                             (match_dup 3)) 0)))]
6479 {
6480   operands[1] = gen_lowpart (Pmode, operands[1]);
6481   operands[2] = gen_lowpart (Pmode, operands[2]);
6482   operands[3] = gen_lowpart (Pmode, operands[3]);
6483 }
6484   [(set_attr "type" "lea")
6485    (set_attr "mode" "SI")])
6486
6487 (define_insn_and_split "*lea_general_2"
6488   [(set (match_operand 0 "register_operand" "=r")
6489         (plus (mult (match_operand 1 "index_register_operand" "l")
6490                     (match_operand 2 "const248_operand" "i"))
6491               (match_operand 3 "nonmemory_operand" "ri")))]
6492   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6493     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6494    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6495    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6496    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6497        || GET_MODE (operands[3]) == VOIDmode)"
6498   "#"
6499   "&& reload_completed"
6500   [(const_int 0)]
6501 {
6502   rtx pat;
6503   operands[0] = gen_lowpart (SImode, operands[0]);
6504   operands[1] = gen_lowpart (Pmode, operands[1]);
6505   operands[3] = gen_lowpart (Pmode, operands[3]);
6506   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
6507                       operands[3]);
6508   if (Pmode != SImode)
6509     pat = gen_rtx_SUBREG (SImode, pat, 0);
6510   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6511   DONE;
6512 }
6513   [(set_attr "type" "lea")
6514    (set_attr "mode" "SI")])
6515
6516 (define_insn_and_split "*lea_general_2_zext"
6517   [(set (match_operand:DI 0 "register_operand" "=r")
6518         (zero_extend:DI
6519           (plus:SI (mult:SI
6520                      (match_operand:SI 1 "index_register_operand" "l")
6521                      (match_operand:SI 2 "const248_operand" "n"))
6522                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
6523   "TARGET_64BIT"
6524   "#"
6525   "&& reload_completed"
6526   [(set (match_dup 0)
6527         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
6528                                                      (match_dup 2))
6529                                             (match_dup 3)) 0)))]
6530 {
6531   operands[1] = gen_lowpart (Pmode, operands[1]);
6532   operands[3] = gen_lowpart (Pmode, operands[3]);
6533 }
6534   [(set_attr "type" "lea")
6535    (set_attr "mode" "SI")])
6536
6537 (define_insn_and_split "*lea_general_3"
6538   [(set (match_operand 0 "register_operand" "=r")
6539         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6540                           (match_operand 2 "const248_operand" "i"))
6541                     (match_operand 3 "register_operand" "r"))
6542               (match_operand 4 "immediate_operand" "i")))]
6543   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6544     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6545    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6546    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6547    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6548   "#"
6549   "&& reload_completed"
6550   [(const_int 0)]
6551 {
6552   rtx pat;
6553   operands[0] = gen_lowpart (SImode, operands[0]);
6554   operands[1] = gen_lowpart (Pmode, operands[1]);
6555   operands[3] = gen_lowpart (Pmode, operands[3]);
6556   operands[4] = gen_lowpart (Pmode, operands[4]);
6557   pat = gen_rtx_PLUS (Pmode,
6558                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
6559                                                          operands[2]),
6560                                     operands[3]),
6561                       operands[4]);
6562   if (Pmode != SImode)
6563     pat = gen_rtx_SUBREG (SImode, pat, 0);
6564   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6565   DONE;
6566 }
6567   [(set_attr "type" "lea")
6568    (set_attr "mode" "SI")])
6569
6570 (define_insn_and_split "*lea_general_3_zext"
6571   [(set (match_operand:DI 0 "register_operand" "=r")
6572         (zero_extend:DI
6573           (plus:SI (plus:SI
6574                      (mult:SI
6575                        (match_operand:SI 1 "index_register_operand" "l")
6576                        (match_operand:SI 2 "const248_operand" "n"))
6577                      (match_operand:SI 3 "register_operand" "r"))
6578                    (match_operand:SI 4 "immediate_operand" "i"))))]
6579   "TARGET_64BIT"
6580   "#"
6581   "&& reload_completed"
6582   [(set (match_dup 0)
6583         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
6584                                                               (match_dup 2))
6585                                                      (match_dup 3))
6586                                             (match_dup 4)) 0)))]
6587 {
6588   operands[1] = gen_lowpart (Pmode, operands[1]);
6589   operands[3] = gen_lowpart (Pmode, operands[3]);
6590   operands[4] = gen_lowpart (Pmode, operands[4]);
6591 }
6592   [(set_attr "type" "lea")
6593    (set_attr "mode" "SI")])
6594 \f
6595 ;; Subtract instructions
6596
6597 (define_expand "sub<mode>3"
6598   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
6599         (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6600                      (match_operand:SDWIM 2 "<general_operand>" "")))]
6601   ""
6602   "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6603
6604 (define_insn_and_split "*sub<dwi>3_doubleword"
6605   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6606         (minus:<DWI>
6607           (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6608           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6609    (clobber (reg:CC FLAGS_REG))]
6610   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6611   "#"
6612   "reload_completed"
6613   [(parallel [(set (reg:CC FLAGS_REG)
6614                    (compare:CC (match_dup 1) (match_dup 2)))
6615               (set (match_dup 0)
6616                    (minus:DWIH (match_dup 1) (match_dup 2)))])
6617    (parallel [(set (match_dup 3)
6618                    (minus:DWIH
6619                      (match_dup 4)
6620                      (plus:DWIH
6621                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6622                        (match_dup 5))))
6623               (clobber (reg:CC FLAGS_REG))])]
6624   "split_<dwi> (&operands[0], 3, &operands[0], &operands[3]);")
6625
6626 (define_insn "*sub<mode>_1"
6627   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6628         (minus:SWI
6629           (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6630           (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6631    (clobber (reg:CC FLAGS_REG))]
6632   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6633   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6634   [(set_attr "type" "alu")
6635    (set_attr "mode" "<MODE>")])
6636
6637 (define_insn "*subsi_1_zext"
6638   [(set (match_operand:DI 0 "register_operand" "=r")
6639         (zero_extend:DI
6640           (minus:SI (match_operand:SI 1 "register_operand" "0")
6641                     (match_operand:SI 2 "general_operand" "g"))))
6642    (clobber (reg:CC FLAGS_REG))]
6643   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6644   "sub{l}\t{%2, %k0|%k0, %2}"
6645   [(set_attr "type" "alu")
6646    (set_attr "mode" "SI")])
6647
6648 (define_insn "*subqi_1_slp"
6649   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6650         (minus:QI (match_dup 0)
6651                   (match_operand:QI 1 "general_operand" "qn,qm")))
6652    (clobber (reg:CC FLAGS_REG))]
6653   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6654    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6655   "sub{b}\t{%1, %0|%0, %1}"
6656   [(set_attr "type" "alu1")
6657    (set_attr "mode" "QI")])
6658
6659 (define_insn "*sub<mode>_2"
6660   [(set (reg FLAGS_REG)
6661         (compare
6662           (minus:SWI
6663             (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6664             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6665           (const_int 0)))
6666    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6667         (minus:SWI (match_dup 1) (match_dup 2)))]
6668   "ix86_match_ccmode (insn, CCGOCmode)
6669    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6670   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6671   [(set_attr "type" "alu")
6672    (set_attr "mode" "<MODE>")])
6673
6674 (define_insn "*subsi_2_zext"
6675   [(set (reg FLAGS_REG)
6676         (compare
6677           (minus:SI (match_operand:SI 1 "register_operand" "0")
6678                     (match_operand:SI 2 "general_operand" "g"))
6679           (const_int 0)))
6680    (set (match_operand:DI 0 "register_operand" "=r")
6681         (zero_extend:DI
6682           (minus:SI (match_dup 1)
6683                     (match_dup 2))))]
6684   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6685    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6686   "sub{l}\t{%2, %k0|%k0, %2}"
6687   [(set_attr "type" "alu")
6688    (set_attr "mode" "SI")])
6689
6690 (define_insn "*sub<mode>_3"
6691   [(set (reg FLAGS_REG)
6692         (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6693                  (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6694    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6695         (minus:SWI (match_dup 1) (match_dup 2)))]
6696   "ix86_match_ccmode (insn, CCmode)
6697    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6698   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6699   [(set_attr "type" "alu")
6700    (set_attr "mode" "<MODE>")])
6701
6702 (define_insn "*subsi_3_zext"
6703   [(set (reg FLAGS_REG)
6704         (compare (match_operand:SI 1 "register_operand" "0")
6705                  (match_operand:SI 2 "general_operand" "g")))
6706    (set (match_operand:DI 0 "register_operand" "=r")
6707         (zero_extend:DI
6708           (minus:SI (match_dup 1)
6709                     (match_dup 2))))]
6710   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6711    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6712   "sub{l}\t{%2, %1|%1, %2}"
6713   [(set_attr "type" "alu")
6714    (set_attr "mode" "SI")])
6715 \f
6716 ;; Add with carry and subtract with borrow
6717
6718 (define_expand "<plusminus_insn><mode>3_carry"
6719   [(parallel
6720     [(set (match_operand:SWI 0 "nonimmediate_operand" "")
6721           (plusminus:SWI
6722             (match_operand:SWI 1 "nonimmediate_operand" "")
6723             (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6724                        [(match_operand 3 "flags_reg_operand" "")
6725                         (const_int 0)])
6726                       (match_operand:SWI 2 "<general_operand>" ""))))
6727      (clobber (reg:CC FLAGS_REG))])]
6728   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6729   "")
6730
6731 (define_insn "*<plusminus_insn><mode>3_carry"
6732   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6733         (plusminus:SWI
6734           (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6735           (plus:SWI
6736             (match_operator 3 "ix86_carry_flag_operator"
6737              [(reg FLAGS_REG) (const_int 0)])
6738             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6739    (clobber (reg:CC FLAGS_REG))]
6740   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6741   "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6742   [(set_attr "type" "alu")
6743    (set_attr "use_carry" "1")
6744    (set_attr "pent_pair" "pu")
6745    (set_attr "mode" "<MODE>")])
6746
6747 (define_insn "*addsi3_carry_zext"
6748   [(set (match_operand:DI 0 "register_operand" "=r")
6749         (zero_extend:DI
6750           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6751                    (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6752                              [(reg FLAGS_REG) (const_int 0)])
6753                             (match_operand:SI 2 "general_operand" "g")))))
6754    (clobber (reg:CC FLAGS_REG))]
6755   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6756   "adc{l}\t{%2, %k0|%k0, %2}"
6757   [(set_attr "type" "alu")
6758    (set_attr "use_carry" "1")
6759    (set_attr "pent_pair" "pu")
6760    (set_attr "mode" "SI")])
6761
6762 (define_insn "*subsi3_carry_zext"
6763   [(set (match_operand:DI 0 "register_operand" "=r")
6764         (zero_extend:DI
6765           (minus:SI (match_operand:SI 1 "register_operand" "0")
6766                     (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6767                               [(reg FLAGS_REG) (const_int 0)])
6768                              (match_operand:SI 2 "general_operand" "g")))))
6769    (clobber (reg:CC FLAGS_REG))]
6770   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6771   "sbb{l}\t{%2, %k0|%k0, %2}"
6772   [(set_attr "type" "alu")
6773    (set_attr "pent_pair" "pu")
6774    (set_attr "mode" "SI")])
6775 \f
6776 ;; Overflow setting add and subtract instructions
6777
6778 (define_insn "*add<mode>3_cconly_overflow"
6779   [(set (reg:CCC FLAGS_REG)
6780         (compare:CCC
6781           (plus:SWI
6782             (match_operand:SWI 1 "nonimmediate_operand" "%0")
6783             (match_operand:SWI 2 "<general_operand>" "<g>"))
6784           (match_dup 1)))
6785    (clobber (match_scratch:SWI 0 "=<r>"))]
6786   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6787   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6788   [(set_attr "type" "alu")
6789    (set_attr "mode" "<MODE>")])
6790
6791 (define_insn "*sub<mode>3_cconly_overflow"
6792   [(set (reg:CCC FLAGS_REG)
6793         (compare:CCC
6794           (minus:SWI
6795             (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6796             (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6797           (match_dup 0)))]
6798   ""
6799   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6800   [(set_attr "type" "icmp")
6801    (set_attr "mode" "<MODE>")])
6802
6803 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6804   [(set (reg:CCC FLAGS_REG)
6805         (compare:CCC
6806             (plusminus:SWI
6807                 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6808                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6809             (match_dup 1)))
6810    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6811         (plusminus:SWI (match_dup 1) (match_dup 2)))]
6812   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6813   "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6814   [(set_attr "type" "alu")
6815    (set_attr "mode" "<MODE>")])
6816
6817 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6818   [(set (reg:CCC FLAGS_REG)
6819         (compare:CCC
6820           (plusminus:SI
6821             (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6822             (match_operand:SI 2 "general_operand" "g"))
6823           (match_dup 1)))
6824    (set (match_operand:DI 0 "register_operand" "=r")
6825         (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6826   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6827   "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6828   [(set_attr "type" "alu")
6829    (set_attr "mode" "SI")])
6830
6831 ;; The patterns that match these are at the end of this file.
6832
6833 (define_expand "<plusminus_insn>xf3"
6834   [(set (match_operand:XF 0 "register_operand" "")
6835         (plusminus:XF
6836           (match_operand:XF 1 "register_operand" "")
6837           (match_operand:XF 2 "register_operand" "")))]
6838   "TARGET_80387"
6839   "")
6840
6841 (define_expand "<plusminus_insn><mode>3"
6842   [(set (match_operand:MODEF 0 "register_operand" "")
6843         (plusminus:MODEF
6844           (match_operand:MODEF 1 "register_operand" "")
6845           (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6846   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6847     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
6848   "")
6849 \f
6850 ;; Multiply instructions
6851
6852 (define_expand "mul<mode>3"
6853   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
6854                    (mult:SWIM248
6855                      (match_operand:SWIM248 1 "register_operand" "")
6856                      (match_operand:SWIM248 2 "<general_operand>" "")))
6857               (clobber (reg:CC FLAGS_REG))])]
6858   ""
6859   "")
6860
6861 (define_expand "mulqi3"
6862   [(parallel [(set (match_operand:QI 0 "register_operand" "")
6863                    (mult:QI
6864                      (match_operand:QI 1 "register_operand" "")
6865                      (match_operand:QI 2 "nonimmediate_operand" "")))
6866               (clobber (reg:CC FLAGS_REG))])]
6867   "TARGET_QIMODE_MATH"
6868   "")
6869
6870 ;; On AMDFAM10
6871 ;; IMUL reg32/64, reg32/64, imm8        Direct
6872 ;; IMUL reg32/64, mem32/64, imm8        VectorPath
6873 ;; IMUL reg32/64, reg32/64, imm32       Direct
6874 ;; IMUL reg32/64, mem32/64, imm32       VectorPath
6875 ;; IMUL reg32/64, reg32/64              Direct
6876 ;; IMUL reg32/64, mem32/64              Direct
6877
6878 (define_insn "*mul<mode>3_1"
6879   [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6880         (mult:SWI48
6881           (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6882           (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6883    (clobber (reg:CC FLAGS_REG))]
6884   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6885   "@
6886    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6887    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6888    imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6889   [(set_attr "type" "imul")
6890    (set_attr "prefix_0f" "0,0,1")
6891    (set (attr "athlon_decode")
6892         (cond [(eq_attr "cpu" "athlon")
6893                   (const_string "vector")
6894                (eq_attr "alternative" "1")
6895                   (const_string "vector")
6896                (and (eq_attr "alternative" "2")
6897                     (match_operand 1 "memory_operand" ""))
6898                   (const_string "vector")]
6899               (const_string "direct")))
6900    (set (attr "amdfam10_decode")
6901         (cond [(and (eq_attr "alternative" "0,1")
6902                     (match_operand 1 "memory_operand" ""))
6903                   (const_string "vector")]
6904               (const_string "direct")))
6905    (set_attr "mode" "<MODE>")])
6906
6907 (define_insn "*mulsi3_1_zext"
6908   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6909         (zero_extend:DI
6910           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6911                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
6912    (clobber (reg:CC FLAGS_REG))]
6913   "TARGET_64BIT
6914    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6915   "@
6916    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6917    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6918    imul{l}\t{%2, %k0|%k0, %2}"
6919   [(set_attr "type" "imul")
6920    (set_attr "prefix_0f" "0,0,1")
6921    (set (attr "athlon_decode")
6922         (cond [(eq_attr "cpu" "athlon")
6923                   (const_string "vector")
6924                (eq_attr "alternative" "1")
6925                   (const_string "vector")
6926                (and (eq_attr "alternative" "2")
6927                     (match_operand 1 "memory_operand" ""))
6928                   (const_string "vector")]
6929               (const_string "direct")))
6930    (set (attr "amdfam10_decode")
6931         (cond [(and (eq_attr "alternative" "0,1")
6932                     (match_operand 1 "memory_operand" ""))
6933                   (const_string "vector")]
6934               (const_string "direct")))
6935    (set_attr "mode" "SI")])
6936
6937 ;; On AMDFAM10
6938 ;; IMUL reg16, reg16, imm8      VectorPath
6939 ;; IMUL reg16, mem16, imm8      VectorPath
6940 ;; IMUL reg16, reg16, imm16     VectorPath
6941 ;; IMUL reg16, mem16, imm16     VectorPath
6942 ;; IMUL reg16, reg16            Direct
6943 ;; IMUL reg16, mem16            Direct
6944
6945 (define_insn "*mulhi3_1"
6946   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6947         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6948                  (match_operand:HI 2 "general_operand" "K,n,mr")))
6949    (clobber (reg:CC FLAGS_REG))]
6950   "TARGET_HIMODE_MATH
6951    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6952   "@
6953    imul{w}\t{%2, %1, %0|%0, %1, %2}
6954    imul{w}\t{%2, %1, %0|%0, %1, %2}
6955    imul{w}\t{%2, %0|%0, %2}"
6956   [(set_attr "type" "imul")
6957    (set_attr "prefix_0f" "0,0,1")
6958    (set (attr "athlon_decode")
6959         (cond [(eq_attr "cpu" "athlon")
6960                   (const_string "vector")
6961                (eq_attr "alternative" "1,2")
6962                   (const_string "vector")]
6963               (const_string "direct")))
6964    (set (attr "amdfam10_decode")
6965         (cond [(eq_attr "alternative" "0,1")
6966                   (const_string "vector")]
6967               (const_string "direct")))
6968    (set_attr "mode" "HI")])
6969
6970 ;;On AMDFAM10
6971 ;; MUL reg8     Direct
6972 ;; MUL mem8     Direct
6973
6974 (define_insn "*mulqi3_1"
6975   [(set (match_operand:QI 0 "register_operand" "=a")
6976         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6977                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
6978    (clobber (reg:CC FLAGS_REG))]
6979   "TARGET_QIMODE_MATH
6980    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6981   "mul{b}\t%2"
6982   [(set_attr "type" "imul")
6983    (set_attr "length_immediate" "0")
6984    (set (attr "athlon_decode")
6985      (if_then_else (eq_attr "cpu" "athlon")
6986         (const_string "vector")
6987         (const_string "direct")))
6988    (set_attr "amdfam10_decode" "direct")
6989    (set_attr "mode" "QI")])
6990
6991 (define_expand "<u>mul<mode><dwi>3"
6992   [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
6993                    (mult:<DWI>
6994                      (any_extend:<DWI>
6995                        (match_operand:DWIH 1 "nonimmediate_operand" ""))
6996                      (any_extend:<DWI>
6997                        (match_operand:DWIH 2 "register_operand" ""))))
6998               (clobber (reg:CC FLAGS_REG))])]
6999   ""
7000   "")
7001
7002 (define_expand "<u>mulqihi3"
7003   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7004                    (mult:HI
7005                      (any_extend:HI
7006                        (match_operand:QI 1 "nonimmediate_operand" ""))
7007                      (any_extend:HI
7008                        (match_operand:QI 2 "register_operand" ""))))
7009               (clobber (reg:CC FLAGS_REG))])]
7010   "TARGET_QIMODE_MATH"
7011   "")
7012
7013 (define_insn "*<u>mul<mode><dwi>3_1"
7014   [(set (match_operand:<DWI> 0 "register_operand" "=A")
7015         (mult:<DWI>
7016           (any_extend:<DWI>
7017             (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
7018           (any_extend:<DWI>
7019             (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7020    (clobber (reg:CC FLAGS_REG))]
7021   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7022   "<sgnprefix>mul{<imodesuffix>}\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 "double")))
7029    (set_attr "amdfam10_decode" "double")
7030    (set_attr "mode" "<MODE>")])
7031
7032 (define_insn "*<u>mulqihi3_1"
7033   [(set (match_operand:HI 0 "register_operand" "=a")
7034         (mult:HI
7035           (any_extend:HI
7036             (match_operand:QI 1 "nonimmediate_operand" "%0"))
7037           (any_extend:HI
7038             (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7039    (clobber (reg:CC FLAGS_REG))]
7040   "TARGET_QIMODE_MATH
7041    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7042   "<sgnprefix>mul{b}\t%2"
7043   [(set_attr "type" "imul")
7044    (set_attr "length_immediate" "0")
7045    (set (attr "athlon_decode")
7046      (if_then_else (eq_attr "cpu" "athlon")
7047         (const_string "vector")
7048         (const_string "direct")))
7049    (set_attr "amdfam10_decode" "direct")
7050    (set_attr "mode" "QI")])
7051
7052 (define_expand "<s>mul<mode>3_highpart"
7053   [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
7054                    (truncate:SWI48
7055                      (lshiftrt:<DWI>
7056                        (mult:<DWI>
7057                          (any_extend:<DWI>
7058                            (match_operand:SWI48 1 "nonimmediate_operand" ""))
7059                          (any_extend:<DWI>
7060                            (match_operand:SWI48 2 "register_operand" "")))
7061                        (match_dup 4))))
7062               (clobber (match_scratch:SWI48 3 ""))
7063               (clobber (reg:CC FLAGS_REG))])]
7064   ""
7065   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7066
7067 (define_insn "*<s>muldi3_highpart_1"
7068   [(set (match_operand:DI 0 "register_operand" "=d")
7069         (truncate:DI
7070           (lshiftrt:TI
7071             (mult:TI
7072               (any_extend:TI
7073                 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7074               (any_extend:TI
7075                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7076             (const_int 64))))
7077    (clobber (match_scratch:DI 3 "=1"))
7078    (clobber (reg:CC FLAGS_REG))]
7079   "TARGET_64BIT
7080    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7081   "<sgnprefix>mul{q}\t%2"
7082   [(set_attr "type" "imul")
7083    (set_attr "length_immediate" "0")
7084    (set (attr "athlon_decode")
7085      (if_then_else (eq_attr "cpu" "athlon")
7086         (const_string "vector")
7087         (const_string "double")))
7088    (set_attr "amdfam10_decode" "double")
7089    (set_attr "mode" "DI")])
7090
7091 (define_insn "*<s>mulsi3_highpart_1"
7092   [(set (match_operand:SI 0 "register_operand" "=d")
7093         (truncate:SI
7094           (lshiftrt:DI
7095             (mult:DI
7096               (any_extend:DI
7097                 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7098               (any_extend:DI
7099                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7100             (const_int 32))))
7101    (clobber (match_scratch:SI 3 "=1"))
7102    (clobber (reg:CC FLAGS_REG))]
7103   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7104   "<sgnprefix>mul{l}\t%2"
7105   [(set_attr "type" "imul")
7106    (set_attr "length_immediate" "0")
7107    (set (attr "athlon_decode")
7108      (if_then_else (eq_attr "cpu" "athlon")
7109         (const_string "vector")
7110         (const_string "double")))
7111    (set_attr "amdfam10_decode" "double")
7112    (set_attr "mode" "SI")])
7113
7114 (define_insn "*<s>mulsi3_highpart_zext"
7115   [(set (match_operand:DI 0 "register_operand" "=d")
7116         (zero_extend:DI (truncate:SI
7117           (lshiftrt:DI
7118             (mult:DI (any_extend:DI
7119                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7120                      (any_extend:DI
7121                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7122             (const_int 32)))))
7123    (clobber (match_scratch:SI 3 "=1"))
7124    (clobber (reg:CC FLAGS_REG))]
7125   "TARGET_64BIT
7126    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7127   "<sgnprefix>mul{l}\t%2"
7128   [(set_attr "type" "imul")
7129    (set_attr "length_immediate" "0")
7130    (set (attr "athlon_decode")
7131      (if_then_else (eq_attr "cpu" "athlon")
7132         (const_string "vector")
7133         (const_string "double")))
7134    (set_attr "amdfam10_decode" "double")
7135    (set_attr "mode" "SI")])
7136
7137 ;; The patterns that match these are at the end of this file.
7138
7139 (define_expand "mulxf3"
7140   [(set (match_operand:XF 0 "register_operand" "")
7141         (mult:XF (match_operand:XF 1 "register_operand" "")
7142                  (match_operand:XF 2 "register_operand" "")))]
7143   "TARGET_80387"
7144   "")
7145
7146 (define_expand "mul<mode>3"
7147   [(set (match_operand:MODEF 0 "register_operand" "")
7148         (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
7149                     (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7150   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7151     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7152   "")
7153 \f
7154 ;; Divide instructions
7155
7156 ;; The patterns that match these are at the end of this file.
7157
7158 (define_expand "divxf3"
7159   [(set (match_operand:XF 0 "register_operand" "")
7160         (div:XF (match_operand:XF 1 "register_operand" "")
7161                 (match_operand:XF 2 "register_operand" "")))]
7162   "TARGET_80387"
7163   "")
7164
7165 (define_expand "divdf3"
7166   [(set (match_operand:DF 0 "register_operand" "")
7167         (div:DF (match_operand:DF 1 "register_operand" "")
7168                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7169    "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7170     || (TARGET_SSE2 && TARGET_SSE_MATH)"
7171    "")
7172
7173 (define_expand "divsf3"
7174   [(set (match_operand:SF 0 "register_operand" "")
7175         (div:SF (match_operand:SF 1 "register_operand" "")
7176                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7177   "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7178     || TARGET_SSE_MATH"
7179 {
7180   if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
7181       && flag_finite_math_only && !flag_trapping_math
7182       && flag_unsafe_math_optimizations)
7183     {
7184       ix86_emit_swdivsf (operands[0], operands[1],
7185                          operands[2], SFmode);
7186       DONE;
7187     }
7188 })
7189 \f
7190 ;; Divmod instructions.
7191
7192 (define_expand "divmodqi4"
7193   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7194                    (div:QI
7195                      (match_operand:QI 1 "register_operand" "")
7196                      (match_operand:QI 2 "nonimmediate_operand" "")))
7197               (set (match_operand:QI 3 "register_operand" "")
7198                    (mod:QI (match_dup 1) (match_dup 2)))
7199               (clobber (reg:CC FLAGS_REG))])]
7200   "TARGET_QIMODE_MATH"
7201 {
7202   rtx div, mod, insn;
7203   rtx tmp0, tmp1;
7204   
7205   tmp0 = gen_reg_rtx (HImode);
7206   tmp1 = gen_reg_rtx (HImode);
7207
7208   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is
7209      in AX.  */
7210   emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7211   emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7212
7213   /* Extract remainder from AH.  */
7214   tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7215   insn = emit_move_insn (operands[3], tmp1);
7216
7217   mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7218   set_unique_reg_note (insn, REG_EQUAL, mod);
7219
7220   /* Extract quotient from AL.  */
7221   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7222
7223   div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7224   set_unique_reg_note (insn, REG_EQUAL, div);
7225
7226   DONE;
7227 })
7228
7229 (define_expand "udivmodqi4"
7230   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7231                    (udiv:QI
7232                      (match_operand:QI 1 "register_operand" "")
7233                      (match_operand:QI 2 "nonimmediate_operand" "")))
7234               (set (match_operand:QI 3 "register_operand" "")
7235                    (umod:QI (match_dup 1) (match_dup 2)))
7236               (clobber (reg:CC FLAGS_REG))])]
7237   "TARGET_QIMODE_MATH"
7238 {
7239   rtx div, mod, insn;
7240   rtx tmp0, tmp1;
7241   
7242   tmp0 = gen_reg_rtx (HImode);
7243   tmp1 = gen_reg_rtx (HImode);
7244
7245   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is
7246      in AX.  */
7247   emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7248   emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7249
7250   /* Extract remainder from AH.  */
7251   tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7252   tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7253   insn = emit_move_insn (operands[3], tmp1);
7254
7255   mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7256   set_unique_reg_note (insn, REG_EQUAL, mod);
7257
7258   /* Extract quotient from AL.  */
7259   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7260
7261   div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7262   set_unique_reg_note (insn, REG_EQUAL, div);
7263
7264   DONE;
7265 })
7266
7267 ;; Divide AX by r/m8, with result stored in
7268 ;; AL <- Quotient
7269 ;; AH <- Remainder
7270 ;; Change div/mod to HImode and extend the second argument to HImode
7271 ;; so that mode of div/mod matches with mode of arguments.  Otherwise
7272 ;; combine may fail.
7273 (define_insn "divmodhiqi3"
7274   [(set (match_operand:HI 0 "register_operand" "=a")
7275         (ior:HI
7276           (ashift:HI
7277             (zero_extend:HI
7278               (truncate:QI
7279                 (mod:HI (match_operand:HI 1 "register_operand" "0")
7280                         (sign_extend:HI
7281                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7282             (const_int 8))
7283           (zero_extend:HI
7284             (truncate:QI
7285               (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7286    (clobber (reg:CC FLAGS_REG))]
7287   "TARGET_QIMODE_MATH"
7288   "idiv{b}\t%2"
7289   [(set_attr "type" "idiv")
7290    (set_attr "mode" "QI")])
7291
7292 (define_insn "udivmodhiqi3"
7293   [(set (match_operand:HI 0 "register_operand" "=a")
7294         (ior:HI
7295           (ashift:HI
7296             (zero_extend:HI
7297               (truncate:QI
7298                 (mod:HI (match_operand:HI 1 "register_operand" "0")
7299                         (zero_extend:HI
7300                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7301             (const_int 8))
7302           (zero_extend:HI
7303             (truncate:QI
7304               (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7305    (clobber (reg:CC FLAGS_REG))]
7306   "TARGET_QIMODE_MATH"
7307   "div{b}\t%2"
7308   [(set_attr "type" "idiv")
7309    (set_attr "mode" "QI")])
7310
7311 (define_expand "divmod<mode>4"
7312   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7313                    (div:SWIM248
7314                      (match_operand:SWIM248 1 "register_operand" "")
7315                      (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7316               (set (match_operand:SWIM248 3 "register_operand" "")
7317                    (mod:SWIM248 (match_dup 1) (match_dup 2)))
7318               (clobber (reg:CC FLAGS_REG))])]
7319   ""
7320   "")
7321
7322 (define_insn_and_split "*divmod<mode>4"
7323   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7324         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7325                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7326    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7327         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7328    (clobber (reg:CC FLAGS_REG))]
7329   ""
7330   "#"
7331   "reload_completed"
7332   [(parallel [(set (match_dup 1)
7333                    (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7334               (clobber (reg:CC FLAGS_REG))])
7335    (parallel [(set (match_dup 0)
7336                    (div:SWIM248 (match_dup 2) (match_dup 3)))
7337               (set (match_dup 1)
7338                    (mod:SWIM248 (match_dup 2) (match_dup 3)))
7339               (use (match_dup 1))
7340               (clobber (reg:CC FLAGS_REG))])]
7341 {
7342   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7343
7344   if (<MODE>mode != HImode
7345       && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7346     operands[4] = operands[2];
7347   else
7348     {
7349       /* Avoid use of cltd in favor of a mov+shift.  */
7350       emit_move_insn (operands[1], operands[2]);
7351       operands[4] = operands[1];
7352     }
7353 }
7354   [(set_attr "type" "multi")
7355    (set_attr "mode" "<MODE>")])
7356
7357 (define_insn "*divmod<mode>4_noext"
7358   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7359         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7360                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7361    (set (match_operand:SWIM248 1 "register_operand" "=d")
7362         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7363    (use (match_operand:SWIM248 4 "register_operand" "1"))
7364    (clobber (reg:CC FLAGS_REG))]
7365   ""
7366   "idiv{<imodesuffix>}\t%3"
7367   [(set_attr "type" "idiv")
7368    (set_attr "mode" "<MODE>")])
7369
7370 (define_expand "udivmod<mode>4"
7371   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7372                    (udiv:SWIM248
7373                      (match_operand:SWIM248 1 "register_operand" "")
7374                      (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7375               (set (match_operand:SWIM248 3 "register_operand" "")
7376                    (umod:SWIM248 (match_dup 1) (match_dup 2)))
7377               (clobber (reg:CC FLAGS_REG))])]
7378   ""
7379   "")
7380
7381 (define_insn_and_split "*udivmod<mode>4"
7382   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7383         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7384                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7385    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7386         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7387    (clobber (reg:CC FLAGS_REG))]
7388   ""
7389   "#"
7390   "reload_completed"
7391   [(set (match_dup 1) (const_int 0))
7392    (parallel [(set (match_dup 0)
7393                    (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7394               (set (match_dup 1)
7395                    (umod:SWIM248 (match_dup 2) (match_dup 3)))
7396               (use (match_dup 1))
7397               (clobber (reg:CC FLAGS_REG))])]
7398   ""
7399   [(set_attr "type" "multi")
7400    (set_attr "mode" "<MODE>")])
7401
7402 (define_insn "*udivmod<mode>4_noext"
7403   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7404         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7405                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7406    (set (match_operand:SWIM248 1 "register_operand" "=d")
7407         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7408    (use (match_operand:SWIM248 4 "register_operand" "1"))
7409    (clobber (reg:CC FLAGS_REG))]
7410   ""
7411   "div{<imodesuffix>}\t%3"
7412   [(set_attr "type" "idiv")
7413    (set_attr "mode" "<MODE>")])
7414
7415 ;; We cannot use div/idiv for double division, because it causes
7416 ;; "division by zero" on the overflow and that's not what we expect
7417 ;; from truncate.  Because true (non truncating) double division is
7418 ;; never generated, we can't create this insn anyway.
7419 ;
7420 ;(define_insn ""
7421 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7422 ;       (truncate:SI
7423 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7424 ;                  (zero_extend:DI
7425 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7426 ;   (set (match_operand:SI 3 "register_operand" "=d")
7427 ;       (truncate:SI
7428 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7429 ;   (clobber (reg:CC FLAGS_REG))]
7430 ;  ""
7431 ;  "div{l}\t{%2, %0|%0, %2}"
7432 ;  [(set_attr "type" "idiv")])
7433 \f
7434 ;;- Logical AND instructions
7435
7436 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7437 ;; Note that this excludes ah.
7438
7439 (define_expand "testsi_ccno_1"
7440   [(set (reg:CCNO FLAGS_REG)
7441         (compare:CCNO
7442           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7443                   (match_operand:SI 1 "nonmemory_operand" ""))
7444           (const_int 0)))]
7445   ""
7446   "")
7447
7448 (define_expand "testqi_ccz_1"
7449   [(set (reg:CCZ FLAGS_REG)
7450         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7451                              (match_operand:QI 1 "nonmemory_operand" ""))
7452                  (const_int 0)))]
7453   ""
7454   "")
7455
7456 (define_insn "*testdi_1"
7457   [(set (reg FLAGS_REG)
7458         (compare
7459          (and:DI
7460           (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7461           (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7462          (const_int 0)))]
7463   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7464    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7465   "@
7466    test{l}\t{%k1, %k0|%k0, %k1}
7467    test{l}\t{%k1, %k0|%k0, %k1}
7468    test{q}\t{%1, %0|%0, %1}
7469    test{q}\t{%1, %0|%0, %1}
7470    test{q}\t{%1, %0|%0, %1}"
7471   [(set_attr "type" "test")
7472    (set_attr "modrm" "0,1,0,1,1")
7473    (set_attr "mode" "SI,SI,DI,DI,DI")])
7474
7475 (define_insn "*testqi_1_maybe_si"
7476   [(set (reg FLAGS_REG)
7477         (compare
7478           (and:QI
7479             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7480             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7481           (const_int 0)))]
7482    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7483     && ix86_match_ccmode (insn,
7484                          CONST_INT_P (operands[1])
7485                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7486 {
7487   if (which_alternative == 3)
7488     {
7489       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7490         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7491       return "test{l}\t{%1, %k0|%k0, %1}";
7492     }
7493   return "test{b}\t{%1, %0|%0, %1}";
7494 }
7495   [(set_attr "type" "test")
7496    (set_attr "modrm" "0,1,1,1")
7497    (set_attr "mode" "QI,QI,QI,SI")
7498    (set_attr "pent_pair" "uv,np,uv,np")])
7499
7500 (define_insn "*test<mode>_1"
7501   [(set (reg FLAGS_REG)
7502         (compare
7503          (and:SWI124
7504           (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7505           (match_operand:SWI124 1 "general_operand" "<i>,<i>,<r><i>"))
7506          (const_int 0)))]
7507   "ix86_match_ccmode (insn, CCNOmode)
7508    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7509   "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7510   [(set_attr "type" "test")
7511    (set_attr "modrm" "0,1,1")
7512    (set_attr "mode" "<MODE>")
7513    (set_attr "pent_pair" "uv,np,uv")])
7514
7515 (define_expand "testqi_ext_ccno_0"
7516   [(set (reg:CCNO FLAGS_REG)
7517         (compare:CCNO
7518           (and:SI
7519             (zero_extract:SI
7520               (match_operand 0 "ext_register_operand" "")
7521               (const_int 8)
7522               (const_int 8))
7523             (match_operand 1 "const_int_operand" ""))
7524           (const_int 0)))]
7525   ""
7526   "")
7527
7528 (define_insn "*testqi_ext_0"
7529   [(set (reg FLAGS_REG)
7530         (compare
7531           (and:SI
7532             (zero_extract:SI
7533               (match_operand 0 "ext_register_operand" "Q")
7534               (const_int 8)
7535               (const_int 8))
7536             (match_operand 1 "const_int_operand" "n"))
7537           (const_int 0)))]
7538   "ix86_match_ccmode (insn, CCNOmode)"
7539   "test{b}\t{%1, %h0|%h0, %1}"
7540   [(set_attr "type" "test")
7541    (set_attr "mode" "QI")
7542    (set_attr "length_immediate" "1")
7543    (set_attr "modrm" "1")
7544    (set_attr "pent_pair" "np")])
7545
7546 (define_insn "*testqi_ext_1_rex64"
7547   [(set (reg FLAGS_REG)
7548         (compare
7549           (and:SI
7550             (zero_extract:SI
7551               (match_operand 0 "ext_register_operand" "Q")
7552               (const_int 8)
7553               (const_int 8))
7554             (zero_extend:SI
7555               (match_operand:QI 1 "register_operand" "Q")))
7556           (const_int 0)))]
7557   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7558   "test{b}\t{%1, %h0|%h0, %1}"
7559   [(set_attr "type" "test")
7560    (set_attr "mode" "QI")])
7561
7562 (define_insn "*testqi_ext_1"
7563   [(set (reg FLAGS_REG)
7564         (compare
7565           (and:SI
7566             (zero_extract:SI
7567               (match_operand 0 "ext_register_operand" "Q")
7568               (const_int 8)
7569               (const_int 8))
7570             (zero_extend:SI
7571               (match_operand:QI 1 "general_operand" "Qm")))
7572           (const_int 0)))]
7573   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7574   "test{b}\t{%1, %h0|%h0, %1}"
7575   [(set_attr "type" "test")
7576    (set_attr "mode" "QI")])
7577
7578 (define_insn "*testqi_ext_2"
7579   [(set (reg FLAGS_REG)
7580         (compare
7581           (and:SI
7582             (zero_extract:SI
7583               (match_operand 0 "ext_register_operand" "Q")
7584               (const_int 8)
7585               (const_int 8))
7586             (zero_extract:SI
7587               (match_operand 1 "ext_register_operand" "Q")
7588               (const_int 8)
7589               (const_int 8)))
7590           (const_int 0)))]
7591   "ix86_match_ccmode (insn, CCNOmode)"
7592   "test{b}\t{%h1, %h0|%h0, %h1}"
7593   [(set_attr "type" "test")
7594    (set_attr "mode" "QI")])
7595
7596 (define_insn "*testqi_ext_3_rex64"
7597   [(set (reg FLAGS_REG)
7598         (compare (zero_extract:DI
7599                    (match_operand 0 "nonimmediate_operand" "rm")
7600                    (match_operand:DI 1 "const_int_operand" "")
7601                    (match_operand:DI 2 "const_int_operand" ""))
7602                  (const_int 0)))]
7603   "TARGET_64BIT
7604    && ix86_match_ccmode (insn, CCNOmode)
7605    && INTVAL (operands[1]) > 0
7606    && INTVAL (operands[2]) >= 0
7607    /* Ensure that resulting mask is zero or sign extended operand.  */
7608    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7609        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7610            && INTVAL (operands[1]) > 32))
7611    && (GET_MODE (operands[0]) == SImode
7612        || GET_MODE (operands[0]) == DImode
7613        || GET_MODE (operands[0]) == HImode
7614        || GET_MODE (operands[0]) == QImode)"
7615   "#")
7616
7617 ;; Combine likes to form bit extractions for some tests.  Humor it.
7618 (define_insn "*testqi_ext_3"
7619   [(set (reg FLAGS_REG)
7620         (compare (zero_extract:SI
7621                    (match_operand 0 "nonimmediate_operand" "rm")
7622                    (match_operand:SI 1 "const_int_operand" "")
7623                    (match_operand:SI 2 "const_int_operand" ""))
7624                  (const_int 0)))]
7625   "ix86_match_ccmode (insn, CCNOmode)
7626    && INTVAL (operands[1]) > 0
7627    && INTVAL (operands[2]) >= 0
7628    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7629    && (GET_MODE (operands[0]) == SImode
7630        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7631        || GET_MODE (operands[0]) == HImode
7632        || GET_MODE (operands[0]) == QImode)"
7633   "#")
7634
7635 (define_split
7636   [(set (match_operand 0 "flags_reg_operand" "")
7637         (match_operator 1 "compare_operator"
7638           [(zero_extract
7639              (match_operand 2 "nonimmediate_operand" "")
7640              (match_operand 3 "const_int_operand" "")
7641              (match_operand 4 "const_int_operand" ""))
7642            (const_int 0)]))]
7643   "ix86_match_ccmode (insn, CCNOmode)"
7644   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7645 {
7646   rtx val = operands[2];
7647   HOST_WIDE_INT len = INTVAL (operands[3]);
7648   HOST_WIDE_INT pos = INTVAL (operands[4]);
7649   HOST_WIDE_INT mask;
7650   enum machine_mode mode, submode;
7651
7652   mode = GET_MODE (val);
7653   if (MEM_P (val))
7654     {
7655       /* ??? Combine likes to put non-volatile mem extractions in QImode
7656          no matter the size of the test.  So find a mode that works.  */
7657       if (! MEM_VOLATILE_P (val))
7658         {
7659           mode = smallest_mode_for_size (pos + len, MODE_INT);
7660           val = adjust_address (val, mode, 0);
7661         }
7662     }
7663   else if (GET_CODE (val) == SUBREG
7664            && (submode = GET_MODE (SUBREG_REG (val)),
7665                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7666            && pos + len <= GET_MODE_BITSIZE (submode)
7667            && GET_MODE_CLASS (submode) == MODE_INT)
7668     {
7669       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
7670       mode = submode;
7671       val = SUBREG_REG (val);
7672     }
7673   else if (mode == HImode && pos + len <= 8)
7674     {
7675       /* Small HImode tests can be converted to QImode.  */
7676       mode = QImode;
7677       val = gen_lowpart (QImode, val);
7678     }
7679
7680   if (len == HOST_BITS_PER_WIDE_INT)
7681     mask = -1;
7682   else
7683     mask = ((HOST_WIDE_INT)1 << len) - 1;
7684   mask <<= pos;
7685
7686   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7687 })
7688
7689 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7690 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7691 ;; this is relatively important trick.
7692 ;; Do the conversion only post-reload to avoid limiting of the register class
7693 ;; to QI regs.
7694 (define_split
7695   [(set (match_operand 0 "flags_reg_operand" "")
7696         (match_operator 1 "compare_operator"
7697           [(and (match_operand 2 "register_operand" "")
7698                 (match_operand 3 "const_int_operand" ""))
7699            (const_int 0)]))]
7700    "reload_completed
7701     && QI_REG_P (operands[2])
7702     && GET_MODE (operands[2]) != QImode
7703     && ((ix86_match_ccmode (insn, CCZmode)
7704          && !(INTVAL (operands[3]) & ~(255 << 8)))
7705         || (ix86_match_ccmode (insn, CCNOmode)
7706             && !(INTVAL (operands[3]) & ~(127 << 8))))"
7707   [(set (match_dup 0)
7708         (match_op_dup 1
7709           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7710                    (match_dup 3))
7711            (const_int 0)]))]
7712   "operands[2] = gen_lowpart (SImode, operands[2]);
7713    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7714
7715 (define_split
7716   [(set (match_operand 0 "flags_reg_operand" "")
7717         (match_operator 1 "compare_operator"
7718           [(and (match_operand 2 "nonimmediate_operand" "")
7719                 (match_operand 3 "const_int_operand" ""))
7720            (const_int 0)]))]
7721    "reload_completed
7722     && GET_MODE (operands[2]) != QImode
7723     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7724     && ((ix86_match_ccmode (insn, CCZmode)
7725          && !(INTVAL (operands[3]) & ~255))
7726         || (ix86_match_ccmode (insn, CCNOmode)
7727             && !(INTVAL (operands[3]) & ~127)))"
7728   [(set (match_dup 0)
7729         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7730                          (const_int 0)]))]
7731   "operands[2] = gen_lowpart (QImode, operands[2]);
7732    operands[3] = gen_lowpart (QImode, operands[3]);")
7733
7734 ;; %%% This used to optimize known byte-wide and operations to memory,
7735 ;; and sometimes to QImode registers.  If this is considered useful,
7736 ;; it should be done with splitters.
7737
7738 (define_expand "and<mode>3"
7739   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
7740         (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
7741                   (match_operand:SWIM 2 "<general_szext_operand>" "")))]
7742   ""
7743   "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
7744
7745 (define_insn "*anddi_1"
7746   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7747         (and:DI
7748          (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7749          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7750    (clobber (reg:CC FLAGS_REG))]
7751   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7752 {
7753   switch (get_attr_type (insn))
7754     {
7755     case TYPE_IMOVX:
7756       {
7757         enum machine_mode mode;
7758
7759         gcc_assert (CONST_INT_P (operands[2]));
7760         if (INTVAL (operands[2]) == 0xff)
7761           mode = QImode;
7762         else
7763           {
7764             gcc_assert (INTVAL (operands[2]) == 0xffff);
7765             mode = HImode;
7766           }
7767
7768         operands[1] = gen_lowpart (mode, operands[1]);
7769         if (mode == QImode)
7770           return "movz{bl|x}\t{%1, %k0|%k0, %1}";
7771         else
7772           return "movz{wl|x}\t{%1, %k0|%k0, %1}";
7773       }
7774
7775     default:
7776       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7777       if (get_attr_mode (insn) == MODE_SI)
7778         return "and{l}\t{%k2, %k0|%k0, %k2}";
7779       else
7780         return "and{q}\t{%2, %0|%0, %2}";
7781     }
7782 }
7783   [(set_attr "type" "alu,alu,alu,imovx")
7784    (set_attr "length_immediate" "*,*,*,0")
7785    (set (attr "prefix_rex")
7786      (if_then_else
7787        (and (eq_attr "type" "imovx")
7788             (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7789                  (match_operand 1 "ext_QIreg_nomode_operand" "")))
7790        (const_string "1")
7791        (const_string "*")))
7792    (set_attr "mode" "SI,DI,DI,SI")])
7793
7794 (define_insn "*andsi_1"
7795   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7796         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7797                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
7798    (clobber (reg:CC FLAGS_REG))]
7799   "ix86_binary_operator_ok (AND, SImode, operands)"
7800 {
7801   switch (get_attr_type (insn))
7802     {
7803     case TYPE_IMOVX:
7804       {
7805         enum machine_mode mode;
7806
7807         gcc_assert (CONST_INT_P (operands[2]));
7808         if (INTVAL (operands[2]) == 0xff)
7809           mode = QImode;
7810         else
7811           {
7812             gcc_assert (INTVAL (operands[2]) == 0xffff);
7813             mode = HImode;
7814           }
7815
7816         operands[1] = gen_lowpart (mode, operands[1]);
7817         if (mode == QImode)
7818           return "movz{bl|x}\t{%1, %0|%0, %1}";
7819         else
7820           return "movz{wl|x}\t{%1, %0|%0, %1}";
7821       }
7822
7823     default:
7824       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7825       return "and{l}\t{%2, %0|%0, %2}";
7826     }
7827 }
7828   [(set_attr "type" "alu,alu,imovx")
7829    (set (attr "prefix_rex")
7830      (if_then_else
7831        (and (eq_attr "type" "imovx")
7832             (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7833                  (match_operand 1 "ext_QIreg_nomode_operand" "")))
7834        (const_string "1")
7835        (const_string "*")))
7836    (set_attr "length_immediate" "*,*,0")
7837    (set_attr "mode" "SI")])
7838
7839 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7840 (define_insn "*andsi_1_zext"
7841   [(set (match_operand:DI 0 "register_operand" "=r")
7842         (zero_extend:DI
7843           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7844                   (match_operand:SI 2 "general_operand" "g"))))
7845    (clobber (reg:CC FLAGS_REG))]
7846   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7847   "and{l}\t{%2, %k0|%k0, %2}"
7848   [(set_attr "type" "alu")
7849    (set_attr "mode" "SI")])
7850
7851 (define_insn "*andhi_1"
7852   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
7853         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7854                 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7855    (clobber (reg:CC FLAGS_REG))]
7856   "ix86_binary_operator_ok (AND, HImode, operands)"
7857 {
7858   switch (get_attr_type (insn))
7859     {
7860     case TYPE_IMOVX:
7861       gcc_assert (CONST_INT_P (operands[2]));
7862       gcc_assert (INTVAL (operands[2]) == 0xff);
7863       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
7864
7865     default:
7866       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7867
7868       return "and{w}\t{%2, %0|%0, %2}";
7869     }
7870 }
7871   [(set_attr "type" "alu,alu,imovx")
7872    (set_attr "length_immediate" "*,*,0")
7873    (set (attr "prefix_rex")
7874      (if_then_else
7875        (and (eq_attr "type" "imovx")
7876             (match_operand 1 "ext_QIreg_nomode_operand" ""))
7877        (const_string "1")
7878        (const_string "*")))
7879    (set_attr "mode" "HI,HI,SI")])
7880
7881 ;; %%% Potential partial reg stall on alternative 2.  What to do?
7882 (define_insn "*andqi_1"
7883   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7884         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7885                 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7886    (clobber (reg:CC FLAGS_REG))]
7887   "ix86_binary_operator_ok (AND, QImode, operands)"
7888   "@
7889    and{b}\t{%2, %0|%0, %2}
7890    and{b}\t{%2, %0|%0, %2}
7891    and{l}\t{%k2, %k0|%k0, %k2}"
7892   [(set_attr "type" "alu")
7893    (set_attr "mode" "QI,QI,SI")])
7894
7895 (define_insn "*andqi_1_slp"
7896   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7897         (and:QI (match_dup 0)
7898                 (match_operand:QI 1 "general_operand" "qn,qmn")))
7899    (clobber (reg:CC FLAGS_REG))]
7900   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7901    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7902   "and{b}\t{%1, %0|%0, %1}"
7903   [(set_attr "type" "alu1")
7904    (set_attr "mode" "QI")])
7905
7906 (define_split
7907   [(set (match_operand 0 "register_operand" "")
7908         (and (match_dup 0)
7909              (const_int -65536)))
7910    (clobber (reg:CC FLAGS_REG))]
7911   "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7912     || optimize_function_for_size_p (cfun)"
7913   [(set (strict_low_part (match_dup 1)) (const_int 0))]
7914   "operands[1] = gen_lowpart (HImode, operands[0]);")
7915
7916 (define_split
7917   [(set (match_operand 0 "ext_register_operand" "")
7918         (and (match_dup 0)
7919              (const_int -256)))
7920    (clobber (reg:CC FLAGS_REG))]
7921   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7922    && reload_completed"
7923   [(set (strict_low_part (match_dup 1)) (const_int 0))]
7924   "operands[1] = gen_lowpart (QImode, operands[0]);")
7925
7926 (define_split
7927   [(set (match_operand 0 "ext_register_operand" "")
7928         (and (match_dup 0)
7929              (const_int -65281)))
7930    (clobber (reg:CC FLAGS_REG))]
7931   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7932    && reload_completed"
7933   [(parallel [(set (zero_extract:SI (match_dup 0)
7934                                     (const_int 8)
7935                                     (const_int 8))
7936                    (xor:SI
7937                      (zero_extract:SI (match_dup 0)
7938                                       (const_int 8)
7939                                       (const_int 8))
7940                      (zero_extract:SI (match_dup 0)
7941                                       (const_int 8)
7942                                       (const_int 8))))
7943               (clobber (reg:CC FLAGS_REG))])]
7944   "operands[0] = gen_lowpart (SImode, operands[0]);")
7945
7946 (define_insn "*anddi_2"
7947   [(set (reg FLAGS_REG)
7948         (compare
7949          (and:DI
7950           (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7951           (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7952          (const_int 0)))
7953    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7954         (and:DI (match_dup 1) (match_dup 2)))]
7955   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7956    && ix86_binary_operator_ok (AND, DImode, operands)"
7957   "@
7958    and{l}\t{%k2, %k0|%k0, %k2}
7959    and{q}\t{%2, %0|%0, %2}
7960    and{q}\t{%2, %0|%0, %2}"
7961   [(set_attr "type" "alu")
7962    (set_attr "mode" "SI,DI,DI")])
7963
7964 (define_insn "*andqi_2_maybe_si"
7965   [(set (reg FLAGS_REG)
7966         (compare (and:QI
7967                   (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7968                   (match_operand:QI 2 "general_operand" "qmn,qn,n"))
7969                  (const_int 0)))
7970    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
7971         (and:QI (match_dup 1) (match_dup 2)))]
7972   "ix86_binary_operator_ok (AND, QImode, operands)
7973    && ix86_match_ccmode (insn,
7974                          CONST_INT_P (operands[2])
7975                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
7976 {
7977   if (which_alternative == 2)
7978     {
7979       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
7980         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
7981       return "and{l}\t{%2, %k0|%k0, %2}";
7982     }
7983   return "and{b}\t{%2, %0|%0, %2}";
7984 }
7985   [(set_attr "type" "alu")
7986    (set_attr "mode" "QI,QI,SI")])
7987
7988 (define_insn "*and<mode>_2"
7989   [(set (reg FLAGS_REG)
7990         (compare (and:SWI124
7991                   (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
7992                   (match_operand:SWI124 2 "general_operand" "<g>,<r><i>"))
7993                  (const_int 0)))
7994    (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
7995         (and:SWI124 (match_dup 1) (match_dup 2)))]
7996   "ix86_match_ccmode (insn, CCNOmode)
7997    && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
7998   "and{<imodesuffix>}\t{%2, %0|%0, %2}"
7999   [(set_attr "type" "alu")
8000    (set_attr "mode" "<MODE>")])
8001
8002 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8003 (define_insn "*andsi_2_zext"
8004   [(set (reg FLAGS_REG)
8005         (compare (and:SI
8006                   (match_operand:SI 1 "nonimmediate_operand" "%0")
8007                   (match_operand:SI 2 "general_operand" "g"))
8008                  (const_int 0)))
8009    (set (match_operand:DI 0 "register_operand" "=r")
8010         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8011   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8012    && ix86_binary_operator_ok (AND, SImode, operands)"
8013   "and{l}\t{%2, %k0|%k0, %2}"
8014   [(set_attr "type" "alu")
8015    (set_attr "mode" "SI")])
8016
8017 (define_insn "*andqi_2_slp"
8018   [(set (reg FLAGS_REG)
8019         (compare (and:QI
8020                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8021                    (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8022                  (const_int 0)))
8023    (set (strict_low_part (match_dup 0))
8024         (and:QI (match_dup 0) (match_dup 1)))]
8025   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8026    && ix86_match_ccmode (insn, CCNOmode)
8027    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8028   "and{b}\t{%1, %0|%0, %1}"
8029   [(set_attr "type" "alu1")
8030    (set_attr "mode" "QI")])
8031
8032 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8033 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8034 ;; for a QImode operand, which of course failed.
8035 (define_insn "andqi_ext_0"
8036   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8037                          (const_int 8)
8038                          (const_int 8))
8039         (and:SI
8040           (zero_extract:SI
8041             (match_operand 1 "ext_register_operand" "0")
8042             (const_int 8)
8043             (const_int 8))
8044           (match_operand 2 "const_int_operand" "n")))
8045    (clobber (reg:CC FLAGS_REG))]
8046   ""
8047   "and{b}\t{%2, %h0|%h0, %2}"
8048   [(set_attr "type" "alu")
8049    (set_attr "length_immediate" "1")
8050    (set_attr "modrm" "1")
8051    (set_attr "mode" "QI")])
8052
8053 ;; Generated by peephole translating test to and.  This shows up
8054 ;; often in fp comparisons.
8055 (define_insn "*andqi_ext_0_cc"
8056   [(set (reg FLAGS_REG)
8057         (compare
8058           (and:SI
8059             (zero_extract:SI
8060               (match_operand 1 "ext_register_operand" "0")
8061               (const_int 8)
8062               (const_int 8))
8063             (match_operand 2 "const_int_operand" "n"))
8064           (const_int 0)))
8065    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8066                          (const_int 8)
8067                          (const_int 8))
8068         (and:SI
8069           (zero_extract:SI
8070             (match_dup 1)
8071             (const_int 8)
8072             (const_int 8))
8073           (match_dup 2)))]
8074   "ix86_match_ccmode (insn, CCNOmode)"
8075   "and{b}\t{%2, %h0|%h0, %2}"
8076   [(set_attr "type" "alu")
8077    (set_attr "length_immediate" "1")
8078    (set_attr "modrm" "1")
8079    (set_attr "mode" "QI")])
8080
8081 (define_insn "*andqi_ext_1_rex64"
8082   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8083                          (const_int 8)
8084                          (const_int 8))
8085         (and:SI
8086           (zero_extract:SI
8087             (match_operand 1 "ext_register_operand" "0")
8088             (const_int 8)
8089             (const_int 8))
8090           (zero_extend:SI
8091             (match_operand 2 "ext_register_operand" "Q"))))
8092    (clobber (reg:CC FLAGS_REG))]
8093   "TARGET_64BIT"
8094   "and{b}\t{%2, %h0|%h0, %2}"
8095   [(set_attr "type" "alu")
8096    (set_attr "length_immediate" "0")
8097    (set_attr "mode" "QI")])
8098
8099 (define_insn "*andqi_ext_1"
8100   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8101                          (const_int 8)
8102                          (const_int 8))
8103         (and:SI
8104           (zero_extract:SI
8105             (match_operand 1 "ext_register_operand" "0")
8106             (const_int 8)
8107             (const_int 8))
8108           (zero_extend:SI
8109             (match_operand:QI 2 "general_operand" "Qm"))))
8110    (clobber (reg:CC FLAGS_REG))]
8111   "!TARGET_64BIT"
8112   "and{b}\t{%2, %h0|%h0, %2}"
8113   [(set_attr "type" "alu")
8114    (set_attr "length_immediate" "0")
8115    (set_attr "mode" "QI")])
8116
8117 (define_insn "*andqi_ext_2"
8118   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8119                          (const_int 8)
8120                          (const_int 8))
8121         (and:SI
8122           (zero_extract:SI
8123             (match_operand 1 "ext_register_operand" "%0")
8124             (const_int 8)
8125             (const_int 8))
8126           (zero_extract:SI
8127             (match_operand 2 "ext_register_operand" "Q")
8128             (const_int 8)
8129             (const_int 8))))
8130    (clobber (reg:CC FLAGS_REG))]
8131   ""
8132   "and{b}\t{%h2, %h0|%h0, %h2}"
8133   [(set_attr "type" "alu")
8134    (set_attr "length_immediate" "0")
8135    (set_attr "mode" "QI")])
8136
8137 ;; Convert wide AND instructions with immediate operand to shorter QImode
8138 ;; equivalents when possible.
8139 ;; Don't do the splitting with memory operands, since it introduces risk
8140 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8141 ;; for size, but that can (should?) be handled by generic code instead.
8142 (define_split
8143   [(set (match_operand 0 "register_operand" "")
8144         (and (match_operand 1 "register_operand" "")
8145              (match_operand 2 "const_int_operand" "")))
8146    (clobber (reg:CC FLAGS_REG))]
8147    "reload_completed
8148     && QI_REG_P (operands[0])
8149     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8150     && !(~INTVAL (operands[2]) & ~(255 << 8))
8151     && GET_MODE (operands[0]) != QImode"
8152   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8153                    (and:SI (zero_extract:SI (match_dup 1)
8154                                             (const_int 8) (const_int 8))
8155                            (match_dup 2)))
8156               (clobber (reg:CC FLAGS_REG))])]
8157   "operands[0] = gen_lowpart (SImode, operands[0]);
8158    operands[1] = gen_lowpart (SImode, operands[1]);
8159    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8160
8161 ;; Since AND can be encoded with sign extended immediate, this is only
8162 ;; profitable when 7th bit is not set.
8163 (define_split
8164   [(set (match_operand 0 "register_operand" "")
8165         (and (match_operand 1 "general_operand" "")
8166              (match_operand 2 "const_int_operand" "")))
8167    (clobber (reg:CC FLAGS_REG))]
8168    "reload_completed
8169     && ANY_QI_REG_P (operands[0])
8170     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8171     && !(~INTVAL (operands[2]) & ~255)
8172     && !(INTVAL (operands[2]) & 128)
8173     && GET_MODE (operands[0]) != QImode"
8174   [(parallel [(set (strict_low_part (match_dup 0))
8175                    (and:QI (match_dup 1)
8176                            (match_dup 2)))
8177               (clobber (reg:CC FLAGS_REG))])]
8178   "operands[0] = gen_lowpart (QImode, operands[0]);
8179    operands[1] = gen_lowpart (QImode, operands[1]);
8180    operands[2] = gen_lowpart (QImode, operands[2]);")
8181 \f
8182 ;; Logical inclusive and exclusive OR instructions
8183
8184 ;; %%% This used to optimize known byte-wide and operations to memory.
8185 ;; If this is considered useful, it should be done with splitters.
8186
8187 (define_expand "<code><mode>3"
8188   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8189         (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8190                      (match_operand:SWIM 2 "<general_operand>" "")))]
8191   ""
8192   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8193
8194 (define_insn "*<code><mode>_1"
8195   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8196         (any_or:SWI248
8197          (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8198          (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8199    (clobber (reg:CC FLAGS_REG))]
8200   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8201   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8202   [(set_attr "type" "alu")
8203    (set_attr "mode" "<MODE>")])
8204
8205 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8206 (define_insn "*<code>qi_1"
8207   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8208         (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8209                    (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8210    (clobber (reg:CC FLAGS_REG))]
8211   "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8212   "@
8213    <logic>{b}\t{%2, %0|%0, %2}
8214    <logic>{b}\t{%2, %0|%0, %2}
8215    <logic>{l}\t{%k2, %k0|%k0, %k2}"
8216   [(set_attr "type" "alu")
8217    (set_attr "mode" "QI,QI,SI")])
8218
8219 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8220 (define_insn "*<code>si_1_zext"
8221   [(set (match_operand:DI 0 "register_operand" "=r")
8222         (zero_extend:DI
8223          (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8224                     (match_operand:SI 2 "general_operand" "g"))))
8225    (clobber (reg:CC FLAGS_REG))]
8226   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8227   "<logic>{l}\t{%2, %k0|%k0, %2}"
8228   [(set_attr "type" "alu")
8229    (set_attr "mode" "SI")])
8230
8231 (define_insn "*<code>si_1_zext_imm"
8232   [(set (match_operand:DI 0 "register_operand" "=r")
8233         (any_or:DI
8234          (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8235          (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8236    (clobber (reg:CC FLAGS_REG))]
8237   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8238   "<logic>{l}\t{%2, %k0|%k0, %2}"
8239   [(set_attr "type" "alu")
8240    (set_attr "mode" "SI")])
8241
8242 (define_insn "*<code>qi_1_slp"
8243   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8244         (any_or:QI (match_dup 0)
8245                    (match_operand:QI 1 "general_operand" "qmn,qn")))
8246    (clobber (reg:CC FLAGS_REG))]
8247   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8248    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8249   "<logic>{b}\t{%1, %0|%0, %1}"
8250   [(set_attr "type" "alu1")
8251    (set_attr "mode" "QI")])
8252
8253 (define_insn "*<code><mode>_2"
8254   [(set (reg FLAGS_REG)
8255         (compare (any_or:SWI
8256                   (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8257                   (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8258                  (const_int 0)))
8259    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8260         (any_or:SWI (match_dup 1) (match_dup 2)))]
8261   "ix86_match_ccmode (insn, CCNOmode)
8262    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8263   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8264   [(set_attr "type" "alu")
8265    (set_attr "mode" "<MODE>")])
8266
8267 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8268 ;; ??? Special case for immediate operand is missing - it is tricky.
8269 (define_insn "*<code>si_2_zext"
8270   [(set (reg FLAGS_REG)
8271         (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8272                             (match_operand:SI 2 "general_operand" "g"))
8273                  (const_int 0)))
8274    (set (match_operand:DI 0 "register_operand" "=r")
8275         (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8276   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8277    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8278   "<logic>{l}\t{%2, %k0|%k0, %2}"
8279   [(set_attr "type" "alu")
8280    (set_attr "mode" "SI")])
8281
8282 (define_insn "*<code>si_2_zext_imm"
8283   [(set (reg FLAGS_REG)
8284         (compare (any_or:SI
8285                   (match_operand:SI 1 "nonimmediate_operand" "%0")
8286                   (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8287                  (const_int 0)))
8288    (set (match_operand:DI 0 "register_operand" "=r")
8289         (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8290   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8291    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8292   "<logic>{l}\t{%2, %k0|%k0, %2}"
8293   [(set_attr "type" "alu")
8294    (set_attr "mode" "SI")])
8295
8296 (define_insn "*<code>qi_2_slp"
8297   [(set (reg FLAGS_REG)
8298         (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8299                             (match_operand:QI 1 "general_operand" "qmn,qn"))
8300                  (const_int 0)))
8301    (set (strict_low_part (match_dup 0))
8302         (any_or:QI (match_dup 0) (match_dup 1)))]
8303   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8304    && ix86_match_ccmode (insn, CCNOmode)
8305    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8306   "<logic>{b}\t{%1, %0|%0, %1}"
8307   [(set_attr "type" "alu1")
8308    (set_attr "mode" "QI")])
8309
8310 (define_insn "*<code><mode>_3"
8311   [(set (reg FLAGS_REG)
8312         (compare (any_or:SWI
8313                   (match_operand:SWI 1 "nonimmediate_operand" "%0")
8314                   (match_operand:SWI 2 "<general_operand>" "<g>"))
8315                  (const_int 0)))
8316    (clobber (match_scratch:SWI 0 "=<r>"))]
8317   "ix86_match_ccmode (insn, CCNOmode)
8318    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8319   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8320   [(set_attr "type" "alu")
8321    (set_attr "mode" "<MODE>")])
8322
8323 (define_insn "*<code>qi_ext_0"
8324   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8325                          (const_int 8)
8326                          (const_int 8))
8327         (any_or:SI
8328           (zero_extract:SI
8329             (match_operand 1 "ext_register_operand" "0")
8330             (const_int 8)
8331             (const_int 8))
8332           (match_operand 2 "const_int_operand" "n")))
8333    (clobber (reg:CC FLAGS_REG))]
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" "1")
8338    (set_attr "modrm" "1")
8339    (set_attr "mode" "QI")])
8340
8341 (define_insn "*<code>qi_ext_1_rex64"
8342   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8343                          (const_int 8)
8344                          (const_int 8))
8345         (any_or:SI
8346           (zero_extract:SI
8347             (match_operand 1 "ext_register_operand" "0")
8348             (const_int 8)
8349             (const_int 8))
8350           (zero_extend:SI
8351             (match_operand 2 "ext_register_operand" "Q"))))
8352    (clobber (reg:CC FLAGS_REG))]
8353   "TARGET_64BIT
8354    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8355   "<logic>{b}\t{%2, %h0|%h0, %2}"
8356   [(set_attr "type" "alu")
8357    (set_attr "length_immediate" "0")
8358    (set_attr "mode" "QI")])
8359
8360 (define_insn "*<code>qi_ext_1"
8361   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8362                          (const_int 8)
8363                          (const_int 8))
8364         (any_or:SI
8365           (zero_extract:SI
8366             (match_operand 1 "ext_register_operand" "0")
8367             (const_int 8)
8368             (const_int 8))
8369           (zero_extend:SI
8370             (match_operand:QI 2 "general_operand" "Qm"))))
8371    (clobber (reg:CC FLAGS_REG))]
8372   "!TARGET_64BIT
8373    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8374   "<logic>{b}\t{%2, %h0|%h0, %2}"
8375   [(set_attr "type" "alu")
8376    (set_attr "length_immediate" "0")
8377    (set_attr "mode" "QI")])
8378
8379 (define_insn "*<code>qi_ext_2"
8380   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8381                          (const_int 8)
8382                          (const_int 8))
8383         (any_or:SI
8384           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8385                            (const_int 8)
8386                            (const_int 8))
8387           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8388                            (const_int 8)
8389                            (const_int 8))))
8390    (clobber (reg:CC FLAGS_REG))]
8391   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8392   "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8393   [(set_attr "type" "alu")
8394    (set_attr "length_immediate" "0")
8395    (set_attr "mode" "QI")])
8396
8397 (define_split
8398   [(set (match_operand 0 "register_operand" "")
8399         (any_or (match_operand 1 "register_operand" "")
8400                 (match_operand 2 "const_int_operand" "")))
8401    (clobber (reg:CC FLAGS_REG))]
8402    "reload_completed
8403     && QI_REG_P (operands[0])
8404     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8405     && !(INTVAL (operands[2]) & ~(255 << 8))
8406     && GET_MODE (operands[0]) != QImode"
8407   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8408                    (any_or:SI (zero_extract:SI (match_dup 1)
8409                                                (const_int 8) (const_int 8))
8410                               (match_dup 2)))
8411               (clobber (reg:CC FLAGS_REG))])]
8412   "operands[0] = gen_lowpart (SImode, operands[0]);
8413    operands[1] = gen_lowpart (SImode, operands[1]);
8414    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8415
8416 ;; Since OR can be encoded with sign extended immediate, this is only
8417 ;; profitable when 7th bit is set.
8418 (define_split
8419   [(set (match_operand 0 "register_operand" "")
8420         (any_or (match_operand 1 "general_operand" "")
8421                 (match_operand 2 "const_int_operand" "")))
8422    (clobber (reg:CC FLAGS_REG))]
8423    "reload_completed
8424     && ANY_QI_REG_P (operands[0])
8425     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8426     && !(INTVAL (operands[2]) & ~255)
8427     && (INTVAL (operands[2]) & 128)
8428     && GET_MODE (operands[0]) != QImode"
8429   [(parallel [(set (strict_low_part (match_dup 0))
8430                    (any_or:QI (match_dup 1)
8431                               (match_dup 2)))
8432               (clobber (reg:CC FLAGS_REG))])]
8433   "operands[0] = gen_lowpart (QImode, operands[0]);
8434    operands[1] = gen_lowpart (QImode, operands[1]);
8435    operands[2] = gen_lowpart (QImode, operands[2]);")
8436
8437 (define_expand "xorqi_cc_ext_1"
8438   [(parallel [
8439      (set (reg:CCNO FLAGS_REG)
8440           (compare:CCNO
8441             (xor:SI
8442               (zero_extract:SI
8443                 (match_operand 1 "ext_register_operand" "")
8444                 (const_int 8)
8445                 (const_int 8))
8446               (match_operand:QI 2 "general_operand" ""))
8447             (const_int 0)))
8448      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8449                            (const_int 8)
8450                            (const_int 8))
8451           (xor:SI
8452             (zero_extract:SI
8453              (match_dup 1)
8454              (const_int 8)
8455              (const_int 8))
8456             (match_dup 2)))])]
8457   ""
8458   "")
8459
8460 (define_insn "*xorqi_cc_ext_1_rex64"
8461   [(set (reg FLAGS_REG)
8462         (compare
8463           (xor:SI
8464             (zero_extract:SI
8465               (match_operand 1 "ext_register_operand" "0")
8466               (const_int 8)
8467               (const_int 8))
8468             (match_operand:QI 2 "nonmemory_operand" "Qn"))
8469           (const_int 0)))
8470    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8471                          (const_int 8)
8472                          (const_int 8))
8473         (xor:SI
8474           (zero_extract:SI
8475            (match_dup 1)
8476            (const_int 8)
8477            (const_int 8))
8478           (match_dup 2)))]
8479   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8480   "xor{b}\t{%2, %h0|%h0, %2}"
8481   [(set_attr "type" "alu")
8482    (set_attr "modrm" "1")
8483    (set_attr "mode" "QI")])
8484
8485 (define_insn "*xorqi_cc_ext_1"
8486   [(set (reg FLAGS_REG)
8487         (compare
8488           (xor:SI
8489             (zero_extract:SI
8490               (match_operand 1 "ext_register_operand" "0")
8491               (const_int 8)
8492               (const_int 8))
8493             (match_operand:QI 2 "general_operand" "qmn"))
8494           (const_int 0)))
8495    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8496                          (const_int 8)
8497                          (const_int 8))
8498         (xor:SI
8499           (zero_extract:SI
8500            (match_dup 1)
8501            (const_int 8)
8502            (const_int 8))
8503           (match_dup 2)))]
8504   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8505   "xor{b}\t{%2, %h0|%h0, %2}"
8506   [(set_attr "type" "alu")
8507    (set_attr "modrm" "1")
8508    (set_attr "mode" "QI")])
8509 \f
8510 ;; Negation instructions
8511
8512 (define_expand "neg<mode>2"
8513   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
8514         (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
8515   ""
8516   "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8517
8518 (define_insn_and_split "*neg<dwi>2_doubleword"
8519   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8520         (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8521    (clobber (reg:CC FLAGS_REG))]
8522   "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8523   "#"
8524   "reload_completed"
8525   [(parallel
8526     [(set (reg:CCZ FLAGS_REG)
8527           (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8528      (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8529    (parallel
8530     [(set (match_dup 2)
8531           (plus:DWIH (match_dup 3)
8532                      (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8533                                 (const_int 0))))
8534      (clobber (reg:CC FLAGS_REG))])
8535    (parallel
8536     [(set (match_dup 2)
8537           (neg:DWIH (match_dup 2)))
8538      (clobber (reg:CC FLAGS_REG))])]
8539   "split_<dwi> (&operands[0], 2, &operands[0], &operands[2]);")
8540
8541 (define_insn "*neg<mode>2_1"
8542   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8543         (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8544    (clobber (reg:CC FLAGS_REG))]
8545   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8546   "neg{<imodesuffix>}\t%0"
8547   [(set_attr "type" "negnot")
8548    (set_attr "mode" "<MODE>")])
8549
8550 ;; Combine is quite creative about this pattern.
8551 (define_insn "*negsi2_1_zext"
8552   [(set (match_operand:DI 0 "register_operand" "=r")
8553         (lshiftrt:DI
8554           (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8555                              (const_int 32)))
8556         (const_int 32)))
8557    (clobber (reg:CC FLAGS_REG))]
8558   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8559   "neg{l}\t%k0"
8560   [(set_attr "type" "negnot")
8561    (set_attr "mode" "SI")])
8562
8563 ;; The problem with neg is that it does not perform (compare x 0),
8564 ;; it really performs (compare 0 x), which leaves us with the zero
8565 ;; flag being the only useful item.
8566
8567 (define_insn "*neg<mode>2_cmpz"
8568   [(set (reg:CCZ FLAGS_REG)
8569         (compare:CCZ
8570           (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8571                    (const_int 0)))
8572    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8573         (neg:SWI (match_dup 1)))]
8574   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8575   "neg{<imodesuffix>}\t%0"
8576   [(set_attr "type" "negnot")
8577    (set_attr "mode" "<MODE>")])
8578
8579 (define_insn "*negsi2_cmpz_zext"
8580   [(set (reg:CCZ FLAGS_REG)
8581         (compare:CCZ
8582           (lshiftrt:DI
8583             (neg:DI (ashift:DI
8584                       (match_operand:DI 1 "register_operand" "0")
8585                       (const_int 32)))
8586             (const_int 32))
8587           (const_int 0)))
8588    (set (match_operand:DI 0 "register_operand" "=r")
8589         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8590                                         (const_int 32)))
8591                      (const_int 32)))]
8592   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8593   "neg{l}\t%k0"
8594   [(set_attr "type" "negnot")
8595    (set_attr "mode" "SI")])
8596
8597 ;; Changing of sign for FP values is doable using integer unit too.
8598
8599 (define_expand "<code><mode>2"
8600   [(set (match_operand:X87MODEF 0 "register_operand" "")
8601         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
8602   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8603   "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8604
8605 (define_insn "*absneg<mode>2_mixed"
8606   [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8607         (match_operator:MODEF 3 "absneg_operator"
8608           [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8609    (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8610    (clobber (reg:CC FLAGS_REG))]
8611   "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8612   "#")
8613
8614 (define_insn "*absneg<mode>2_sse"
8615   [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8616         (match_operator:MODEF 3 "absneg_operator"
8617           [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8618    (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8619    (clobber (reg:CC FLAGS_REG))]
8620   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8621   "#")
8622
8623 (define_insn "*absneg<mode>2_i387"
8624   [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8625         (match_operator:X87MODEF 3 "absneg_operator"
8626           [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8627    (use (match_operand 2 "" ""))
8628    (clobber (reg:CC FLAGS_REG))]
8629   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8630   "#")
8631
8632 (define_expand "<code>tf2"
8633   [(set (match_operand:TF 0 "register_operand" "")
8634         (absneg:TF (match_operand:TF 1 "register_operand" "")))]
8635   "TARGET_SSE2"
8636   "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8637
8638 (define_insn "*absnegtf2_sse"
8639   [(set (match_operand:TF 0 "register_operand" "=x,x")
8640         (match_operator:TF 3 "absneg_operator"
8641           [(match_operand:TF 1 "register_operand" "0,x")]))
8642    (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8643    (clobber (reg:CC FLAGS_REG))]
8644   "TARGET_SSE2"
8645   "#")
8646
8647 ;; Splitters for fp abs and neg.
8648
8649 (define_split
8650   [(set (match_operand 0 "fp_register_operand" "")
8651         (match_operator 1 "absneg_operator" [(match_dup 0)]))
8652    (use (match_operand 2 "" ""))
8653    (clobber (reg:CC FLAGS_REG))]
8654   "reload_completed"
8655   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8656
8657 (define_split
8658   [(set (match_operand 0 "register_operand" "")
8659         (match_operator 3 "absneg_operator"
8660           [(match_operand 1 "register_operand" "")]))
8661    (use (match_operand 2 "nonimmediate_operand" ""))
8662    (clobber (reg:CC FLAGS_REG))]
8663   "reload_completed && SSE_REG_P (operands[0])"
8664   [(set (match_dup 0) (match_dup 3))]
8665 {
8666   enum machine_mode mode = GET_MODE (operands[0]);
8667   enum machine_mode vmode = GET_MODE (operands[2]);
8668   rtx tmp;
8669
8670   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8671   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8672   if (operands_match_p (operands[0], operands[2]))
8673     {
8674       tmp = operands[1];
8675       operands[1] = operands[2];
8676       operands[2] = tmp;
8677     }
8678   if (GET_CODE (operands[3]) == ABS)
8679     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8680   else
8681     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8682   operands[3] = tmp;
8683 })
8684
8685 (define_split
8686   [(set (match_operand:SF 0 "register_operand" "")
8687         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8688    (use (match_operand:V4SF 2 "" ""))
8689    (clobber (reg:CC FLAGS_REG))]
8690   "reload_completed"
8691   [(parallel [(set (match_dup 0) (match_dup 1))
8692               (clobber (reg:CC FLAGS_REG))])]
8693 {
8694   rtx tmp;
8695   operands[0] = gen_lowpart (SImode, operands[0]);
8696   if (GET_CODE (operands[1]) == ABS)
8697     {
8698       tmp = gen_int_mode (0x7fffffff, SImode);
8699       tmp = gen_rtx_AND (SImode, operands[0], tmp);
8700     }
8701   else
8702     {
8703       tmp = gen_int_mode (0x80000000, SImode);
8704       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8705     }
8706   operands[1] = tmp;
8707 })
8708
8709 (define_split
8710   [(set (match_operand:DF 0 "register_operand" "")
8711         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8712    (use (match_operand 2 "" ""))
8713    (clobber (reg:CC FLAGS_REG))]
8714   "reload_completed"
8715   [(parallel [(set (match_dup 0) (match_dup 1))
8716               (clobber (reg:CC FLAGS_REG))])]
8717 {
8718   rtx tmp;
8719   if (TARGET_64BIT)
8720     {
8721       tmp = gen_lowpart (DImode, operands[0]);
8722       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8723       operands[0] = tmp;
8724
8725       if (GET_CODE (operands[1]) == ABS)
8726         tmp = const0_rtx;
8727       else
8728         tmp = gen_rtx_NOT (DImode, tmp);
8729     }
8730   else
8731     {
8732       operands[0] = gen_highpart (SImode, operands[0]);
8733       if (GET_CODE (operands[1]) == ABS)
8734         {
8735           tmp = gen_int_mode (0x7fffffff, SImode);
8736           tmp = gen_rtx_AND (SImode, operands[0], tmp);
8737         }
8738       else
8739         {
8740           tmp = gen_int_mode (0x80000000, SImode);
8741           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8742         }
8743     }
8744   operands[1] = tmp;
8745 })
8746
8747 (define_split
8748   [(set (match_operand:XF 0 "register_operand" "")
8749         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8750    (use (match_operand 2 "" ""))
8751    (clobber (reg:CC FLAGS_REG))]
8752   "reload_completed"
8753   [(parallel [(set (match_dup 0) (match_dup 1))
8754               (clobber (reg:CC FLAGS_REG))])]
8755 {
8756   rtx tmp;
8757   operands[0] = gen_rtx_REG (SImode,
8758                              true_regnum (operands[0])
8759                              + (TARGET_64BIT ? 1 : 2));
8760   if (GET_CODE (operands[1]) == ABS)
8761     {
8762       tmp = GEN_INT (0x7fff);
8763       tmp = gen_rtx_AND (SImode, operands[0], tmp);
8764     }
8765   else
8766     {
8767       tmp = GEN_INT (0x8000);
8768       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8769     }
8770   operands[1] = tmp;
8771 })
8772
8773 ;; Conditionalize these after reload. If they match before reload, we
8774 ;; lose the clobber and ability to use integer instructions.
8775
8776 (define_insn "*<code><mode>2_1"
8777   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8778         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8779   "TARGET_80387
8780    && (reload_completed
8781        || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8782   "f<absneg_mnemonic>"
8783   [(set_attr "type" "fsgn")
8784    (set_attr "mode" "<MODE>")])
8785
8786 (define_insn "*<code>extendsfdf2"
8787   [(set (match_operand:DF 0 "register_operand" "=f")
8788         (absneg:DF (float_extend:DF
8789                      (match_operand:SF 1 "register_operand" "0"))))]
8790   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8791   "f<absneg_mnemonic>"
8792   [(set_attr "type" "fsgn")
8793    (set_attr "mode" "DF")])
8794
8795 (define_insn "*<code>extendsfxf2"
8796   [(set (match_operand:XF 0 "register_operand" "=f")
8797         (absneg:XF (float_extend:XF
8798                      (match_operand:SF 1 "register_operand" "0"))))]
8799   "TARGET_80387"
8800   "f<absneg_mnemonic>"
8801   [(set_attr "type" "fsgn")
8802    (set_attr "mode" "XF")])
8803
8804 (define_insn "*<code>extenddfxf2"
8805   [(set (match_operand:XF 0 "register_operand" "=f")
8806         (absneg:XF (float_extend:XF
8807                      (match_operand:DF 1 "register_operand" "0"))))]
8808   "TARGET_80387"
8809   "f<absneg_mnemonic>"
8810   [(set_attr "type" "fsgn")
8811    (set_attr "mode" "XF")])
8812
8813 ;; Copysign instructions
8814
8815 (define_mode_iterator CSGNMODE [SF DF TF])
8816 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8817
8818 (define_expand "copysign<mode>3"
8819   [(match_operand:CSGNMODE 0 "register_operand" "")
8820    (match_operand:CSGNMODE 1 "nonmemory_operand" "")
8821    (match_operand:CSGNMODE 2 "register_operand" "")]
8822   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8823    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8824   "ix86_expand_copysign (operands); DONE;")
8825
8826 (define_insn_and_split "copysign<mode>3_const"
8827   [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8828         (unspec:CSGNMODE
8829           [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8830            (match_operand:CSGNMODE 2 "register_operand" "0")
8831            (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8832           UNSPEC_COPYSIGN))]
8833   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8834    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8835   "#"
8836   "&& reload_completed"
8837   [(const_int 0)]
8838   "ix86_split_copysign_const (operands); DONE;")
8839
8840 (define_insn "copysign<mode>3_var"
8841   [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8842         (unspec:CSGNMODE
8843           [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8844            (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8845            (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8846            (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8847           UNSPEC_COPYSIGN))
8848    (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8849   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8850    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8851   "#")
8852
8853 (define_split
8854   [(set (match_operand:CSGNMODE 0 "register_operand" "")
8855         (unspec:CSGNMODE
8856           [(match_operand:CSGNMODE 2 "register_operand" "")
8857            (match_operand:CSGNMODE 3 "register_operand" "")
8858            (match_operand:<CSGNVMODE> 4 "" "")
8859            (match_operand:<CSGNVMODE> 5 "" "")]
8860           UNSPEC_COPYSIGN))
8861    (clobber (match_scratch:<CSGNVMODE> 1 ""))]
8862   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8863     || (TARGET_SSE2 && (<MODE>mode == TFmode)))
8864    && reload_completed"
8865   [(const_int 0)]
8866   "ix86_split_copysign_var (operands); DONE;")
8867 \f
8868 ;; One complement instructions
8869
8870 (define_expand "one_cmpl<mode>2"
8871   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8872         (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
8873   ""
8874   "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8875
8876 (define_insn "*one_cmpl<mode>2_1"
8877   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8878         (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8879   "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8880   "not{<imodesuffix>}\t%0"
8881   [(set_attr "type" "negnot")
8882    (set_attr "mode" "<MODE>")])
8883
8884 ;; %%% Potential partial reg stall on alternative 1.  What to do?
8885 (define_insn "*one_cmplqi2_1"
8886   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8887         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8888   "ix86_unary_operator_ok (NOT, QImode, operands)"
8889   "@
8890    not{b}\t%0
8891    not{l}\t%k0"
8892   [(set_attr "type" "negnot")
8893    (set_attr "mode" "QI,SI")])
8894
8895 ;; ??? Currently never generated - xor is used instead.
8896 (define_insn "*one_cmplsi2_1_zext"
8897   [(set (match_operand:DI 0 "register_operand" "=r")
8898         (zero_extend:DI
8899           (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8900   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8901   "not{l}\t%k0"
8902   [(set_attr "type" "negnot")
8903    (set_attr "mode" "SI")])
8904
8905 (define_insn "*one_cmpl<mode>2_2"
8906   [(set (reg FLAGS_REG)
8907         (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8908                  (const_int 0)))
8909    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8910         (not:SWI (match_dup 1)))]
8911   "ix86_match_ccmode (insn, CCNOmode)
8912    && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8913   "#"
8914   [(set_attr "type" "alu1")
8915    (set_attr "mode" "<MODE>")])
8916
8917 (define_split
8918   [(set (match_operand 0 "flags_reg_operand" "")
8919         (match_operator 2 "compare_operator"
8920           [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
8921            (const_int 0)]))
8922    (set (match_operand:SWI 1 "nonimmediate_operand" "")
8923         (not:SWI (match_dup 3)))]
8924   "ix86_match_ccmode (insn, CCNOmode)"
8925   [(parallel [(set (match_dup 0)
8926                    (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
8927                                     (const_int 0)]))
8928               (set (match_dup 1)
8929                    (xor:SWI (match_dup 3) (const_int -1)))])])
8930
8931 ;; ??? Currently never generated - xor is used instead.
8932 (define_insn "*one_cmplsi2_2_zext"
8933   [(set (reg FLAGS_REG)
8934         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
8935                  (const_int 0)))
8936    (set (match_operand:DI 0 "register_operand" "=r")
8937         (zero_extend:DI (not:SI (match_dup 1))))]
8938   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8939    && ix86_unary_operator_ok (NOT, SImode, operands)"
8940   "#"
8941   [(set_attr "type" "alu1")
8942    (set_attr "mode" "SI")])
8943
8944 (define_split
8945   [(set (match_operand 0 "flags_reg_operand" "")
8946         (match_operator 2 "compare_operator"
8947           [(not:SI (match_operand:SI 3 "register_operand" ""))
8948            (const_int 0)]))
8949    (set (match_operand:DI 1 "register_operand" "")
8950         (zero_extend:DI (not:SI (match_dup 3))))]
8951   "ix86_match_ccmode (insn, CCNOmode)"
8952   [(parallel [(set (match_dup 0)
8953                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
8954                                     (const_int 0)]))
8955               (set (match_dup 1)
8956                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
8957 \f
8958 ;; Shift instructions
8959
8960 ;; DImode shifts are implemented using the i386 "shift double" opcode,
8961 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
8962 ;; is variable, then the count is in %cl and the "imm" operand is dropped
8963 ;; from the assembler input.
8964 ;;
8965 ;; This instruction shifts the target reg/mem as usual, but instead of
8966 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
8967 ;; is a left shift double, bits are taken from the high order bits of
8968 ;; reg, else if the insn is a shift right double, bits are taken from the
8969 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
8970 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
8971 ;;
8972 ;; Since sh[lr]d does not change the `reg' operand, that is done
8973 ;; separately, making all shifts emit pairs of shift double and normal
8974 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
8975 ;; support a 63 bit shift, each shift where the count is in a reg expands
8976 ;; to a pair of shifts, a branch, a shift by 32 and a label.
8977 ;;
8978 ;; If the shift count is a constant, we need never emit more than one
8979 ;; shift pair, instead using moves and sign extension for counts greater
8980 ;; than 31.
8981
8982 (define_expand "ashl<mode>3"
8983   [(set (match_operand:SDWIM 0 "<shift_operand>" "")
8984         (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
8985                       (match_operand:QI 2 "nonmemory_operand" "")))]
8986   ""
8987   "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
8988
8989 (define_insn "*ashl<mode>3_doubleword"
8990   [(set (match_operand:DWI 0 "register_operand" "=&r,r")
8991         (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
8992                     (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
8993    (clobber (reg:CC FLAGS_REG))]
8994   ""
8995   "#"
8996   [(set_attr "type" "multi")])
8997
8998 (define_split
8999   [(set (match_operand:DWI 0 "register_operand" "")
9000         (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
9001                     (match_operand:QI 2 "nonmemory_operand" "")))
9002    (clobber (reg:CC FLAGS_REG))]
9003   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9004   [(const_int 0)]
9005   "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9006
9007 ;; By default we don't ask for a scratch register, because when DWImode
9008 ;; values are manipulated, registers are already at a premium.  But if
9009 ;; we have one handy, we won't turn it away.
9010
9011 (define_peephole2
9012   [(match_scratch:DWIH 3 "r")
9013    (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9014                    (ashift:<DWI>
9015                      (match_operand:<DWI> 1 "nonmemory_operand" "")
9016                      (match_operand:QI 2 "nonmemory_operand" "")))
9017               (clobber (reg:CC FLAGS_REG))])
9018    (match_dup 3)]
9019   "TARGET_CMOVE"
9020   [(const_int 0)]
9021   "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9022
9023 (define_insn "x86_64_shld"
9024   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9025         (ior:DI (ashift:DI (match_dup 0)
9026                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
9027                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9028                   (minus:QI (const_int 64) (match_dup 2)))))
9029    (clobber (reg:CC FLAGS_REG))]
9030   "TARGET_64BIT"
9031   "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9032   [(set_attr "type" "ishift")
9033    (set_attr "prefix_0f" "1")
9034    (set_attr "mode" "DI")
9035    (set_attr "athlon_decode" "vector")
9036    (set_attr "amdfam10_decode" "vector")])
9037
9038 (define_insn "x86_shld"
9039   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9040         (ior:SI (ashift:SI (match_dup 0)
9041                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
9042                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9043                   (minus:QI (const_int 32) (match_dup 2)))))
9044    (clobber (reg:CC FLAGS_REG))]
9045   ""
9046   "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9047   [(set_attr "type" "ishift")
9048    (set_attr "prefix_0f" "1")
9049    (set_attr "mode" "SI")
9050    (set_attr "pent_pair" "np")
9051    (set_attr "athlon_decode" "vector")
9052    (set_attr "amdfam10_decode" "vector")])
9053
9054 (define_expand "x86_shift<mode>_adj_1"
9055   [(set (reg:CCZ FLAGS_REG)
9056         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
9057                              (match_dup 4))
9058                      (const_int 0)))
9059    (set (match_operand:SWI48 0 "register_operand" "")
9060         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9061                             (match_operand:SWI48 1 "register_operand" "")
9062                             (match_dup 0)))
9063    (set (match_dup 1)
9064         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9065                             (match_operand:SWI48 3 "register_operand" "r")
9066                             (match_dup 1)))]
9067   "TARGET_CMOVE"
9068   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9069
9070 (define_expand "x86_shift<mode>_adj_2"
9071   [(use (match_operand:SWI48 0 "register_operand" ""))
9072    (use (match_operand:SWI48 1 "register_operand" ""))
9073    (use (match_operand:QI 2 "register_operand" ""))]
9074   ""
9075 {
9076   rtx label = gen_label_rtx ();
9077   rtx tmp;
9078
9079   emit_insn (gen_testqi_ccz_1 (operands[2],
9080                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9081
9082   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9083   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9084   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9085                               gen_rtx_LABEL_REF (VOIDmode, label),
9086                               pc_rtx);
9087   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9088   JUMP_LABEL (tmp) = label;
9089
9090   emit_move_insn (operands[0], operands[1]);
9091   ix86_expand_clear (operands[1]);
9092
9093   emit_label (label);
9094   LABEL_NUSES (label) = 1;
9095
9096   DONE;
9097 })
9098
9099 (define_insn "*ashl<mode>3_1"
9100   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9101         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l")
9102                       (match_operand:QI 2 "nonmemory_operand" "c<S>,M")))
9103    (clobber (reg:CC FLAGS_REG))]
9104   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9105 {
9106   switch (get_attr_type (insn))
9107     {
9108     case TYPE_LEA:
9109       return "#";
9110
9111     case TYPE_ALU:
9112       gcc_assert (operands[2] == const1_rtx);
9113       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9114       return "add{<imodesuffix>}\t%0, %0";
9115
9116     default:
9117       if (operands[2] == const1_rtx
9118           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9119         return "sal{<imodesuffix>}\t%0";
9120       else
9121         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9122     }
9123 }
9124   [(set (attr "type")
9125      (cond [(eq_attr "alternative" "1")
9126               (const_string "lea")
9127             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9128                           (const_int 0))
9129                       (match_operand 0 "register_operand" ""))
9130                  (match_operand 2 "const1_operand" ""))
9131               (const_string "alu")
9132            ]
9133            (const_string "ishift")))
9134    (set (attr "length_immediate")
9135      (if_then_else
9136        (ior (eq_attr "type" "alu")
9137             (and (eq_attr "type" "ishift")
9138                  (and (match_operand 2 "const1_operand" "")
9139                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9140                           (const_int 0)))))
9141        (const_string "0")
9142        (const_string "*")))
9143    (set_attr "mode" "<MODE>")])
9144
9145 (define_insn "*ashlsi3_1_zext"
9146   [(set (match_operand:DI 0 "register_operand" "=r,r")
9147         (zero_extend:DI
9148           (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
9149                      (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
9150    (clobber (reg:CC FLAGS_REG))]
9151   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9152 {
9153   switch (get_attr_type (insn))
9154     {
9155     case TYPE_LEA:
9156       return "#";
9157
9158     case TYPE_ALU:
9159       gcc_assert (operands[2] == const1_rtx);
9160       return "add{l}\t%k0, %k0";
9161
9162     default:
9163       if (operands[2] == const1_rtx
9164           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9165         return "sal{l}\t%k0";
9166       else
9167         return "sal{l}\t{%2, %k0|%k0, %2}";
9168     }
9169 }
9170   [(set (attr "type")
9171      (cond [(eq_attr "alternative" "1")
9172               (const_string "lea")
9173             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9174                      (const_int 0))
9175                  (match_operand 2 "const1_operand" ""))
9176               (const_string "alu")
9177            ]
9178            (const_string "ishift")))
9179    (set (attr "length_immediate")
9180      (if_then_else
9181        (ior (eq_attr "type" "alu")
9182             (and (eq_attr "type" "ishift")
9183                  (and (match_operand 2 "const1_operand" "")
9184                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9185                           (const_int 0)))))
9186        (const_string "0")
9187        (const_string "*")))
9188    (set_attr "mode" "SI")])
9189
9190 (define_insn "*ashlhi3_1"
9191   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9192         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
9193                    (match_operand:QI 2 "nonmemory_operand" "cI")))
9194    (clobber (reg:CC FLAGS_REG))]
9195   "TARGET_PARTIAL_REG_STALL
9196    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9197 {
9198   switch (get_attr_type (insn))
9199     {
9200     case TYPE_ALU:
9201       gcc_assert (operands[2] == const1_rtx);
9202       return "add{w}\t%0, %0";
9203
9204     default:
9205       if (operands[2] == const1_rtx
9206           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9207         return "sal{w}\t%0";
9208       else
9209         return "sal{w}\t{%2, %0|%0, %2}";
9210     }
9211 }
9212   [(set (attr "type")
9213      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9214                           (const_int 0))
9215                       (match_operand 0 "register_operand" ""))
9216                  (match_operand 2 "const1_operand" ""))
9217               (const_string "alu")
9218            ]
9219            (const_string "ishift")))
9220    (set (attr "length_immediate")
9221      (if_then_else
9222        (ior (eq_attr "type" "alu")
9223             (and (eq_attr "type" "ishift")
9224                  (and (match_operand 2 "const1_operand" "")
9225                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9226                           (const_int 0)))))
9227        (const_string "0")
9228        (const_string "*")))
9229    (set_attr "mode" "HI")])
9230
9231 (define_insn "*ashlhi3_1_lea"
9232   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
9233         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9234                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9235    (clobber (reg:CC FLAGS_REG))]
9236   "!TARGET_PARTIAL_REG_STALL
9237    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9238 {
9239   switch (get_attr_type (insn))
9240     {
9241     case TYPE_LEA:
9242       return "#";
9243
9244     case TYPE_ALU:
9245       gcc_assert (operands[2] == const1_rtx);
9246       return "add{w}\t%0, %0";
9247
9248     default:
9249       if (operands[2] == const1_rtx
9250           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9251         return "sal{w}\t%0";
9252       else
9253         return "sal{w}\t{%2, %0|%0, %2}";
9254     }
9255 }
9256   [(set (attr "type")
9257      (cond [(eq_attr "alternative" "1")
9258               (const_string "lea")
9259             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9260                           (const_int 0))
9261                       (match_operand 0 "register_operand" ""))
9262                  (match_operand 2 "const1_operand" ""))
9263               (const_string "alu")
9264            ]
9265            (const_string "ishift")))
9266    (set (attr "length_immediate")
9267      (if_then_else
9268        (ior (eq_attr "type" "alu")
9269             (and (eq_attr "type" "ishift")
9270                  (and (match_operand 2 "const1_operand" "")
9271                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9272                           (const_int 0)))))
9273        (const_string "0")
9274        (const_string "*")))
9275    (set_attr "mode" "HI,SI")])
9276
9277 (define_insn "*ashlqi3_1"
9278   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9279         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
9280                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
9281    (clobber (reg:CC FLAGS_REG))]
9282   "TARGET_PARTIAL_REG_STALL
9283    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9284 {
9285   switch (get_attr_type (insn))
9286     {
9287     case TYPE_ALU:
9288       gcc_assert (operands[2] == const1_rtx);
9289       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9290         return "add{l}\t%k0, %k0";
9291       else
9292         return "add{b}\t%0, %0";
9293
9294     default:
9295       if (operands[2] == const1_rtx
9296           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9297         {
9298           if (get_attr_mode (insn) == MODE_SI)
9299             return "sal{l}\t%k0";
9300           else
9301             return "sal{b}\t%0";
9302         }
9303       else
9304         {
9305           if (get_attr_mode (insn) == MODE_SI)
9306             return "sal{l}\t{%2, %k0|%k0, %2}";
9307           else
9308             return "sal{b}\t{%2, %0|%0, %2}";
9309         }
9310     }
9311 }
9312   [(set (attr "type")
9313      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9314                           (const_int 0))
9315                       (match_operand 0 "register_operand" ""))
9316                  (match_operand 2 "const1_operand" ""))
9317               (const_string "alu")
9318            ]
9319            (const_string "ishift")))
9320    (set (attr "length_immediate")
9321      (if_then_else
9322        (ior (eq_attr "type" "alu")
9323             (and (eq_attr "type" "ishift")
9324                  (and (match_operand 2 "const1_operand" "")
9325                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9326                           (const_int 0)))))
9327        (const_string "0")
9328        (const_string "*")))
9329    (set_attr "mode" "QI,SI")])
9330
9331 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9332 (define_insn "*ashlqi3_1_lea"
9333   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
9334         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9335                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9336    (clobber (reg:CC FLAGS_REG))]
9337   "!TARGET_PARTIAL_REG_STALL
9338    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9339 {
9340   switch (get_attr_type (insn))
9341     {
9342     case TYPE_LEA:
9343       return "#";
9344
9345     case TYPE_ALU:
9346       gcc_assert (operands[2] == const1_rtx);
9347       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9348         return "add{l}\t%k0, %k0";
9349       else
9350         return "add{b}\t%0, %0";
9351
9352     default:
9353       if (operands[2] == const1_rtx
9354           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9355         {
9356           if (get_attr_mode (insn) == MODE_SI)
9357             return "sal{l}\t%k0";
9358           else
9359             return "sal{b}\t%0";
9360         }
9361       else
9362         {
9363           if (get_attr_mode (insn) == MODE_SI)
9364             return "sal{l}\t{%2, %k0|%k0, %2}";
9365           else
9366             return "sal{b}\t{%2, %0|%0, %2}";
9367         }
9368     }
9369 }
9370   [(set (attr "type")
9371      (cond [(eq_attr "alternative" "2")
9372               (const_string "lea")
9373             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9374                           (const_int 0))
9375                       (match_operand 0 "register_operand" ""))
9376                  (match_operand 2 "const1_operand" ""))
9377               (const_string "alu")
9378            ]
9379            (const_string "ishift")))
9380    (set (attr "length_immediate")
9381      (if_then_else
9382        (ior (eq_attr "type" "alu")
9383             (and (eq_attr "type" "ishift")
9384                  (and (match_operand 2 "const1_operand" "")
9385                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9386                           (const_int 0)))))
9387        (const_string "0")
9388        (const_string "*")))
9389    (set_attr "mode" "QI,SI,SI")])
9390
9391 (define_insn "*ashlqi3_1_slp"
9392   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9393         (ashift:QI (match_dup 0)
9394                    (match_operand:QI 1 "nonmemory_operand" "cI")))
9395    (clobber (reg:CC FLAGS_REG))]
9396   "(optimize_function_for_size_p (cfun)
9397     || !TARGET_PARTIAL_FLAG_REG_STALL
9398     || (operands[1] == const1_rtx
9399         && (TARGET_SHIFT1
9400             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9401 {
9402   switch (get_attr_type (insn))
9403     {
9404     case TYPE_ALU:
9405       gcc_assert (operands[1] == const1_rtx);
9406       return "add{b}\t%0, %0";
9407
9408     default:
9409       if (operands[1] == const1_rtx
9410           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9411         return "sal{b}\t%0";
9412       else
9413         return "sal{b}\t{%1, %0|%0, %1}";
9414     }
9415 }
9416   [(set (attr "type")
9417      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9418                           (const_int 0))
9419                       (match_operand 0 "register_operand" ""))
9420                  (match_operand 1 "const1_operand" ""))
9421               (const_string "alu")
9422            ]
9423            (const_string "ishift1")))
9424    (set (attr "length_immediate")
9425      (if_then_else
9426        (ior (eq_attr "type" "alu")
9427             (and (eq_attr "type" "ishift1")
9428                  (and (match_operand 1 "const1_operand" "")
9429                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9430                           (const_int 0)))))
9431        (const_string "0")
9432        (const_string "*")))
9433    (set_attr "mode" "QI")])
9434
9435 ;; Convert lea to the lea pattern to avoid flags dependency.
9436 (define_split
9437   [(set (match_operand 0 "register_operand" "")
9438         (ashift (match_operand 1 "index_register_operand" "")
9439                 (match_operand:QI 2 "const_int_operand" "")))
9440    (clobber (reg:CC FLAGS_REG))]
9441   "reload_completed
9442    && true_regnum (operands[0]) != true_regnum (operands[1])"
9443   [(const_int 0)]
9444 {
9445   rtx pat;
9446   enum machine_mode mode = GET_MODE (operands[0]);
9447
9448   if (mode != Pmode)
9449     operands[1] = gen_lowpart (Pmode, operands[1]);
9450   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
9451
9452   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
9453
9454   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9455     operands[0] = gen_lowpart (SImode, operands[0]);
9456
9457   if (TARGET_64BIT && mode != Pmode)
9458     pat = gen_rtx_SUBREG (SImode, pat, 0);
9459
9460   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9461   DONE;
9462 })
9463
9464 ;; Convert lea to the lea pattern to avoid flags dependency.
9465 (define_split
9466   [(set (match_operand:DI 0 "register_operand" "")
9467         (zero_extend:DI
9468           (ashift:SI (match_operand:SI 1 "index_register_operand" "")
9469                      (match_operand:QI 2 "const_int_operand" ""))))
9470    (clobber (reg:CC FLAGS_REG))]
9471   "TARGET_64BIT && reload_completed
9472    && true_regnum (operands[0]) != true_regnum (operands[1])"
9473   [(set (match_dup 0)
9474         (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9475 {
9476   operands[1] = gen_lowpart (DImode, operands[1]);
9477   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9478 })
9479
9480 ;; This pattern can't accept a variable shift count, since shifts by
9481 ;; zero don't affect the flags.  We assume that shifts by constant
9482 ;; zero are optimized away.
9483 (define_insn "*ashl<mode>3_cmp"
9484   [(set (reg FLAGS_REG)
9485         (compare
9486           (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9487                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9488           (const_int 0)))
9489    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9490         (ashift:SWI (match_dup 1) (match_dup 2)))]
9491   "(optimize_function_for_size_p (cfun)
9492     || !TARGET_PARTIAL_FLAG_REG_STALL
9493     || (operands[2] == const1_rtx
9494         && (TARGET_SHIFT1
9495             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9496    && ix86_match_ccmode (insn, CCGOCmode)
9497    && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9498 {
9499   switch (get_attr_type (insn))
9500     {
9501     case TYPE_ALU:
9502       gcc_assert (operands[2] == const1_rtx);
9503       return "add{<imodesuffix>}\t%0, %0";
9504
9505     default:
9506       if (operands[2] == const1_rtx
9507           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9508         return "sal{<imodesuffix>}\t%0";
9509       else
9510         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9511     }
9512 }
9513   [(set (attr "type")
9514      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9515                           (const_int 0))
9516                       (match_operand 0 "register_operand" ""))
9517                  (match_operand 2 "const1_operand" ""))
9518               (const_string "alu")
9519            ]
9520            (const_string "ishift")))
9521    (set (attr "length_immediate")
9522      (if_then_else
9523        (ior (eq_attr "type" "alu")
9524             (and (eq_attr "type" "ishift")
9525                  (and (match_operand 2 "const1_operand" "")
9526                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9527                           (const_int 0)))))
9528        (const_string "0")
9529        (const_string "*")))
9530    (set_attr "mode" "<MODE>")])
9531
9532 (define_insn "*ashlsi3_cmp_zext"
9533   [(set (reg FLAGS_REG)
9534         (compare
9535           (ashift:SI (match_operand:SI 1 "register_operand" "0")
9536                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
9537           (const_int 0)))
9538    (set (match_operand:DI 0 "register_operand" "=r")
9539         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9540   "TARGET_64BIT
9541    && (optimize_function_for_size_p (cfun)
9542        || !TARGET_PARTIAL_FLAG_REG_STALL
9543        || (operands[2] == const1_rtx
9544            && (TARGET_SHIFT1
9545                || TARGET_DOUBLE_WITH_ADD)))
9546    && ix86_match_ccmode (insn, CCGOCmode)
9547    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9548 {
9549   switch (get_attr_type (insn))
9550     {
9551     case TYPE_ALU:
9552       gcc_assert (operands[2] == const1_rtx);
9553       return "add{l}\t%k0, %k0";
9554
9555     default:
9556       if (operands[2] == const1_rtx
9557           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9558         return "sal{l}\t%k0";
9559       else
9560         return "sal{l}\t{%2, %k0|%k0, %2}";
9561     }
9562 }
9563   [(set (attr "type")
9564      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9565                      (const_int 0))
9566                  (match_operand 2 "const1_operand" ""))
9567               (const_string "alu")
9568            ]
9569            (const_string "ishift")))
9570    (set (attr "length_immediate")
9571      (if_then_else
9572        (ior (eq_attr "type" "alu")
9573             (and (eq_attr "type" "ishift")
9574                  (and (match_operand 2 "const1_operand" "")
9575                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9576                           (const_int 0)))))
9577        (const_string "0")
9578        (const_string "*")))
9579    (set_attr "mode" "SI")])
9580
9581 (define_insn "*ashl<mode>3_cconly"
9582   [(set (reg FLAGS_REG)
9583         (compare
9584           (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9585                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9586           (const_int 0)))
9587    (clobber (match_scratch:SWI 0 "=<r>"))]
9588   "(optimize_function_for_size_p (cfun)
9589     || !TARGET_PARTIAL_FLAG_REG_STALL
9590     || (operands[2] == const1_rtx
9591         && (TARGET_SHIFT1
9592             || TARGET_DOUBLE_WITH_ADD)))
9593    && ix86_match_ccmode (insn, CCGOCmode)
9594    && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9595 {
9596   switch (get_attr_type (insn))
9597     {
9598     case TYPE_ALU:
9599       gcc_assert (operands[2] == const1_rtx);
9600       return "add{<imodesuffix>}\t%0, %0";
9601
9602     default:
9603       if (operands[2] == const1_rtx
9604           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9605         return "sal{<imodesuffix>}\t%0";
9606       else
9607         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9608     }
9609 }
9610   [(set (attr "type")
9611      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9612                           (const_int 0))
9613                       (match_operand 0 "register_operand" ""))
9614                  (match_operand 2 "const1_operand" ""))
9615               (const_string "alu")
9616            ]
9617            (const_string "ishift")))
9618    (set (attr "length_immediate")
9619      (if_then_else
9620        (ior (eq_attr "type" "alu")
9621             (and (eq_attr "type" "ishift")
9622                  (and (match_operand 2 "const1_operand" "")
9623                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9624                           (const_int 0)))))
9625        (const_string "0")
9626        (const_string "*")))
9627    (set_attr "mode" "<MODE>")])
9628
9629 ;; See comment above `ashl<mode>3' about how this works.
9630
9631 (define_expand "<shiftrt_insn><mode>3"
9632   [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9633         (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
9634                            (match_operand:QI 2 "nonmemory_operand" "")))]
9635   ""
9636   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9637
9638 (define_insn_and_split "*<shiftrt_insn><mode>3_doubleword"
9639   [(set (match_operand:DWI 0 "register_operand" "=r")
9640         (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9641                          (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9642    (clobber (reg:CC FLAGS_REG))]
9643   ""
9644   "#"
9645   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9646   [(const_int 0)]
9647   "ix86_split_<shiftrt_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9648   [(set_attr "type" "multi")])
9649
9650 ;; By default we don't ask for a scratch register, because when DWImode
9651 ;; values are manipulated, registers are already at a premium.  But if
9652 ;; we have one handy, we won't turn it away.
9653
9654 (define_peephole2
9655   [(match_scratch:DWIH 3 "r")
9656    (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9657                    (any_shiftrt:<DWI>
9658                      (match_operand:<DWI> 1 "register_operand" "")
9659                      (match_operand:QI 2 "nonmemory_operand" "")))
9660               (clobber (reg:CC FLAGS_REG))])
9661    (match_dup 3)]
9662   "TARGET_CMOVE"
9663   [(const_int 0)]
9664   "ix86_split_<shiftrt_insn> (operands, operands[3], <DWI>mode); DONE;")
9665
9666 (define_insn "x86_64_shrd"
9667   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9668         (ior:DI (ashiftrt:DI (match_dup 0)
9669                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
9670                 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9671                   (minus:QI (const_int 64) (match_dup 2)))))
9672    (clobber (reg:CC FLAGS_REG))]
9673   "TARGET_64BIT"
9674   "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9675   [(set_attr "type" "ishift")
9676    (set_attr "prefix_0f" "1")
9677    (set_attr "mode" "DI")
9678    (set_attr "athlon_decode" "vector")
9679    (set_attr "amdfam10_decode" "vector")])
9680
9681 (define_insn "x86_shrd"
9682   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9683         (ior:SI (ashiftrt:SI (match_dup 0)
9684                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
9685                 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9686                   (minus:QI (const_int 32) (match_dup 2)))))
9687    (clobber (reg:CC FLAGS_REG))]
9688   ""
9689   "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9690   [(set_attr "type" "ishift")
9691    (set_attr "prefix_0f" "1")
9692    (set_attr "mode" "SI")
9693    (set_attr "pent_pair" "np")
9694    (set_attr "athlon_decode" "vector")
9695    (set_attr "amdfam10_decode" "vector")])
9696
9697 (define_insn "ashrdi3_cvt"
9698   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9699         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9700                      (match_operand:QI 2 "const_int_operand" "")))
9701    (clobber (reg:CC FLAGS_REG))]
9702   "TARGET_64BIT && INTVAL (operands[2]) == 63
9703    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9704    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9705   "@
9706    {cqto|cqo}
9707    sar{q}\t{%2, %0|%0, %2}"
9708   [(set_attr "type" "imovx,ishift")
9709    (set_attr "prefix_0f" "0,*")
9710    (set_attr "length_immediate" "0,*")
9711    (set_attr "modrm" "0,1")
9712    (set_attr "mode" "DI")])
9713
9714 (define_insn "ashrsi3_cvt"
9715   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9716         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9717                      (match_operand:QI 2 "const_int_operand" "")))
9718    (clobber (reg:CC FLAGS_REG))]
9719   "INTVAL (operands[2]) == 31
9720    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9721    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9722   "@
9723    {cltd|cdq}
9724    sar{l}\t{%2, %0|%0, %2}"
9725   [(set_attr "type" "imovx,ishift")
9726    (set_attr "prefix_0f" "0,*")
9727    (set_attr "length_immediate" "0,*")
9728    (set_attr "modrm" "0,1")
9729    (set_attr "mode" "SI")])
9730
9731 (define_insn "*ashrsi3_cvt_zext"
9732   [(set (match_operand:DI 0 "register_operand" "=*d,r")
9733         (zero_extend:DI
9734           (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9735                        (match_operand:QI 2 "const_int_operand" ""))))
9736    (clobber (reg:CC FLAGS_REG))]
9737   "TARGET_64BIT && INTVAL (operands[2]) == 31
9738    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9739    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9740   "@
9741    {cltd|cdq}
9742    sar{l}\t{%2, %k0|%k0, %2}"
9743   [(set_attr "type" "imovx,ishift")
9744    (set_attr "prefix_0f" "0,*")
9745    (set_attr "length_immediate" "0,*")
9746    (set_attr "modrm" "0,1")
9747    (set_attr "mode" "SI")])
9748
9749 (define_expand "x86_shift<mode>_adj_3"
9750   [(use (match_operand:SWI48 0 "register_operand" ""))
9751    (use (match_operand:SWI48 1 "register_operand" ""))
9752    (use (match_operand:QI 2 "register_operand" ""))]
9753   ""
9754 {
9755   rtx label = gen_label_rtx ();
9756   rtx tmp;
9757
9758   emit_insn (gen_testqi_ccz_1 (operands[2],
9759                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9760
9761   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9762   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9763   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9764                               gen_rtx_LABEL_REF (VOIDmode, label),
9765                               pc_rtx);
9766   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9767   JUMP_LABEL (tmp) = label;
9768
9769   emit_move_insn (operands[0], operands[1]);
9770   emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9771                                   GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9772   emit_label (label);
9773   LABEL_NUSES (label) = 1;
9774
9775   DONE;
9776 })
9777
9778 (define_insn "*<shiftrt_insn><mode>3_1"
9779   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9780         (any_shiftrt:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9781                          (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9782    (clobber (reg:CC FLAGS_REG))]
9783   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9784 {
9785   if (operands[2] == const1_rtx
9786       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9787     return "<shiftrt>{<imodesuffix>}\t%0";
9788   else
9789     return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9790 }
9791   [(set_attr "type" "ishift")
9792    (set (attr "length_immediate")
9793      (if_then_else
9794        (and (match_operand 2 "const1_operand" "")
9795             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9796                 (const_int 0)))
9797        (const_string "0")
9798        (const_string "*")))
9799    (set_attr "mode" "<MODE>")])
9800
9801 (define_insn "*<shiftrt_insn>si3_1_zext"
9802   [(set (match_operand:DI 0 "register_operand" "=r")
9803         (zero_extend:DI
9804           (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9805                           (match_operand:QI 2 "nonmemory_operand" "cI"))))
9806    (clobber (reg:CC FLAGS_REG))]
9807   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9808 {
9809   if (operands[2] == const1_rtx
9810       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9811     return "<shiftrt>{l}\t%k0";
9812   else
9813     return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
9814 }
9815   [(set_attr "type" "ishift")
9816    (set (attr "length_immediate")
9817      (if_then_else
9818        (and (match_operand 2 "const1_operand" "")
9819             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9820                 (const_int 0)))
9821        (const_string "0")
9822        (const_string "*")))
9823    (set_attr "mode" "SI")])
9824
9825 (define_insn "*<shiftrt_insn>qi3_1_slp"
9826   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9827         (any_shiftrt:QI (match_dup 0)
9828                         (match_operand:QI 1 "nonmemory_operand" "cI")))
9829    (clobber (reg:CC FLAGS_REG))]
9830   "(optimize_function_for_size_p (cfun)
9831     || !TARGET_PARTIAL_REG_STALL
9832     || (operands[1] == const1_rtx
9833         && TARGET_SHIFT1))"
9834 {
9835   if (operands[1] == const1_rtx
9836       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9837     return "<shiftrt>{b}\t%0";
9838   else
9839     return "<shiftrt>{b}\t{%1, %0|%0, %1}";
9840 }
9841   [(set_attr "type" "ishift1")
9842    (set (attr "length_immediate")
9843      (if_then_else
9844        (and (match_operand 1 "const1_operand" "")
9845             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9846                 (const_int 0)))
9847        (const_string "0")
9848        (const_string "*")))
9849    (set_attr "mode" "QI")])
9850
9851 ;; This pattern can't accept a variable shift count, since shifts by
9852 ;; zero don't affect the flags.  We assume that shifts by constant
9853 ;; zero are optimized away.
9854 (define_insn "*<shiftrt_insn><mode>3_cmp"
9855   [(set (reg FLAGS_REG)
9856         (compare
9857           (any_shiftrt:SWI
9858             (match_operand:SWI 1 "nonimmediate_operand" "0")
9859             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9860           (const_int 0)))
9861    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9862         (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
9863   "(optimize_function_for_size_p (cfun)
9864     || !TARGET_PARTIAL_FLAG_REG_STALL
9865     || (operands[2] == const1_rtx
9866         && TARGET_SHIFT1))
9867    && ix86_match_ccmode (insn, CCGOCmode)
9868    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9869 {
9870   if (operands[2] == const1_rtx
9871       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9872     return "<shiftrt>{<imodesuffix>}\t%0";
9873   else
9874     return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9875 }
9876   [(set_attr "type" "ishift")
9877    (set (attr "length_immediate")
9878      (if_then_else
9879        (and (match_operand 2 "const1_operand" "")
9880             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9881                 (const_int 0)))
9882        (const_string "0")
9883        (const_string "*")))
9884    (set_attr "mode" "<MODE>")])
9885
9886 (define_insn "*<shiftrt_insn>si3_cmp_zext"
9887   [(set (reg FLAGS_REG)
9888         (compare
9889           (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9890                           (match_operand:QI 2 "const_1_to_31_operand" "I"))
9891           (const_int 0)))
9892    (set (match_operand:DI 0 "register_operand" "=r")
9893         (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9894   "TARGET_64BIT
9895    && (optimize_function_for_size_p (cfun)
9896        || !TARGET_PARTIAL_FLAG_REG_STALL
9897        || (operands[2] == const1_rtx
9898            && TARGET_SHIFT1))
9899    && ix86_match_ccmode (insn, CCGOCmode)
9900    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9901 {
9902   if (operands[2] == const1_rtx
9903       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9904     return "<shiftrt>{l}\t%k0";
9905   else
9906     return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
9907 }
9908   [(set_attr "type" "ishift")
9909    (set (attr "length_immediate")
9910      (if_then_else
9911        (and (match_operand 2 "const1_operand" "")
9912             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9913                 (const_int 0)))
9914        (const_string "0")
9915        (const_string "*")))
9916    (set_attr "mode" "SI")])
9917
9918 (define_insn "*<shiftrt_insn><mode>3_cconly"
9919   [(set (reg FLAGS_REG)
9920         (compare
9921           (any_shiftrt:SWI
9922             (match_operand:SWI 1 "nonimmediate_operand" "0")
9923             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9924           (const_int 0)))
9925    (clobber (match_scratch:SWI 0 "=<r>"))]
9926   "(optimize_function_for_size_p (cfun)
9927     || !TARGET_PARTIAL_FLAG_REG_STALL
9928     || (operands[2] == const1_rtx
9929         && TARGET_SHIFT1))
9930    && ix86_match_ccmode (insn, CCGOCmode)
9931    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9932 {
9933   if (operands[2] == const1_rtx
9934       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9935     return "<shiftrt>{<imodesuffix>}\t%0";
9936   else
9937     return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9938 }
9939   [(set_attr "type" "ishift")
9940    (set (attr "length_immediate")
9941      (if_then_else
9942        (and (match_operand 2 "const1_operand" "")
9943             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9944                 (const_int 0)))
9945        (const_string "0")
9946        (const_string "*")))
9947    (set_attr "mode" "<MODE>")])
9948 \f
9949 ;; Rotate instructions
9950
9951 (define_expand "<rotate_insn>ti3"
9952   [(set (match_operand:TI 0 "register_operand" "")
9953         (any_rotate:TI (match_operand:TI 1 "register_operand" "")
9954                        (match_operand:QI 2 "nonmemory_operand" "")))]
9955   "TARGET_64BIT"
9956 {
9957   if (const_1_to_63_operand (operands[2], VOIDmode))
9958     emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
9959                 (operands[0], operands[1], operands[2]));
9960   else
9961     FAIL;
9962
9963   DONE;
9964 })
9965
9966 (define_expand "<rotate_insn>di3"
9967   [(set (match_operand:DI 0 "shiftdi_operand" "")
9968         (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
9969                        (match_operand:QI 2 "nonmemory_operand" "")))]
9970  ""
9971 {
9972   if (TARGET_64BIT)
9973     ix86_expand_binary_operator (<CODE>, DImode, operands);
9974   else if (const_1_to_31_operand (operands[2], VOIDmode))
9975     emit_insn (gen_ix86_<rotate_insn>di3_doubleword
9976                 (operands[0], operands[1], operands[2]));
9977   else
9978     FAIL;
9979
9980   DONE;
9981 })
9982
9983 (define_expand "<rotate_insn><mode>3"
9984   [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
9985         (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
9986                             (match_operand:QI 2 "nonmemory_operand" "")))]
9987   ""
9988   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9989
9990 ;; Implement rotation using two double-precision
9991 ;; shift instructions and a scratch register.
9992
9993 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
9994  [(set (match_operand:<DWI> 0 "register_operand" "=r")
9995        (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
9996                      (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
9997   (clobber (reg:CC FLAGS_REG))
9998   (clobber (match_scratch:DWIH 3 "=&r"))]
9999  ""
10000  "#"
10001  "reload_completed"
10002  [(set (match_dup 3) (match_dup 4))
10003   (parallel
10004    [(set (match_dup 4)
10005          (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10006                    (lshiftrt:DWIH (match_dup 5)
10007                                   (minus:QI (match_dup 6) (match_dup 2)))))
10008     (clobber (reg:CC FLAGS_REG))])
10009   (parallel
10010    [(set (match_dup 5)
10011          (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10012                    (lshiftrt:DWIH (match_dup 3)
10013                                   (minus:QI (match_dup 6) (match_dup 2)))))
10014     (clobber (reg:CC FLAGS_REG))])]
10015 {
10016   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10017
10018   split_<dwi> (&operands[0], 1, &operands[4], &operands[5]);
10019 })
10020
10021 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10022  [(set (match_operand:<DWI> 0 "register_operand" "=r")
10023        (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10024                        (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10025   (clobber (reg:CC FLAGS_REG))
10026   (clobber (match_scratch:DWIH 3 "=&r"))]
10027  ""
10028  "#"
10029  "reload_completed"
10030  [(set (match_dup 3) (match_dup 4))
10031   (parallel
10032    [(set (match_dup 4)
10033          (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10034                    (ashift:DWIH (match_dup 5)
10035                                 (minus:QI (match_dup 6) (match_dup 2)))))
10036     (clobber (reg:CC FLAGS_REG))])
10037   (parallel
10038    [(set (match_dup 5)
10039          (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10040                    (ashift:DWIH (match_dup 3)
10041                                 (minus:QI (match_dup 6) (match_dup 2)))))
10042     (clobber (reg:CC FLAGS_REG))])]
10043 {
10044   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10045
10046   split_<dwi> (&operands[0], 1, &operands[4], &operands[5]);
10047 })
10048
10049 (define_insn "*<rotate_insn><mode>3_1"
10050   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10051         (any_rotate:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10052                         (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10053    (clobber (reg:CC FLAGS_REG))]
10054   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10055 {
10056   if (operands[2] == const1_rtx
10057       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10058     return "<rotate>{<imodesuffix>}\t%0";
10059   else
10060     return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10061 }
10062   [(set_attr "type" "rotate")
10063    (set (attr "length_immediate")
10064      (if_then_else
10065        (and (match_operand 2 "const1_operand" "")
10066             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10067                 (const_int 0)))
10068        (const_string "0")
10069        (const_string "*")))
10070    (set_attr "mode" "<MODE>")])
10071
10072 (define_insn "*<rotate_insn>si3_1_zext"
10073   [(set (match_operand:DI 0 "register_operand" "=r")
10074         (zero_extend:DI
10075           (any_rotate:SI (match_operand:SI 1 "register_operand" "0")
10076                          (match_operand:QI 2 "nonmemory_operand" "cI"))))
10077    (clobber (reg:CC FLAGS_REG))]
10078   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10079 {
10080     if (operands[2] == const1_rtx
10081         && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10082     return "<rotate>{l}\t%k0";
10083   else
10084     return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10085 }
10086   [(set_attr "type" "rotate")
10087    (set (attr "length_immediate")
10088      (if_then_else
10089        (and (match_operand 2 "const1_operand" "")
10090             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10091                 (const_int 0)))
10092        (const_string "0")
10093        (const_string "*")))
10094    (set_attr "mode" "SI")])
10095
10096 (define_insn "*<rotate_insn>qi3_1_slp"
10097   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10098         (any_rotate:QI (match_dup 0)
10099                        (match_operand:QI 1 "nonmemory_operand" "cI")))
10100    (clobber (reg:CC FLAGS_REG))]
10101   "(optimize_function_for_size_p (cfun)
10102     || !TARGET_PARTIAL_REG_STALL
10103     || (operands[1] == const1_rtx
10104         && TARGET_SHIFT1))"
10105 {
10106   if (operands[1] == const1_rtx
10107       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10108     return "<rotate>{b}\t%0";
10109   else
10110     return "<rotate>{b}\t{%1, %0|%0, %1}";
10111 }
10112   [(set_attr "type" "rotate1")
10113    (set (attr "length_immediate")
10114      (if_then_else
10115        (and (match_operand 1 "const1_operand" "")
10116             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10117                 (const_int 0)))
10118        (const_string "0")
10119        (const_string "*")))
10120    (set_attr "mode" "QI")])
10121
10122 (define_split
10123  [(set (match_operand:HI 0 "register_operand" "")
10124        (any_rotate:HI (match_dup 0) (const_int 8)))
10125   (clobber (reg:CC FLAGS_REG))]
10126  "reload_completed
10127   && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10128  [(parallel [(set (strict_low_part (match_dup 0))
10129                   (bswap:HI (match_dup 0)))
10130              (clobber (reg:CC FLAGS_REG))])])
10131 \f
10132 ;; Bit set / bit test instructions
10133
10134 (define_expand "extv"
10135   [(set (match_operand:SI 0 "register_operand" "")
10136         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10137                          (match_operand:SI 2 "const8_operand" "")
10138                          (match_operand:SI 3 "const8_operand" "")))]
10139   ""
10140 {
10141   /* Handle extractions from %ah et al.  */
10142   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10143     FAIL;
10144
10145   /* From mips.md: extract_bit_field doesn't verify that our source
10146      matches the predicate, so check it again here.  */
10147   if (! ext_register_operand (operands[1], VOIDmode))
10148     FAIL;
10149 })
10150
10151 (define_expand "extzv"
10152   [(set (match_operand:SI 0 "register_operand" "")
10153         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10154                          (match_operand:SI 2 "const8_operand" "")
10155                          (match_operand:SI 3 "const8_operand" "")))]
10156   ""
10157 {
10158   /* Handle extractions from %ah et al.  */
10159   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10160     FAIL;
10161
10162   /* From mips.md: extract_bit_field doesn't verify that our source
10163      matches the predicate, so check it again here.  */
10164   if (! ext_register_operand (operands[1], VOIDmode))
10165     FAIL;
10166 })
10167
10168 (define_expand "insv"
10169   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
10170                       (match_operand 1 "const8_operand" "")
10171                       (match_operand 2 "const8_operand" ""))
10172         (match_operand 3 "register_operand" ""))]
10173   ""
10174 {
10175   rtx (*gen_mov_insv_1) (rtx, rtx);
10176
10177   /* Handle insertions to %ah et al.  */
10178   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10179     FAIL;
10180
10181   /* From mips.md: insert_bit_field doesn't verify that our source
10182      matches the predicate, so check it again here.  */
10183   if (! ext_register_operand (operands[0], VOIDmode))
10184     FAIL;
10185
10186   gen_mov_insv_1 = (TARGET_64BIT
10187                     ? gen_movdi_insv_1 : gen_movsi_insv_1);
10188
10189   emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10190   DONE;
10191 })
10192
10193 ;; %%% bts, btr, btc, bt.
10194 ;; In general these instructions are *slow* when applied to memory,
10195 ;; since they enforce atomic operation.  When applied to registers,
10196 ;; it depends on the cpu implementation.  They're never faster than
10197 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10198 ;; no point.  But in 64-bit, we can't hold the relevant immediates
10199 ;; within the instruction itself, so operating on bits in the high
10200 ;; 32-bits of a register becomes easier.
10201 ;;
10202 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
10203 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10204 ;; negdf respectively, so they can never be disabled entirely.
10205
10206 (define_insn "*btsq"
10207   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10208                          (const_int 1)
10209                          (match_operand:DI 1 "const_0_to_63_operand" ""))
10210         (const_int 1))
10211    (clobber (reg:CC FLAGS_REG))]
10212   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10213   "bts{q}\t{%1, %0|%0, %1}"
10214   [(set_attr "type" "alu1")
10215    (set_attr "prefix_0f" "1")
10216    (set_attr "mode" "DI")])
10217
10218 (define_insn "*btrq"
10219   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10220                          (const_int 1)
10221                          (match_operand:DI 1 "const_0_to_63_operand" ""))
10222         (const_int 0))
10223    (clobber (reg:CC FLAGS_REG))]
10224   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10225   "btr{q}\t{%1, %0|%0, %1}"
10226   [(set_attr "type" "alu1")
10227    (set_attr "prefix_0f" "1")
10228    (set_attr "mode" "DI")])
10229
10230 (define_insn "*btcq"
10231   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10232                          (const_int 1)
10233                          (match_operand:DI 1 "const_0_to_63_operand" ""))
10234         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10235    (clobber (reg:CC FLAGS_REG))]
10236   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10237   "btc{q}\t{%1, %0|%0, %1}"
10238   [(set_attr "type" "alu1")
10239    (set_attr "prefix_0f" "1")
10240    (set_attr "mode" "DI")])
10241
10242 ;; Allow Nocona to avoid these instructions if a register is available.
10243
10244 (define_peephole2
10245   [(match_scratch:DI 2 "r")
10246    (parallel [(set (zero_extract:DI
10247                      (match_operand:DI 0 "register_operand" "")
10248                      (const_int 1)
10249                      (match_operand:DI 1 "const_0_to_63_operand" ""))
10250                    (const_int 1))
10251               (clobber (reg:CC FLAGS_REG))])]
10252   "TARGET_64BIT && !TARGET_USE_BT"
10253   [(const_int 0)]
10254 {
10255   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10256   rtx op1;
10257
10258   if (HOST_BITS_PER_WIDE_INT >= 64)
10259     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10260   else if (i < HOST_BITS_PER_WIDE_INT)
10261     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10262   else
10263     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10264
10265   op1 = immed_double_const (lo, hi, DImode);
10266   if (i >= 31)
10267     {
10268       emit_move_insn (operands[2], op1);
10269       op1 = operands[2];
10270     }
10271
10272   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10273   DONE;
10274 })
10275
10276 (define_peephole2
10277   [(match_scratch:DI 2 "r")
10278    (parallel [(set (zero_extract:DI
10279                      (match_operand:DI 0 "register_operand" "")
10280                      (const_int 1)
10281                      (match_operand:DI 1 "const_0_to_63_operand" ""))
10282                    (const_int 0))
10283               (clobber (reg:CC FLAGS_REG))])]
10284   "TARGET_64BIT && !TARGET_USE_BT"
10285   [(const_int 0)]
10286 {
10287   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10288   rtx op1;
10289
10290   if (HOST_BITS_PER_WIDE_INT >= 64)
10291     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10292   else if (i < HOST_BITS_PER_WIDE_INT)
10293     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10294   else
10295     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10296
10297   op1 = immed_double_const (~lo, ~hi, DImode);
10298   if (i >= 32)
10299     {
10300       emit_move_insn (operands[2], op1);
10301       op1 = operands[2];
10302     }
10303
10304   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10305   DONE;
10306 })
10307
10308 (define_peephole2
10309   [(match_scratch:DI 2 "r")
10310    (parallel [(set (zero_extract:DI
10311                      (match_operand:DI 0 "register_operand" "")
10312                      (const_int 1)
10313                      (match_operand:DI 1 "const_0_to_63_operand" ""))
10314               (not:DI (zero_extract:DI
10315                         (match_dup 0) (const_int 1) (match_dup 1))))
10316               (clobber (reg:CC FLAGS_REG))])]
10317   "TARGET_64BIT && !TARGET_USE_BT"
10318   [(const_int 0)]
10319 {
10320   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10321   rtx op1;
10322
10323   if (HOST_BITS_PER_WIDE_INT >= 64)
10324     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10325   else if (i < HOST_BITS_PER_WIDE_INT)
10326     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10327   else
10328     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10329
10330   op1 = immed_double_const (lo, hi, DImode);
10331   if (i >= 31)
10332     {
10333       emit_move_insn (operands[2], op1);
10334       op1 = operands[2];
10335     }
10336
10337   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10338   DONE;
10339 })
10340
10341 (define_insn "*bt<mode>"
10342   [(set (reg:CCC FLAGS_REG)
10343         (compare:CCC
10344           (zero_extract:SWI48
10345             (match_operand:SWI48 0 "register_operand" "r")
10346             (const_int 1)
10347             (match_operand:SWI48 1 "nonmemory_operand" "rN"))
10348           (const_int 0)))]
10349   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10350   "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10351   [(set_attr "type" "alu1")
10352    (set_attr "prefix_0f" "1")
10353    (set_attr "mode" "<MODE>")])
10354 \f
10355 ;; Store-flag instructions.
10356
10357 ;; For all sCOND expanders, also expand the compare or test insn that
10358 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
10359
10360 (define_insn_and_split "*setcc_di_1"
10361   [(set (match_operand:DI 0 "register_operand" "=q")
10362         (match_operator:DI 1 "ix86_comparison_operator"
10363           [(reg FLAGS_REG) (const_int 0)]))]
10364   "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10365   "#"
10366   "&& reload_completed"
10367   [(set (match_dup 2) (match_dup 1))
10368    (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10369 {
10370   PUT_MODE (operands[1], QImode);
10371   operands[2] = gen_lowpart (QImode, operands[0]);
10372 })
10373
10374 (define_insn_and_split "*setcc_si_1_and"
10375   [(set (match_operand:SI 0 "register_operand" "=q")
10376         (match_operator:SI 1 "ix86_comparison_operator"
10377           [(reg FLAGS_REG) (const_int 0)]))
10378    (clobber (reg:CC FLAGS_REG))]
10379   "!TARGET_PARTIAL_REG_STALL
10380    && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10381   "#"
10382   "&& reload_completed"
10383   [(set (match_dup 2) (match_dup 1))
10384    (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10385               (clobber (reg:CC FLAGS_REG))])]
10386 {
10387   PUT_MODE (operands[1], QImode);
10388   operands[2] = gen_lowpart (QImode, operands[0]);
10389 })
10390
10391 (define_insn_and_split "*setcc_si_1_movzbl"
10392   [(set (match_operand:SI 0 "register_operand" "=q")
10393         (match_operator:SI 1 "ix86_comparison_operator"
10394           [(reg FLAGS_REG) (const_int 0)]))]
10395   "!TARGET_PARTIAL_REG_STALL
10396    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10397   "#"
10398   "&& reload_completed"
10399   [(set (match_dup 2) (match_dup 1))
10400    (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10401 {
10402   PUT_MODE (operands[1], QImode);
10403   operands[2] = gen_lowpart (QImode, operands[0]);
10404 })
10405
10406 (define_insn "*setcc_qi"
10407   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10408         (match_operator:QI 1 "ix86_comparison_operator"
10409           [(reg FLAGS_REG) (const_int 0)]))]
10410   ""
10411   "set%C1\t%0"
10412   [(set_attr "type" "setcc")
10413    (set_attr "mode" "QI")])
10414
10415 (define_insn "*setcc_qi_slp"
10416   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10417         (match_operator:QI 1 "ix86_comparison_operator"
10418           [(reg FLAGS_REG) (const_int 0)]))]
10419   ""
10420   "set%C1\t%0"
10421   [(set_attr "type" "setcc")
10422    (set_attr "mode" "QI")])
10423
10424 ;; In general it is not safe to assume too much about CCmode registers,
10425 ;; so simplify-rtx stops when it sees a second one.  Under certain
10426 ;; conditions this is safe on x86, so help combine not create
10427 ;;
10428 ;;      seta    %al
10429 ;;      testb   %al, %al
10430 ;;      sete    %al
10431
10432 (define_split
10433   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10434         (ne:QI (match_operator 1 "ix86_comparison_operator"
10435                  [(reg FLAGS_REG) (const_int 0)])
10436             (const_int 0)))]
10437   ""
10438   [(set (match_dup 0) (match_dup 1))]
10439   "PUT_MODE (operands[1], QImode);")
10440
10441 (define_split
10442   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10443         (ne:QI (match_operator 1 "ix86_comparison_operator"
10444                  [(reg FLAGS_REG) (const_int 0)])
10445             (const_int 0)))]
10446   ""
10447   [(set (match_dup 0) (match_dup 1))]
10448   "PUT_MODE (operands[1], QImode);")
10449
10450 (define_split
10451   [(set (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 (define_split
10471   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10472         (eq:QI (match_operator 1 "ix86_comparison_operator"
10473                  [(reg FLAGS_REG) (const_int 0)])
10474             (const_int 0)))]
10475   ""
10476   [(set (match_dup 0) (match_dup 1))]
10477 {
10478   rtx new_op1 = copy_rtx (operands[1]);
10479   operands[1] = new_op1;
10480   PUT_MODE (new_op1, QImode);
10481   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10482                                              GET_MODE (XEXP (new_op1, 0))));
10483
10484   /* Make sure that (a) the CCmode we have for the flags is strong
10485      enough for the reversed compare or (b) we have a valid FP compare.  */
10486   if (! ix86_comparison_operator (new_op1, VOIDmode))
10487     FAIL;
10488 })
10489
10490 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10491 ;; subsequent logical operations are used to imitate conditional moves.
10492 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10493 ;; it directly.
10494
10495 (define_insn "*avx_setcc<mode>"
10496   [(set (match_operand:MODEF 0 "register_operand" "=x")
10497         (match_operator:MODEF 1 "avx_comparison_float_operator"
10498           [(match_operand:MODEF 2 "register_operand" "x")
10499            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
10500   "TARGET_AVX"
10501   "vcmp%D1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
10502   [(set_attr "type" "ssecmp")
10503    (set_attr "prefix" "vex")
10504    (set_attr "length_immediate" "1")
10505    (set_attr "mode" "<MODE>")])
10506
10507 (define_insn "*sse_setcc<mode>"
10508   [(set (match_operand:MODEF 0 "register_operand" "=x")
10509         (match_operator:MODEF 1 "sse_comparison_operator"
10510           [(match_operand:MODEF 2 "register_operand" "0")
10511            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
10512   "SSE_FLOAT_MODE_P (<MODE>mode)"
10513   "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
10514   [(set_attr "type" "ssecmp")
10515    (set_attr "length_immediate" "1")
10516    (set_attr "mode" "<MODE>")])
10517 \f
10518 ;; Basic conditional jump instructions.
10519 ;; We ignore the overflow flag for signed branch instructions.
10520
10521 (define_insn "*jcc_1"
10522   [(set (pc)
10523         (if_then_else (match_operator 1 "ix86_comparison_operator"
10524                                       [(reg FLAGS_REG) (const_int 0)])
10525                       (label_ref (match_operand 0 "" ""))
10526                       (pc)))]
10527   ""
10528   "%+j%C1\t%l0"
10529   [(set_attr "type" "ibr")
10530    (set_attr "modrm" "0")
10531    (set (attr "length")
10532            (if_then_else (and (ge (minus (match_dup 0) (pc))
10533                                   (const_int -126))
10534                               (lt (minus (match_dup 0) (pc))
10535                                   (const_int 128)))
10536              (const_int 2)
10537              (const_int 6)))])
10538
10539 (define_insn "*jcc_2"
10540   [(set (pc)
10541         (if_then_else (match_operator 1 "ix86_comparison_operator"
10542                                       [(reg FLAGS_REG) (const_int 0)])
10543                       (pc)
10544                       (label_ref (match_operand 0 "" ""))))]
10545   ""
10546   "%+j%c1\t%l0"
10547   [(set_attr "type" "ibr")
10548    (set_attr "modrm" "0")
10549    (set (attr "length")
10550            (if_then_else (and (ge (minus (match_dup 0) (pc))
10551                                   (const_int -126))
10552                               (lt (minus (match_dup 0) (pc))
10553                                   (const_int 128)))
10554              (const_int 2)
10555              (const_int 6)))])
10556
10557 ;; In general it is not safe to assume too much about CCmode registers,
10558 ;; so simplify-rtx stops when it sees a second one.  Under certain
10559 ;; conditions this is safe on x86, so help combine not create
10560 ;;
10561 ;;      seta    %al
10562 ;;      testb   %al, %al
10563 ;;      je      Lfoo
10564
10565 (define_split
10566   [(set (pc)
10567         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10568                                       [(reg FLAGS_REG) (const_int 0)])
10569                           (const_int 0))
10570                       (label_ref (match_operand 1 "" ""))
10571                       (pc)))]
10572   ""
10573   [(set (pc)
10574         (if_then_else (match_dup 0)
10575                       (label_ref (match_dup 1))
10576                       (pc)))]
10577   "PUT_MODE (operands[0], VOIDmode);")
10578
10579 (define_split
10580   [(set (pc)
10581         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10582                                       [(reg FLAGS_REG) (const_int 0)])
10583                           (const_int 0))
10584                       (label_ref (match_operand 1 "" ""))
10585                       (pc)))]
10586   ""
10587   [(set (pc)
10588         (if_then_else (match_dup 0)
10589                       (label_ref (match_dup 1))
10590                       (pc)))]
10591 {
10592   rtx new_op0 = copy_rtx (operands[0]);
10593   operands[0] = new_op0;
10594   PUT_MODE (new_op0, VOIDmode);
10595   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10596                                              GET_MODE (XEXP (new_op0, 0))));
10597
10598   /* Make sure that (a) the CCmode we have for the flags is strong
10599      enough for the reversed compare or (b) we have a valid FP compare.  */
10600   if (! ix86_comparison_operator (new_op0, VOIDmode))
10601     FAIL;
10602 })
10603
10604 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10605 ;; pass generates from shift insn with QImode operand.  Actually, the mode
10606 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10607 ;; appropriate modulo of the bit offset value.
10608
10609 (define_insn_and_split "*jcc_bt<mode>"
10610   [(set (pc)
10611         (if_then_else (match_operator 0 "bt_comparison_operator"
10612                         [(zero_extract:SWI48
10613                            (match_operand:SWI48 1 "register_operand" "r")
10614                            (const_int 1)
10615                            (zero_extend:SI
10616                              (match_operand:QI 2 "register_operand" "r")))
10617                          (const_int 0)])
10618                       (label_ref (match_operand 3 "" ""))
10619                       (pc)))
10620    (clobber (reg:CC FLAGS_REG))]
10621   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10622   "#"
10623   "&& 1"
10624   [(set (reg:CCC FLAGS_REG)
10625         (compare:CCC
10626           (zero_extract:SWI48
10627             (match_dup 1)
10628             (const_int 1)
10629             (match_dup 2))
10630           (const_int 0)))
10631    (set (pc)
10632         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10633                       (label_ref (match_dup 3))
10634                       (pc)))]
10635 {
10636   operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10637
10638   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10639 })
10640
10641 ;; Avoid useless masking of bit offset operand.  "and" in SImode is correct
10642 ;; also for DImode, this is what combine produces.
10643 (define_insn_and_split "*jcc_bt<mode>_mask"
10644   [(set (pc)
10645         (if_then_else (match_operator 0 "bt_comparison_operator"
10646                         [(zero_extract:SWI48
10647                            (match_operand:SWI48 1 "register_operand" "r")
10648                            (const_int 1)
10649                            (and:SI
10650                              (match_operand:SI 2 "register_operand" "r")
10651                              (match_operand:SI 3 "const_int_operand" "n")))])
10652                       (label_ref (match_operand 4 "" ""))
10653                       (pc)))
10654    (clobber (reg:CC FLAGS_REG))]
10655   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10656    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10657       == GET_MODE_BITSIZE (<MODE>mode)-1"
10658   "#"
10659   "&& 1"
10660   [(set (reg:CCC FLAGS_REG)
10661         (compare:CCC
10662           (zero_extract:SWI48
10663             (match_dup 1)
10664             (const_int 1)
10665             (match_dup 2))
10666           (const_int 0)))
10667    (set (pc)
10668         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10669                       (label_ref (match_dup 4))
10670                       (pc)))]
10671 {
10672   operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10673
10674   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10675 })
10676
10677 (define_insn_and_split "*jcc_btsi_1"
10678   [(set (pc)
10679         (if_then_else (match_operator 0 "bt_comparison_operator"
10680                         [(and:SI
10681                            (lshiftrt:SI
10682                              (match_operand:SI 1 "register_operand" "r")
10683                              (match_operand:QI 2 "register_operand" "r"))
10684                            (const_int 1))
10685                          (const_int 0)])
10686                       (label_ref (match_operand 3 "" ""))
10687                       (pc)))
10688    (clobber (reg:CC FLAGS_REG))]
10689   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10690   "#"
10691   "&& 1"
10692   [(set (reg:CCC FLAGS_REG)
10693         (compare:CCC
10694           (zero_extract:SI
10695             (match_dup 1)
10696             (const_int 1)
10697             (match_dup 2))
10698           (const_int 0)))
10699    (set (pc)
10700         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10701                       (label_ref (match_dup 3))
10702                       (pc)))]
10703 {
10704   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10705
10706   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10707 })
10708
10709 ;; avoid useless masking of bit offset operand
10710 (define_insn_and_split "*jcc_btsi_mask_1"
10711   [(set (pc)
10712         (if_then_else
10713           (match_operator 0 "bt_comparison_operator"
10714             [(and:SI
10715                (lshiftrt:SI
10716                  (match_operand:SI 1 "register_operand" "r")
10717                  (subreg:QI
10718                    (and:SI
10719                      (match_operand:SI 2 "register_operand" "r")
10720                      (match_operand:SI 3 "const_int_operand" "n")) 0))
10721                (const_int 1))
10722              (const_int 0)])
10723           (label_ref (match_operand 4 "" ""))
10724           (pc)))
10725    (clobber (reg:CC FLAGS_REG))]
10726   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10727    && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10728   "#"
10729   "&& 1"
10730   [(set (reg:CCC FLAGS_REG)
10731         (compare:CCC
10732           (zero_extract:SI
10733             (match_dup 1)
10734             (const_int 1)
10735             (match_dup 2))
10736           (const_int 0)))
10737    (set (pc)
10738         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10739                       (label_ref (match_dup 4))
10740                       (pc)))]
10741   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10742
10743 ;; Define combination compare-and-branch fp compare instructions to help
10744 ;; combine.
10745
10746 (define_insn "*fp_jcc_1_387"
10747   [(set (pc)
10748         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10749                         [(match_operand 1 "register_operand" "f")
10750                          (match_operand 2 "nonimmediate_operand" "fm")])
10751           (label_ref (match_operand 3 "" ""))
10752           (pc)))
10753    (clobber (reg:CCFP FPSR_REG))
10754    (clobber (reg:CCFP FLAGS_REG))
10755    (clobber (match_scratch:HI 4 "=a"))]
10756   "TARGET_80387
10757    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10758    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10759    && SELECT_CC_MODE (GET_CODE (operands[0]),
10760                       operands[1], operands[2]) == CCFPmode
10761    && !TARGET_CMOVE"
10762   "#")
10763
10764 (define_insn "*fp_jcc_1r_387"
10765   [(set (pc)
10766         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10767                         [(match_operand 1 "register_operand" "f")
10768                          (match_operand 2 "nonimmediate_operand" "fm")])
10769           (pc)
10770           (label_ref (match_operand 3 "" ""))))
10771    (clobber (reg:CCFP FPSR_REG))
10772    (clobber (reg:CCFP FLAGS_REG))
10773    (clobber (match_scratch:HI 4 "=a"))]
10774   "TARGET_80387
10775    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10776    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10777    && SELECT_CC_MODE (GET_CODE (operands[0]),
10778                       operands[1], operands[2]) == CCFPmode
10779    && !TARGET_CMOVE"
10780   "#")
10781
10782 (define_insn "*fp_jcc_2_387"
10783   [(set (pc)
10784         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10785                         [(match_operand 1 "register_operand" "f")
10786                          (match_operand 2 "register_operand" "f")])
10787           (label_ref (match_operand 3 "" ""))
10788           (pc)))
10789    (clobber (reg:CCFP FPSR_REG))
10790    (clobber (reg:CCFP FLAGS_REG))
10791    (clobber (match_scratch:HI 4 "=a"))]
10792   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10793    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10794    && !TARGET_CMOVE"
10795   "#")
10796
10797 (define_insn "*fp_jcc_2r_387"
10798   [(set (pc)
10799         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10800                         [(match_operand 1 "register_operand" "f")
10801                          (match_operand 2 "register_operand" "f")])
10802           (pc)
10803           (label_ref (match_operand 3 "" ""))))
10804    (clobber (reg:CCFP FPSR_REG))
10805    (clobber (reg:CCFP FLAGS_REG))
10806    (clobber (match_scratch:HI 4 "=a"))]
10807   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10808    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10809    && !TARGET_CMOVE"
10810   "#")
10811
10812 (define_insn "*fp_jcc_3_387"
10813   [(set (pc)
10814         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10815                         [(match_operand 1 "register_operand" "f")
10816                          (match_operand 2 "const0_operand" "")])
10817           (label_ref (match_operand 3 "" ""))
10818           (pc)))
10819    (clobber (reg:CCFP FPSR_REG))
10820    (clobber (reg:CCFP FLAGS_REG))
10821    (clobber (match_scratch:HI 4 "=a"))]
10822   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10823    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10824    && SELECT_CC_MODE (GET_CODE (operands[0]),
10825                       operands[1], operands[2]) == CCFPmode
10826    && !TARGET_CMOVE"
10827   "#")
10828
10829 (define_split
10830   [(set (pc)
10831         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10832                         [(match_operand 1 "register_operand" "")
10833                          (match_operand 2 "nonimmediate_operand" "")])
10834           (match_operand 3 "" "")
10835           (match_operand 4 "" "")))
10836    (clobber (reg:CCFP FPSR_REG))
10837    (clobber (reg:CCFP FLAGS_REG))]
10838   "reload_completed"
10839   [(const_int 0)]
10840 {
10841   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10842                         operands[3], operands[4], NULL_RTX, NULL_RTX);
10843   DONE;
10844 })
10845
10846 (define_split
10847   [(set (pc)
10848         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10849                         [(match_operand 1 "register_operand" "")
10850                          (match_operand 2 "general_operand" "")])
10851           (match_operand 3 "" "")
10852           (match_operand 4 "" "")))
10853    (clobber (reg:CCFP FPSR_REG))
10854    (clobber (reg:CCFP FLAGS_REG))
10855    (clobber (match_scratch:HI 5 "=a"))]
10856   "reload_completed"
10857   [(const_int 0)]
10858 {
10859   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10860                         operands[3], operands[4], operands[5], NULL_RTX);
10861   DONE;
10862 })
10863
10864 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
10865 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
10866 ;; with a precedence over other operators and is always put in the first
10867 ;; place. Swap condition and operands to match ficom instruction.
10868
10869 (define_insn "*fp_jcc_4_<mode>_387"
10870   [(set (pc)
10871         (if_then_else
10872           (match_operator 0 "ix86_swapped_fp_comparison_operator"
10873             [(match_operator 1 "float_operator"
10874               [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
10875              (match_operand 3 "register_operand" "f,f")])
10876           (label_ref (match_operand 4 "" ""))
10877           (pc)))
10878    (clobber (reg:CCFP FPSR_REG))
10879    (clobber (reg:CCFP FLAGS_REG))
10880    (clobber (match_scratch:HI 5 "=a,a"))]
10881   "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
10882    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
10883    && GET_MODE (operands[1]) == GET_MODE (operands[3])
10884    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
10885    && !TARGET_CMOVE"
10886   "#")
10887
10888 (define_split
10889   [(set (pc)
10890         (if_then_else
10891           (match_operator 0 "ix86_swapped_fp_comparison_operator"
10892             [(match_operator 1 "float_operator"
10893               [(match_operand:X87MODEI12 2 "memory_operand" "")])
10894              (match_operand 3 "register_operand" "")])
10895           (match_operand 4 "" "")
10896           (match_operand 5 "" "")))
10897    (clobber (reg:CCFP FPSR_REG))
10898    (clobber (reg:CCFP FLAGS_REG))
10899    (clobber (match_scratch:HI 6 "=a"))]
10900   "reload_completed"
10901   [(const_int 0)]
10902 {
10903   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
10904
10905   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
10906                         operands[3], operands[7],
10907                         operands[4], operands[5], operands[6], NULL_RTX);
10908   DONE;
10909 })
10910
10911 ;; %%% Kill this when reload knows how to do it.
10912 (define_split
10913   [(set (pc)
10914         (if_then_else
10915           (match_operator 0 "ix86_swapped_fp_comparison_operator"
10916             [(match_operator 1 "float_operator"
10917               [(match_operand:X87MODEI12 2 "register_operand" "")])
10918              (match_operand 3 "register_operand" "")])
10919           (match_operand 4 "" "")
10920           (match_operand 5 "" "")))
10921    (clobber (reg:CCFP FPSR_REG))
10922    (clobber (reg:CCFP FLAGS_REG))
10923    (clobber (match_scratch:HI 6 "=a"))]
10924   "reload_completed"
10925   [(const_int 0)]
10926 {
10927   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
10928   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
10929
10930   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
10931                         operands[3], operands[7],
10932                         operands[4], operands[5], operands[6], operands[2]);
10933   DONE;
10934 })
10935 \f
10936 ;; Unconditional and other jump instructions
10937
10938 (define_insn "jump"
10939   [(set (pc)
10940         (label_ref (match_operand 0 "" "")))]
10941   ""
10942   "jmp\t%l0"
10943   [(set_attr "type" "ibr")
10944    (set (attr "length")
10945            (if_then_else (and (ge (minus (match_dup 0) (pc))
10946                                   (const_int -126))
10947                               (lt (minus (match_dup 0) (pc))
10948                                   (const_int 128)))
10949              (const_int 2)
10950              (const_int 5)))
10951    (set_attr "modrm" "0")])
10952
10953 (define_expand "indirect_jump"
10954   [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
10955   ""
10956   "")
10957
10958 (define_insn "*indirect_jump"
10959   [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
10960   ""
10961   "jmp\t%A0"
10962   [(set_attr "type" "ibr")
10963    (set_attr "length_immediate" "0")])
10964
10965 (define_expand "tablejump"
10966   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
10967               (use (label_ref (match_operand 1 "" "")))])]
10968   ""
10969 {
10970   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
10971      relative.  Convert the relative address to an absolute address.  */
10972   if (flag_pic)
10973     {
10974       rtx op0, op1;
10975       enum rtx_code code;
10976
10977       /* We can't use @GOTOFF for text labels on VxWorks;
10978          see gotoff_operand.  */
10979       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
10980         {
10981           code = PLUS;
10982           op0 = operands[0];
10983           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
10984         }
10985       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
10986         {
10987           code = PLUS;
10988           op0 = operands[0];
10989           op1 = pic_offset_table_rtx;
10990         }
10991       else
10992         {
10993           code = MINUS;
10994           op0 = pic_offset_table_rtx;
10995           op1 = operands[0];
10996         }
10997
10998       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
10999                                          OPTAB_DIRECT);
11000     }
11001 })
11002
11003 (define_insn "*tablejump_1"
11004   [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
11005    (use (label_ref (match_operand 1 "" "")))]
11006   ""
11007   "jmp\t%A0"
11008   [(set_attr "type" "ibr")
11009    (set_attr "length_immediate" "0")])
11010 \f
11011 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11012
11013 (define_peephole2
11014   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11015    (set (match_operand:QI 1 "register_operand" "")
11016         (match_operator:QI 2 "ix86_comparison_operator"
11017           [(reg FLAGS_REG) (const_int 0)]))
11018    (set (match_operand 3 "q_regs_operand" "")
11019         (zero_extend (match_dup 1)))]
11020   "(peep2_reg_dead_p (3, operands[1])
11021     || operands_match_p (operands[1], operands[3]))
11022    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11023   [(set (match_dup 4) (match_dup 0))
11024    (set (strict_low_part (match_dup 5))
11025         (match_dup 2))]
11026 {
11027   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11028   operands[5] = gen_lowpart (QImode, operands[3]);
11029   ix86_expand_clear (operands[3]);
11030 })
11031
11032 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
11033
11034 (define_peephole2
11035   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11036    (set (match_operand:QI 1 "register_operand" "")
11037         (match_operator:QI 2 "ix86_comparison_operator"
11038           [(reg FLAGS_REG) (const_int 0)]))
11039    (parallel [(set (match_operand 3 "q_regs_operand" "")
11040                    (zero_extend (match_dup 1)))
11041               (clobber (reg:CC FLAGS_REG))])]
11042   "(peep2_reg_dead_p (3, operands[1])
11043     || operands_match_p (operands[1], operands[3]))
11044    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11045   [(set (match_dup 4) (match_dup 0))
11046    (set (strict_low_part (match_dup 5))
11047         (match_dup 2))]
11048 {
11049   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11050   operands[5] = gen_lowpart (QImode, operands[3]);
11051   ix86_expand_clear (operands[3]);
11052 })
11053 \f
11054 ;; Call instructions.
11055
11056 ;; The predicates normally associated with named expanders are not properly
11057 ;; checked for calls.  This is a bug in the generic code, but it isn't that
11058 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
11059
11060 ;; P6 processors will jump to the address after the decrement when %esp
11061 ;; is used as a call operand, so they will execute return address as a code.
11062 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11063  
11064 ;; Call subroutine returning no value.
11065
11066 (define_expand "call_pop"
11067   [(parallel [(call (match_operand:QI 0 "" "")
11068                     (match_operand:SI 1 "" ""))
11069               (set (reg:SI SP_REG)
11070                    (plus:SI (reg:SI SP_REG)
11071                             (match_operand:SI 3 "" "")))])]
11072   "!TARGET_64BIT"
11073 {
11074   ix86_expand_call (NULL, operands[0], operands[1],
11075                     operands[2], operands[3], 0);
11076   DONE;
11077 })
11078
11079 (define_insn "*call_pop_0"
11080   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
11081          (match_operand:SI 1 "" ""))
11082    (set (reg:SI SP_REG)
11083         (plus:SI (reg:SI SP_REG)
11084                  (match_operand:SI 2 "immediate_operand" "")))]
11085   "!TARGET_64BIT"
11086 {
11087   if (SIBLING_CALL_P (insn))
11088     return "jmp\t%P0";
11089   else
11090     return "call\t%P0";
11091 }
11092   [(set_attr "type" "call")])
11093
11094 (define_insn "*call_pop_1"
11095   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11096          (match_operand:SI 1 "" ""))
11097    (set (reg:SI SP_REG)
11098         (plus:SI (reg:SI SP_REG)
11099                  (match_operand:SI 2 "immediate_operand" "i")))]
11100   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11101 {
11102   if (constant_call_address_operand (operands[0], Pmode))
11103     return "call\t%P0";
11104   return "call\t%A0";
11105 }
11106   [(set_attr "type" "call")])
11107
11108 (define_insn "*sibcall_pop_1"
11109   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11110          (match_operand:SI 1 "" ""))
11111    (set (reg:SI SP_REG)
11112         (plus:SI (reg:SI SP_REG)
11113                  (match_operand:SI 2 "immediate_operand" "i,i")))]
11114   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11115   "@
11116    jmp\t%P0
11117    jmp\t%A0"
11118   [(set_attr "type" "call")])
11119
11120 (define_expand "call"
11121   [(call (match_operand:QI 0 "" "")
11122          (match_operand 1 "" ""))
11123    (use (match_operand 2 "" ""))]
11124   ""
11125 {
11126   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
11127   DONE;
11128 })
11129
11130 (define_expand "sibcall"
11131   [(call (match_operand:QI 0 "" "")
11132          (match_operand 1 "" ""))
11133    (use (match_operand 2 "" ""))]
11134   ""
11135 {
11136   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
11137   DONE;
11138 })
11139
11140 (define_insn "*call_0"
11141   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
11142          (match_operand 1 "" ""))]
11143   ""
11144 {
11145   if (SIBLING_CALL_P (insn))
11146     return "jmp\t%P0";
11147   else
11148     return "call\t%P0";
11149 }
11150   [(set_attr "type" "call")])
11151
11152 (define_insn "*call_1"
11153   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11154          (match_operand 1 "" ""))]
11155   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11156 {
11157   if (constant_call_address_operand (operands[0], Pmode))
11158     return "call\t%P0";
11159   return "call\t%A0";
11160 }
11161   [(set_attr "type" "call")])
11162
11163 (define_insn "*sibcall_1"
11164   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11165          (match_operand 1 "" ""))]
11166   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11167   "@
11168    jmp\t%P0
11169    jmp\t%A0"
11170   [(set_attr "type" "call")])
11171
11172 (define_insn "*call_1_rex64"
11173   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11174          (match_operand 1 "" ""))]
11175   "TARGET_64BIT && !SIBLING_CALL_P (insn)
11176    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
11177 {
11178   if (constant_call_address_operand (operands[0], Pmode))
11179     return "call\t%P0";
11180   return "call\t%A0";
11181 }
11182   [(set_attr "type" "call")])
11183
11184 (define_insn "*call_1_rex64_ms_sysv"
11185   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11186          (match_operand 1 "" ""))
11187    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11188    (clobber (reg:TI XMM6_REG))
11189    (clobber (reg:TI XMM7_REG))
11190    (clobber (reg:TI XMM8_REG))
11191    (clobber (reg:TI XMM9_REG))
11192    (clobber (reg:TI XMM10_REG))
11193    (clobber (reg:TI XMM11_REG))
11194    (clobber (reg:TI XMM12_REG))
11195    (clobber (reg:TI XMM13_REG))
11196    (clobber (reg:TI XMM14_REG))
11197    (clobber (reg:TI XMM15_REG))
11198    (clobber (reg:DI SI_REG))
11199    (clobber (reg:DI DI_REG))]
11200   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11201 {
11202   if (constant_call_address_operand (operands[0], Pmode))
11203     return "call\t%P0";
11204   return "call\t%A0";
11205 }
11206   [(set_attr "type" "call")])
11207
11208 (define_insn "*call_1_rex64_large"
11209   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
11210          (match_operand 1 "" ""))]
11211   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11212   "call\t%A0"
11213   [(set_attr "type" "call")])
11214
11215 (define_insn "*sibcall_1_rex64"
11216   [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
11217          (match_operand 1 "" ""))]
11218   "TARGET_64BIT && SIBLING_CALL_P (insn)"
11219   "@
11220    jmp\t%P0
11221    jmp\t%A0"
11222   [(set_attr "type" "call")])
11223
11224 ;; Call subroutine, returning value in operand 0
11225 (define_expand "call_value_pop"
11226   [(parallel [(set (match_operand 0 "" "")
11227                    (call (match_operand:QI 1 "" "")
11228                          (match_operand:SI 2 "" "")))
11229               (set (reg:SI SP_REG)
11230                    (plus:SI (reg:SI SP_REG)
11231                             (match_operand:SI 4 "" "")))])]
11232   "!TARGET_64BIT"
11233 {
11234   ix86_expand_call (operands[0], operands[1], operands[2],
11235                     operands[3], operands[4], 0);
11236   DONE;
11237 })
11238
11239 (define_expand "call_value"
11240   [(set (match_operand 0 "" "")
11241         (call (match_operand:QI 1 "" "")
11242               (match_operand:SI 2 "" "")))
11243    (use (match_operand:SI 3 "" ""))]
11244   ;; Operand 3 is not used on the i386.
11245   ""
11246 {
11247   ix86_expand_call (operands[0], operands[1], operands[2],
11248                     operands[3], NULL, 0);
11249   DONE;
11250 })
11251
11252 (define_expand "sibcall_value"
11253   [(set (match_operand 0 "" "")
11254         (call (match_operand:QI 1 "" "")
11255               (match_operand:SI 2 "" "")))
11256    (use (match_operand:SI 3 "" ""))]
11257   ;; Operand 3 is not used on the i386.
11258   ""
11259 {
11260   ix86_expand_call (operands[0], operands[1], operands[2],
11261                     operands[3], NULL, 1);
11262   DONE;
11263 })
11264
11265 ;; Call subroutine returning any type.
11266
11267 (define_expand "untyped_call"
11268   [(parallel [(call (match_operand 0 "" "")
11269                     (const_int 0))
11270               (match_operand 1 "" "")
11271               (match_operand 2 "" "")])]
11272   ""
11273 {
11274   int i;
11275
11276   /* In order to give reg-stack an easier job in validating two
11277      coprocessor registers as containing a possible return value,
11278      simply pretend the untyped call returns a complex long double
11279      value. 
11280
11281      We can't use SSE_REGPARM_MAX here since callee is unprototyped
11282      and should have the default ABI.  */
11283
11284   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11285                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11286                     operands[0], const0_rtx,
11287                     GEN_INT ((TARGET_64BIT
11288                               ? (ix86_abi == SYSV_ABI
11289                                  ? X86_64_SSE_REGPARM_MAX
11290                                  : X86_64_MS_SSE_REGPARM_MAX)
11291                               : X86_32_SSE_REGPARM_MAX)
11292                              - 1),
11293                     NULL, 0);
11294
11295   for (i = 0; i < XVECLEN (operands[2], 0); i++)
11296     {
11297       rtx set = XVECEXP (operands[2], 0, i);
11298       emit_move_insn (SET_DEST (set), SET_SRC (set));
11299     }
11300
11301   /* The optimizer does not know that the call sets the function value
11302      registers we stored in the result block.  We avoid problems by
11303      claiming that all hard registers are used and clobbered at this
11304      point.  */
11305   emit_insn (gen_blockage ());
11306
11307   DONE;
11308 })
11309 \f
11310 ;; Prologue and epilogue instructions
11311
11312 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11313 ;; all of memory.  This blocks insns from being moved across this point.
11314
11315 (define_insn "blockage"
11316   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11317   ""
11318   ""
11319   [(set_attr "length" "0")])
11320
11321 ;; Do not schedule instructions accessing memory across this point.
11322
11323 (define_expand "memory_blockage"
11324   [(set (match_dup 0)
11325         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11326   ""
11327 {
11328   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11329   MEM_VOLATILE_P (operands[0]) = 1;
11330 })
11331
11332 (define_insn "*memory_blockage"
11333   [(set (match_operand:BLK 0 "" "")
11334         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11335   ""
11336   ""
11337   [(set_attr "length" "0")])
11338
11339 ;; As USE insns aren't meaningful after reload, this is used instead
11340 ;; to prevent deleting instructions setting registers for PIC code
11341 (define_insn "prologue_use"
11342   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11343   ""
11344   ""
11345   [(set_attr "length" "0")])
11346
11347 ;; Insn emitted into the body of a function to return from a function.
11348 ;; This is only done if the function's epilogue is known to be simple.
11349 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11350
11351 (define_expand "return"
11352   [(return)]
11353   "ix86_can_use_return_insn_p ()"
11354 {
11355   if (crtl->args.pops_args)
11356     {
11357       rtx popc = GEN_INT (crtl->args.pops_args);
11358       emit_jump_insn (gen_return_pop_internal (popc));
11359       DONE;
11360     }
11361 })
11362
11363 (define_insn "return_internal"
11364   [(return)]
11365   "reload_completed"
11366   "ret"
11367   [(set_attr "length" "1")
11368    (set_attr "atom_unit" "jeu")
11369    (set_attr "length_immediate" "0")
11370    (set_attr "modrm" "0")])
11371
11372 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11373 ;; instruction Athlon and K8 have.
11374
11375 (define_insn "return_internal_long"
11376   [(return)
11377    (unspec [(const_int 0)] UNSPEC_REP)]
11378   "reload_completed"
11379   "rep\;ret"
11380   [(set_attr "length" "2")
11381    (set_attr "atom_unit" "jeu")
11382    (set_attr "length_immediate" "0")
11383    (set_attr "prefix_rep" "1")
11384    (set_attr "modrm" "0")])
11385
11386 (define_insn "return_pop_internal"
11387   [(return)
11388    (use (match_operand:SI 0 "const_int_operand" ""))]
11389   "reload_completed"
11390   "ret\t%0"
11391   [(set_attr "length" "3")
11392    (set_attr "atom_unit" "jeu")
11393    (set_attr "length_immediate" "2")
11394    (set_attr "modrm" "0")])
11395
11396 (define_insn "return_indirect_internal"
11397   [(return)
11398    (use (match_operand:SI 0 "register_operand" "r"))]
11399   "reload_completed"
11400   "jmp\t%A0"
11401   [(set_attr "type" "ibr")
11402    (set_attr "length_immediate" "0")])
11403
11404 (define_insn "nop"
11405   [(const_int 0)]
11406   ""
11407   "nop"
11408   [(set_attr "length" "1")
11409    (set_attr "length_immediate" "0")
11410    (set_attr "modrm" "0")])
11411
11412 ;; Pad to 16-byte boundary, max skip in op0.  Used to avoid
11413 ;; branch prediction penalty for the third jump in a 16-byte
11414 ;; block on K8.
11415
11416 (define_insn "pad"
11417   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
11418   ""
11419 {
11420 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11421   ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11422 #else
11423   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11424      The align insn is used to avoid 3 jump instructions in the row to improve
11425      branch prediction and the benefits hardly outweigh the cost of extra 8
11426      nops on the average inserted by full alignment pseudo operation.  */
11427 #endif
11428   return "";
11429 }
11430   [(set_attr "length" "16")])
11431
11432 (define_expand "prologue"
11433   [(const_int 0)]
11434   ""
11435   "ix86_expand_prologue (); DONE;")
11436
11437 (define_insn "set_got"
11438   [(set (match_operand:SI 0 "register_operand" "=r")
11439         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11440    (clobber (reg:CC FLAGS_REG))]
11441   "!TARGET_64BIT"
11442   { return output_set_got (operands[0], NULL_RTX); }
11443   [(set_attr "type" "multi")
11444    (set_attr "length" "12")])
11445
11446 (define_insn "set_got_labelled"
11447   [(set (match_operand:SI 0 "register_operand" "=r")
11448         (unspec:SI [(label_ref (match_operand 1 "" ""))]
11449          UNSPEC_SET_GOT))
11450    (clobber (reg:CC FLAGS_REG))]
11451   "!TARGET_64BIT"
11452   { return output_set_got (operands[0], operands[1]); }
11453   [(set_attr "type" "multi")
11454    (set_attr "length" "12")])
11455
11456 (define_insn "set_got_rex64"
11457   [(set (match_operand:DI 0 "register_operand" "=r")
11458         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11459   "TARGET_64BIT"
11460   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11461   [(set_attr "type" "lea")
11462    (set_attr "length_address" "4")
11463    (set_attr "mode" "DI")])
11464
11465 (define_insn "set_rip_rex64"
11466   [(set (match_operand:DI 0 "register_operand" "=r")
11467         (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
11468   "TARGET_64BIT"
11469   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11470   [(set_attr "type" "lea")
11471    (set_attr "length_address" "4")
11472    (set_attr "mode" "DI")])
11473
11474 (define_insn "set_got_offset_rex64"
11475   [(set (match_operand:DI 0 "register_operand" "=r")
11476         (unspec:DI
11477           [(label_ref (match_operand 1 "" ""))]
11478           UNSPEC_SET_GOT_OFFSET))]
11479   "TARGET_64BIT"
11480   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11481   [(set_attr "type" "imov")
11482    (set_attr "length_immediate" "0")
11483    (set_attr "length_address" "8")
11484    (set_attr "mode" "DI")])
11485
11486 (define_expand "epilogue"
11487   [(const_int 0)]
11488   ""
11489   "ix86_expand_epilogue (1); DONE;")
11490
11491 (define_expand "sibcall_epilogue"
11492   [(const_int 0)]
11493   ""
11494   "ix86_expand_epilogue (0); DONE;")
11495
11496 (define_expand "eh_return"
11497   [(use (match_operand 0 "register_operand" ""))]
11498   ""
11499 {
11500   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11501
11502   /* Tricky bit: we write the address of the handler to which we will
11503      be returning into someone else's stack frame, one word below the
11504      stack address we wish to restore.  */
11505   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11506   tmp = plus_constant (tmp, -UNITS_PER_WORD);
11507   tmp = gen_rtx_MEM (Pmode, tmp);
11508   emit_move_insn (tmp, ra);
11509
11510   emit_jump_insn (gen_eh_return_internal ());
11511   emit_barrier ();
11512   DONE;
11513 })
11514
11515 (define_insn_and_split "eh_return_internal"
11516   [(eh_return)]
11517   ""
11518   "#"
11519   "epilogue_completed"
11520   [(const_int 0)]
11521   "ix86_expand_epilogue (2); DONE;")
11522
11523 (define_insn "leave"
11524   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11525    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11526    (clobber (mem:BLK (scratch)))]
11527   "!TARGET_64BIT"
11528   "leave"
11529   [(set_attr "type" "leave")])
11530
11531 (define_insn "leave_rex64"
11532   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11533    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11534    (clobber (mem:BLK (scratch)))]
11535   "TARGET_64BIT"
11536   "leave"
11537   [(set_attr "type" "leave")])
11538 \f
11539 ;; Bit manipulation instructions.
11540
11541 (define_expand "ffs<mode>2"
11542   [(set (match_dup 2) (const_int -1))
11543    (parallel [(set (reg:CCZ FLAGS_REG)
11544                    (compare:CCZ
11545                      (match_operand:SWI48 1 "nonimmediate_operand" "")
11546                      (const_int 0)))
11547               (set (match_operand:SWI48 0 "register_operand" "")
11548                    (ctz:SWI48 (match_dup 1)))])
11549    (set (match_dup 0) (if_then_else:SWI48
11550                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
11551                         (match_dup 2)
11552                         (match_dup 0)))
11553    (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11554               (clobber (reg:CC FLAGS_REG))])]
11555   ""
11556 {
11557   if (<MODE>mode == SImode && !TARGET_CMOVE)
11558     {
11559       emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
11560       DONE;
11561     }
11562   operands[2] = gen_reg_rtx (<MODE>mode);
11563 })
11564
11565 (define_insn_and_split "ffssi2_no_cmove"
11566   [(set (match_operand:SI 0 "register_operand" "=r")
11567         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
11568    (clobber (match_scratch:SI 2 "=&q"))
11569    (clobber (reg:CC FLAGS_REG))]
11570   "!TARGET_CMOVE"
11571   "#"
11572   "&& reload_completed"
11573   [(parallel [(set (reg:CCZ FLAGS_REG)
11574                    (compare:CCZ (match_dup 1) (const_int 0)))
11575               (set (match_dup 0) (ctz:SI (match_dup 1)))])
11576    (set (strict_low_part (match_dup 3))
11577         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
11578    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
11579               (clobber (reg:CC FLAGS_REG))])
11580    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
11581               (clobber (reg:CC FLAGS_REG))])
11582    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
11583               (clobber (reg:CC FLAGS_REG))])]
11584 {
11585   operands[3] = gen_lowpart (QImode, operands[2]);
11586   ix86_expand_clear (operands[2]);
11587 })
11588
11589 (define_insn "*ffs<mode>_1"
11590   [(set (reg:CCZ FLAGS_REG)
11591         (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11592                      (const_int 0)))
11593    (set (match_operand:SWI48 0 "register_operand" "=r")
11594         (ctz:SWI48 (match_dup 1)))]
11595   ""
11596   "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
11597   [(set_attr "type" "alu1")
11598    (set_attr "prefix_0f" "1")
11599    (set_attr "mode" "<MODE>")])
11600
11601 (define_insn "ctz<mode>2"
11602   [(set (match_operand:SWI48 0 "register_operand" "=r")
11603         (ctz:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
11604    (clobber (reg:CC FLAGS_REG))]
11605   ""
11606   "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
11607   [(set_attr "type" "alu1")
11608    (set_attr "prefix_0f" "1")
11609    (set_attr "mode" "<MODE>")])
11610
11611 (define_expand "clz<mode>2"
11612   [(parallel
11613      [(set (match_operand:SWI248 0 "register_operand" "")
11614            (minus:SWI248
11615              (match_dup 2)
11616              (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
11617       (clobber (reg:CC FLAGS_REG))])
11618    (parallel
11619      [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
11620       (clobber (reg:CC FLAGS_REG))])]
11621   ""
11622 {
11623   if (TARGET_ABM)
11624     {
11625       emit_insn (gen_clz<mode>2_abm (operands[0], operands[1]));
11626       DONE;
11627     }
11628   operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
11629 })
11630
11631 (define_insn "clz<mode>2_abm"
11632   [(set (match_operand:SWI248 0 "register_operand" "=r")
11633         (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11634    (clobber (reg:CC FLAGS_REG))]
11635   "TARGET_ABM"
11636   "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
11637   [(set_attr "prefix_rep" "1")
11638    (set_attr "type" "bitmanip")
11639    (set_attr "mode" "<MODE>")])
11640
11641 (define_insn "bsr_rex64"
11642   [(set (match_operand:DI 0 "register_operand" "=r")
11643         (minus:DI (const_int 63)
11644                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
11645    (clobber (reg:CC FLAGS_REG))]
11646   "TARGET_64BIT"
11647   "bsr{q}\t{%1, %0|%0, %1}"
11648   [(set_attr "type" "alu1")
11649    (set_attr "prefix_0f" "1")
11650    (set_attr "mode" "DI")])
11651
11652 (define_insn "bsr"
11653   [(set (match_operand:SI 0 "register_operand" "=r")
11654         (minus:SI (const_int 31)
11655                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
11656    (clobber (reg:CC FLAGS_REG))]
11657   ""
11658   "bsr{l}\t{%1, %0|%0, %1}"
11659   [(set_attr "type" "alu1")
11660    (set_attr "prefix_0f" "1")
11661    (set_attr "mode" "SI")])
11662
11663 (define_insn "*bsrhi"
11664   [(set (match_operand:HI 0 "register_operand" "=r")
11665         (minus:HI (const_int 15)
11666                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
11667    (clobber (reg:CC FLAGS_REG))]
11668   ""
11669   "bsr{w}\t{%1, %0|%0, %1}"
11670   [(set_attr "type" "alu1")
11671    (set_attr "prefix_0f" "1")
11672    (set_attr "mode" "HI")])
11673
11674 (define_insn "popcount<mode>2"
11675   [(set (match_operand:SWI248 0 "register_operand" "=r")
11676         (popcount:SWI248
11677           (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11678    (clobber (reg:CC FLAGS_REG))]
11679   "TARGET_POPCNT"
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 "*popcount<mode>2_cmp"
11692   [(set (reg FLAGS_REG)
11693         (compare
11694           (popcount:SWI248
11695             (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
11696           (const_int 0)))
11697    (set (match_operand:SWI248 0 "register_operand" "=r")
11698         (popcount:SWI248 (match_dup 1)))]
11699   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
11700 {
11701 #if TARGET_MACHO
11702   return "popcnt\t{%1, %0|%0, %1}";
11703 #else
11704   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
11705 #endif
11706 }
11707   [(set_attr "prefix_rep" "1")
11708    (set_attr "type" "bitmanip")
11709    (set_attr "mode" "<MODE>")])
11710
11711 (define_insn "*popcountsi2_cmp_zext"
11712   [(set (reg FLAGS_REG)
11713         (compare
11714           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
11715           (const_int 0)))
11716    (set (match_operand:DI 0 "register_operand" "=r")
11717         (zero_extend:DI(popcount:SI (match_dup 1))))]
11718   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
11719 {
11720 #if TARGET_MACHO
11721   return "popcnt\t{%1, %0|%0, %1}";
11722 #else
11723   return "popcnt{l}\t{%1, %0|%0, %1}";
11724 #endif
11725 }
11726   [(set_attr "prefix_rep" "1")
11727    (set_attr "type" "bitmanip")
11728    (set_attr "mode" "SI")])
11729
11730 (define_expand "bswap<mode>2"
11731   [(set (match_operand:SWI48 0 "register_operand" "")
11732         (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
11733   ""
11734 {
11735   if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
11736     {
11737       rtx x = operands[0];
11738
11739       emit_move_insn (x, operands[1]);
11740       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
11741       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
11742       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
11743       DONE;
11744     }
11745 })
11746
11747 (define_insn "*bswap<mode>2_movbe"
11748   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
11749         (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
11750   "TARGET_MOVBE
11751    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
11752   "@
11753     bswap\t%0
11754     movbe\t{%1, %0|%0, %1}
11755     movbe\t{%1, %0|%0, %1}"
11756   [(set_attr "type" "bitmanip,imov,imov")
11757    (set_attr "modrm" "0,1,1")
11758    (set_attr "prefix_0f" "*,1,1")
11759    (set_attr "prefix_extra" "*,1,1")
11760    (set_attr "mode" "<MODE>")])
11761
11762 (define_insn "*bswap<mode>2_1"
11763   [(set (match_operand:SWI48 0 "register_operand" "=r")
11764         (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
11765   "TARGET_BSWAP"
11766   "bswap\t%0"
11767   [(set_attr "type" "bitmanip")
11768    (set_attr "modrm" "0")
11769    (set_attr "mode" "<MODE>")])
11770
11771 (define_insn "*bswaphi_lowpart_1"
11772   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
11773         (bswap:HI (match_dup 0)))
11774    (clobber (reg:CC FLAGS_REG))]
11775   "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
11776   "@
11777     xchg{b}\t{%h0, %b0|%b0, %h0}
11778     rol{w}\t{$8, %0|%0, 8}"
11779   [(set_attr "length" "2,4")
11780    (set_attr "mode" "QI,HI")])
11781
11782 (define_insn "bswaphi_lowpart"
11783   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
11784         (bswap:HI (match_dup 0)))
11785    (clobber (reg:CC FLAGS_REG))]
11786   ""
11787   "rol{w}\t{$8, %0|%0, 8}"
11788   [(set_attr "length" "4")
11789    (set_attr "mode" "HI")])
11790
11791 (define_expand "paritydi2"
11792   [(set (match_operand:DI 0 "register_operand" "")
11793         (parity:DI (match_operand:DI 1 "register_operand" "")))]
11794   "! TARGET_POPCNT"
11795 {
11796   rtx scratch = gen_reg_rtx (QImode);
11797   rtx cond;
11798
11799   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
11800                                 NULL_RTX, operands[1]));
11801
11802   cond = gen_rtx_fmt_ee (ORDERED, QImode,
11803                          gen_rtx_REG (CCmode, FLAGS_REG),
11804                          const0_rtx);
11805   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
11806
11807   if (TARGET_64BIT)
11808     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
11809   else
11810     {
11811       rtx tmp = gen_reg_rtx (SImode);
11812
11813       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
11814       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
11815     }
11816   DONE;
11817 })
11818
11819 (define_expand "paritysi2"
11820   [(set (match_operand:SI 0 "register_operand" "")
11821         (parity:SI (match_operand:SI 1 "register_operand" "")))]
11822   "! TARGET_POPCNT"
11823 {
11824   rtx scratch = gen_reg_rtx (QImode);
11825   rtx cond;
11826
11827   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
11828
11829   cond = gen_rtx_fmt_ee (ORDERED, QImode,
11830                          gen_rtx_REG (CCmode, FLAGS_REG),
11831                          const0_rtx);
11832   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
11833
11834   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
11835   DONE;
11836 })
11837
11838 (define_insn_and_split "paritydi2_cmp"
11839   [(set (reg:CC FLAGS_REG)
11840         (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
11841                    UNSPEC_PARITY))
11842    (clobber (match_scratch:DI 0 "=r"))
11843    (clobber (match_scratch:SI 1 "=&r"))
11844    (clobber (match_scratch:HI 2 "=Q"))]
11845   "! TARGET_POPCNT"
11846   "#"
11847   "&& reload_completed"
11848   [(parallel
11849      [(set (match_dup 1)
11850            (xor:SI (match_dup 1) (match_dup 4)))
11851       (clobber (reg:CC FLAGS_REG))])
11852    (parallel
11853      [(set (reg:CC FLAGS_REG)
11854            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
11855       (clobber (match_dup 1))
11856       (clobber (match_dup 2))])]
11857 {
11858   operands[4] = gen_lowpart (SImode, operands[3]);
11859
11860   if (TARGET_64BIT)
11861     {
11862       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
11863       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
11864     }
11865   else
11866     operands[1] = gen_highpart (SImode, operands[3]);
11867 })
11868
11869 (define_insn_and_split "paritysi2_cmp"
11870   [(set (reg:CC FLAGS_REG)
11871         (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
11872                    UNSPEC_PARITY))
11873    (clobber (match_scratch:SI 0 "=r"))
11874    (clobber (match_scratch:HI 1 "=&Q"))]
11875   "! TARGET_POPCNT"
11876   "#"
11877   "&& reload_completed"
11878   [(parallel
11879      [(set (match_dup 1)
11880            (xor:HI (match_dup 1) (match_dup 3)))
11881       (clobber (reg:CC FLAGS_REG))])
11882    (parallel
11883      [(set (reg:CC FLAGS_REG)
11884            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
11885       (clobber (match_dup 1))])]
11886 {
11887   operands[3] = gen_lowpart (HImode, operands[2]);
11888
11889   emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
11890   emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
11891 })
11892
11893 (define_insn "*parityhi2_cmp"
11894   [(set (reg:CC FLAGS_REG)
11895         (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
11896                    UNSPEC_PARITY))
11897    (clobber (match_scratch:HI 0 "=Q"))]
11898   "! TARGET_POPCNT"
11899   "xor{b}\t{%h0, %b0|%b0, %h0}"
11900   [(set_attr "length" "2")
11901    (set_attr "mode" "HI")])
11902 \f
11903 ;; Thread-local storage patterns for ELF.
11904 ;;
11905 ;; Note that these code sequences must appear exactly as shown
11906 ;; in order to allow linker relaxation.
11907
11908 (define_insn "*tls_global_dynamic_32_gnu"
11909   [(set (match_operand:SI 0 "register_operand" "=a")
11910         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
11911                     (match_operand:SI 2 "tls_symbolic_operand" "")
11912                     (match_operand:SI 3 "call_insn_operand" "")]
11913                     UNSPEC_TLS_GD))
11914    (clobber (match_scratch:SI 4 "=d"))
11915    (clobber (match_scratch:SI 5 "=c"))
11916    (clobber (reg:CC FLAGS_REG))]
11917   "!TARGET_64BIT && TARGET_GNU_TLS"
11918   "lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}\;call\t%P3"
11919   [(set_attr "type" "multi")
11920    (set_attr "length" "12")])
11921
11922 (define_expand "tls_global_dynamic_32"
11923   [(parallel [(set (match_operand:SI 0 "register_operand" "")
11924                    (unspec:SI
11925                     [(match_dup 2)
11926                      (match_operand:SI 1 "tls_symbolic_operand" "")
11927                      (match_dup 3)]
11928                     UNSPEC_TLS_GD))
11929               (clobber (match_scratch:SI 4 ""))
11930               (clobber (match_scratch:SI 5 ""))
11931               (clobber (reg:CC FLAGS_REG))])]
11932   ""
11933 {
11934   if (flag_pic)
11935     operands[2] = pic_offset_table_rtx;
11936   else
11937     {
11938       operands[2] = gen_reg_rtx (Pmode);
11939       emit_insn (gen_set_got (operands[2]));
11940     }
11941   if (TARGET_GNU2_TLS)
11942     {
11943        emit_insn (gen_tls_dynamic_gnu2_32
11944                   (operands[0], operands[1], operands[2]));
11945        DONE;
11946     }
11947   operands[3] = ix86_tls_get_addr ();
11948 })
11949
11950 (define_insn "*tls_global_dynamic_64"
11951   [(set (match_operand:DI 0 "register_operand" "=a")
11952         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
11953                  (match_operand:DI 3 "" "")))
11954    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
11955               UNSPEC_TLS_GD)]
11956   "TARGET_64BIT"
11957   { 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"; }
11958   [(set_attr "type" "multi")
11959    (set_attr "length" "16")])
11960
11961 (define_expand "tls_global_dynamic_64"
11962   [(parallel [(set (match_operand:DI 0 "register_operand" "")
11963                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
11964               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
11965                          UNSPEC_TLS_GD)])]
11966   ""
11967 {
11968   if (TARGET_GNU2_TLS)
11969     {
11970        emit_insn (gen_tls_dynamic_gnu2_64
11971                   (operands[0], operands[1]));
11972        DONE;
11973     }
11974   operands[2] = ix86_tls_get_addr ();
11975 })
11976
11977 (define_insn "*tls_local_dynamic_base_32_gnu"
11978   [(set (match_operand:SI 0 "register_operand" "=a")
11979         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
11980                     (match_operand:SI 2 "call_insn_operand" "")]
11981                    UNSPEC_TLS_LD_BASE))
11982    (clobber (match_scratch:SI 3 "=d"))
11983    (clobber (match_scratch:SI 4 "=c"))
11984    (clobber (reg:CC FLAGS_REG))]
11985   "!TARGET_64BIT && TARGET_GNU_TLS"
11986   "lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}\;call\t%P2"
11987   [(set_attr "type" "multi")
11988    (set_attr "length" "11")])
11989
11990 (define_expand "tls_local_dynamic_base_32"
11991   [(parallel [(set (match_operand:SI 0 "register_operand" "")
11992                    (unspec:SI [(match_dup 1) (match_dup 2)]
11993                               UNSPEC_TLS_LD_BASE))
11994               (clobber (match_scratch:SI 3 ""))
11995               (clobber (match_scratch:SI 4 ""))
11996               (clobber (reg:CC FLAGS_REG))])]
11997   ""
11998 {
11999   if (flag_pic)
12000     operands[1] = pic_offset_table_rtx;
12001   else
12002     {
12003       operands[1] = gen_reg_rtx (Pmode);
12004       emit_insn (gen_set_got (operands[1]));
12005     }
12006   if (TARGET_GNU2_TLS)
12007     {
12008        emit_insn (gen_tls_dynamic_gnu2_32
12009                   (operands[0], ix86_tls_module_base (), operands[1]));
12010        DONE;
12011     }
12012   operands[2] = ix86_tls_get_addr ();
12013 })
12014
12015 (define_insn "*tls_local_dynamic_base_64"
12016   [(set (match_operand:DI 0 "register_operand" "=a")
12017         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
12018                  (match_operand:DI 2 "" "")))
12019    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12020   "TARGET_64BIT"
12021   "lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}\;call\t%P1"
12022   [(set_attr "type" "multi")
12023    (set_attr "length" "12")])
12024
12025 (define_expand "tls_local_dynamic_base_64"
12026   [(parallel [(set (match_operand:DI 0 "register_operand" "")
12027                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
12028               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
12029   ""
12030 {
12031   if (TARGET_GNU2_TLS)
12032     {
12033        emit_insn (gen_tls_dynamic_gnu2_64
12034                   (operands[0], ix86_tls_module_base ()));
12035        DONE;
12036     }
12037   operands[1] = ix86_tls_get_addr ();
12038 })
12039
12040 ;; Local dynamic of a single variable is a lose.  Show combine how
12041 ;; to convert that back to global dynamic.
12042
12043 (define_insn_and_split "*tls_local_dynamic_32_once"
12044   [(set (match_operand:SI 0 "register_operand" "=a")
12045         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12046                              (match_operand:SI 2 "call_insn_operand" "")]
12047                             UNSPEC_TLS_LD_BASE)
12048                  (const:SI (unspec:SI
12049                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
12050                             UNSPEC_DTPOFF))))
12051    (clobber (match_scratch:SI 4 "=d"))
12052    (clobber (match_scratch:SI 5 "=c"))
12053    (clobber (reg:CC FLAGS_REG))]
12054   ""
12055   "#"
12056   ""
12057   [(parallel [(set (match_dup 0)
12058                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12059                               UNSPEC_TLS_GD))
12060               (clobber (match_dup 4))
12061               (clobber (match_dup 5))
12062               (clobber (reg:CC FLAGS_REG))])]
12063   "")
12064
12065 ;; Load and add the thread base pointer from %gs:0.
12066
12067 (define_insn "*load_tp_si"
12068   [(set (match_operand:SI 0 "register_operand" "=r")
12069         (unspec:SI [(const_int 0)] UNSPEC_TP))]
12070   "!TARGET_64BIT"
12071   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
12072   [(set_attr "type" "imov")
12073    (set_attr "modrm" "0")
12074    (set_attr "length" "7")
12075    (set_attr "memory" "load")
12076    (set_attr "imm_disp" "false")])
12077
12078 (define_insn "*add_tp_si"
12079   [(set (match_operand:SI 0 "register_operand" "=r")
12080         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12081                  (match_operand:SI 1 "register_operand" "0")))
12082    (clobber (reg:CC FLAGS_REG))]
12083   "!TARGET_64BIT"
12084   "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
12085   [(set_attr "type" "alu")
12086    (set_attr "modrm" "0")
12087    (set_attr "length" "7")
12088    (set_attr "memory" "load")
12089    (set_attr "imm_disp" "false")])
12090
12091 (define_insn "*load_tp_di"
12092   [(set (match_operand:DI 0 "register_operand" "=r")
12093         (unspec:DI [(const_int 0)] UNSPEC_TP))]
12094   "TARGET_64BIT"
12095   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
12096   [(set_attr "type" "imov")
12097    (set_attr "modrm" "0")
12098    (set_attr "length" "7")
12099    (set_attr "memory" "load")
12100    (set_attr "imm_disp" "false")])
12101
12102 (define_insn "*add_tp_di"
12103   [(set (match_operand:DI 0 "register_operand" "=r")
12104         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
12105                  (match_operand:DI 1 "register_operand" "0")))
12106    (clobber (reg:CC FLAGS_REG))]
12107   "TARGET_64BIT"
12108   "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
12109   [(set_attr "type" "alu")
12110    (set_attr "modrm" "0")
12111    (set_attr "length" "7")
12112    (set_attr "memory" "load")
12113    (set_attr "imm_disp" "false")])
12114
12115 ;; GNU2 TLS patterns can be split.
12116
12117 (define_expand "tls_dynamic_gnu2_32"
12118   [(set (match_dup 3)
12119         (plus:SI (match_operand:SI 2 "register_operand" "")
12120                  (const:SI
12121                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12122                              UNSPEC_TLSDESC))))
12123    (parallel
12124     [(set (match_operand:SI 0 "register_operand" "")
12125           (unspec:SI [(match_dup 1) (match_dup 3)
12126                       (match_dup 2) (reg:SI SP_REG)]
12127                       UNSPEC_TLSDESC))
12128      (clobber (reg:CC FLAGS_REG))])]
12129   "!TARGET_64BIT && TARGET_GNU2_TLS"
12130 {
12131   operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12132   ix86_tls_descriptor_calls_expanded_in_cfun = true;
12133 })
12134
12135 (define_insn "*tls_dynamic_lea_32"
12136   [(set (match_operand:SI 0 "register_operand" "=r")
12137         (plus:SI (match_operand:SI 1 "register_operand" "b")
12138                  (const:SI
12139                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12140                               UNSPEC_TLSDESC))))]
12141   "!TARGET_64BIT && TARGET_GNU2_TLS"
12142   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
12143   [(set_attr "type" "lea")
12144    (set_attr "mode" "SI")
12145    (set_attr "length" "6")
12146    (set_attr "length_address" "4")])
12147
12148 (define_insn "*tls_dynamic_call_32"
12149   [(set (match_operand:SI 0 "register_operand" "=a")
12150         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12151                     (match_operand:SI 2 "register_operand" "0")
12152                     ;; we have to make sure %ebx still points to the GOT
12153                     (match_operand:SI 3 "register_operand" "b")
12154                     (reg:SI SP_REG)]
12155                    UNSPEC_TLSDESC))
12156    (clobber (reg:CC FLAGS_REG))]
12157   "!TARGET_64BIT && TARGET_GNU2_TLS"
12158   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12159   [(set_attr "type" "call")
12160    (set_attr "length" "2")
12161    (set_attr "length_address" "0")])
12162
12163 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12164   [(set (match_operand:SI 0 "register_operand" "=&a")
12165         (plus:SI
12166          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12167                      (match_operand:SI 4 "" "")
12168                      (match_operand:SI 2 "register_operand" "b")
12169                      (reg:SI SP_REG)]
12170                     UNSPEC_TLSDESC)
12171          (const:SI (unspec:SI
12172                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
12173                     UNSPEC_DTPOFF))))
12174    (clobber (reg:CC FLAGS_REG))]
12175   "!TARGET_64BIT && TARGET_GNU2_TLS"
12176   "#"
12177   ""
12178   [(set (match_dup 0) (match_dup 5))]
12179 {
12180   operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12181   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12182 })
12183
12184 (define_expand "tls_dynamic_gnu2_64"
12185   [(set (match_dup 2)
12186         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12187                    UNSPEC_TLSDESC))
12188    (parallel
12189     [(set (match_operand:DI 0 "register_operand" "")
12190           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12191                      UNSPEC_TLSDESC))
12192      (clobber (reg:CC FLAGS_REG))])]
12193   "TARGET_64BIT && TARGET_GNU2_TLS"
12194 {
12195   operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12196   ix86_tls_descriptor_calls_expanded_in_cfun = true;
12197 })
12198
12199 (define_insn "*tls_dynamic_lea_64"
12200   [(set (match_operand:DI 0 "register_operand" "=r")
12201         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12202                    UNSPEC_TLSDESC))]
12203   "TARGET_64BIT && TARGET_GNU2_TLS"
12204   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
12205   [(set_attr "type" "lea")
12206    (set_attr "mode" "DI")
12207    (set_attr "length" "7")
12208    (set_attr "length_address" "4")])
12209
12210 (define_insn "*tls_dynamic_call_64"
12211   [(set (match_operand:DI 0 "register_operand" "=a")
12212         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
12213                     (match_operand:DI 2 "register_operand" "0")
12214                     (reg:DI SP_REG)]
12215                    UNSPEC_TLSDESC))
12216    (clobber (reg:CC FLAGS_REG))]
12217   "TARGET_64BIT && TARGET_GNU2_TLS"
12218   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12219   [(set_attr "type" "call")
12220    (set_attr "length" "2")
12221    (set_attr "length_address" "0")])
12222
12223 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12224   [(set (match_operand:DI 0 "register_operand" "=&a")
12225         (plus:DI
12226          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12227                      (match_operand:DI 3 "" "")
12228                      (reg:DI SP_REG)]
12229                     UNSPEC_TLSDESC)
12230          (const:DI (unspec:DI
12231                     [(match_operand:DI 1 "tls_symbolic_operand" "")]
12232                     UNSPEC_DTPOFF))))
12233    (clobber (reg:CC FLAGS_REG))]
12234   "TARGET_64BIT && TARGET_GNU2_TLS"
12235   "#"
12236   ""
12237   [(set (match_dup 0) (match_dup 4))]
12238 {
12239   operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12240   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12241 })
12242
12243 ;;
12244 \f
12245 ;; These patterns match the binary 387 instructions for addM3, subM3,
12246 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
12247 ;; SFmode.  The first is the normal insn, the second the same insn but
12248 ;; with one operand a conversion, and the third the same insn but with
12249 ;; the other operand a conversion.  The conversion may be SFmode or
12250 ;; SImode if the target mode DFmode, but only SImode if the target mode
12251 ;; is SFmode.
12252
12253 ;; Gcc is slightly more smart about handling normal two address instructions
12254 ;; so use special patterns for add and mull.
12255
12256 (define_insn "*fop_<mode>_comm_mixed_avx"
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,x")
12260            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
12261   "AVX_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 "prefix" "orig,maybe_vex")
12274    (set_attr "mode" "<MODE>")])
12275
12276 (define_insn "*fop_<mode>_comm_mixed"
12277   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
12278         (match_operator:MODEF 3 "binary_fp_operator"
12279           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
12280            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
12281   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12282    && COMMUTATIVE_ARITH_P (operands[3])
12283    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12284   "* return output_387_binary_op (insn, operands);"
12285   [(set (attr "type")
12286         (if_then_else (eq_attr "alternative" "1")
12287            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12288               (const_string "ssemul")
12289               (const_string "sseadd"))
12290            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12291               (const_string "fmul")
12292               (const_string "fop"))))
12293    (set_attr "mode" "<MODE>")])
12294
12295 (define_insn "*fop_<mode>_comm_avx"
12296   [(set (match_operand:MODEF 0 "register_operand" "=x")
12297         (match_operator:MODEF 3 "binary_fp_operator"
12298           [(match_operand:MODEF 1 "nonimmediate_operand" "%x")
12299            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12300   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12301    && COMMUTATIVE_ARITH_P (operands[3])
12302    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12303   "* return output_387_binary_op (insn, operands);"
12304   [(set (attr "type")
12305         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12306            (const_string "ssemul")
12307            (const_string "sseadd")))
12308    (set_attr "prefix" "vex")
12309    (set_attr "mode" "<MODE>")])
12310
12311 (define_insn "*fop_<mode>_comm_sse"
12312   [(set (match_operand:MODEF 0 "register_operand" "=x")
12313         (match_operator:MODEF 3 "binary_fp_operator"
12314           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12315            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12316   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12317    && COMMUTATIVE_ARITH_P (operands[3])
12318    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12319   "* return output_387_binary_op (insn, operands);"
12320   [(set (attr "type")
12321         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12322            (const_string "ssemul")
12323            (const_string "sseadd")))
12324    (set_attr "mode" "<MODE>")])
12325
12326 (define_insn "*fop_<mode>_comm_i387"
12327   [(set (match_operand:MODEF 0 "register_operand" "=f")
12328         (match_operator:MODEF 3 "binary_fp_operator"
12329           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12330            (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
12331   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12332    && COMMUTATIVE_ARITH_P (operands[3])
12333    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12334   "* return output_387_binary_op (insn, operands);"
12335   [(set (attr "type")
12336         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12337            (const_string "fmul")
12338            (const_string "fop")))
12339    (set_attr "mode" "<MODE>")])
12340
12341 (define_insn "*fop_<mode>_1_mixed_avx"
12342   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
12343         (match_operator:MODEF 3 "binary_fp_operator"
12344           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,x")
12345            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
12346   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12347    && !COMMUTATIVE_ARITH_P (operands[3])
12348    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12349   "* return output_387_binary_op (insn, operands);"
12350   [(set (attr "type")
12351         (cond [(and (eq_attr "alternative" "2")
12352                     (match_operand:MODEF 3 "mult_operator" ""))
12353                  (const_string "ssemul")
12354                (and (eq_attr "alternative" "2")
12355                     (match_operand:MODEF 3 "div_operator" ""))
12356                  (const_string "ssediv")
12357                (eq_attr "alternative" "2")
12358                  (const_string "sseadd")
12359                (match_operand:MODEF 3 "mult_operator" "")
12360                  (const_string "fmul")
12361                (match_operand:MODEF 3 "div_operator" "")
12362                  (const_string "fdiv")
12363               ]
12364               (const_string "fop")))
12365    (set_attr "prefix" "orig,orig,maybe_vex")
12366    (set_attr "mode" "<MODE>")])
12367
12368 (define_insn "*fop_<mode>_1_mixed"
12369   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
12370         (match_operator:MODEF 3 "binary_fp_operator"
12371           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
12372            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
12373   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12374    && !COMMUTATIVE_ARITH_P (operands[3])
12375    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12376   "* return output_387_binary_op (insn, operands);"
12377   [(set (attr "type")
12378         (cond [(and (eq_attr "alternative" "2")
12379                     (match_operand:MODEF 3 "mult_operator" ""))
12380                  (const_string "ssemul")
12381                (and (eq_attr "alternative" "2")
12382                     (match_operand:MODEF 3 "div_operator" ""))
12383                  (const_string "ssediv")
12384                (eq_attr "alternative" "2")
12385                  (const_string "sseadd")
12386                (match_operand:MODEF 3 "mult_operator" "")
12387                  (const_string "fmul")
12388                (match_operand:MODEF 3 "div_operator" "")
12389                  (const_string "fdiv")
12390               ]
12391               (const_string "fop")))
12392    (set_attr "mode" "<MODE>")])
12393
12394 (define_insn "*rcpsf2_sse"
12395   [(set (match_operand:SF 0 "register_operand" "=x")
12396         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
12397                    UNSPEC_RCP))]
12398   "TARGET_SSE_MATH"
12399   "%vrcpss\t{%1, %d0|%d0, %1}"
12400   [(set_attr "type" "sse")
12401    (set_attr "atom_sse_attr" "rcp")
12402    (set_attr "prefix" "maybe_vex")
12403    (set_attr "mode" "SF")])
12404
12405 (define_insn "*fop_<mode>_1_avx"
12406   [(set (match_operand:MODEF 0 "register_operand" "=x")
12407         (match_operator:MODEF 3 "binary_fp_operator"
12408           [(match_operand:MODEF 1 "register_operand" "x")
12409            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12410   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12411    && !COMMUTATIVE_ARITH_P (operands[3])"
12412   "* return output_387_binary_op (insn, operands);"
12413   [(set (attr "type")
12414         (cond [(match_operand:MODEF 3 "mult_operator" "")
12415                  (const_string "ssemul")
12416                (match_operand:MODEF 3 "div_operator" "")
12417                  (const_string "ssediv")
12418               ]
12419               (const_string "sseadd")))
12420    (set_attr "prefix" "vex")
12421    (set_attr "mode" "<MODE>")])
12422
12423 (define_insn "*fop_<mode>_1_sse"
12424   [(set (match_operand:MODEF 0 "register_operand" "=x")
12425         (match_operator:MODEF 3 "binary_fp_operator"
12426           [(match_operand:MODEF 1 "register_operand" "0")
12427            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12428   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12429    && !COMMUTATIVE_ARITH_P (operands[3])"
12430   "* return output_387_binary_op (insn, operands);"
12431   [(set (attr "type")
12432         (cond [(match_operand:MODEF 3 "mult_operator" "")
12433                  (const_string "ssemul")
12434                (match_operand:MODEF 3 "div_operator" "")
12435                  (const_string "ssediv")
12436               ]
12437               (const_string "sseadd")))
12438    (set_attr "mode" "<MODE>")])
12439
12440 ;; This pattern is not fully shadowed by the pattern above.
12441 (define_insn "*fop_<mode>_1_i387"
12442   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12443         (match_operator:MODEF 3 "binary_fp_operator"
12444           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
12445            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
12446   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12447    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
12448    && !COMMUTATIVE_ARITH_P (operands[3])
12449    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12450   "* return 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 "mode" "<MODE>")])
12459
12460 ;; ??? Add SSE splitters for these!
12461 (define_insn "*fop_<MODEF:mode>_2_i387"
12462   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12463         (match_operator:MODEF 3 "binary_fp_operator"
12464           [(float:MODEF
12465              (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
12466            (match_operand:MODEF 2 "register_operand" "0,0")]))]
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" "<X87MODEI12:MODE>")])
12480
12481 (define_insn "*fop_<MODEF:mode>_3_i387"
12482   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12483         (match_operator:MODEF 3 "binary_fp_operator"
12484           [(match_operand:MODEF 1 "register_operand" "0,0")
12485            (float:MODEF
12486              (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
12487   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
12488    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12489    && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12490   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12491   [(set (attr "type")
12492         (cond [(match_operand:MODEF 3 "mult_operator" "")
12493                  (const_string "fmul")
12494                (match_operand:MODEF 3 "div_operator" "")
12495                  (const_string "fdiv")
12496               ]
12497               (const_string "fop")))
12498    (set_attr "fp_int_src" "true")
12499    (set_attr "mode" "<MODE>")])
12500
12501 (define_insn "*fop_df_4_i387"
12502   [(set (match_operand:DF 0 "register_operand" "=f,f")
12503         (match_operator:DF 3 "binary_fp_operator"
12504            [(float_extend:DF
12505              (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
12506             (match_operand:DF 2 "register_operand" "0,f")]))]
12507   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12508    && !(TARGET_SSE2 && TARGET_SSE_MATH)
12509    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12510   "* return output_387_binary_op (insn, operands);"
12511   [(set (attr "type")
12512         (cond [(match_operand:DF 3 "mult_operator" "")
12513                  (const_string "fmul")
12514                (match_operand:DF 3 "div_operator" "")
12515                  (const_string "fdiv")
12516               ]
12517               (const_string "fop")))
12518    (set_attr "mode" "SF")])
12519
12520 (define_insn "*fop_df_5_i387"
12521   [(set (match_operand:DF 0 "register_operand" "=f,f")
12522         (match_operator:DF 3 "binary_fp_operator"
12523           [(match_operand:DF 1 "register_operand" "0,f")
12524            (float_extend:DF
12525             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12526   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12527    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12528   "* return output_387_binary_op (insn, operands);"
12529   [(set (attr "type")
12530         (cond [(match_operand:DF 3 "mult_operator" "")
12531                  (const_string "fmul")
12532                (match_operand:DF 3 "div_operator" "")
12533                  (const_string "fdiv")
12534               ]
12535               (const_string "fop")))
12536    (set_attr "mode" "SF")])
12537
12538 (define_insn "*fop_df_6_i387"
12539   [(set (match_operand:DF 0 "register_operand" "=f,f")
12540         (match_operator:DF 3 "binary_fp_operator"
12541           [(float_extend:DF
12542             (match_operand:SF 1 "register_operand" "0,f"))
12543            (float_extend:DF
12544             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12545   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12546    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12547   "* return output_387_binary_op (insn, operands);"
12548   [(set (attr "type")
12549         (cond [(match_operand:DF 3 "mult_operator" "")
12550                  (const_string "fmul")
12551                (match_operand:DF 3 "div_operator" "")
12552                  (const_string "fdiv")
12553               ]
12554               (const_string "fop")))
12555    (set_attr "mode" "SF")])
12556
12557 (define_insn "*fop_xf_comm_i387"
12558   [(set (match_operand:XF 0 "register_operand" "=f")
12559         (match_operator:XF 3 "binary_fp_operator"
12560                         [(match_operand:XF 1 "register_operand" "%0")
12561                          (match_operand:XF 2 "register_operand" "f")]))]
12562   "TARGET_80387
12563    && COMMUTATIVE_ARITH_P (operands[3])"
12564   "* return output_387_binary_op (insn, operands);"
12565   [(set (attr "type")
12566         (if_then_else (match_operand:XF 3 "mult_operator" "")
12567            (const_string "fmul")
12568            (const_string "fop")))
12569    (set_attr "mode" "XF")])
12570
12571 (define_insn "*fop_xf_1_i387"
12572   [(set (match_operand:XF 0 "register_operand" "=f,f")
12573         (match_operator:XF 3 "binary_fp_operator"
12574                         [(match_operand:XF 1 "register_operand" "0,f")
12575                          (match_operand:XF 2 "register_operand" "f,0")]))]
12576   "TARGET_80387
12577    && !COMMUTATIVE_ARITH_P (operands[3])"
12578   "* return output_387_binary_op (insn, operands);"
12579   [(set (attr "type")
12580         (cond [(match_operand:XF 3 "mult_operator" "")
12581                  (const_string "fmul")
12582                (match_operand:XF 3 "div_operator" "")
12583                  (const_string "fdiv")
12584               ]
12585               (const_string "fop")))
12586    (set_attr "mode" "XF")])
12587
12588 (define_insn "*fop_xf_2_i387"
12589   [(set (match_operand:XF 0 "register_operand" "=f,f")
12590         (match_operator:XF 3 "binary_fp_operator"
12591           [(float:XF
12592              (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
12593            (match_operand:XF 2 "register_operand" "0,0")]))]
12594   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12595   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12596   [(set (attr "type")
12597         (cond [(match_operand:XF 3 "mult_operator" "")
12598                  (const_string "fmul")
12599                (match_operand:XF 3 "div_operator" "")
12600                  (const_string "fdiv")
12601               ]
12602               (const_string "fop")))
12603    (set_attr "fp_int_src" "true")
12604    (set_attr "mode" "<MODE>")])
12605
12606 (define_insn "*fop_xf_3_i387"
12607   [(set (match_operand:XF 0 "register_operand" "=f,f")
12608         (match_operator:XF 3 "binary_fp_operator"
12609           [(match_operand:XF 1 "register_operand" "0,0")
12610            (float:XF
12611              (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
12612   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12613   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12614   [(set (attr "type")
12615         (cond [(match_operand:XF 3 "mult_operator" "")
12616                  (const_string "fmul")
12617                (match_operand:XF 3 "div_operator" "")
12618                  (const_string "fdiv")
12619               ]
12620               (const_string "fop")))
12621    (set_attr "fp_int_src" "true")
12622    (set_attr "mode" "<MODE>")])
12623
12624 (define_insn "*fop_xf_4_i387"
12625   [(set (match_operand:XF 0 "register_operand" "=f,f")
12626         (match_operator:XF 3 "binary_fp_operator"
12627            [(float_extend:XF
12628               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
12629             (match_operand:XF 2 "register_operand" "0,f")]))]
12630   "TARGET_80387"
12631   "* return output_387_binary_op (insn, operands);"
12632   [(set (attr "type")
12633         (cond [(match_operand:XF 3 "mult_operator" "")
12634                  (const_string "fmul")
12635                (match_operand:XF 3 "div_operator" "")
12636                  (const_string "fdiv")
12637               ]
12638               (const_string "fop")))
12639    (set_attr "mode" "<MODE>")])
12640
12641 (define_insn "*fop_xf_5_i387"
12642   [(set (match_operand:XF 0 "register_operand" "=f,f")
12643         (match_operator:XF 3 "binary_fp_operator"
12644           [(match_operand:XF 1 "register_operand" "0,f")
12645            (float_extend:XF
12646              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
12647   "TARGET_80387"
12648   "* return output_387_binary_op (insn, operands);"
12649   [(set (attr "type")
12650         (cond [(match_operand:XF 3 "mult_operator" "")
12651                  (const_string "fmul")
12652                (match_operand:XF 3 "div_operator" "")
12653                  (const_string "fdiv")
12654               ]
12655               (const_string "fop")))
12656    (set_attr "mode" "<MODE>")])
12657
12658 (define_insn "*fop_xf_6_i387"
12659   [(set (match_operand:XF 0 "register_operand" "=f,f")
12660         (match_operator:XF 3 "binary_fp_operator"
12661           [(float_extend:XF
12662              (match_operand:MODEF 1 "register_operand" "0,f"))
12663            (float_extend:XF
12664              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
12665   "TARGET_80387"
12666   "* return output_387_binary_op (insn, operands);"
12667   [(set (attr "type")
12668         (cond [(match_operand:XF 3 "mult_operator" "")
12669                  (const_string "fmul")
12670                (match_operand:XF 3 "div_operator" "")
12671                  (const_string "fdiv")
12672               ]
12673               (const_string "fop")))
12674    (set_attr "mode" "<MODE>")])
12675
12676 (define_split
12677   [(set (match_operand 0 "register_operand" "")
12678         (match_operator 3 "binary_fp_operator"
12679            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
12680             (match_operand 2 "register_operand" "")]))]
12681   "reload_completed
12682    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
12683    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
12684   [(const_int 0)]
12685 {
12686   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
12687   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
12688   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
12689                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
12690                                           GET_MODE (operands[3]),
12691                                           operands[4],
12692                                           operands[2])));
12693   ix86_free_from_memory (GET_MODE (operands[1]));
12694   DONE;
12695 })
12696
12697 (define_split
12698   [(set (match_operand 0 "register_operand" "")
12699         (match_operator 3 "binary_fp_operator"
12700            [(match_operand 1 "register_operand" "")
12701             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
12702   "reload_completed
12703    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
12704    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
12705   [(const_int 0)]
12706 {
12707   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
12708   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
12709   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
12710                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
12711                                           GET_MODE (operands[3]),
12712                                           operands[1],
12713                                           operands[4])));
12714   ix86_free_from_memory (GET_MODE (operands[2]));
12715   DONE;
12716 })
12717 \f
12718 ;; FPU special functions.
12719
12720 ;; This pattern implements a no-op XFmode truncation for
12721 ;; all fancy i386 XFmode math functions.
12722
12723 (define_insn "truncxf<mode>2_i387_noop_unspec"
12724   [(set (match_operand:MODEF 0 "register_operand" "=f")
12725         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
12726         UNSPEC_TRUNC_NOOP))]
12727   "TARGET_USE_FANCY_MATH_387"
12728   "* return output_387_reg_move (insn, operands);"
12729   [(set_attr "type" "fmov")
12730    (set_attr "mode" "<MODE>")])
12731
12732 (define_insn "sqrtxf2"
12733   [(set (match_operand:XF 0 "register_operand" "=f")
12734         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
12735   "TARGET_USE_FANCY_MATH_387"
12736   "fsqrt"
12737   [(set_attr "type" "fpspc")
12738    (set_attr "mode" "XF")
12739    (set_attr "athlon_decode" "direct")
12740    (set_attr "amdfam10_decode" "direct")])
12741
12742 (define_insn "sqrt_extend<mode>xf2_i387"
12743   [(set (match_operand:XF 0 "register_operand" "=f")
12744         (sqrt:XF
12745           (float_extend:XF
12746             (match_operand:MODEF 1 "register_operand" "0"))))]
12747   "TARGET_USE_FANCY_MATH_387"
12748   "fsqrt"
12749   [(set_attr "type" "fpspc")
12750    (set_attr "mode" "XF")
12751    (set_attr "athlon_decode" "direct")
12752    (set_attr "amdfam10_decode" "direct")])
12753
12754 (define_insn "*rsqrtsf2_sse"
12755   [(set (match_operand:SF 0 "register_operand" "=x")
12756         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
12757                    UNSPEC_RSQRT))]
12758   "TARGET_SSE_MATH"
12759   "%vrsqrtss\t{%1, %d0|%d0, %1}"
12760   [(set_attr "type" "sse")
12761    (set_attr "atom_sse_attr" "rcp")
12762    (set_attr "prefix" "maybe_vex")
12763    (set_attr "mode" "SF")])
12764
12765 (define_expand "rsqrtsf2"
12766   [(set (match_operand:SF 0 "register_operand" "")
12767         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
12768                    UNSPEC_RSQRT))]
12769   "TARGET_SSE_MATH"
12770 {
12771   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
12772   DONE;
12773 })
12774
12775 (define_insn "*sqrt<mode>2_sse"
12776   [(set (match_operand:MODEF 0 "register_operand" "=x")
12777         (sqrt:MODEF
12778           (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
12779   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
12780   "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}"
12781   [(set_attr "type" "sse")
12782    (set_attr "atom_sse_attr" "sqrt")
12783    (set_attr "prefix" "maybe_vex")
12784    (set_attr "mode" "<MODE>")
12785    (set_attr "athlon_decode" "*")
12786    (set_attr "amdfam10_decode" "*")])
12787
12788 (define_expand "sqrt<mode>2"
12789   [(set (match_operand:MODEF 0 "register_operand" "")
12790         (sqrt:MODEF
12791           (match_operand:MODEF 1 "nonimmediate_operand" "")))]
12792   "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
12793    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
12794 {
12795   if (<MODE>mode == SFmode
12796       && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
12797       && flag_finite_math_only && !flag_trapping_math
12798       && flag_unsafe_math_optimizations)
12799     {
12800       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
12801       DONE;
12802     }
12803
12804   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
12805     {
12806       rtx op0 = gen_reg_rtx (XFmode);
12807       rtx op1 = force_reg (<MODE>mode, operands[1]);
12808
12809       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
12810       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
12811       DONE;
12812    }
12813 })
12814
12815 (define_insn "fpremxf4_i387"
12816   [(set (match_operand:XF 0 "register_operand" "=f")
12817         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
12818                     (match_operand:XF 3 "register_operand" "1")]
12819                    UNSPEC_FPREM_F))
12820    (set (match_operand:XF 1 "register_operand" "=u")
12821         (unspec:XF [(match_dup 2) (match_dup 3)]
12822                    UNSPEC_FPREM_U))
12823    (set (reg:CCFP FPSR_REG)
12824         (unspec:CCFP [(match_dup 2) (match_dup 3)]
12825                      UNSPEC_C2_FLAG))]
12826   "TARGET_USE_FANCY_MATH_387"
12827   "fprem"
12828   [(set_attr "type" "fpspc")
12829    (set_attr "mode" "XF")])
12830
12831 (define_expand "fmodxf3"
12832   [(use (match_operand:XF 0 "register_operand" ""))
12833    (use (match_operand:XF 1 "general_operand" ""))
12834    (use (match_operand:XF 2 "general_operand" ""))]
12835   "TARGET_USE_FANCY_MATH_387"
12836 {
12837   rtx label = gen_label_rtx ();
12838
12839   rtx op1 = gen_reg_rtx (XFmode);
12840   rtx op2 = gen_reg_rtx (XFmode);
12841
12842   emit_move_insn (op2, operands[2]);
12843   emit_move_insn (op1, operands[1]);
12844
12845   emit_label (label);
12846   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
12847   ix86_emit_fp_unordered_jump (label);
12848   LABEL_NUSES (label) = 1;
12849
12850   emit_move_insn (operands[0], op1);
12851   DONE;
12852 })
12853
12854 (define_expand "fmod<mode>3"
12855   [(use (match_operand:MODEF 0 "register_operand" ""))
12856    (use (match_operand:MODEF 1 "general_operand" ""))
12857    (use (match_operand:MODEF 2 "general_operand" ""))]
12858   "TARGET_USE_FANCY_MATH_387"
12859 {
12860   rtx (*gen_truncxf) (rtx, rtx);
12861
12862   rtx label = gen_label_rtx ();
12863
12864   rtx op1 = gen_reg_rtx (XFmode);
12865   rtx op2 = gen_reg_rtx (XFmode);
12866
12867   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
12868   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
12869
12870   emit_label (label);
12871   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
12872   ix86_emit_fp_unordered_jump (label);
12873   LABEL_NUSES (label) = 1;
12874
12875   /* Truncate the result properly for strict SSE math.  */
12876   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12877       && !TARGET_MIX_SSE_I387)
12878     gen_truncxf = gen_truncxf<mode>2;
12879   else
12880     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
12881
12882   emit_insn (gen_truncxf (operands[0], op1));
12883   DONE;
12884 })
12885
12886 (define_insn "fprem1xf4_i387"
12887   [(set (match_operand:XF 0 "register_operand" "=f")
12888         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
12889                     (match_operand:XF 3 "register_operand" "1")]
12890                    UNSPEC_FPREM1_F))
12891    (set (match_operand:XF 1 "register_operand" "=u")
12892         (unspec:XF [(match_dup 2) (match_dup 3)]
12893                    UNSPEC_FPREM1_U))
12894    (set (reg:CCFP FPSR_REG)
12895         (unspec:CCFP [(match_dup 2) (match_dup 3)]
12896                      UNSPEC_C2_FLAG))]
12897   "TARGET_USE_FANCY_MATH_387"
12898   "fprem1"
12899   [(set_attr "type" "fpspc")
12900    (set_attr "mode" "XF")])
12901
12902 (define_expand "remainderxf3"
12903   [(use (match_operand:XF 0 "register_operand" ""))
12904    (use (match_operand:XF 1 "general_operand" ""))
12905    (use (match_operand:XF 2 "general_operand" ""))]
12906   "TARGET_USE_FANCY_MATH_387"
12907 {
12908   rtx label = gen_label_rtx ();
12909
12910   rtx op1 = gen_reg_rtx (XFmode);
12911   rtx op2 = gen_reg_rtx (XFmode);
12912
12913   emit_move_insn (op2, operands[2]);
12914   emit_move_insn (op1, operands[1]);
12915
12916   emit_label (label);
12917   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
12918   ix86_emit_fp_unordered_jump (label);
12919   LABEL_NUSES (label) = 1;
12920
12921   emit_move_insn (operands[0], op1);
12922   DONE;
12923 })
12924
12925 (define_expand "remainder<mode>3"
12926   [(use (match_operand:MODEF 0 "register_operand" ""))
12927    (use (match_operand:MODEF 1 "general_operand" ""))
12928    (use (match_operand:MODEF 2 "general_operand" ""))]
12929   "TARGET_USE_FANCY_MATH_387"
12930 {
12931   rtx (*gen_truncxf) (rtx, rtx);
12932
12933   rtx label = gen_label_rtx ();
12934
12935   rtx op1 = gen_reg_rtx (XFmode);
12936   rtx op2 = gen_reg_rtx (XFmode);
12937
12938   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
12939   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
12940
12941   emit_label (label);
12942
12943   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
12944   ix86_emit_fp_unordered_jump (label);
12945   LABEL_NUSES (label) = 1;
12946
12947   /* Truncate the result properly for strict SSE math.  */
12948   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12949       && !TARGET_MIX_SSE_I387)
12950     gen_truncxf = gen_truncxf<mode>2;
12951   else
12952     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
12953
12954   emit_insn (gen_truncxf (operands[0], op1));
12955   DONE;
12956 })
12957
12958 (define_insn "*sinxf2_i387"
12959   [(set (match_operand:XF 0 "register_operand" "=f")
12960         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
12961   "TARGET_USE_FANCY_MATH_387
12962    && flag_unsafe_math_optimizations"
12963   "fsin"
12964   [(set_attr "type" "fpspc")
12965    (set_attr "mode" "XF")])
12966
12967 (define_insn "*sin_extend<mode>xf2_i387"
12968   [(set (match_operand:XF 0 "register_operand" "=f")
12969         (unspec:XF [(float_extend:XF
12970                       (match_operand:MODEF 1 "register_operand" "0"))]
12971                    UNSPEC_SIN))]
12972   "TARGET_USE_FANCY_MATH_387
12973    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
12974        || TARGET_MIX_SSE_I387)
12975    && flag_unsafe_math_optimizations"
12976   "fsin"
12977   [(set_attr "type" "fpspc")
12978    (set_attr "mode" "XF")])
12979
12980 (define_insn "*cosxf2_i387"
12981   [(set (match_operand:XF 0 "register_operand" "=f")
12982         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
12983   "TARGET_USE_FANCY_MATH_387
12984    && flag_unsafe_math_optimizations"
12985   "fcos"
12986   [(set_attr "type" "fpspc")
12987    (set_attr "mode" "XF")])
12988
12989 (define_insn "*cos_extend<mode>xf2_i387"
12990   [(set (match_operand:XF 0 "register_operand" "=f")
12991         (unspec:XF [(float_extend:XF
12992                       (match_operand:MODEF 1 "register_operand" "0"))]
12993                    UNSPEC_COS))]
12994   "TARGET_USE_FANCY_MATH_387
12995    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
12996        || TARGET_MIX_SSE_I387)
12997    && flag_unsafe_math_optimizations"
12998   "fcos"
12999   [(set_attr "type" "fpspc")
13000    (set_attr "mode" "XF")])
13001
13002 ;; When sincos pattern is defined, sin and cos builtin functions will be
13003 ;; expanded to sincos pattern with one of its outputs left unused.
13004 ;; CSE pass will figure out if two sincos patterns can be combined,
13005 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13006 ;; depending on the unused output.
13007
13008 (define_insn "sincosxf3"
13009   [(set (match_operand:XF 0 "register_operand" "=f")
13010         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13011                    UNSPEC_SINCOS_COS))
13012    (set (match_operand:XF 1 "register_operand" "=u")
13013         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13014   "TARGET_USE_FANCY_MATH_387
13015    && flag_unsafe_math_optimizations"
13016   "fsincos"
13017   [(set_attr "type" "fpspc")
13018    (set_attr "mode" "XF")])
13019
13020 (define_split
13021   [(set (match_operand:XF 0 "register_operand" "")
13022         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13023                    UNSPEC_SINCOS_COS))
13024    (set (match_operand:XF 1 "register_operand" "")
13025         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13026   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13027    && !(reload_completed || reload_in_progress)"
13028   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13029
13030 (define_split
13031   [(set (match_operand:XF 0 "register_operand" "")
13032         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13033                    UNSPEC_SINCOS_COS))
13034    (set (match_operand:XF 1 "register_operand" "")
13035         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13036   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13037    && !(reload_completed || reload_in_progress)"
13038   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13039
13040 (define_insn "sincos_extend<mode>xf3_i387"
13041   [(set (match_operand:XF 0 "register_operand" "=f")
13042         (unspec:XF [(float_extend:XF
13043                       (match_operand:MODEF 2 "register_operand" "0"))]
13044                    UNSPEC_SINCOS_COS))
13045    (set (match_operand:XF 1 "register_operand" "=u")
13046         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13047   "TARGET_USE_FANCY_MATH_387
13048    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13049        || TARGET_MIX_SSE_I387)
13050    && flag_unsafe_math_optimizations"
13051   "fsincos"
13052   [(set_attr "type" "fpspc")
13053    (set_attr "mode" "XF")])
13054
13055 (define_split
13056   [(set (match_operand:XF 0 "register_operand" "")
13057         (unspec:XF [(float_extend:XF
13058                       (match_operand:MODEF 2 "register_operand" ""))]
13059                    UNSPEC_SINCOS_COS))
13060    (set (match_operand:XF 1 "register_operand" "")
13061         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13062   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13063    && !(reload_completed || reload_in_progress)"
13064   [(set (match_dup 1)
13065         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13066
13067 (define_split
13068   [(set (match_operand:XF 0 "register_operand" "")
13069         (unspec:XF [(float_extend:XF
13070                       (match_operand:MODEF 2 "register_operand" ""))]
13071                    UNSPEC_SINCOS_COS))
13072    (set (match_operand:XF 1 "register_operand" "")
13073         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13074   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13075    && !(reload_completed || reload_in_progress)"
13076   [(set (match_dup 0)
13077         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13078
13079 (define_expand "sincos<mode>3"
13080   [(use (match_operand:MODEF 0 "register_operand" ""))
13081    (use (match_operand:MODEF 1 "register_operand" ""))
13082    (use (match_operand:MODEF 2 "register_operand" ""))]
13083   "TARGET_USE_FANCY_MATH_387
13084    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13085        || TARGET_MIX_SSE_I387)
13086    && flag_unsafe_math_optimizations"
13087 {
13088   rtx op0 = gen_reg_rtx (XFmode);
13089   rtx op1 = gen_reg_rtx (XFmode);
13090
13091   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13092   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13093   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13094   DONE;
13095 })
13096
13097 (define_insn "fptanxf4_i387"
13098   [(set (match_operand:XF 0 "register_operand" "=f")
13099         (match_operand:XF 3 "const_double_operand" "F"))
13100    (set (match_operand:XF 1 "register_operand" "=u")
13101         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13102                    UNSPEC_TAN))]
13103   "TARGET_USE_FANCY_MATH_387
13104    && flag_unsafe_math_optimizations
13105    && standard_80387_constant_p (operands[3]) == 2"
13106   "fptan"
13107   [(set_attr "type" "fpspc")
13108    (set_attr "mode" "XF")])
13109
13110 (define_insn "fptan_extend<mode>xf4_i387"
13111   [(set (match_operand:MODEF 0 "register_operand" "=f")
13112         (match_operand:MODEF 3 "const_double_operand" "F"))
13113    (set (match_operand:XF 1 "register_operand" "=u")
13114         (unspec:XF [(float_extend:XF
13115                       (match_operand:MODEF 2 "register_operand" "0"))]
13116                    UNSPEC_TAN))]
13117   "TARGET_USE_FANCY_MATH_387
13118    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13119        || TARGET_MIX_SSE_I387)
13120    && flag_unsafe_math_optimizations
13121    && standard_80387_constant_p (operands[3]) == 2"
13122   "fptan"
13123   [(set_attr "type" "fpspc")
13124    (set_attr "mode" "XF")])
13125
13126 (define_expand "tanxf2"
13127   [(use (match_operand:XF 0 "register_operand" ""))
13128    (use (match_operand:XF 1 "register_operand" ""))]
13129   "TARGET_USE_FANCY_MATH_387
13130    && flag_unsafe_math_optimizations"
13131 {
13132   rtx one = gen_reg_rtx (XFmode);
13133   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13134
13135   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13136   DONE;
13137 })
13138
13139 (define_expand "tan<mode>2"
13140   [(use (match_operand:MODEF 0 "register_operand" ""))
13141    (use (match_operand:MODEF 1 "register_operand" ""))]
13142   "TARGET_USE_FANCY_MATH_387
13143    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13144        || TARGET_MIX_SSE_I387)
13145    && flag_unsafe_math_optimizations"
13146 {
13147   rtx op0 = gen_reg_rtx (XFmode);
13148
13149   rtx one = gen_reg_rtx (<MODE>mode);
13150   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13151
13152   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13153                                              operands[1], op2));
13154   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13155   DONE;
13156 })
13157
13158 (define_insn "*fpatanxf3_i387"
13159   [(set (match_operand:XF 0 "register_operand" "=f")
13160         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13161                     (match_operand:XF 2 "register_operand" "u")]
13162                    UNSPEC_FPATAN))
13163    (clobber (match_scratch:XF 3 "=2"))]
13164   "TARGET_USE_FANCY_MATH_387
13165    && flag_unsafe_math_optimizations"
13166   "fpatan"
13167   [(set_attr "type" "fpspc")
13168    (set_attr "mode" "XF")])
13169
13170 (define_insn "fpatan_extend<mode>xf3_i387"
13171   [(set (match_operand:XF 0 "register_operand" "=f")
13172         (unspec:XF [(float_extend:XF
13173                       (match_operand:MODEF 1 "register_operand" "0"))
13174                     (float_extend:XF
13175                       (match_operand:MODEF 2 "register_operand" "u"))]
13176                    UNSPEC_FPATAN))
13177    (clobber (match_scratch:XF 3 "=2"))]
13178   "TARGET_USE_FANCY_MATH_387
13179    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13180        || TARGET_MIX_SSE_I387)
13181    && flag_unsafe_math_optimizations"
13182   "fpatan"
13183   [(set_attr "type" "fpspc")
13184    (set_attr "mode" "XF")])
13185
13186 (define_expand "atan2xf3"
13187   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13188                    (unspec:XF [(match_operand:XF 2 "register_operand" "")
13189                                (match_operand:XF 1 "register_operand" "")]
13190                               UNSPEC_FPATAN))
13191               (clobber (match_scratch:XF 3 ""))])]
13192   "TARGET_USE_FANCY_MATH_387
13193    && flag_unsafe_math_optimizations"
13194   "")
13195
13196 (define_expand "atan2<mode>3"
13197   [(use (match_operand:MODEF 0 "register_operand" ""))
13198    (use (match_operand:MODEF 1 "register_operand" ""))
13199    (use (match_operand:MODEF 2 "register_operand" ""))]
13200   "TARGET_USE_FANCY_MATH_387
13201    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13202        || TARGET_MIX_SSE_I387)
13203    && flag_unsafe_math_optimizations"
13204 {
13205   rtx op0 = gen_reg_rtx (XFmode);
13206
13207   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13208   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13209   DONE;
13210 })
13211
13212 (define_expand "atanxf2"
13213   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13214                    (unspec:XF [(match_dup 2)
13215                                (match_operand:XF 1 "register_operand" "")]
13216                               UNSPEC_FPATAN))
13217               (clobber (match_scratch:XF 3 ""))])]
13218   "TARGET_USE_FANCY_MATH_387
13219    && flag_unsafe_math_optimizations"
13220 {
13221   operands[2] = gen_reg_rtx (XFmode);
13222   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
13223 })
13224
13225 (define_expand "atan<mode>2"
13226   [(use (match_operand:MODEF 0 "register_operand" ""))
13227    (use (match_operand:MODEF 1 "register_operand" ""))]
13228   "TARGET_USE_FANCY_MATH_387
13229    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13230        || TARGET_MIX_SSE_I387)
13231    && flag_unsafe_math_optimizations"
13232 {
13233   rtx op0 = gen_reg_rtx (XFmode);
13234
13235   rtx op2 = gen_reg_rtx (<MODE>mode);
13236   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
13237
13238   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13239   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13240   DONE;
13241 })
13242
13243 (define_expand "asinxf2"
13244   [(set (match_dup 2)
13245         (mult:XF (match_operand:XF 1 "register_operand" "")
13246                  (match_dup 1)))
13247    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13248    (set (match_dup 5) (sqrt:XF (match_dup 4)))
13249    (parallel [(set (match_operand:XF 0 "register_operand" "")
13250                    (unspec:XF [(match_dup 5) (match_dup 1)]
13251                               UNSPEC_FPATAN))
13252               (clobber (match_scratch:XF 6 ""))])]
13253   "TARGET_USE_FANCY_MATH_387
13254    && flag_unsafe_math_optimizations"
13255 {
13256   int i;
13257
13258   if (optimize_insn_for_size_p ())
13259     FAIL;
13260
13261   for (i = 2; i < 6; i++)
13262     operands[i] = gen_reg_rtx (XFmode);
13263
13264   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
13265 })
13266
13267 (define_expand "asin<mode>2"
13268   [(use (match_operand:MODEF 0 "register_operand" ""))
13269    (use (match_operand:MODEF 1 "general_operand" ""))]
13270  "TARGET_USE_FANCY_MATH_387
13271    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13272        || TARGET_MIX_SSE_I387)
13273    && flag_unsafe_math_optimizations"
13274 {
13275   rtx op0 = gen_reg_rtx (XFmode);
13276   rtx op1 = gen_reg_rtx (XFmode);
13277
13278   if (optimize_insn_for_size_p ())
13279     FAIL;
13280
13281   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13282   emit_insn (gen_asinxf2 (op0, op1));
13283   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13284   DONE;
13285 })
13286
13287 (define_expand "acosxf2"
13288   [(set (match_dup 2)
13289         (mult:XF (match_operand:XF 1 "register_operand" "")
13290                  (match_dup 1)))
13291    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13292    (set (match_dup 5) (sqrt:XF (match_dup 4)))
13293    (parallel [(set (match_operand:XF 0 "register_operand" "")
13294                    (unspec:XF [(match_dup 1) (match_dup 5)]
13295                               UNSPEC_FPATAN))
13296               (clobber (match_scratch:XF 6 ""))])]
13297   "TARGET_USE_FANCY_MATH_387
13298    && flag_unsafe_math_optimizations"
13299 {
13300   int i;
13301
13302   if (optimize_insn_for_size_p ())
13303     FAIL;
13304
13305   for (i = 2; i < 6; i++)
13306     operands[i] = gen_reg_rtx (XFmode);
13307
13308   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
13309 })
13310
13311 (define_expand "acos<mode>2"
13312   [(use (match_operand:MODEF 0 "register_operand" ""))
13313    (use (match_operand:MODEF 1 "general_operand" ""))]
13314  "TARGET_USE_FANCY_MATH_387
13315    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13316        || TARGET_MIX_SSE_I387)
13317    && flag_unsafe_math_optimizations"
13318 {
13319   rtx op0 = gen_reg_rtx (XFmode);
13320   rtx op1 = gen_reg_rtx (XFmode);
13321
13322   if (optimize_insn_for_size_p ())
13323     FAIL;
13324
13325   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13326   emit_insn (gen_acosxf2 (op0, op1));
13327   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13328   DONE;
13329 })
13330
13331 (define_insn "fyl2xxf3_i387"
13332   [(set (match_operand:XF 0 "register_operand" "=f")
13333         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13334                     (match_operand:XF 2 "register_operand" "u")]
13335                    UNSPEC_FYL2X))
13336    (clobber (match_scratch:XF 3 "=2"))]
13337   "TARGET_USE_FANCY_MATH_387
13338    && flag_unsafe_math_optimizations"
13339   "fyl2x"
13340   [(set_attr "type" "fpspc")
13341    (set_attr "mode" "XF")])
13342
13343 (define_insn "fyl2x_extend<mode>xf3_i387"
13344   [(set (match_operand:XF 0 "register_operand" "=f")
13345         (unspec:XF [(float_extend:XF
13346                       (match_operand:MODEF 1 "register_operand" "0"))
13347                     (match_operand:XF 2 "register_operand" "u")]
13348                    UNSPEC_FYL2X))
13349    (clobber (match_scratch:XF 3 "=2"))]
13350   "TARGET_USE_FANCY_MATH_387
13351    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13352        || TARGET_MIX_SSE_I387)
13353    && flag_unsafe_math_optimizations"
13354   "fyl2x"
13355   [(set_attr "type" "fpspc")
13356    (set_attr "mode" "XF")])
13357
13358 (define_expand "logxf2"
13359   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13360                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
13361                                (match_dup 2)] UNSPEC_FYL2X))
13362               (clobber (match_scratch:XF 3 ""))])]
13363   "TARGET_USE_FANCY_MATH_387
13364    && flag_unsafe_math_optimizations"
13365 {
13366   operands[2] = gen_reg_rtx (XFmode);
13367   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
13368 })
13369
13370 (define_expand "log<mode>2"
13371   [(use (match_operand:MODEF 0 "register_operand" ""))
13372    (use (match_operand:MODEF 1 "register_operand" ""))]
13373   "TARGET_USE_FANCY_MATH_387
13374    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13375        || TARGET_MIX_SSE_I387)
13376    && flag_unsafe_math_optimizations"
13377 {
13378   rtx op0 = gen_reg_rtx (XFmode);
13379
13380   rtx op2 = gen_reg_rtx (XFmode);
13381   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
13382
13383   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13384   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13385   DONE;
13386 })
13387
13388 (define_expand "log10xf2"
13389   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13390                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
13391                                (match_dup 2)] UNSPEC_FYL2X))
13392               (clobber (match_scratch:XF 3 ""))])]
13393   "TARGET_USE_FANCY_MATH_387
13394    && flag_unsafe_math_optimizations"
13395 {
13396   operands[2] = gen_reg_rtx (XFmode);
13397   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
13398 })
13399
13400 (define_expand "log10<mode>2"
13401   [(use (match_operand:MODEF 0 "register_operand" ""))
13402    (use (match_operand:MODEF 1 "register_operand" ""))]
13403   "TARGET_USE_FANCY_MATH_387
13404    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13405        || TARGET_MIX_SSE_I387)
13406    && flag_unsafe_math_optimizations"
13407 {
13408   rtx op0 = gen_reg_rtx (XFmode);
13409
13410   rtx op2 = gen_reg_rtx (XFmode);
13411   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
13412
13413   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13414   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13415   DONE;
13416 })
13417
13418 (define_expand "log2xf2"
13419   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13420                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
13421                                (match_dup 2)] UNSPEC_FYL2X))
13422               (clobber (match_scratch:XF 3 ""))])]
13423   "TARGET_USE_FANCY_MATH_387
13424    && flag_unsafe_math_optimizations"
13425 {
13426   operands[2] = gen_reg_rtx (XFmode);
13427   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13428 })
13429
13430 (define_expand "log2<mode>2"
13431   [(use (match_operand:MODEF 0 "register_operand" ""))
13432    (use (match_operand:MODEF 1 "register_operand" ""))]
13433   "TARGET_USE_FANCY_MATH_387
13434    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13435        || TARGET_MIX_SSE_I387)
13436    && flag_unsafe_math_optimizations"
13437 {
13438   rtx op0 = gen_reg_rtx (XFmode);
13439
13440   rtx op2 = gen_reg_rtx (XFmode);
13441   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
13442
13443   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13444   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13445   DONE;
13446 })
13447
13448 (define_insn "fyl2xp1xf3_i387"
13449   [(set (match_operand:XF 0 "register_operand" "=f")
13450         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13451                     (match_operand:XF 2 "register_operand" "u")]
13452                    UNSPEC_FYL2XP1))
13453    (clobber (match_scratch:XF 3 "=2"))]
13454   "TARGET_USE_FANCY_MATH_387
13455    && flag_unsafe_math_optimizations"
13456   "fyl2xp1"
13457   [(set_attr "type" "fpspc")
13458    (set_attr "mode" "XF")])
13459
13460 (define_insn "fyl2xp1_extend<mode>xf3_i387"
13461   [(set (match_operand:XF 0 "register_operand" "=f")
13462         (unspec:XF [(float_extend:XF
13463                       (match_operand:MODEF 1 "register_operand" "0"))
13464                     (match_operand:XF 2 "register_operand" "u")]
13465                    UNSPEC_FYL2XP1))
13466    (clobber (match_scratch:XF 3 "=2"))]
13467   "TARGET_USE_FANCY_MATH_387
13468    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13469        || TARGET_MIX_SSE_I387)
13470    && flag_unsafe_math_optimizations"
13471   "fyl2xp1"
13472   [(set_attr "type" "fpspc")
13473    (set_attr "mode" "XF")])
13474
13475 (define_expand "log1pxf2"
13476   [(use (match_operand:XF 0 "register_operand" ""))
13477    (use (match_operand:XF 1 "register_operand" ""))]
13478   "TARGET_USE_FANCY_MATH_387
13479    && flag_unsafe_math_optimizations"
13480 {
13481   if (optimize_insn_for_size_p ())
13482     FAIL;
13483
13484   ix86_emit_i387_log1p (operands[0], operands[1]);
13485   DONE;
13486 })
13487
13488 (define_expand "log1p<mode>2"
13489   [(use (match_operand:MODEF 0 "register_operand" ""))
13490    (use (match_operand:MODEF 1 "register_operand" ""))]
13491   "TARGET_USE_FANCY_MATH_387
13492    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13493        || TARGET_MIX_SSE_I387)
13494    && flag_unsafe_math_optimizations"
13495 {
13496   rtx op0;
13497
13498   if (optimize_insn_for_size_p ())
13499     FAIL;
13500
13501   op0 = gen_reg_rtx (XFmode);
13502
13503   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
13504
13505   ix86_emit_i387_log1p (op0, operands[1]);
13506   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13507   DONE;
13508 })
13509
13510 (define_insn "fxtractxf3_i387"
13511   [(set (match_operand:XF 0 "register_operand" "=f")
13512         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13513                    UNSPEC_XTRACT_FRACT))
13514    (set (match_operand:XF 1 "register_operand" "=u")
13515         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
13516   "TARGET_USE_FANCY_MATH_387
13517    && flag_unsafe_math_optimizations"
13518   "fxtract"
13519   [(set_attr "type" "fpspc")
13520    (set_attr "mode" "XF")])
13521
13522 (define_insn "fxtract_extend<mode>xf3_i387"
13523   [(set (match_operand:XF 0 "register_operand" "=f")
13524         (unspec:XF [(float_extend:XF
13525                       (match_operand:MODEF 2 "register_operand" "0"))]
13526                    UNSPEC_XTRACT_FRACT))
13527    (set (match_operand:XF 1 "register_operand" "=u")
13528         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
13529   "TARGET_USE_FANCY_MATH_387
13530    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13531        || TARGET_MIX_SSE_I387)
13532    && flag_unsafe_math_optimizations"
13533   "fxtract"
13534   [(set_attr "type" "fpspc")
13535    (set_attr "mode" "XF")])
13536
13537 (define_expand "logbxf2"
13538   [(parallel [(set (match_dup 2)
13539                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
13540                               UNSPEC_XTRACT_FRACT))
13541               (set (match_operand:XF 0 "register_operand" "")
13542                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
13543   "TARGET_USE_FANCY_MATH_387
13544    && flag_unsafe_math_optimizations"
13545 {
13546   operands[2] = gen_reg_rtx (XFmode);
13547 })
13548
13549 (define_expand "logb<mode>2"
13550   [(use (match_operand:MODEF 0 "register_operand" ""))
13551    (use (match_operand:MODEF 1 "register_operand" ""))]
13552   "TARGET_USE_FANCY_MATH_387
13553    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13554        || TARGET_MIX_SSE_I387)
13555    && flag_unsafe_math_optimizations"
13556 {
13557   rtx op0 = gen_reg_rtx (XFmode);
13558   rtx op1 = gen_reg_rtx (XFmode);
13559
13560   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13561   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
13562   DONE;
13563 })
13564
13565 (define_expand "ilogbxf2"
13566   [(use (match_operand:SI 0 "register_operand" ""))
13567    (use (match_operand:XF 1 "register_operand" ""))]
13568   "TARGET_USE_FANCY_MATH_387
13569    && flag_unsafe_math_optimizations"
13570 {
13571   rtx op0, op1;
13572
13573   if (optimize_insn_for_size_p ())
13574     FAIL;
13575
13576   op0 = gen_reg_rtx (XFmode);
13577   op1 = gen_reg_rtx (XFmode);
13578
13579   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
13580   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13581   DONE;
13582 })
13583
13584 (define_expand "ilogb<mode>2"
13585   [(use (match_operand:SI 0 "register_operand" ""))
13586    (use (match_operand:MODEF 1 "register_operand" ""))]
13587   "TARGET_USE_FANCY_MATH_387
13588    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13589        || TARGET_MIX_SSE_I387)
13590    && flag_unsafe_math_optimizations"
13591 {
13592   rtx op0, op1;
13593
13594   if (optimize_insn_for_size_p ())
13595     FAIL;
13596
13597   op0 = gen_reg_rtx (XFmode);
13598   op1 = gen_reg_rtx (XFmode);
13599
13600   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13601   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13602   DONE;
13603 })
13604
13605 (define_insn "*f2xm1xf2_i387"
13606   [(set (match_operand:XF 0 "register_operand" "=f")
13607         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13608                    UNSPEC_F2XM1))]
13609   "TARGET_USE_FANCY_MATH_387
13610    && flag_unsafe_math_optimizations"
13611   "f2xm1"
13612   [(set_attr "type" "fpspc")
13613    (set_attr "mode" "XF")])
13614
13615 (define_insn "*fscalexf4_i387"
13616   [(set (match_operand:XF 0 "register_operand" "=f")
13617         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13618                     (match_operand:XF 3 "register_operand" "1")]
13619                    UNSPEC_FSCALE_FRACT))
13620    (set (match_operand:XF 1 "register_operand" "=u")
13621         (unspec:XF [(match_dup 2) (match_dup 3)]
13622                    UNSPEC_FSCALE_EXP))]
13623   "TARGET_USE_FANCY_MATH_387
13624    && flag_unsafe_math_optimizations"
13625   "fscale"
13626   [(set_attr "type" "fpspc")
13627    (set_attr "mode" "XF")])
13628
13629 (define_expand "expNcorexf3"
13630   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
13631                                (match_operand:XF 2 "register_operand" "")))
13632    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
13633    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
13634    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
13635    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
13636    (parallel [(set (match_operand:XF 0 "register_operand" "")
13637                    (unspec:XF [(match_dup 8) (match_dup 4)]
13638                               UNSPEC_FSCALE_FRACT))
13639               (set (match_dup 9)
13640                    (unspec:XF [(match_dup 8) (match_dup 4)]
13641                               UNSPEC_FSCALE_EXP))])]
13642   "TARGET_USE_FANCY_MATH_387
13643    && flag_unsafe_math_optimizations"
13644 {
13645   int i;
13646
13647   if (optimize_insn_for_size_p ())
13648     FAIL;
13649
13650   for (i = 3; i < 10; i++)
13651     operands[i] = gen_reg_rtx (XFmode);
13652
13653   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
13654 })
13655
13656 (define_expand "expxf2"
13657   [(use (match_operand:XF 0 "register_operand" ""))
13658    (use (match_operand:XF 1 "register_operand" ""))]
13659   "TARGET_USE_FANCY_MATH_387
13660    && flag_unsafe_math_optimizations"
13661 {
13662   rtx op2;
13663
13664   if (optimize_insn_for_size_p ())
13665     FAIL;
13666
13667   op2 = gen_reg_rtx (XFmode);
13668   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
13669
13670   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
13671   DONE;
13672 })
13673
13674 (define_expand "exp<mode>2"
13675   [(use (match_operand:MODEF 0 "register_operand" ""))
13676    (use (match_operand:MODEF 1 "general_operand" ""))]
13677  "TARGET_USE_FANCY_MATH_387
13678    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13679        || TARGET_MIX_SSE_I387)
13680    && flag_unsafe_math_optimizations"
13681 {
13682   rtx op0, op1;
13683
13684   if (optimize_insn_for_size_p ())
13685     FAIL;
13686
13687   op0 = gen_reg_rtx (XFmode);
13688   op1 = gen_reg_rtx (XFmode);
13689
13690   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13691   emit_insn (gen_expxf2 (op0, op1));
13692   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13693   DONE;
13694 })
13695
13696 (define_expand "exp10xf2"
13697   [(use (match_operand:XF 0 "register_operand" ""))
13698    (use (match_operand:XF 1 "register_operand" ""))]
13699   "TARGET_USE_FANCY_MATH_387
13700    && flag_unsafe_math_optimizations"
13701 {
13702   rtx op2;
13703
13704   if (optimize_insn_for_size_p ())
13705     FAIL;
13706
13707   op2 = gen_reg_rtx (XFmode);
13708   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
13709
13710   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
13711   DONE;
13712 })
13713
13714 (define_expand "exp10<mode>2"
13715   [(use (match_operand:MODEF 0 "register_operand" ""))
13716    (use (match_operand:MODEF 1 "general_operand" ""))]
13717  "TARGET_USE_FANCY_MATH_387
13718    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13719        || TARGET_MIX_SSE_I387)
13720    && flag_unsafe_math_optimizations"
13721 {
13722   rtx op0, op1;
13723
13724   if (optimize_insn_for_size_p ())
13725     FAIL;
13726
13727   op0 = gen_reg_rtx (XFmode);
13728   op1 = gen_reg_rtx (XFmode);
13729
13730   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13731   emit_insn (gen_exp10xf2 (op0, op1));
13732   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13733   DONE;
13734 })
13735
13736 (define_expand "exp2xf2"
13737   [(use (match_operand:XF 0 "register_operand" ""))
13738    (use (match_operand:XF 1 "register_operand" ""))]
13739   "TARGET_USE_FANCY_MATH_387
13740    && flag_unsafe_math_optimizations"
13741 {
13742   rtx op2;
13743
13744   if (optimize_insn_for_size_p ())
13745     FAIL;
13746
13747   op2 = gen_reg_rtx (XFmode);
13748   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
13749
13750   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
13751   DONE;
13752 })
13753
13754 (define_expand "exp2<mode>2"
13755   [(use (match_operand:MODEF 0 "register_operand" ""))
13756    (use (match_operand:MODEF 1 "general_operand" ""))]
13757  "TARGET_USE_FANCY_MATH_387
13758    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13759        || TARGET_MIX_SSE_I387)
13760    && flag_unsafe_math_optimizations"
13761 {
13762   rtx op0, op1;
13763
13764   if (optimize_insn_for_size_p ())
13765     FAIL;
13766
13767   op0 = gen_reg_rtx (XFmode);
13768   op1 = gen_reg_rtx (XFmode);
13769
13770   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13771   emit_insn (gen_exp2xf2 (op0, op1));
13772   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13773   DONE;
13774 })
13775
13776 (define_expand "expm1xf2"
13777   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
13778                                (match_dup 2)))
13779    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
13780    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
13781    (set (match_dup 9) (float_extend:XF (match_dup 13)))
13782    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
13783    (parallel [(set (match_dup 7)
13784                    (unspec:XF [(match_dup 6) (match_dup 4)]
13785                               UNSPEC_FSCALE_FRACT))
13786               (set (match_dup 8)
13787                    (unspec:XF [(match_dup 6) (match_dup 4)]
13788                               UNSPEC_FSCALE_EXP))])
13789    (parallel [(set (match_dup 10)
13790                    (unspec:XF [(match_dup 9) (match_dup 8)]
13791                               UNSPEC_FSCALE_FRACT))
13792               (set (match_dup 11)
13793                    (unspec:XF [(match_dup 9) (match_dup 8)]
13794                               UNSPEC_FSCALE_EXP))])
13795    (set (match_dup 12) (minus:XF (match_dup 10)
13796                                  (float_extend:XF (match_dup 13))))
13797    (set (match_operand:XF 0 "register_operand" "")
13798         (plus:XF (match_dup 12) (match_dup 7)))]
13799   "TARGET_USE_FANCY_MATH_387
13800    && flag_unsafe_math_optimizations"
13801 {
13802   int i;
13803
13804   if (optimize_insn_for_size_p ())
13805     FAIL;
13806
13807   for (i = 2; i < 13; i++)
13808     operands[i] = gen_reg_rtx (XFmode);
13809
13810   operands[13]
13811     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
13812
13813   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
13814 })
13815
13816 (define_expand "expm1<mode>2"
13817   [(use (match_operand:MODEF 0 "register_operand" ""))
13818    (use (match_operand:MODEF 1 "general_operand" ""))]
13819  "TARGET_USE_FANCY_MATH_387
13820    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13821        || TARGET_MIX_SSE_I387)
13822    && flag_unsafe_math_optimizations"
13823 {
13824   rtx op0, op1;
13825
13826   if (optimize_insn_for_size_p ())
13827     FAIL;
13828
13829   op0 = gen_reg_rtx (XFmode);
13830   op1 = gen_reg_rtx (XFmode);
13831
13832   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13833   emit_insn (gen_expm1xf2 (op0, op1));
13834   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13835   DONE;
13836 })
13837
13838 (define_expand "ldexpxf3"
13839   [(set (match_dup 3)
13840         (float:XF (match_operand:SI 2 "register_operand" "")))
13841    (parallel [(set (match_operand:XF 0 " register_operand" "")
13842                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
13843                                (match_dup 3)]
13844                               UNSPEC_FSCALE_FRACT))
13845               (set (match_dup 4)
13846                    (unspec:XF [(match_dup 1) (match_dup 3)]
13847                               UNSPEC_FSCALE_EXP))])]
13848   "TARGET_USE_FANCY_MATH_387
13849    && flag_unsafe_math_optimizations"
13850 {
13851   if (optimize_insn_for_size_p ())
13852     FAIL;
13853
13854   operands[3] = gen_reg_rtx (XFmode);
13855   operands[4] = gen_reg_rtx (XFmode);
13856 })
13857
13858 (define_expand "ldexp<mode>3"
13859   [(use (match_operand:MODEF 0 "register_operand" ""))
13860    (use (match_operand:MODEF 1 "general_operand" ""))
13861    (use (match_operand:SI 2 "register_operand" ""))]
13862  "TARGET_USE_FANCY_MATH_387
13863    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13864        || TARGET_MIX_SSE_I387)
13865    && flag_unsafe_math_optimizations"
13866 {
13867   rtx op0, op1;
13868
13869   if (optimize_insn_for_size_p ())
13870     FAIL;
13871
13872   op0 = gen_reg_rtx (XFmode);
13873   op1 = gen_reg_rtx (XFmode);
13874
13875   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13876   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
13877   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13878   DONE;
13879 })
13880
13881 (define_expand "scalbxf3"
13882   [(parallel [(set (match_operand:XF 0 " register_operand" "")
13883                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
13884                                (match_operand:XF 2 "register_operand" "")]
13885                               UNSPEC_FSCALE_FRACT))
13886               (set (match_dup 3)
13887                    (unspec:XF [(match_dup 1) (match_dup 2)]
13888                               UNSPEC_FSCALE_EXP))])]
13889   "TARGET_USE_FANCY_MATH_387
13890    && flag_unsafe_math_optimizations"
13891 {
13892   if (optimize_insn_for_size_p ())
13893     FAIL;
13894
13895   operands[3] = gen_reg_rtx (XFmode);
13896 })
13897
13898 (define_expand "scalb<mode>3"
13899   [(use (match_operand:MODEF 0 "register_operand" ""))
13900    (use (match_operand:MODEF 1 "general_operand" ""))
13901    (use (match_operand:MODEF 2 "general_operand" ""))]
13902  "TARGET_USE_FANCY_MATH_387
13903    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13904        || TARGET_MIX_SSE_I387)
13905    && flag_unsafe_math_optimizations"
13906 {
13907   rtx op0, op1, op2;
13908
13909   if (optimize_insn_for_size_p ())
13910     FAIL;
13911
13912   op0 = gen_reg_rtx (XFmode);
13913   op1 = gen_reg_rtx (XFmode);
13914   op2 = gen_reg_rtx (XFmode);
13915
13916   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13917   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13918   emit_insn (gen_scalbxf3 (op0, op1, op2));
13919   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13920   DONE;
13921 })
13922
13923 (define_expand "significandxf2"
13924   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13925                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
13926                               UNSPEC_XTRACT_FRACT))
13927               (set (match_dup 2)
13928                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
13929   "TARGET_USE_FANCY_MATH_387
13930    && flag_unsafe_math_optimizations"
13931 {
13932   operands[2] = gen_reg_rtx (XFmode);
13933 })
13934
13935 (define_expand "significand<mode>2"
13936   [(use (match_operand:MODEF 0 "register_operand" ""))
13937    (use (match_operand:MODEF 1 "register_operand" ""))]
13938   "TARGET_USE_FANCY_MATH_387
13939    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13940        || TARGET_MIX_SSE_I387)
13941    && flag_unsafe_math_optimizations"
13942 {
13943   rtx op0 = gen_reg_rtx (XFmode);
13944   rtx op1 = gen_reg_rtx (XFmode);
13945
13946   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13947   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13948   DONE;
13949 })
13950 \f
13951
13952 (define_insn "sse4_1_round<mode>2"
13953   [(set (match_operand:MODEF 0 "register_operand" "=x")
13954         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
13955                        (match_operand:SI 2 "const_0_to_15_operand" "n")]
13956                       UNSPEC_ROUND))]
13957   "TARGET_ROUND"
13958   "%vrounds<ssemodefsuffix>\t{%2, %1, %d0|%d0, %1, %2}"
13959   [(set_attr "type" "ssecvt")
13960    (set_attr "prefix_extra" "1")
13961    (set_attr "prefix" "maybe_vex")
13962    (set_attr "mode" "<MODE>")])
13963
13964 (define_insn "rintxf2"
13965   [(set (match_operand:XF 0 "register_operand" "=f")
13966         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13967                    UNSPEC_FRNDINT))]
13968   "TARGET_USE_FANCY_MATH_387
13969    && flag_unsafe_math_optimizations"
13970   "frndint"
13971   [(set_attr "type" "fpspc")
13972    (set_attr "mode" "XF")])
13973
13974 (define_expand "rint<mode>2"
13975   [(use (match_operand:MODEF 0 "register_operand" ""))
13976    (use (match_operand:MODEF 1 "register_operand" ""))]
13977   "(TARGET_USE_FANCY_MATH_387
13978     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13979         || TARGET_MIX_SSE_I387)
13980     && flag_unsafe_math_optimizations)
13981    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13982        && !flag_trapping_math)"
13983 {
13984   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13985       && !flag_trapping_math)
13986     {
13987       if (!TARGET_ROUND && optimize_insn_for_size_p ())
13988         FAIL;
13989       if (TARGET_ROUND)
13990         emit_insn (gen_sse4_1_round<mode>2
13991                    (operands[0], operands[1], GEN_INT (0x04)));
13992       else
13993         ix86_expand_rint (operand0, operand1);
13994     }
13995   else
13996     {
13997       rtx op0 = gen_reg_rtx (XFmode);
13998       rtx op1 = gen_reg_rtx (XFmode);
13999
14000       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14001       emit_insn (gen_rintxf2 (op0, op1));
14002
14003       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14004     }
14005   DONE;
14006 })
14007
14008 (define_expand "round<mode>2"
14009   [(match_operand:MODEF 0 "register_operand" "")
14010    (match_operand:MODEF 1 "nonimmediate_operand" "")]
14011   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14012    && !flag_trapping_math && !flag_rounding_math"
14013 {
14014   if (optimize_insn_for_size_p ())
14015     FAIL;
14016   if (TARGET_64BIT || (<MODE>mode != DFmode))
14017     ix86_expand_round (operand0, operand1);
14018   else
14019     ix86_expand_rounddf_32 (operand0, operand1);
14020   DONE;
14021 })
14022
14023 (define_insn_and_split "*fistdi2_1"
14024   [(set (match_operand:DI 0 "nonimmediate_operand" "")
14025         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14026                    UNSPEC_FIST))]
14027   "TARGET_USE_FANCY_MATH_387
14028    && can_create_pseudo_p ()"
14029   "#"
14030   "&& 1"
14031   [(const_int 0)]
14032 {
14033   if (memory_operand (operands[0], VOIDmode))
14034     emit_insn (gen_fistdi2 (operands[0], operands[1]));
14035   else
14036     {
14037       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14038       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14039                                          operands[2]));
14040     }
14041   DONE;
14042 }
14043   [(set_attr "type" "fpspc")
14044    (set_attr "mode" "DI")])
14045
14046 (define_insn "fistdi2"
14047   [(set (match_operand:DI 0 "memory_operand" "=m")
14048         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14049                    UNSPEC_FIST))
14050    (clobber (match_scratch:XF 2 "=&1f"))]
14051   "TARGET_USE_FANCY_MATH_387"
14052   "* return output_fix_trunc (insn, operands, 0);"
14053   [(set_attr "type" "fpspc")
14054    (set_attr "mode" "DI")])
14055
14056 (define_insn "fistdi2_with_temp"
14057   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14058         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14059                    UNSPEC_FIST))
14060    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14061    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14062   "TARGET_USE_FANCY_MATH_387"
14063   "#"
14064   [(set_attr "type" "fpspc")
14065    (set_attr "mode" "DI")])
14066
14067 (define_split
14068   [(set (match_operand:DI 0 "register_operand" "")
14069         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14070                    UNSPEC_FIST))
14071    (clobber (match_operand:DI 2 "memory_operand" ""))
14072    (clobber (match_scratch 3 ""))]
14073   "reload_completed"
14074   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14075               (clobber (match_dup 3))])
14076    (set (match_dup 0) (match_dup 2))])
14077
14078 (define_split
14079   [(set (match_operand:DI 0 "memory_operand" "")
14080         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14081                    UNSPEC_FIST))
14082    (clobber (match_operand:DI 2 "memory_operand" ""))
14083    (clobber (match_scratch 3 ""))]
14084   "reload_completed"
14085   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14086               (clobber (match_dup 3))])])
14087
14088 (define_insn_and_split "*fist<mode>2_1"
14089   [(set (match_operand:X87MODEI12 0 "register_operand" "")
14090         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14091                            UNSPEC_FIST))]
14092   "TARGET_USE_FANCY_MATH_387
14093    && can_create_pseudo_p ()"
14094   "#"
14095   "&& 1"
14096   [(const_int 0)]
14097 {
14098   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14099   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14100                                         operands[2]));
14101   DONE;
14102 }
14103   [(set_attr "type" "fpspc")
14104    (set_attr "mode" "<MODE>")])
14105
14106 (define_insn "fist<mode>2"
14107   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14108         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14109                            UNSPEC_FIST))]
14110   "TARGET_USE_FANCY_MATH_387"
14111   "* return output_fix_trunc (insn, operands, 0);"
14112   [(set_attr "type" "fpspc")
14113    (set_attr "mode" "<MODE>")])
14114
14115 (define_insn "fist<mode>2_with_temp"
14116   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
14117         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14118                            UNSPEC_FIST))
14119    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
14120   "TARGET_USE_FANCY_MATH_387"
14121   "#"
14122   [(set_attr "type" "fpspc")
14123    (set_attr "mode" "<MODE>")])
14124
14125 (define_split
14126   [(set (match_operand:X87MODEI12 0 "register_operand" "")
14127         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14128                            UNSPEC_FIST))
14129    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14130   "reload_completed"
14131   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
14132    (set (match_dup 0) (match_dup 2))])
14133
14134 (define_split
14135   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14136         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14137                            UNSPEC_FIST))
14138    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14139   "reload_completed"
14140   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))])
14141
14142 (define_expand "lrintxf<mode>2"
14143   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14144      (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14145                       UNSPEC_FIST))]
14146   "TARGET_USE_FANCY_MATH_387"
14147   "")
14148
14149 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
14150   [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14151      (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
14152                         UNSPEC_FIX_NOTRUNC))]
14153   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14154    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
14155   "")
14156
14157 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
14158   [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14159    (match_operand:MODEF 1 "register_operand" "")]
14160   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14161    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
14162    && !flag_trapping_math && !flag_rounding_math"
14163 {
14164   if (optimize_insn_for_size_p ())
14165     FAIL;
14166   ix86_expand_lround (operand0, operand1);
14167   DONE;
14168 })
14169
14170 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14171 (define_insn_and_split "frndintxf2_floor"
14172   [(set (match_operand:XF 0 "register_operand" "")
14173         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14174          UNSPEC_FRNDINT_FLOOR))
14175    (clobber (reg:CC FLAGS_REG))]
14176   "TARGET_USE_FANCY_MATH_387
14177    && flag_unsafe_math_optimizations
14178    && can_create_pseudo_p ()"
14179   "#"
14180   "&& 1"
14181   [(const_int 0)]
14182 {
14183   ix86_optimize_mode_switching[I387_FLOOR] = 1;
14184
14185   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14186   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14187
14188   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14189                                         operands[2], operands[3]));
14190   DONE;
14191 }
14192   [(set_attr "type" "frndint")
14193    (set_attr "i387_cw" "floor")
14194    (set_attr "mode" "XF")])
14195
14196 (define_insn "frndintxf2_floor_i387"
14197   [(set (match_operand:XF 0 "register_operand" "=f")
14198         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14199          UNSPEC_FRNDINT_FLOOR))
14200    (use (match_operand:HI 2 "memory_operand" "m"))
14201    (use (match_operand:HI 3 "memory_operand" "m"))]
14202   "TARGET_USE_FANCY_MATH_387
14203    && flag_unsafe_math_optimizations"
14204   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14205   [(set_attr "type" "frndint")
14206    (set_attr "i387_cw" "floor")
14207    (set_attr "mode" "XF")])
14208
14209 (define_expand "floorxf2"
14210   [(use (match_operand:XF 0 "register_operand" ""))
14211    (use (match_operand:XF 1 "register_operand" ""))]
14212   "TARGET_USE_FANCY_MATH_387
14213    && flag_unsafe_math_optimizations"
14214 {
14215   if (optimize_insn_for_size_p ())
14216     FAIL;
14217   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14218   DONE;
14219 })
14220
14221 (define_expand "floor<mode>2"
14222   [(use (match_operand:MODEF 0 "register_operand" ""))
14223    (use (match_operand:MODEF 1 "register_operand" ""))]
14224   "(TARGET_USE_FANCY_MATH_387
14225     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14226         || TARGET_MIX_SSE_I387)
14227     && flag_unsafe_math_optimizations)
14228    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14229        && !flag_trapping_math)"
14230 {
14231   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14232       && !flag_trapping_math
14233       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14234     {
14235       if (!TARGET_ROUND && optimize_insn_for_size_p ())
14236         FAIL;
14237       if (TARGET_ROUND)
14238         emit_insn (gen_sse4_1_round<mode>2
14239                    (operands[0], operands[1], GEN_INT (0x01)));
14240       else if (TARGET_64BIT || (<MODE>mode != DFmode))
14241         ix86_expand_floorceil (operand0, operand1, true);
14242       else
14243         ix86_expand_floorceildf_32 (operand0, operand1, true);
14244     }
14245   else
14246     {
14247       rtx op0, op1;
14248
14249       if (optimize_insn_for_size_p ())
14250         FAIL;
14251
14252       op0 = gen_reg_rtx (XFmode);
14253       op1 = gen_reg_rtx (XFmode);
14254       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14255       emit_insn (gen_frndintxf2_floor (op0, op1));
14256
14257       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14258     }
14259   DONE;
14260 })
14261
14262 (define_insn_and_split "*fist<mode>2_floor_1"
14263   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14264         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14265          UNSPEC_FIST_FLOOR))
14266    (clobber (reg:CC FLAGS_REG))]
14267   "TARGET_USE_FANCY_MATH_387
14268    && flag_unsafe_math_optimizations
14269    && can_create_pseudo_p ()"
14270   "#"
14271   "&& 1"
14272   [(const_int 0)]
14273 {
14274   ix86_optimize_mode_switching[I387_FLOOR] = 1;
14275
14276   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14277   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14278   if (memory_operand (operands[0], VOIDmode))
14279     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14280                                       operands[2], operands[3]));
14281   else
14282     {
14283       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14284       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14285                                                   operands[2], operands[3],
14286                                                   operands[4]));
14287     }
14288   DONE;
14289 }
14290   [(set_attr "type" "fistp")
14291    (set_attr "i387_cw" "floor")
14292    (set_attr "mode" "<MODE>")])
14293
14294 (define_insn "fistdi2_floor"
14295   [(set (match_operand:DI 0 "memory_operand" "=m")
14296         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14297          UNSPEC_FIST_FLOOR))
14298    (use (match_operand:HI 2 "memory_operand" "m"))
14299    (use (match_operand:HI 3 "memory_operand" "m"))
14300    (clobber (match_scratch:XF 4 "=&1f"))]
14301   "TARGET_USE_FANCY_MATH_387
14302    && flag_unsafe_math_optimizations"
14303   "* return output_fix_trunc (insn, operands, 0);"
14304   [(set_attr "type" "fistp")
14305    (set_attr "i387_cw" "floor")
14306    (set_attr "mode" "DI")])
14307
14308 (define_insn "fistdi2_floor_with_temp"
14309   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14310         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14311          UNSPEC_FIST_FLOOR))
14312    (use (match_operand:HI 2 "memory_operand" "m,m"))
14313    (use (match_operand:HI 3 "memory_operand" "m,m"))
14314    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14315    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14316   "TARGET_USE_FANCY_MATH_387
14317    && flag_unsafe_math_optimizations"
14318   "#"
14319   [(set_attr "type" "fistp")
14320    (set_attr "i387_cw" "floor")
14321    (set_attr "mode" "DI")])
14322
14323 (define_split
14324   [(set (match_operand:DI 0 "register_operand" "")
14325         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14326          UNSPEC_FIST_FLOOR))
14327    (use (match_operand:HI 2 "memory_operand" ""))
14328    (use (match_operand:HI 3 "memory_operand" ""))
14329    (clobber (match_operand:DI 4 "memory_operand" ""))
14330    (clobber (match_scratch 5 ""))]
14331   "reload_completed"
14332   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14333               (use (match_dup 2))
14334               (use (match_dup 3))
14335               (clobber (match_dup 5))])
14336    (set (match_dup 0) (match_dup 4))])
14337
14338 (define_split
14339   [(set (match_operand:DI 0 "memory_operand" "")
14340         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14341          UNSPEC_FIST_FLOOR))
14342    (use (match_operand:HI 2 "memory_operand" ""))
14343    (use (match_operand:HI 3 "memory_operand" ""))
14344    (clobber (match_operand:DI 4 "memory_operand" ""))
14345    (clobber (match_scratch 5 ""))]
14346   "reload_completed"
14347   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14348               (use (match_dup 2))
14349               (use (match_dup 3))
14350               (clobber (match_dup 5))])])
14351
14352 (define_insn "fist<mode>2_floor"
14353   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14354         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14355          UNSPEC_FIST_FLOOR))
14356    (use (match_operand:HI 2 "memory_operand" "m"))
14357    (use (match_operand:HI 3 "memory_operand" "m"))]
14358   "TARGET_USE_FANCY_MATH_387
14359    && flag_unsafe_math_optimizations"
14360   "* return output_fix_trunc (insn, operands, 0);"
14361   [(set_attr "type" "fistp")
14362    (set_attr "i387_cw" "floor")
14363    (set_attr "mode" "<MODE>")])
14364
14365 (define_insn "fist<mode>2_floor_with_temp"
14366   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
14367         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
14368          UNSPEC_FIST_FLOOR))
14369    (use (match_operand:HI 2 "memory_operand" "m,m"))
14370    (use (match_operand:HI 3 "memory_operand" "m,m"))
14371    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
14372   "TARGET_USE_FANCY_MATH_387
14373    && flag_unsafe_math_optimizations"
14374   "#"
14375   [(set_attr "type" "fistp")
14376    (set_attr "i387_cw" "floor")
14377    (set_attr "mode" "<MODE>")])
14378
14379 (define_split
14380   [(set (match_operand:X87MODEI12 0 "register_operand" "")
14381         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14382          UNSPEC_FIST_FLOOR))
14383    (use (match_operand:HI 2 "memory_operand" ""))
14384    (use (match_operand:HI 3 "memory_operand" ""))
14385    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14386   "reload_completed"
14387   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
14388                                   UNSPEC_FIST_FLOOR))
14389               (use (match_dup 2))
14390               (use (match_dup 3))])
14391    (set (match_dup 0) (match_dup 4))])
14392
14393 (define_split
14394   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14395         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14396          UNSPEC_FIST_FLOOR))
14397    (use (match_operand:HI 2 "memory_operand" ""))
14398    (use (match_operand:HI 3 "memory_operand" ""))
14399    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14400   "reload_completed"
14401   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
14402                                   UNSPEC_FIST_FLOOR))
14403               (use (match_dup 2))
14404               (use (match_dup 3))])])
14405
14406 (define_expand "lfloorxf<mode>2"
14407   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14408                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14409                     UNSPEC_FIST_FLOOR))
14410               (clobber (reg:CC FLAGS_REG))])]
14411   "TARGET_USE_FANCY_MATH_387
14412    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14413    && flag_unsafe_math_optimizations"
14414   "")
14415
14416 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
14417   [(match_operand:SWI48 0 "nonimmediate_operand" "")
14418    (match_operand:MODEF 1 "register_operand" "")]
14419   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14420    && !flag_trapping_math"
14421 {
14422   if (TARGET_64BIT && optimize_insn_for_size_p ())
14423     FAIL;
14424   ix86_expand_lfloorceil (operand0, operand1, true);
14425   DONE;
14426 })
14427
14428 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14429 (define_insn_and_split "frndintxf2_ceil"
14430   [(set (match_operand:XF 0 "register_operand" "")
14431         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14432          UNSPEC_FRNDINT_CEIL))
14433    (clobber (reg:CC FLAGS_REG))]
14434   "TARGET_USE_FANCY_MATH_387
14435    && flag_unsafe_math_optimizations
14436    && can_create_pseudo_p ()"
14437   "#"
14438   "&& 1"
14439   [(const_int 0)]
14440 {
14441   ix86_optimize_mode_switching[I387_CEIL] = 1;
14442
14443   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14444   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14445
14446   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
14447                                        operands[2], operands[3]));
14448   DONE;
14449 }
14450   [(set_attr "type" "frndint")
14451    (set_attr "i387_cw" "ceil")
14452    (set_attr "mode" "XF")])
14453
14454 (define_insn "frndintxf2_ceil_i387"
14455   [(set (match_operand:XF 0 "register_operand" "=f")
14456         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14457          UNSPEC_FRNDINT_CEIL))
14458    (use (match_operand:HI 2 "memory_operand" "m"))
14459    (use (match_operand:HI 3 "memory_operand" "m"))]
14460   "TARGET_USE_FANCY_MATH_387
14461    && flag_unsafe_math_optimizations"
14462   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14463   [(set_attr "type" "frndint")
14464    (set_attr "i387_cw" "ceil")
14465    (set_attr "mode" "XF")])
14466
14467 (define_expand "ceilxf2"
14468   [(use (match_operand:XF 0 "register_operand" ""))
14469    (use (match_operand:XF 1 "register_operand" ""))]
14470   "TARGET_USE_FANCY_MATH_387
14471    && flag_unsafe_math_optimizations"
14472 {
14473   if (optimize_insn_for_size_p ())
14474     FAIL;
14475   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
14476   DONE;
14477 })
14478
14479 (define_expand "ceil<mode>2"
14480   [(use (match_operand:MODEF 0 "register_operand" ""))
14481    (use (match_operand:MODEF 1 "register_operand" ""))]
14482   "(TARGET_USE_FANCY_MATH_387
14483     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14484         || TARGET_MIX_SSE_I387)
14485     && flag_unsafe_math_optimizations)
14486    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14487        && !flag_trapping_math)"
14488 {
14489   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14490       && !flag_trapping_math
14491       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14492     {
14493       if (TARGET_ROUND)
14494         emit_insn (gen_sse4_1_round<mode>2
14495                    (operands[0], operands[1], GEN_INT (0x02)));
14496       else if (optimize_insn_for_size_p ())
14497         FAIL;
14498       else if (TARGET_64BIT || (<MODE>mode != DFmode))
14499         ix86_expand_floorceil (operand0, operand1, false);
14500       else
14501         ix86_expand_floorceildf_32 (operand0, operand1, false);
14502     }
14503   else
14504     {
14505       rtx op0, op1;
14506
14507       if (optimize_insn_for_size_p ())
14508         FAIL;
14509
14510       op0 = gen_reg_rtx (XFmode);
14511       op1 = gen_reg_rtx (XFmode);
14512       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14513       emit_insn (gen_frndintxf2_ceil (op0, op1));
14514
14515       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14516     }
14517   DONE;
14518 })
14519
14520 (define_insn_and_split "*fist<mode>2_ceil_1"
14521   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14522         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14523          UNSPEC_FIST_CEIL))
14524    (clobber (reg:CC FLAGS_REG))]
14525   "TARGET_USE_FANCY_MATH_387
14526    && flag_unsafe_math_optimizations
14527    && can_create_pseudo_p ()"
14528   "#"
14529   "&& 1"
14530   [(const_int 0)]
14531 {
14532   ix86_optimize_mode_switching[I387_CEIL] = 1;
14533
14534   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14535   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14536   if (memory_operand (operands[0], VOIDmode))
14537     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
14538                                      operands[2], operands[3]));
14539   else
14540     {
14541       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14542       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
14543                                                  operands[2], operands[3],
14544                                                  operands[4]));
14545     }
14546   DONE;
14547 }
14548   [(set_attr "type" "fistp")
14549    (set_attr "i387_cw" "ceil")
14550    (set_attr "mode" "<MODE>")])
14551
14552 (define_insn "fistdi2_ceil"
14553   [(set (match_operand:DI 0 "memory_operand" "=m")
14554         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14555          UNSPEC_FIST_CEIL))
14556    (use (match_operand:HI 2 "memory_operand" "m"))
14557    (use (match_operand:HI 3 "memory_operand" "m"))
14558    (clobber (match_scratch:XF 4 "=&1f"))]
14559   "TARGET_USE_FANCY_MATH_387
14560    && flag_unsafe_math_optimizations"
14561   "* return output_fix_trunc (insn, operands, 0);"
14562   [(set_attr "type" "fistp")
14563    (set_attr "i387_cw" "ceil")
14564    (set_attr "mode" "DI")])
14565
14566 (define_insn "fistdi2_ceil_with_temp"
14567   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14568         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14569          UNSPEC_FIST_CEIL))
14570    (use (match_operand:HI 2 "memory_operand" "m,m"))
14571    (use (match_operand:HI 3 "memory_operand" "m,m"))
14572    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14573    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14574   "TARGET_USE_FANCY_MATH_387
14575    && flag_unsafe_math_optimizations"
14576   "#"
14577   [(set_attr "type" "fistp")
14578    (set_attr "i387_cw" "ceil")
14579    (set_attr "mode" "DI")])
14580
14581 (define_split
14582   [(set (match_operand:DI 0 "register_operand" "")
14583         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14584          UNSPEC_FIST_CEIL))
14585    (use (match_operand:HI 2 "memory_operand" ""))
14586    (use (match_operand:HI 3 "memory_operand" ""))
14587    (clobber (match_operand:DI 4 "memory_operand" ""))
14588    (clobber (match_scratch 5 ""))]
14589   "reload_completed"
14590   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
14591               (use (match_dup 2))
14592               (use (match_dup 3))
14593               (clobber (match_dup 5))])
14594    (set (match_dup 0) (match_dup 4))])
14595
14596 (define_split
14597   [(set (match_operand:DI 0 "memory_operand" "")
14598         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14599          UNSPEC_FIST_CEIL))
14600    (use (match_operand:HI 2 "memory_operand" ""))
14601    (use (match_operand:HI 3 "memory_operand" ""))
14602    (clobber (match_operand:DI 4 "memory_operand" ""))
14603    (clobber (match_scratch 5 ""))]
14604   "reload_completed"
14605   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
14606               (use (match_dup 2))
14607               (use (match_dup 3))
14608               (clobber (match_dup 5))])])
14609
14610 (define_insn "fist<mode>2_ceil"
14611   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14612         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14613          UNSPEC_FIST_CEIL))
14614    (use (match_operand:HI 2 "memory_operand" "m"))
14615    (use (match_operand:HI 3 "memory_operand" "m"))]
14616   "TARGET_USE_FANCY_MATH_387
14617    && flag_unsafe_math_optimizations"
14618   "* return output_fix_trunc (insn, operands, 0);"
14619   [(set_attr "type" "fistp")
14620    (set_attr "i387_cw" "ceil")
14621    (set_attr "mode" "<MODE>")])
14622
14623 (define_insn "fist<mode>2_ceil_with_temp"
14624   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
14625         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
14626          UNSPEC_FIST_CEIL))
14627    (use (match_operand:HI 2 "memory_operand" "m,m"))
14628    (use (match_operand:HI 3 "memory_operand" "m,m"))
14629    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
14630   "TARGET_USE_FANCY_MATH_387
14631    && flag_unsafe_math_optimizations"
14632   "#"
14633   [(set_attr "type" "fistp")
14634    (set_attr "i387_cw" "ceil")
14635    (set_attr "mode" "<MODE>")])
14636
14637 (define_split
14638   [(set (match_operand:X87MODEI12 0 "register_operand" "")
14639         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14640          UNSPEC_FIST_CEIL))
14641    (use (match_operand:HI 2 "memory_operand" ""))
14642    (use (match_operand:HI 3 "memory_operand" ""))
14643    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14644   "reload_completed"
14645   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
14646                                   UNSPEC_FIST_CEIL))
14647               (use (match_dup 2))
14648               (use (match_dup 3))])
14649    (set (match_dup 0) (match_dup 4))])
14650
14651 (define_split
14652   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14653         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14654          UNSPEC_FIST_CEIL))
14655    (use (match_operand:HI 2 "memory_operand" ""))
14656    (use (match_operand:HI 3 "memory_operand" ""))
14657    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14658   "reload_completed"
14659   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
14660                                   UNSPEC_FIST_CEIL))
14661               (use (match_dup 2))
14662               (use (match_dup 3))])])
14663
14664 (define_expand "lceilxf<mode>2"
14665   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14666                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14667                     UNSPEC_FIST_CEIL))
14668               (clobber (reg:CC FLAGS_REG))])]
14669   "TARGET_USE_FANCY_MATH_387
14670    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14671    && flag_unsafe_math_optimizations"
14672   "")
14673
14674 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
14675   [(match_operand:SWI48 0 "nonimmediate_operand" "")
14676    (match_operand:MODEF 1 "register_operand" "")]
14677   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14678    && !flag_trapping_math"
14679 {
14680   ix86_expand_lfloorceil (operand0, operand1, false);
14681   DONE;
14682 })
14683
14684 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14685 (define_insn_and_split "frndintxf2_trunc"
14686   [(set (match_operand:XF 0 "register_operand" "")
14687         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14688          UNSPEC_FRNDINT_TRUNC))
14689    (clobber (reg:CC FLAGS_REG))]
14690   "TARGET_USE_FANCY_MATH_387
14691    && flag_unsafe_math_optimizations
14692    && can_create_pseudo_p ()"
14693   "#"
14694   "&& 1"
14695   [(const_int 0)]
14696 {
14697   ix86_optimize_mode_switching[I387_TRUNC] = 1;
14698
14699   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14700   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
14701
14702   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
14703                                         operands[2], operands[3]));
14704   DONE;
14705 }
14706   [(set_attr "type" "frndint")
14707    (set_attr "i387_cw" "trunc")
14708    (set_attr "mode" "XF")])
14709
14710 (define_insn "frndintxf2_trunc_i387"
14711   [(set (match_operand:XF 0 "register_operand" "=f")
14712         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14713          UNSPEC_FRNDINT_TRUNC))
14714    (use (match_operand:HI 2 "memory_operand" "m"))
14715    (use (match_operand:HI 3 "memory_operand" "m"))]
14716   "TARGET_USE_FANCY_MATH_387
14717    && flag_unsafe_math_optimizations"
14718   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14719   [(set_attr "type" "frndint")
14720    (set_attr "i387_cw" "trunc")
14721    (set_attr "mode" "XF")])
14722
14723 (define_expand "btruncxf2"
14724   [(use (match_operand:XF 0 "register_operand" ""))
14725    (use (match_operand:XF 1 "register_operand" ""))]
14726   "TARGET_USE_FANCY_MATH_387
14727    && flag_unsafe_math_optimizations"
14728 {
14729   if (optimize_insn_for_size_p ())
14730     FAIL;
14731   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
14732   DONE;
14733 })
14734
14735 (define_expand "btrunc<mode>2"
14736   [(use (match_operand:MODEF 0 "register_operand" ""))
14737    (use (match_operand:MODEF 1 "register_operand" ""))]
14738   "(TARGET_USE_FANCY_MATH_387
14739     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14740         || TARGET_MIX_SSE_I387)
14741     && flag_unsafe_math_optimizations)
14742    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14743        && !flag_trapping_math)"
14744 {
14745   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14746       && !flag_trapping_math
14747       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14748     {
14749       if (TARGET_ROUND)
14750         emit_insn (gen_sse4_1_round<mode>2
14751                    (operands[0], operands[1], GEN_INT (0x03)));
14752       else if (optimize_insn_for_size_p ())
14753         FAIL;
14754       else if (TARGET_64BIT || (<MODE>mode != DFmode))
14755         ix86_expand_trunc (operand0, operand1);
14756       else
14757         ix86_expand_truncdf_32 (operand0, operand1);
14758     }
14759   else
14760     {
14761       rtx op0, op1;
14762
14763       if (optimize_insn_for_size_p ())
14764         FAIL;
14765
14766       op0 = gen_reg_rtx (XFmode);
14767       op1 = gen_reg_rtx (XFmode);
14768       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14769       emit_insn (gen_frndintxf2_trunc (op0, op1));
14770
14771       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14772     }
14773   DONE;
14774 })
14775
14776 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14777 (define_insn_and_split "frndintxf2_mask_pm"
14778   [(set (match_operand:XF 0 "register_operand" "")
14779         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14780          UNSPEC_FRNDINT_MASK_PM))
14781    (clobber (reg:CC FLAGS_REG))]
14782   "TARGET_USE_FANCY_MATH_387
14783    && flag_unsafe_math_optimizations
14784    && can_create_pseudo_p ()"
14785   "#"
14786   "&& 1"
14787   [(const_int 0)]
14788 {
14789   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
14790
14791   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14792   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
14793
14794   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
14795                                           operands[2], operands[3]));
14796   DONE;
14797 }
14798   [(set_attr "type" "frndint")
14799    (set_attr "i387_cw" "mask_pm")
14800    (set_attr "mode" "XF")])
14801
14802 (define_insn "frndintxf2_mask_pm_i387"
14803   [(set (match_operand:XF 0 "register_operand" "=f")
14804         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14805          UNSPEC_FRNDINT_MASK_PM))
14806    (use (match_operand:HI 2 "memory_operand" "m"))
14807    (use (match_operand:HI 3 "memory_operand" "m"))]
14808   "TARGET_USE_FANCY_MATH_387
14809    && flag_unsafe_math_optimizations"
14810   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
14811   [(set_attr "type" "frndint")
14812    (set_attr "i387_cw" "mask_pm")
14813    (set_attr "mode" "XF")])
14814
14815 (define_expand "nearbyintxf2"
14816   [(use (match_operand:XF 0 "register_operand" ""))
14817    (use (match_operand:XF 1 "register_operand" ""))]
14818   "TARGET_USE_FANCY_MATH_387
14819    && flag_unsafe_math_optimizations"
14820 {
14821   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
14822
14823   DONE;
14824 })
14825
14826 (define_expand "nearbyint<mode>2"
14827   [(use (match_operand:MODEF 0 "register_operand" ""))
14828    (use (match_operand:MODEF 1 "register_operand" ""))]
14829   "TARGET_USE_FANCY_MATH_387
14830    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14831        || TARGET_MIX_SSE_I387)
14832    && flag_unsafe_math_optimizations"
14833 {
14834   rtx op0 = gen_reg_rtx (XFmode);
14835   rtx op1 = gen_reg_rtx (XFmode);
14836
14837   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14838   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
14839
14840   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14841   DONE;
14842 })
14843
14844 (define_insn "fxam<mode>2_i387"
14845   [(set (match_operand:HI 0 "register_operand" "=a")
14846         (unspec:HI
14847           [(match_operand:X87MODEF 1 "register_operand" "f")]
14848           UNSPEC_FXAM))]
14849   "TARGET_USE_FANCY_MATH_387"
14850   "fxam\n\tfnstsw\t%0"
14851   [(set_attr "type" "multi")
14852    (set_attr "length" "4")
14853    (set_attr "unit" "i387")
14854    (set_attr "mode" "<MODE>")])
14855
14856 (define_insn_and_split "fxam<mode>2_i387_with_temp"
14857   [(set (match_operand:HI 0 "register_operand" "")
14858         (unspec:HI
14859           [(match_operand:MODEF 1 "memory_operand" "")]
14860           UNSPEC_FXAM_MEM))]
14861   "TARGET_USE_FANCY_MATH_387
14862    && can_create_pseudo_p ()"
14863   "#"
14864   "&& 1"
14865   [(set (match_dup 2)(match_dup 1))
14866    (set (match_dup 0)
14867         (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
14868 {
14869   operands[2] = gen_reg_rtx (<MODE>mode);
14870
14871   MEM_VOLATILE_P (operands[1]) = 1;
14872 }
14873   [(set_attr "type" "multi")
14874    (set_attr "unit" "i387")
14875    (set_attr "mode" "<MODE>")])
14876
14877 (define_expand "isinfxf2"
14878   [(use (match_operand:SI 0 "register_operand" ""))
14879    (use (match_operand:XF 1 "register_operand" ""))]
14880   "TARGET_USE_FANCY_MATH_387
14881    && TARGET_C99_FUNCTIONS"
14882 {
14883   rtx mask = GEN_INT (0x45);
14884   rtx val = GEN_INT (0x05);
14885
14886   rtx cond;
14887
14888   rtx scratch = gen_reg_rtx (HImode);
14889   rtx res = gen_reg_rtx (QImode);
14890
14891   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
14892
14893   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
14894   emit_insn (gen_cmpqi_ext_3 (scratch, val));
14895   cond = gen_rtx_fmt_ee (EQ, QImode,
14896                          gen_rtx_REG (CCmode, FLAGS_REG),
14897                          const0_rtx);
14898   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
14899   emit_insn (gen_zero_extendqisi2 (operands[0], res));
14900   DONE;
14901 })
14902
14903 (define_expand "isinf<mode>2"
14904   [(use (match_operand:SI 0 "register_operand" ""))
14905    (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
14906   "TARGET_USE_FANCY_MATH_387
14907    && TARGET_C99_FUNCTIONS
14908    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
14909 {
14910   rtx mask = GEN_INT (0x45);
14911   rtx val = GEN_INT (0x05);
14912
14913   rtx cond;
14914
14915   rtx scratch = gen_reg_rtx (HImode);
14916   rtx res = gen_reg_rtx (QImode);
14917
14918   /* Remove excess precision by forcing value through memory. */
14919   if (memory_operand (operands[1], VOIDmode))
14920     emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
14921   else
14922     {
14923       enum ix86_stack_slot slot = (virtuals_instantiated
14924                                    ? SLOT_TEMP
14925                                    : SLOT_VIRTUAL);
14926       rtx temp = assign_386_stack_local (<MODE>mode, slot);
14927
14928       emit_move_insn (temp, operands[1]);
14929       emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
14930     }
14931
14932   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
14933   emit_insn (gen_cmpqi_ext_3 (scratch, val));
14934   cond = gen_rtx_fmt_ee (EQ, QImode,
14935                          gen_rtx_REG (CCmode, FLAGS_REG),
14936                          const0_rtx);
14937   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
14938   emit_insn (gen_zero_extendqisi2 (operands[0], res));
14939   DONE;
14940 })
14941
14942 (define_expand "signbit<mode>2"
14943   [(use (match_operand:SI 0 "register_operand" ""))
14944    (use (match_operand:X87MODEF 1 "register_operand" ""))]
14945   "TARGET_USE_FANCY_MATH_387
14946    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
14947 {
14948   rtx mask = GEN_INT (0x0200);
14949
14950   rtx scratch = gen_reg_rtx (HImode);
14951
14952   emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
14953   emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
14954   DONE;
14955 })
14956 \f
14957 ;; Block operation instructions
14958
14959 (define_insn "cld"
14960   [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
14961   ""
14962   "cld"
14963   [(set_attr "length" "1")
14964    (set_attr "length_immediate" "0")
14965    (set_attr "modrm" "0")])
14966
14967 (define_expand "movmemsi"
14968   [(use (match_operand:BLK 0 "memory_operand" ""))
14969    (use (match_operand:BLK 1 "memory_operand" ""))
14970    (use (match_operand:SI 2 "nonmemory_operand" ""))
14971    (use (match_operand:SI 3 "const_int_operand" ""))
14972    (use (match_operand:SI 4 "const_int_operand" ""))
14973    (use (match_operand:SI 5 "const_int_operand" ""))]
14974   ""
14975 {
14976  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
14977                          operands[4], operands[5]))
14978    DONE;
14979  else
14980    FAIL;
14981 })
14982
14983 (define_expand "movmemdi"
14984   [(use (match_operand:BLK 0 "memory_operand" ""))
14985    (use (match_operand:BLK 1 "memory_operand" ""))
14986    (use (match_operand:DI 2 "nonmemory_operand" ""))
14987    (use (match_operand:DI 3 "const_int_operand" ""))
14988    (use (match_operand:SI 4 "const_int_operand" ""))
14989    (use (match_operand:SI 5 "const_int_operand" ""))]
14990   "TARGET_64BIT"
14991 {
14992  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
14993                          operands[4], operands[5]))
14994    DONE;
14995  else
14996    FAIL;
14997 })
14998
14999 ;; Most CPUs don't like single string operations
15000 ;; Handle this case here to simplify previous expander.
15001
15002 (define_expand "strmov"
15003   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15004    (set (match_operand 1 "memory_operand" "") (match_dup 4))
15005    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15006               (clobber (reg:CC FLAGS_REG))])
15007    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15008               (clobber (reg:CC FLAGS_REG))])]
15009   ""
15010 {
15011   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15012
15013   /* If .md ever supports :P for Pmode, these can be directly
15014      in the pattern above.  */
15015   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15016   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15017
15018   /* Can't use this if the user has appropriated esi or edi.  */
15019   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15020       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15021     {
15022       emit_insn (gen_strmov_singleop (operands[0], operands[1],
15023                                       operands[2], operands[3],
15024                                       operands[5], operands[6]));
15025       DONE;
15026     }
15027
15028   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15029 })
15030
15031 (define_expand "strmov_singleop"
15032   [(parallel [(set (match_operand 1 "memory_operand" "")
15033                    (match_operand 3 "memory_operand" ""))
15034               (set (match_operand 0 "register_operand" "")
15035                    (match_operand 4 "" ""))
15036               (set (match_operand 2 "register_operand" "")
15037                    (match_operand 5 "" ""))])]
15038   ""
15039   "ix86_current_function_needs_cld = 1;")
15040
15041 (define_insn "*strmovdi_rex_1"
15042   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15043         (mem:DI (match_operand:DI 3 "register_operand" "1")))
15044    (set (match_operand:DI 0 "register_operand" "=D")
15045         (plus:DI (match_dup 2)
15046                  (const_int 8)))
15047    (set (match_operand:DI 1 "register_operand" "=S")
15048         (plus:DI (match_dup 3)
15049                  (const_int 8)))]
15050   "TARGET_64BIT"
15051   "movsq"
15052   [(set_attr "type" "str")
15053    (set_attr "mode" "DI")
15054    (set_attr "memory" "both")])
15055
15056 (define_insn "*strmovsi_1"
15057   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
15058         (mem:SI (match_operand:SI 3 "register_operand" "1")))
15059    (set (match_operand:SI 0 "register_operand" "=D")
15060         (plus:SI (match_dup 2)
15061                  (const_int 4)))
15062    (set (match_operand:SI 1 "register_operand" "=S")
15063         (plus:SI (match_dup 3)
15064                  (const_int 4)))]
15065   "!TARGET_64BIT"
15066   "movs{l|d}"
15067   [(set_attr "type" "str")
15068    (set_attr "mode" "SI")
15069    (set_attr "memory" "both")])
15070
15071 (define_insn "*strmovsi_rex_1"
15072   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
15073         (mem:SI (match_operand:DI 3 "register_operand" "1")))
15074    (set (match_operand:DI 0 "register_operand" "=D")
15075         (plus:DI (match_dup 2)
15076                  (const_int 4)))
15077    (set (match_operand:DI 1 "register_operand" "=S")
15078         (plus:DI (match_dup 3)
15079                  (const_int 4)))]
15080   "TARGET_64BIT"
15081   "movs{l|d}"
15082   [(set_attr "type" "str")
15083    (set_attr "mode" "SI")
15084    (set_attr "memory" "both")])
15085
15086 (define_insn "*strmovhi_1"
15087   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
15088         (mem:HI (match_operand:SI 3 "register_operand" "1")))
15089    (set (match_operand:SI 0 "register_operand" "=D")
15090         (plus:SI (match_dup 2)
15091                  (const_int 2)))
15092    (set (match_operand:SI 1 "register_operand" "=S")
15093         (plus:SI (match_dup 3)
15094                  (const_int 2)))]
15095   "!TARGET_64BIT"
15096   "movsw"
15097   [(set_attr "type" "str")
15098    (set_attr "memory" "both")
15099    (set_attr "mode" "HI")])
15100
15101 (define_insn "*strmovhi_rex_1"
15102   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
15103         (mem:HI (match_operand:DI 3 "register_operand" "1")))
15104    (set (match_operand:DI 0 "register_operand" "=D")
15105         (plus:DI (match_dup 2)
15106                  (const_int 2)))
15107    (set (match_operand:DI 1 "register_operand" "=S")
15108         (plus:DI (match_dup 3)
15109                  (const_int 2)))]
15110   "TARGET_64BIT"
15111   "movsw"
15112   [(set_attr "type" "str")
15113    (set_attr "memory" "both")
15114    (set_attr "mode" "HI")])
15115
15116 (define_insn "*strmovqi_1"
15117   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
15118         (mem:QI (match_operand:SI 3 "register_operand" "1")))
15119    (set (match_operand:SI 0 "register_operand" "=D")
15120         (plus:SI (match_dup 2)
15121                  (const_int 1)))
15122    (set (match_operand:SI 1 "register_operand" "=S")
15123         (plus:SI (match_dup 3)
15124                  (const_int 1)))]
15125   "!TARGET_64BIT"
15126   "movsb"
15127   [(set_attr "type" "str")
15128    (set_attr "memory" "both")
15129    (set_attr "mode" "QI")])
15130
15131 (define_insn "*strmovqi_rex_1"
15132   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
15133         (mem:QI (match_operand:DI 3 "register_operand" "1")))
15134    (set (match_operand:DI 0 "register_operand" "=D")
15135         (plus:DI (match_dup 2)
15136                  (const_int 1)))
15137    (set (match_operand:DI 1 "register_operand" "=S")
15138         (plus:DI (match_dup 3)
15139                  (const_int 1)))]
15140   "TARGET_64BIT"
15141   "movsb"
15142   [(set_attr "type" "str")
15143    (set_attr "memory" "both")
15144    (set_attr "prefix_rex" "0")
15145    (set_attr "mode" "QI")])
15146
15147 (define_expand "rep_mov"
15148   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15149               (set (match_operand 0 "register_operand" "")
15150                    (match_operand 5 "" ""))
15151               (set (match_operand 2 "register_operand" "")
15152                    (match_operand 6 "" ""))
15153               (set (match_operand 1 "memory_operand" "")
15154                    (match_operand 3 "memory_operand" ""))
15155               (use (match_dup 4))])]
15156   ""
15157   "ix86_current_function_needs_cld = 1;")
15158
15159 (define_insn "*rep_movdi_rex64"
15160   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15161    (set (match_operand:DI 0 "register_operand" "=D")
15162         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15163                             (const_int 3))
15164                  (match_operand:DI 3 "register_operand" "0")))
15165    (set (match_operand:DI 1 "register_operand" "=S")
15166         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15167                  (match_operand:DI 4 "register_operand" "1")))
15168    (set (mem:BLK (match_dup 3))
15169         (mem:BLK (match_dup 4)))
15170    (use (match_dup 5))]
15171   "TARGET_64BIT"
15172   "rep{%;} movsq"
15173   [(set_attr "type" "str")
15174    (set_attr "prefix_rep" "1")
15175    (set_attr "memory" "both")
15176    (set_attr "mode" "DI")])
15177
15178 (define_insn "*rep_movsi"
15179   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
15180    (set (match_operand:SI 0 "register_operand" "=D")
15181         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
15182                             (const_int 2))
15183                  (match_operand:SI 3 "register_operand" "0")))
15184    (set (match_operand:SI 1 "register_operand" "=S")
15185         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
15186                  (match_operand:SI 4 "register_operand" "1")))
15187    (set (mem:BLK (match_dup 3))
15188         (mem:BLK (match_dup 4)))
15189    (use (match_dup 5))]
15190   "!TARGET_64BIT"
15191   "rep{%;} movs{l|d}"
15192   [(set_attr "type" "str")
15193    (set_attr "prefix_rep" "1")
15194    (set_attr "memory" "both")
15195    (set_attr "mode" "SI")])
15196
15197 (define_insn "*rep_movsi_rex64"
15198   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15199    (set (match_operand:DI 0 "register_operand" "=D")
15200         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15201                             (const_int 2))
15202                  (match_operand:DI 3 "register_operand" "0")))
15203    (set (match_operand:DI 1 "register_operand" "=S")
15204         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
15205                  (match_operand:DI 4 "register_operand" "1")))
15206    (set (mem:BLK (match_dup 3))
15207         (mem:BLK (match_dup 4)))
15208    (use (match_dup 5))]
15209   "TARGET_64BIT"
15210   "rep{%;} movs{l|d}"
15211   [(set_attr "type" "str")
15212    (set_attr "prefix_rep" "1")
15213    (set_attr "memory" "both")
15214    (set_attr "mode" "SI")])
15215
15216 (define_insn "*rep_movqi"
15217   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
15218    (set (match_operand:SI 0 "register_operand" "=D")
15219         (plus:SI (match_operand:SI 3 "register_operand" "0")
15220                  (match_operand:SI 5 "register_operand" "2")))
15221    (set (match_operand:SI 1 "register_operand" "=S")
15222         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
15223    (set (mem:BLK (match_dup 3))
15224         (mem:BLK (match_dup 4)))
15225    (use (match_dup 5))]
15226   "!TARGET_64BIT"
15227   "rep{%;} movsb"
15228   [(set_attr "type" "str")
15229    (set_attr "prefix_rep" "1")
15230    (set_attr "memory" "both")
15231    (set_attr "mode" "SI")])
15232
15233 (define_insn "*rep_movqi_rex64"
15234   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15235    (set (match_operand:DI 0 "register_operand" "=D")
15236         (plus:DI (match_operand:DI 3 "register_operand" "0")
15237                  (match_operand:DI 5 "register_operand" "2")))
15238    (set (match_operand:DI 1 "register_operand" "=S")
15239         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
15240    (set (mem:BLK (match_dup 3))
15241         (mem:BLK (match_dup 4)))
15242    (use (match_dup 5))]
15243   "TARGET_64BIT"
15244   "rep{%;} movsb"
15245   [(set_attr "type" "str")
15246    (set_attr "prefix_rep" "1")
15247    (set_attr "memory" "both")
15248    (set_attr "mode" "SI")])
15249
15250 (define_expand "setmemsi"
15251    [(use (match_operand:BLK 0 "memory_operand" ""))
15252     (use (match_operand:SI 1 "nonmemory_operand" ""))
15253     (use (match_operand 2 "const_int_operand" ""))
15254     (use (match_operand 3 "const_int_operand" ""))
15255     (use (match_operand:SI 4 "const_int_operand" ""))
15256     (use (match_operand:SI 5 "const_int_operand" ""))]
15257   ""
15258 {
15259  if (ix86_expand_setmem (operands[0], operands[1],
15260                          operands[2], operands[3],
15261                          operands[4], operands[5]))
15262    DONE;
15263  else
15264    FAIL;
15265 })
15266
15267 (define_expand "setmemdi"
15268    [(use (match_operand:BLK 0 "memory_operand" ""))
15269     (use (match_operand:DI 1 "nonmemory_operand" ""))
15270     (use (match_operand 2 "const_int_operand" ""))
15271     (use (match_operand 3 "const_int_operand" ""))
15272     (use (match_operand 4 "const_int_operand" ""))
15273     (use (match_operand 5 "const_int_operand" ""))]
15274   "TARGET_64BIT"
15275 {
15276  if (ix86_expand_setmem (operands[0], operands[1],
15277                          operands[2], operands[3],
15278                          operands[4], operands[5]))
15279    DONE;
15280  else
15281    FAIL;
15282 })
15283
15284 ;; Most CPUs don't like single string operations
15285 ;; Handle this case here to simplify previous expander.
15286
15287 (define_expand "strset"
15288   [(set (match_operand 1 "memory_operand" "")
15289         (match_operand 2 "register_operand" ""))
15290    (parallel [(set (match_operand 0 "register_operand" "")
15291                    (match_dup 3))
15292               (clobber (reg:CC FLAGS_REG))])]
15293   ""
15294 {
15295   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15296     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15297
15298   /* If .md ever supports :P for Pmode, this can be directly
15299      in the pattern above.  */
15300   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15301                               GEN_INT (GET_MODE_SIZE (GET_MODE
15302                                                       (operands[2]))));
15303   if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15304     {
15305       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15306                                       operands[3]));
15307       DONE;
15308     }
15309 })
15310
15311 (define_expand "strset_singleop"
15312   [(parallel [(set (match_operand 1 "memory_operand" "")
15313                    (match_operand 2 "register_operand" ""))
15314               (set (match_operand 0 "register_operand" "")
15315                    (match_operand 3 "" ""))])]
15316   ""
15317   "ix86_current_function_needs_cld = 1;")
15318
15319 (define_insn "*strsetdi_rex_1"
15320   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
15321         (match_operand:DI 2 "register_operand" "a"))
15322    (set (match_operand:DI 0 "register_operand" "=D")
15323         (plus:DI (match_dup 1)
15324                  (const_int 8)))]
15325   "TARGET_64BIT"
15326   "stosq"
15327   [(set_attr "type" "str")
15328    (set_attr "memory" "store")
15329    (set_attr "mode" "DI")])
15330
15331 (define_insn "*strsetsi_1"
15332   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
15333         (match_operand:SI 2 "register_operand" "a"))
15334    (set (match_operand:SI 0 "register_operand" "=D")
15335         (plus:SI (match_dup 1)
15336                  (const_int 4)))]
15337   "!TARGET_64BIT"
15338   "stos{l|d}"
15339   [(set_attr "type" "str")
15340    (set_attr "memory" "store")
15341    (set_attr "mode" "SI")])
15342
15343 (define_insn "*strsetsi_rex_1"
15344   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
15345         (match_operand:SI 2 "register_operand" "a"))
15346    (set (match_operand:DI 0 "register_operand" "=D")
15347         (plus:DI (match_dup 1)
15348                  (const_int 4)))]
15349   "TARGET_64BIT"
15350   "stos{l|d}"
15351   [(set_attr "type" "str")
15352    (set_attr "memory" "store")
15353    (set_attr "mode" "SI")])
15354
15355 (define_insn "*strsethi_1"
15356   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
15357         (match_operand:HI 2 "register_operand" "a"))
15358    (set (match_operand:SI 0 "register_operand" "=D")
15359         (plus:SI (match_dup 1)
15360                  (const_int 2)))]
15361   "!TARGET_64BIT"
15362   "stosw"
15363   [(set_attr "type" "str")
15364    (set_attr "memory" "store")
15365    (set_attr "mode" "HI")])
15366
15367 (define_insn "*strsethi_rex_1"
15368   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
15369         (match_operand:HI 2 "register_operand" "a"))
15370    (set (match_operand:DI 0 "register_operand" "=D")
15371         (plus:DI (match_dup 1)
15372                  (const_int 2)))]
15373   "TARGET_64BIT"
15374   "stosw"
15375   [(set_attr "type" "str")
15376    (set_attr "memory" "store")
15377    (set_attr "mode" "HI")])
15378
15379 (define_insn "*strsetqi_1"
15380   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
15381         (match_operand:QI 2 "register_operand" "a"))
15382    (set (match_operand:SI 0 "register_operand" "=D")
15383         (plus:SI (match_dup 1)
15384                  (const_int 1)))]
15385   "!TARGET_64BIT"
15386   "stosb"
15387   [(set_attr "type" "str")
15388    (set_attr "memory" "store")
15389    (set_attr "mode" "QI")])
15390
15391 (define_insn "*strsetqi_rex_1"
15392   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
15393         (match_operand:QI 2 "register_operand" "a"))
15394    (set (match_operand:DI 0 "register_operand" "=D")
15395         (plus:DI (match_dup 1)
15396                  (const_int 1)))]
15397   "TARGET_64BIT"
15398   "stosb"
15399   [(set_attr "type" "str")
15400    (set_attr "memory" "store")
15401    (set_attr "prefix_rex" "0")
15402    (set_attr "mode" "QI")])
15403
15404 (define_expand "rep_stos"
15405   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15406               (set (match_operand 0 "register_operand" "")
15407                    (match_operand 4 "" ""))
15408               (set (match_operand 2 "memory_operand" "") (const_int 0))
15409               (use (match_operand 3 "register_operand" ""))
15410               (use (match_dup 1))])]
15411   ""
15412   "ix86_current_function_needs_cld = 1;")
15413
15414 (define_insn "*rep_stosdi_rex64"
15415   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15416    (set (match_operand:DI 0 "register_operand" "=D")
15417         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15418                             (const_int 3))
15419                  (match_operand:DI 3 "register_operand" "0")))
15420    (set (mem:BLK (match_dup 3))
15421         (const_int 0))
15422    (use (match_operand:DI 2 "register_operand" "a"))
15423    (use (match_dup 4))]
15424   "TARGET_64BIT"
15425   "rep{%;} stosq"
15426   [(set_attr "type" "str")
15427    (set_attr "prefix_rep" "1")
15428    (set_attr "memory" "store")
15429    (set_attr "mode" "DI")])
15430
15431 (define_insn "*rep_stossi"
15432   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
15433    (set (match_operand:SI 0 "register_operand" "=D")
15434         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
15435                             (const_int 2))
15436                  (match_operand:SI 3 "register_operand" "0")))
15437    (set (mem:BLK (match_dup 3))
15438         (const_int 0))
15439    (use (match_operand:SI 2 "register_operand" "a"))
15440    (use (match_dup 4))]
15441   "!TARGET_64BIT"
15442   "rep{%;} stos{l|d}"
15443   [(set_attr "type" "str")
15444    (set_attr "prefix_rep" "1")
15445    (set_attr "memory" "store")
15446    (set_attr "mode" "SI")])
15447
15448 (define_insn "*rep_stossi_rex64"
15449   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15450    (set (match_operand:DI 0 "register_operand" "=D")
15451         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15452                             (const_int 2))
15453                  (match_operand:DI 3 "register_operand" "0")))
15454    (set (mem:BLK (match_dup 3))
15455         (const_int 0))
15456    (use (match_operand:SI 2 "register_operand" "a"))
15457    (use (match_dup 4))]
15458   "TARGET_64BIT"
15459   "rep{%;} stos{l|d}"
15460   [(set_attr "type" "str")
15461    (set_attr "prefix_rep" "1")
15462    (set_attr "memory" "store")
15463    (set_attr "mode" "SI")])
15464
15465 (define_insn "*rep_stosqi"
15466   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
15467    (set (match_operand:SI 0 "register_operand" "=D")
15468         (plus:SI (match_operand:SI 3 "register_operand" "0")
15469                  (match_operand:SI 4 "register_operand" "1")))
15470    (set (mem:BLK (match_dup 3))
15471         (const_int 0))
15472    (use (match_operand:QI 2 "register_operand" "a"))
15473    (use (match_dup 4))]
15474   "!TARGET_64BIT"
15475   "rep{%;} stosb"
15476   [(set_attr "type" "str")
15477    (set_attr "prefix_rep" "1")
15478    (set_attr "memory" "store")
15479    (set_attr "mode" "QI")])
15480
15481 (define_insn "*rep_stosqi_rex64"
15482   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15483    (set (match_operand:DI 0 "register_operand" "=D")
15484         (plus:DI (match_operand:DI 3 "register_operand" "0")
15485                  (match_operand:DI 4 "register_operand" "1")))
15486    (set (mem:BLK (match_dup 3))
15487         (const_int 0))
15488    (use (match_operand:QI 2 "register_operand" "a"))
15489    (use (match_dup 4))]
15490   "TARGET_64BIT"
15491   "rep{%;} stosb"
15492   [(set_attr "type" "str")
15493    (set_attr "prefix_rep" "1")
15494    (set_attr "memory" "store")
15495    (set_attr "prefix_rex" "0")
15496    (set_attr "mode" "QI")])
15497
15498 (define_expand "cmpstrnsi"
15499   [(set (match_operand:SI 0 "register_operand" "")
15500         (compare:SI (match_operand:BLK 1 "general_operand" "")
15501                     (match_operand:BLK 2 "general_operand" "")))
15502    (use (match_operand 3 "general_operand" ""))
15503    (use (match_operand 4 "immediate_operand" ""))]
15504   ""
15505 {
15506   rtx addr1, addr2, out, outlow, count, countreg, align;
15507
15508   if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
15509     FAIL;
15510
15511   /* Can't use this if the user has appropriated esi or edi.  */
15512   if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
15513     FAIL;
15514
15515   out = operands[0];
15516   if (!REG_P (out))
15517     out = gen_reg_rtx (SImode);
15518
15519   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
15520   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
15521   if (addr1 != XEXP (operands[1], 0))
15522     operands[1] = replace_equiv_address_nv (operands[1], addr1);
15523   if (addr2 != XEXP (operands[2], 0))
15524     operands[2] = replace_equiv_address_nv (operands[2], addr2);
15525
15526   count = operands[3];
15527   countreg = ix86_zero_extend_to_Pmode (count);
15528
15529   /* %%% Iff we are testing strict equality, we can use known alignment
15530      to good advantage.  This may be possible with combine, particularly
15531      once cc0 is dead.  */
15532   align = operands[4];
15533
15534   if (CONST_INT_P (count))
15535     {
15536       if (INTVAL (count) == 0)
15537         {
15538           emit_move_insn (operands[0], const0_rtx);
15539           DONE;
15540         }
15541       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
15542                                      operands[1], operands[2]));
15543     }
15544   else
15545     {
15546       rtx (*gen_cmp) (rtx, rtx);
15547
15548       gen_cmp = (TARGET_64BIT
15549                  ? gen_cmpdi_1 : gen_cmpsi_1);
15550
15551       emit_insn (gen_cmp (countreg, countreg));
15552       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
15553                                   operands[1], operands[2]));
15554     }
15555
15556   outlow = gen_lowpart (QImode, out);
15557   emit_insn (gen_cmpintqi (outlow));
15558   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
15559
15560   if (operands[0] != out)
15561     emit_move_insn (operands[0], out);
15562
15563   DONE;
15564 })
15565
15566 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
15567
15568 (define_expand "cmpintqi"
15569   [(set (match_dup 1)
15570         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15571    (set (match_dup 2)
15572         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15573    (parallel [(set (match_operand:QI 0 "register_operand" "")
15574                    (minus:QI (match_dup 1)
15575                              (match_dup 2)))
15576               (clobber (reg:CC FLAGS_REG))])]
15577   ""
15578   "operands[1] = gen_reg_rtx (QImode);
15579    operands[2] = gen_reg_rtx (QImode);")
15580
15581 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
15582 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
15583
15584 (define_expand "cmpstrnqi_nz_1"
15585   [(parallel [(set (reg:CC FLAGS_REG)
15586                    (compare:CC (match_operand 4 "memory_operand" "")
15587                                (match_operand 5 "memory_operand" "")))
15588               (use (match_operand 2 "register_operand" ""))
15589               (use (match_operand:SI 3 "immediate_operand" ""))
15590               (clobber (match_operand 0 "register_operand" ""))
15591               (clobber (match_operand 1 "register_operand" ""))
15592               (clobber (match_dup 2))])]
15593   ""
15594   "ix86_current_function_needs_cld = 1;")
15595
15596 (define_insn "*cmpstrnqi_nz_1"
15597   [(set (reg:CC FLAGS_REG)
15598         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
15599                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
15600    (use (match_operand:SI 6 "register_operand" "2"))
15601    (use (match_operand:SI 3 "immediate_operand" "i"))
15602    (clobber (match_operand:SI 0 "register_operand" "=S"))
15603    (clobber (match_operand:SI 1 "register_operand" "=D"))
15604    (clobber (match_operand:SI 2 "register_operand" "=c"))]
15605   "!TARGET_64BIT"
15606   "repz{%;} cmpsb"
15607   [(set_attr "type" "str")
15608    (set_attr "mode" "QI")
15609    (set_attr "prefix_rep" "1")])
15610
15611 (define_insn "*cmpstrnqi_nz_rex_1"
15612   [(set (reg:CC FLAGS_REG)
15613         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
15614                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
15615    (use (match_operand:DI 6 "register_operand" "2"))
15616    (use (match_operand:SI 3 "immediate_operand" "i"))
15617    (clobber (match_operand:DI 0 "register_operand" "=S"))
15618    (clobber (match_operand:DI 1 "register_operand" "=D"))
15619    (clobber (match_operand:DI 2 "register_operand" "=c"))]
15620   "TARGET_64BIT"
15621   "repz{%;} cmpsb"
15622   [(set_attr "type" "str")
15623    (set_attr "mode" "QI")
15624    (set_attr "prefix_rex" "0")
15625    (set_attr "prefix_rep" "1")])
15626
15627 ;; The same, but the count is not known to not be zero.
15628
15629 (define_expand "cmpstrnqi_1"
15630   [(parallel [(set (reg:CC FLAGS_REG)
15631                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
15632                                      (const_int 0))
15633                   (compare:CC (match_operand 4 "memory_operand" "")
15634                               (match_operand 5 "memory_operand" ""))
15635                   (const_int 0)))
15636               (use (match_operand:SI 3 "immediate_operand" ""))
15637               (use (reg:CC FLAGS_REG))
15638               (clobber (match_operand 0 "register_operand" ""))
15639               (clobber (match_operand 1 "register_operand" ""))
15640               (clobber (match_dup 2))])]
15641   ""
15642   "ix86_current_function_needs_cld = 1;")
15643
15644 (define_insn "*cmpstrnqi_1"
15645   [(set (reg:CC FLAGS_REG)
15646         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
15647                              (const_int 0))
15648           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
15649                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
15650           (const_int 0)))
15651    (use (match_operand:SI 3 "immediate_operand" "i"))
15652    (use (reg:CC FLAGS_REG))
15653    (clobber (match_operand:SI 0 "register_operand" "=S"))
15654    (clobber (match_operand:SI 1 "register_operand" "=D"))
15655    (clobber (match_operand:SI 2 "register_operand" "=c"))]
15656   "!TARGET_64BIT"
15657   "repz{%;} cmpsb"
15658   [(set_attr "type" "str")
15659    (set_attr "mode" "QI")
15660    (set_attr "prefix_rep" "1")])
15661
15662 (define_insn "*cmpstrnqi_rex_1"
15663   [(set (reg:CC FLAGS_REG)
15664         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
15665                              (const_int 0))
15666           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
15667                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
15668           (const_int 0)))
15669    (use (match_operand:SI 3 "immediate_operand" "i"))
15670    (use (reg:CC FLAGS_REG))
15671    (clobber (match_operand:DI 0 "register_operand" "=S"))
15672    (clobber (match_operand:DI 1 "register_operand" "=D"))
15673    (clobber (match_operand:DI 2 "register_operand" "=c"))]
15674   "TARGET_64BIT"
15675   "repz{%;} cmpsb"
15676   [(set_attr "type" "str")
15677    (set_attr "mode" "QI")
15678    (set_attr "prefix_rex" "0")
15679    (set_attr "prefix_rep" "1")])
15680
15681 (define_expand "strlensi"
15682   [(set (match_operand:SI 0 "register_operand" "")
15683         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
15684                     (match_operand:QI 2 "immediate_operand" "")
15685                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
15686   ""
15687 {
15688  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
15689    DONE;
15690  else
15691    FAIL;
15692 })
15693
15694 (define_expand "strlendi"
15695   [(set (match_operand:DI 0 "register_operand" "")
15696         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
15697                     (match_operand:QI 2 "immediate_operand" "")
15698                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
15699   ""
15700 {
15701  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
15702    DONE;
15703  else
15704    FAIL;
15705 })
15706
15707 (define_expand "strlenqi_1"
15708   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
15709               (clobber (match_operand 1 "register_operand" ""))
15710               (clobber (reg:CC FLAGS_REG))])]
15711   ""
15712   "ix86_current_function_needs_cld = 1;")
15713
15714 (define_insn "*strlenqi_1"
15715   [(set (match_operand:SI 0 "register_operand" "=&c")
15716         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
15717                     (match_operand:QI 2 "register_operand" "a")
15718                     (match_operand:SI 3 "immediate_operand" "i")
15719                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
15720    (clobber (match_operand:SI 1 "register_operand" "=D"))
15721    (clobber (reg:CC FLAGS_REG))]
15722   "!TARGET_64BIT"
15723   "repnz{%;} scasb"
15724   [(set_attr "type" "str")
15725    (set_attr "mode" "QI")
15726    (set_attr "prefix_rep" "1")])
15727
15728 (define_insn "*strlenqi_rex_1"
15729   [(set (match_operand:DI 0 "register_operand" "=&c")
15730         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
15731                     (match_operand:QI 2 "register_operand" "a")
15732                     (match_operand:DI 3 "immediate_operand" "i")
15733                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
15734    (clobber (match_operand:DI 1 "register_operand" "=D"))
15735    (clobber (reg:CC FLAGS_REG))]
15736   "TARGET_64BIT"
15737   "repnz{%;} scasb"
15738   [(set_attr "type" "str")
15739    (set_attr "mode" "QI")
15740    (set_attr "prefix_rex" "0")
15741    (set_attr "prefix_rep" "1")])
15742
15743 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
15744 ;; handled in combine, but it is not currently up to the task.
15745 ;; When used for their truth value, the cmpstrn* expanders generate
15746 ;; code like this:
15747 ;;
15748 ;;   repz cmpsb
15749 ;;   seta       %al
15750 ;;   setb       %dl
15751 ;;   cmpb       %al, %dl
15752 ;;   jcc        label
15753 ;;
15754 ;; The intermediate three instructions are unnecessary.
15755
15756 ;; This one handles cmpstrn*_nz_1...
15757 (define_peephole2
15758   [(parallel[
15759      (set (reg:CC FLAGS_REG)
15760           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15761                       (mem:BLK (match_operand 5 "register_operand" ""))))
15762      (use (match_operand 6 "register_operand" ""))
15763      (use (match_operand:SI 3 "immediate_operand" ""))
15764      (clobber (match_operand 0 "register_operand" ""))
15765      (clobber (match_operand 1 "register_operand" ""))
15766      (clobber (match_operand 2 "register_operand" ""))])
15767    (set (match_operand:QI 7 "register_operand" "")
15768         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15769    (set (match_operand:QI 8 "register_operand" "")
15770         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15771    (set (reg FLAGS_REG)
15772         (compare (match_dup 7) (match_dup 8)))
15773   ]
15774   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15775   [(parallel[
15776      (set (reg:CC FLAGS_REG)
15777           (compare:CC (mem:BLK (match_dup 4))
15778                       (mem:BLK (match_dup 5))))
15779      (use (match_dup 6))
15780      (use (match_dup 3))
15781      (clobber (match_dup 0))
15782      (clobber (match_dup 1))
15783      (clobber (match_dup 2))])])
15784
15785 ;; ...and this one handles cmpstrn*_1.
15786 (define_peephole2
15787   [(parallel[
15788      (set (reg:CC FLAGS_REG)
15789           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
15790                                (const_int 0))
15791             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15792                         (mem:BLK (match_operand 5 "register_operand" "")))
15793             (const_int 0)))
15794      (use (match_operand:SI 3 "immediate_operand" ""))
15795      (use (reg:CC FLAGS_REG))
15796      (clobber (match_operand 0 "register_operand" ""))
15797      (clobber (match_operand 1 "register_operand" ""))
15798      (clobber (match_operand 2 "register_operand" ""))])
15799    (set (match_operand:QI 7 "register_operand" "")
15800         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15801    (set (match_operand:QI 8 "register_operand" "")
15802         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15803    (set (reg FLAGS_REG)
15804         (compare (match_dup 7) (match_dup 8)))
15805   ]
15806   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15807   [(parallel[
15808      (set (reg:CC FLAGS_REG)
15809           (if_then_else:CC (ne (match_dup 6)
15810                                (const_int 0))
15811             (compare:CC (mem:BLK (match_dup 4))
15812                         (mem:BLK (match_dup 5)))
15813             (const_int 0)))
15814      (use (match_dup 3))
15815      (use (reg:CC FLAGS_REG))
15816      (clobber (match_dup 0))
15817      (clobber (match_dup 1))
15818      (clobber (match_dup 2))])])
15819 \f
15820 ;; Conditional move instructions.
15821
15822 (define_expand "mov<mode>cc"
15823   [(set (match_operand:SWIM 0 "register_operand" "")
15824         (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator" "")
15825                            (match_operand:SWIM 2 "general_operand" "")
15826                            (match_operand:SWIM 3 "general_operand" "")))]
15827   ""
15828   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
15829
15830 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
15831 ;; the register first winds up with `sbbl $0,reg', which is also weird.
15832 ;; So just document what we're doing explicitly.
15833
15834 (define_expand "x86_mov<mode>cc_0_m1"
15835   [(parallel
15836     [(set (match_operand:SWI48 0 "register_operand" "")
15837           (if_then_else:SWI48
15838             (match_operator:SWI48 2 "ix86_carry_flag_operator"
15839              [(match_operand 1 "flags_reg_operand" "")
15840               (const_int 0)])
15841             (const_int -1)
15842             (const_int 0)))
15843      (clobber (reg:CC FLAGS_REG))])]
15844   ""
15845   "")
15846
15847 (define_insn "*x86_mov<mode>cc_0_m1"
15848   [(set (match_operand:SWI48 0 "register_operand" "=r")
15849         (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
15850                              [(reg FLAGS_REG) (const_int 0)])
15851           (const_int -1)
15852           (const_int 0)))
15853    (clobber (reg:CC FLAGS_REG))]
15854   ""
15855   "sbb{<imodesuffix>}\t%0, %0"
15856   ; Since we don't have the proper number of operands for an alu insn,
15857   ; fill in all the blanks.
15858   [(set_attr "type" "alu")
15859    (set_attr "use_carry" "1")
15860    (set_attr "pent_pair" "pu")
15861    (set_attr "memory" "none")
15862    (set_attr "imm_disp" "false")
15863    (set_attr "mode" "<MODE>")
15864    (set_attr "length_immediate" "0")])
15865
15866 (define_insn "*x86_mov<mode>cc_0_m1_se"
15867   [(set (match_operand:SWI48 0 "register_operand" "=r")
15868         (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
15869                              [(reg FLAGS_REG) (const_int 0)])
15870                             (const_int 1)
15871                             (const_int 0)))
15872    (clobber (reg:CC FLAGS_REG))]
15873   ""
15874   "sbb{<imodesuffix>}\t%0, %0"
15875   [(set_attr "type" "alu")
15876    (set_attr "use_carry" "1")
15877    (set_attr "pent_pair" "pu")
15878    (set_attr "memory" "none")
15879    (set_attr "imm_disp" "false")
15880    (set_attr "mode" "<MODE>")
15881    (set_attr "length_immediate" "0")])
15882
15883 (define_insn "*x86_mov<mode>cc_0_m1_neg"
15884   [(set (match_operand:SWI48 0 "register_operand" "=r")
15885         (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
15886                     [(reg FLAGS_REG) (const_int 0)])))]
15887   ""
15888   "sbb{<imodesuffix>}\t%0, %0"
15889   [(set_attr "type" "alu")
15890    (set_attr "use_carry" "1")
15891    (set_attr "pent_pair" "pu")
15892    (set_attr "memory" "none")
15893    (set_attr "imm_disp" "false")
15894    (set_attr "mode" "<MODE>")
15895    (set_attr "length_immediate" "0")])
15896
15897 (define_insn "*mov<mode>cc_noc"
15898   [(set (match_operand:SWI248 0 "register_operand" "=r,r")
15899         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
15900                                [(reg FLAGS_REG) (const_int 0)])
15901           (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
15902           (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
15903   "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
15904   "@
15905    cmov%O2%C1\t{%2, %0|%0, %2}
15906    cmov%O2%c1\t{%3, %0|%0, %3}"
15907   [(set_attr "type" "icmov")
15908    (set_attr "mode" "<MODE>")])
15909
15910 (define_insn_and_split "*movqicc_noc"
15911   [(set (match_operand:QI 0 "register_operand" "=r,r")
15912         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
15913                            [(match_operand 4 "flags_reg_operand" "")
15914                             (const_int 0)])
15915                       (match_operand:QI 2 "register_operand" "r,0")
15916                       (match_operand:QI 3 "register_operand" "0,r")))]
15917   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
15918   "#"
15919   "&& reload_completed"
15920   [(set (match_dup 0)
15921         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
15922                       (match_dup 2)
15923                       (match_dup 3)))]
15924   "operands[0] = gen_lowpart (SImode, operands[0]);
15925    operands[2] = gen_lowpart (SImode, operands[2]);
15926    operands[3] = gen_lowpart (SImode, operands[3]);"
15927   [(set_attr "type" "icmov")
15928    (set_attr "mode" "SI")])
15929
15930 (define_expand "mov<mode>cc"
15931   [(set (match_operand:X87MODEF 0 "register_operand" "")
15932         (if_then_else:X87MODEF
15933           (match_operand 1 "ix86_fp_comparison_operator" "")
15934           (match_operand:X87MODEF 2 "register_operand" "")
15935           (match_operand:X87MODEF 3 "register_operand" "")))]
15936   "(TARGET_80387 && TARGET_CMOVE)
15937    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15938   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
15939
15940 (define_insn "*movsfcc_1_387"
15941   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
15942         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
15943                                 [(reg FLAGS_REG) (const_int 0)])
15944                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
15945                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
15946   "TARGET_80387 && TARGET_CMOVE
15947    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
15948   "@
15949    fcmov%F1\t{%2, %0|%0, %2}
15950    fcmov%f1\t{%3, %0|%0, %3}
15951    cmov%O2%C1\t{%2, %0|%0, %2}
15952    cmov%O2%c1\t{%3, %0|%0, %3}"
15953   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
15954    (set_attr "mode" "SF,SF,SI,SI")])
15955
15956 (define_insn "*movdfcc_1"
15957   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
15958         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
15959                                 [(reg FLAGS_REG) (const_int 0)])
15960                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
15961                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
15962   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
15963    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
15964   "@
15965    fcmov%F1\t{%2, %0|%0, %2}
15966    fcmov%f1\t{%3, %0|%0, %3}
15967    #
15968    #"
15969   [(set_attr "type" "fcmov,fcmov,multi,multi")
15970    (set_attr "mode" "DF")])
15971
15972 (define_insn "*movdfcc_1_rex64"
15973   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
15974         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
15975                                 [(reg FLAGS_REG) (const_int 0)])
15976                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
15977                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
15978   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
15979    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
15980   "@
15981    fcmov%F1\t{%2, %0|%0, %2}
15982    fcmov%f1\t{%3, %0|%0, %3}
15983    cmov%O2%C1\t{%2, %0|%0, %2}
15984    cmov%O2%c1\t{%3, %0|%0, %3}"
15985   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
15986    (set_attr "mode" "DF")])
15987
15988 (define_split
15989   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
15990         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
15991                                 [(match_operand 4 "flags_reg_operand" "")
15992                                  (const_int 0)])
15993                       (match_operand:DF 2 "nonimmediate_operand" "")
15994                       (match_operand:DF 3 "nonimmediate_operand" "")))]
15995   "!TARGET_64BIT && reload_completed"
15996   [(set (match_dup 2)
15997         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
15998                       (match_dup 5)
15999                       (match_dup 6)))
16000    (set (match_dup 3)
16001         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16002                       (match_dup 7)
16003                       (match_dup 8)))]
16004 {
16005   split_di (&operands[2], 2, &operands[5], &operands[7]);
16006   split_di (&operands[0], 1, &operands[2], &operands[3]);
16007 })
16008
16009 (define_insn "*movxfcc_1"
16010   [(set (match_operand:XF 0 "register_operand" "=f,f")
16011         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16012                                 [(reg FLAGS_REG) (const_int 0)])
16013                       (match_operand:XF 2 "register_operand" "f,0")
16014                       (match_operand:XF 3 "register_operand" "0,f")))]
16015   "TARGET_80387 && TARGET_CMOVE"
16016   "@
16017    fcmov%F1\t{%2, %0|%0, %2}
16018    fcmov%f1\t{%3, %0|%0, %3}"
16019   [(set_attr "type" "fcmov")
16020    (set_attr "mode" "XF")])
16021
16022 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16023 ;; the scalar versions to have only XMM registers as operands.
16024
16025 ;; XOP conditional move
16026 (define_insn "*xop_pcmov_<mode>"
16027   [(set (match_operand:MODEF 0 "register_operand" "=x")
16028         (if_then_else:MODEF
16029           (match_operand:MODEF 1 "register_operand" "x")
16030           (match_operand:MODEF 2 "register_operand" "x")
16031           (match_operand:MODEF 3 "register_operand" "x")))]
16032   "TARGET_XOP"
16033   "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16034   [(set_attr "type" "sse4arg")])
16035
16036 ;; These versions of the min/max patterns are intentionally ignorant of
16037 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16038 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16039 ;; are undefined in this condition, we're certain this is correct.
16040
16041 (define_insn "*avx_<code><mode>3"
16042   [(set (match_operand:MODEF 0 "register_operand" "=x")
16043         (smaxmin:MODEF
16044           (match_operand:MODEF 1 "nonimmediate_operand" "%x")
16045           (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
16046   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16047   "v<maxmin_float>s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16048   [(set_attr "type" "sseadd")
16049    (set_attr "prefix" "vex")
16050    (set_attr "mode" "<MODE>")])
16051
16052 (define_insn "<code><mode>3"
16053   [(set (match_operand:MODEF 0 "register_operand" "=x")
16054         (smaxmin:MODEF
16055           (match_operand:MODEF 1 "nonimmediate_operand" "%0")
16056           (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
16057   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16058   "<maxmin_float>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
16059   [(set_attr "type" "sseadd")
16060    (set_attr "mode" "<MODE>")])
16061
16062 ;; These versions of the min/max patterns implement exactly the operations
16063 ;;   min = (op1 < op2 ? op1 : op2)
16064 ;;   max = (!(op1 < op2) ? op1 : op2)
16065 ;; Their operands are not commutative, and thus they may be used in the
16066 ;; presence of -0.0 and NaN.
16067
16068 (define_insn "*avx_ieee_smin<mode>3"
16069   [(set (match_operand:MODEF 0 "register_operand" "=x")
16070         (unspec:MODEF
16071           [(match_operand:MODEF 1 "register_operand" "x")
16072            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16073          UNSPEC_IEEE_MIN))]
16074   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16075   "vmins<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16076   [(set_attr "type" "sseadd")
16077    (set_attr "prefix" "vex")
16078    (set_attr "mode" "<MODE>")])
16079
16080 (define_insn "*ieee_smin<mode>3"
16081   [(set (match_operand:MODEF 0 "register_operand" "=x")
16082         (unspec:MODEF
16083           [(match_operand:MODEF 1 "register_operand" "0")
16084            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16085          UNSPEC_IEEE_MIN))]
16086   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16087   "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
16088   [(set_attr "type" "sseadd")
16089    (set_attr "mode" "<MODE>")])
16090
16091 (define_insn "*avx_ieee_smax<mode>3"
16092   [(set (match_operand:MODEF 0 "register_operand" "=x")
16093         (unspec:MODEF
16094           [(match_operand:MODEF 1 "register_operand" "0")
16095            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16096          UNSPEC_IEEE_MAX))]
16097   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16098   "vmaxs<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16099   [(set_attr "type" "sseadd")
16100    (set_attr "prefix" "vex")
16101    (set_attr "mode" "<MODE>")])
16102
16103 (define_insn "*ieee_smax<mode>3"
16104   [(set (match_operand:MODEF 0 "register_operand" "=x")
16105         (unspec:MODEF
16106           [(match_operand:MODEF 1 "register_operand" "0")
16107            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16108          UNSPEC_IEEE_MAX))]
16109   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16110   "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
16111   [(set_attr "type" "sseadd")
16112    (set_attr "mode" "<MODE>")])
16113
16114 ;; Make two stack loads independent:
16115 ;;   fld aa              fld aa
16116 ;;   fld %st(0)     ->   fld bb
16117 ;;   fmul bb             fmul %st(1), %st
16118 ;;
16119 ;; Actually we only match the last two instructions for simplicity.
16120 (define_peephole2
16121   [(set (match_operand 0 "fp_register_operand" "")
16122         (match_operand 1 "fp_register_operand" ""))
16123    (set (match_dup 0)
16124         (match_operator 2 "binary_fp_operator"
16125            [(match_dup 0)
16126             (match_operand 3 "memory_operand" "")]))]
16127   "REGNO (operands[0]) != REGNO (operands[1])"
16128   [(set (match_dup 0) (match_dup 3))
16129    (set (match_dup 0) (match_dup 4))]
16130
16131   ;; The % modifier is not operational anymore in peephole2's, so we have to
16132   ;; swap the operands manually in the case of addition and multiplication.
16133   "if (COMMUTATIVE_ARITH_P (operands[2]))
16134      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16135                                    GET_MODE (operands[2]),
16136                                    operands[0], operands[1]);
16137    else
16138      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16139                                    GET_MODE (operands[2]),
16140                                    operands[1], operands[0]);")
16141
16142 ;; Conditional addition patterns
16143 (define_expand "add<mode>cc"
16144   [(match_operand:SWI 0 "register_operand" "")
16145    (match_operand 1 "ordered_comparison_operator" "")
16146    (match_operand:SWI 2 "register_operand" "")
16147    (match_operand:SWI 3 "const_int_operand" "")]
16148   ""
16149   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16150 \f
16151 ;; Misc patterns (?)
16152
16153 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16154 ;; Otherwise there will be nothing to keep
16155 ;;
16156 ;; [(set (reg ebp) (reg esp))]
16157 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16158 ;;  (clobber (eflags)]
16159 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16160 ;;
16161 ;; in proper program order.
16162
16163 (define_insn "pro_epilogue_adjust_stack_<mode>_1"
16164   [(set (match_operand:P 0 "register_operand" "=r,r")
16165         (plus:P (match_operand:P 1 "register_operand" "0,r")
16166                 (match_operand:P 2 "<immediate_operand>" "<i>,<i>")))
16167    (clobber (reg:CC FLAGS_REG))
16168    (clobber (mem:BLK (scratch)))]
16169   ""
16170 {
16171   switch (get_attr_type (insn))
16172     {
16173     case TYPE_IMOV:
16174       return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16175
16176     case TYPE_ALU:
16177       gcc_assert (rtx_equal_p (operands[0], operands[1]));
16178       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16179         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16180
16181       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16182
16183     default:
16184       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16185       return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
16186     }
16187 }
16188   [(set (attr "type")
16189         (cond [(and (eq_attr "alternative" "0")
16190                     (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
16191                  (const_string "alu")
16192                (match_operand:<MODE> 2 "const0_operand" "")
16193                  (const_string "imov")
16194               ]
16195               (const_string "lea")))
16196    (set (attr "length_immediate")
16197         (cond [(eq_attr "type" "imov")
16198                  (const_string "0")
16199                (and (eq_attr "type" "alu")
16200                     (match_operand 2 "const128_operand" ""))
16201                  (const_string "1")
16202               ]
16203               (const_string "*")))
16204    (set_attr "mode" "<MODE>")])
16205
16206 (define_insn "pro_epilogue_adjust_stack_di_2"
16207   [(set (match_operand:DI 0 "register_operand" "=r,r")
16208         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
16209                  (match_operand:DI 3 "immediate_operand" "i,i")))
16210    (use (match_operand:DI 2 "register_operand" "r,l"))
16211    (clobber (reg:CC FLAGS_REG))
16212    (clobber (mem:BLK (scratch)))]
16213   "TARGET_64BIT"
16214 {
16215   switch (get_attr_type (insn))
16216     {
16217     case TYPE_ALU:
16218       return "add{q}\t{%2, %0|%0, %2}";
16219
16220     case TYPE_LEA:
16221       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
16222       return "lea{q}\t{%a2, %0|%0, %a2}";
16223
16224     default:
16225       gcc_unreachable ();
16226     }
16227 }
16228   [(set_attr "type" "alu,lea")
16229    (set_attr "mode" "DI")])
16230
16231 (define_insn "allocate_stack_worker_32"
16232   [(set (match_operand:SI 0 "register_operand" "=a")
16233         (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")]
16234                             UNSPECV_STACK_PROBE))
16235    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 1)))
16236    (clobber (reg:CC FLAGS_REG))]
16237   "!TARGET_64BIT && ix86_target_stack_probe ()"
16238   "call\t___chkstk"
16239   [(set_attr "type" "multi")
16240    (set_attr "length" "5")])
16241
16242 (define_insn "allocate_stack_worker_64"
16243   [(set (match_operand:DI 0 "register_operand" "=a")
16244         (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "0")]
16245                             UNSPECV_STACK_PROBE))
16246    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 1)))
16247    (clobber (reg:DI R10_REG))
16248    (clobber (reg:DI R11_REG))
16249    (clobber (reg:CC FLAGS_REG))]
16250   "TARGET_64BIT && ix86_target_stack_probe ()"
16251   "call\t___chkstk"
16252   [(set_attr "type" "multi")
16253    (set_attr "length" "5")])
16254
16255 (define_expand "allocate_stack"
16256   [(match_operand 0 "register_operand" "")
16257    (match_operand 1 "general_operand" "")]
16258   "ix86_target_stack_probe ()"
16259 {
16260   rtx x;
16261
16262 #ifndef CHECK_STACK_LIMIT
16263 #define CHECK_STACK_LIMIT 0
16264 #endif
16265
16266   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16267       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16268     {
16269       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16270                                stack_pointer_rtx, 0, OPTAB_DIRECT);
16271       if (x != stack_pointer_rtx)
16272         emit_move_insn (stack_pointer_rtx, x);
16273     }
16274   else
16275     {
16276       rtx (*gen_allocate_stack_worker) (rtx, rtx);
16277
16278       if (TARGET_64BIT)
16279         gen_allocate_stack_worker = gen_allocate_stack_worker_64;
16280       else
16281         gen_allocate_stack_worker = gen_allocate_stack_worker_32;
16282
16283       x = copy_to_mode_reg (Pmode, operands[1]);
16284       emit_insn (gen_allocate_stack_worker (x, x));
16285     }
16286
16287   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16288   DONE;
16289 })
16290
16291 ;; Use IOR for stack probes, this is shorter.
16292 (define_expand "probe_stack"
16293   [(match_operand 0 "memory_operand" "")]
16294   ""
16295 {
16296   rtx (*gen_ior3) (rtx, rtx, rtx);
16297
16298   gen_ior3 = (GET_MODE (operands[0]) == DImode
16299               ? gen_iordi3 : gen_iorsi3);
16300
16301   emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16302   DONE;
16303 })
16304
16305 (define_insn "adjust_stack_and_probe<mode>"
16306   [(set (match_operand:P 0 "register_operand" "=r")
16307         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16308                             UNSPECV_PROBE_STACK_RANGE))
16309    (set (reg:P SP_REG)
16310         (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16311    (clobber (reg:CC FLAGS_REG))
16312    (clobber (mem:BLK (scratch)))]
16313   ""
16314   "* return output_adjust_stack_and_probe (operands[0]);"
16315   [(set_attr "type" "multi")])
16316
16317 (define_insn "probe_stack_range<mode>"
16318   [(set (match_operand:P 0 "register_operand" "=r")
16319         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16320                             (match_operand:P 2 "const_int_operand" "n")]
16321                             UNSPECV_PROBE_STACK_RANGE))
16322    (clobber (reg:CC FLAGS_REG))]
16323   ""
16324   "* return output_probe_stack_range (operands[0], operands[2]);"
16325   [(set_attr "type" "multi")])
16326
16327 (define_expand "builtin_setjmp_receiver"
16328   [(label_ref (match_operand 0 "" ""))]
16329   "!TARGET_64BIT && flag_pic"
16330 {
16331 #if TARGET_MACHO
16332   if (TARGET_MACHO)
16333     {
16334       rtx xops[3];
16335       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16336       rtx label_rtx = gen_label_rtx ();
16337       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16338       xops[0] = xops[1] = picreg;
16339       xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16340       ix86_expand_binary_operator (MINUS, SImode, xops);
16341     }
16342   else
16343 #endif
16344     emit_insn (gen_set_got (pic_offset_table_rtx));
16345   DONE;
16346 })
16347 \f
16348 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16349
16350 (define_split
16351   [(set (match_operand 0 "register_operand" "")
16352         (match_operator 3 "promotable_binary_operator"
16353            [(match_operand 1 "register_operand" "")
16354             (match_operand 2 "aligned_operand" "")]))
16355    (clobber (reg:CC FLAGS_REG))]
16356   "! TARGET_PARTIAL_REG_STALL && reload_completed
16357    && ((GET_MODE (operands[0]) == HImode
16358         && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16359             /* ??? next two lines just !satisfies_constraint_K (...) */
16360             || !CONST_INT_P (operands[2])
16361             || satisfies_constraint_K (operands[2])))
16362        || (GET_MODE (operands[0]) == QImode
16363            && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16364   [(parallel [(set (match_dup 0)
16365                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16366               (clobber (reg:CC FLAGS_REG))])]
16367   "operands[0] = gen_lowpart (SImode, operands[0]);
16368    operands[1] = gen_lowpart (SImode, operands[1]);
16369    if (GET_CODE (operands[3]) != ASHIFT)
16370      operands[2] = gen_lowpart (SImode, operands[2]);
16371    PUT_MODE (operands[3], SImode);")
16372
16373 ; Promote the QImode tests, as i386 has encoding of the AND
16374 ; instruction with 32-bit sign-extended immediate and thus the
16375 ; instruction size is unchanged, except in the %eax case for
16376 ; which it is increased by one byte, hence the ! optimize_size.
16377 (define_split
16378   [(set (match_operand 0 "flags_reg_operand" "")
16379         (match_operator 2 "compare_operator"
16380           [(and (match_operand 3 "aligned_operand" "")
16381                 (match_operand 4 "const_int_operand" ""))
16382            (const_int 0)]))
16383    (set (match_operand 1 "register_operand" "")
16384         (and (match_dup 3) (match_dup 4)))]
16385   "! TARGET_PARTIAL_REG_STALL && reload_completed
16386    && optimize_insn_for_speed_p ()
16387    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16388        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16389    /* Ensure that the operand will remain sign-extended immediate.  */
16390    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16391   [(parallel [(set (match_dup 0)
16392                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16393                                     (const_int 0)]))
16394               (set (match_dup 1)
16395                    (and:SI (match_dup 3) (match_dup 4)))])]
16396 {
16397   operands[4]
16398     = gen_int_mode (INTVAL (operands[4])
16399                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16400   operands[1] = gen_lowpart (SImode, operands[1]);
16401   operands[3] = gen_lowpart (SImode, operands[3]);
16402 })
16403
16404 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16405 ; the TEST instruction with 32-bit sign-extended immediate and thus
16406 ; the instruction size would at least double, which is not what we
16407 ; want even with ! optimize_size.
16408 (define_split
16409   [(set (match_operand 0 "flags_reg_operand" "")
16410         (match_operator 1 "compare_operator"
16411           [(and (match_operand:HI 2 "aligned_operand" "")
16412                 (match_operand:HI 3 "const_int_operand" ""))
16413            (const_int 0)]))]
16414   "! TARGET_PARTIAL_REG_STALL && reload_completed
16415    && ! TARGET_FAST_PREFIX
16416    && optimize_insn_for_speed_p ()
16417    /* Ensure that the operand will remain sign-extended immediate.  */
16418    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16419   [(set (match_dup 0)
16420         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16421                          (const_int 0)]))]
16422 {
16423   operands[3]
16424     = gen_int_mode (INTVAL (operands[3])
16425                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16426   operands[2] = gen_lowpart (SImode, operands[2]);
16427 })
16428
16429 (define_split
16430   [(set (match_operand 0 "register_operand" "")
16431         (neg (match_operand 1 "register_operand" "")))
16432    (clobber (reg:CC FLAGS_REG))]
16433   "! TARGET_PARTIAL_REG_STALL && reload_completed
16434    && (GET_MODE (operands[0]) == HImode
16435        || (GET_MODE (operands[0]) == QImode
16436            && (TARGET_PROMOTE_QImode
16437                || optimize_insn_for_size_p ())))"
16438   [(parallel [(set (match_dup 0)
16439                    (neg:SI (match_dup 1)))
16440               (clobber (reg:CC FLAGS_REG))])]
16441   "operands[0] = gen_lowpart (SImode, operands[0]);
16442    operands[1] = gen_lowpart (SImode, operands[1]);")
16443
16444 (define_split
16445   [(set (match_operand 0 "register_operand" "")
16446         (not (match_operand 1 "register_operand" "")))]
16447   "! TARGET_PARTIAL_REG_STALL && reload_completed
16448    && (GET_MODE (operands[0]) == HImode
16449        || (GET_MODE (operands[0]) == QImode
16450            && (TARGET_PROMOTE_QImode
16451                || optimize_insn_for_size_p ())))"
16452   [(set (match_dup 0)
16453         (not:SI (match_dup 1)))]
16454   "operands[0] = gen_lowpart (SImode, operands[0]);
16455    operands[1] = gen_lowpart (SImode, operands[1]);")
16456
16457 (define_split
16458   [(set (match_operand 0 "register_operand" "")
16459         (if_then_else (match_operator 1 "ordered_comparison_operator"
16460                                 [(reg FLAGS_REG) (const_int 0)])
16461                       (match_operand 2 "register_operand" "")
16462                       (match_operand 3 "register_operand" "")))]
16463   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
16464    && (GET_MODE (operands[0]) == HImode
16465        || (GET_MODE (operands[0]) == QImode
16466            && (TARGET_PROMOTE_QImode
16467                || optimize_insn_for_size_p ())))"
16468   [(set (match_dup 0)
16469         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16470   "operands[0] = gen_lowpart (SImode, operands[0]);
16471    operands[2] = gen_lowpart (SImode, operands[2]);
16472    operands[3] = gen_lowpart (SImode, operands[3]);")
16473 \f
16474 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
16475 ;; transform a complex memory operation into two memory to register operations.
16476
16477 ;; Don't push memory operands
16478 (define_peephole2
16479   [(set (match_operand:SWI 0 "push_operand" "")
16480         (match_operand:SWI 1 "memory_operand" ""))
16481    (match_scratch:SWI 2 "<r>")]
16482   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16483    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16484   [(set (match_dup 2) (match_dup 1))
16485    (set (match_dup 0) (match_dup 2))])
16486
16487 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16488 ;; SImode pushes.
16489 (define_peephole2
16490   [(set (match_operand:SF 0 "push_operand" "")
16491         (match_operand:SF 1 "memory_operand" ""))
16492    (match_scratch:SF 2 "r")]
16493   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16494    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16495   [(set (match_dup 2) (match_dup 1))
16496    (set (match_dup 0) (match_dup 2))])
16497
16498 ;; Don't move an immediate directly to memory when the instruction
16499 ;; gets too big.
16500 (define_peephole2
16501   [(match_scratch:SWI124 1 "<r>")
16502    (set (match_operand:SWI124 0 "memory_operand" "")
16503         (const_int 0))]
16504   "optimize_insn_for_speed_p ()
16505    && !TARGET_USE_MOV0
16506    && TARGET_SPLIT_LONG_MOVES
16507    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16508    && peep2_regno_dead_p (0, FLAGS_REG)"
16509   [(parallel [(set (match_dup 2) (const_int 0))
16510               (clobber (reg:CC FLAGS_REG))])
16511    (set (match_dup 0) (match_dup 1))]
16512   "operands[2] = gen_lowpart (SImode, operands[1]);")
16513
16514 (define_peephole2
16515   [(match_scratch:SWI124 2 "<r>")
16516    (set (match_operand:SWI124 0 "memory_operand" "")
16517         (match_operand:SWI124 1 "immediate_operand" ""))]
16518   "optimize_insn_for_speed_p ()
16519    && TARGET_SPLIT_LONG_MOVES
16520    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16521   [(set (match_dup 2) (match_dup 1))
16522    (set (match_dup 0) (match_dup 2))])
16523
16524 ;; Don't compare memory with zero, load and use a test instead.
16525 (define_peephole2
16526   [(set (match_operand 0 "flags_reg_operand" "")
16527         (match_operator 1 "compare_operator"
16528           [(match_operand:SI 2 "memory_operand" "")
16529            (const_int 0)]))
16530    (match_scratch:SI 3 "r")]
16531   "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16532   [(set (match_dup 3) (match_dup 2))
16533    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16534
16535 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16536 ;; Don't split NOTs with a displacement operand, because resulting XOR
16537 ;; will not be pairable anyway.
16538 ;;
16539 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16540 ;; represented using a modRM byte.  The XOR replacement is long decoded,
16541 ;; so this split helps here as well.
16542 ;;
16543 ;; Note: Can't do this as a regular split because we can't get proper
16544 ;; lifetime information then.
16545
16546 (define_peephole2
16547   [(set (match_operand:SWI124 0 "nonimmediate_operand" "")
16548         (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand" "")))]
16549   "optimize_insn_for_speed_p ()
16550    && ((TARGET_NOT_UNPAIRABLE
16551         && (!MEM_P (operands[0])
16552             || !memory_displacement_operand (operands[0], <MODE>mode)))
16553        || (TARGET_NOT_VECTORMODE
16554            && long_memory_operand (operands[0], <MODE>mode)))
16555    && peep2_regno_dead_p (0, FLAGS_REG)"
16556   [(parallel [(set (match_dup 0)
16557                    (xor:SWI124 (match_dup 1) (const_int -1)))
16558               (clobber (reg:CC FLAGS_REG))])])
16559
16560 ;; Non pairable "test imm, reg" instructions can be translated to
16561 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
16562 ;; byte opcode instead of two, have a short form for byte operands),
16563 ;; so do it for other CPUs as well.  Given that the value was dead,
16564 ;; this should not create any new dependencies.  Pass on the sub-word
16565 ;; versions if we're concerned about partial register stalls.
16566
16567 (define_peephole2
16568   [(set (match_operand 0 "flags_reg_operand" "")
16569         (match_operator 1 "compare_operator"
16570           [(and:SI (match_operand:SI 2 "register_operand" "")
16571                    (match_operand:SI 3 "immediate_operand" ""))
16572            (const_int 0)]))]
16573   "ix86_match_ccmode (insn, CCNOmode)
16574    && (true_regnum (operands[2]) != AX_REG
16575        || satisfies_constraint_K (operands[3]))
16576    && peep2_reg_dead_p (1, operands[2])"
16577   [(parallel
16578      [(set (match_dup 0)
16579            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16580                             (const_int 0)]))
16581       (set (match_dup 2)
16582            (and:SI (match_dup 2) (match_dup 3)))])])
16583
16584 ;; We don't need to handle HImode case, because it will be promoted to SImode
16585 ;; on ! TARGET_PARTIAL_REG_STALL
16586
16587 (define_peephole2
16588   [(set (match_operand 0 "flags_reg_operand" "")
16589         (match_operator 1 "compare_operator"
16590           [(and:QI (match_operand:QI 2 "register_operand" "")
16591                    (match_operand:QI 3 "immediate_operand" ""))
16592            (const_int 0)]))]
16593   "! TARGET_PARTIAL_REG_STALL
16594    && ix86_match_ccmode (insn, CCNOmode)
16595    && true_regnum (operands[2]) != AX_REG
16596    && peep2_reg_dead_p (1, operands[2])"
16597   [(parallel
16598      [(set (match_dup 0)
16599            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
16600                             (const_int 0)]))
16601       (set (match_dup 2)
16602            (and:QI (match_dup 2) (match_dup 3)))])])
16603
16604 (define_peephole2
16605   [(set (match_operand 0 "flags_reg_operand" "")
16606         (match_operator 1 "compare_operator"
16607           [(and:SI
16608              (zero_extract:SI
16609                (match_operand 2 "ext_register_operand" "")
16610                (const_int 8)
16611                (const_int 8))
16612              (match_operand 3 "const_int_operand" ""))
16613            (const_int 0)]))]
16614   "! TARGET_PARTIAL_REG_STALL
16615    && ix86_match_ccmode (insn, CCNOmode)
16616    && true_regnum (operands[2]) != AX_REG
16617    && peep2_reg_dead_p (1, operands[2])"
16618   [(parallel [(set (match_dup 0)
16619                    (match_op_dup 1
16620                      [(and:SI
16621                         (zero_extract:SI
16622                           (match_dup 2)
16623                           (const_int 8)
16624                           (const_int 8))
16625                         (match_dup 3))
16626                       (const_int 0)]))
16627               (set (zero_extract:SI (match_dup 2)
16628                                     (const_int 8)
16629                                     (const_int 8))
16630                    (and:SI
16631                      (zero_extract:SI
16632                        (match_dup 2)
16633                        (const_int 8)
16634                        (const_int 8))
16635                      (match_dup 3)))])])
16636
16637 ;; Don't do logical operations with memory inputs.
16638 (define_peephole2
16639   [(match_scratch:SI 2 "r")
16640    (parallel [(set (match_operand:SI 0 "register_operand" "")
16641                    (match_operator:SI 3 "arith_or_logical_operator"
16642                      [(match_dup 0)
16643                       (match_operand:SI 1 "memory_operand" "")]))
16644               (clobber (reg:CC FLAGS_REG))])]
16645   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
16646   [(set (match_dup 2) (match_dup 1))
16647    (parallel [(set (match_dup 0)
16648                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
16649               (clobber (reg:CC FLAGS_REG))])])
16650
16651 (define_peephole2
16652   [(match_scratch:SI 2 "r")
16653    (parallel [(set (match_operand:SI 0 "register_operand" "")
16654                    (match_operator:SI 3 "arith_or_logical_operator"
16655                      [(match_operand:SI 1 "memory_operand" "")
16656                       (match_dup 0)]))
16657               (clobber (reg:CC FLAGS_REG))])]
16658   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
16659   [(set (match_dup 2) (match_dup 1))
16660    (parallel [(set (match_dup 0)
16661                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
16662               (clobber (reg:CC FLAGS_REG))])])
16663
16664 ;; Prefer Load+RegOp to Mov+MemOp.  Watch out for cases when the memory address
16665 ;; refers to the destination of the load!
16666
16667 (define_peephole2
16668   [(set (match_operand:SI 0 "register_operand" "")
16669         (match_operand:SI 1 "register_operand" ""))
16670    (parallel [(set (match_dup 0)
16671                    (match_operator:SI 3 "commutative_operator"
16672                      [(match_dup 0)
16673                       (match_operand:SI 2 "memory_operand" "")]))
16674               (clobber (reg:CC FLAGS_REG))])]
16675   "REGNO (operands[0]) != REGNO (operands[1])
16676    && GENERAL_REGNO_P (REGNO (operands[0]))
16677    && GENERAL_REGNO_P (REGNO (operands[1]))"
16678   [(set (match_dup 0) (match_dup 4))
16679    (parallel [(set (match_dup 0)
16680                    (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
16681               (clobber (reg:CC FLAGS_REG))])]
16682   "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
16683
16684 (define_peephole2
16685   [(set (match_operand 0 "register_operand" "")
16686         (match_operand 1 "register_operand" ""))
16687    (set (match_dup 0)
16688                    (match_operator 3 "commutative_operator"
16689                      [(match_dup 0)
16690                       (match_operand 2 "memory_operand" "")]))]
16691   "REGNO (operands[0]) != REGNO (operands[1])
16692    && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1])) 
16693        || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
16694   [(set (match_dup 0) (match_dup 2))
16695    (set (match_dup 0)
16696         (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
16697
16698 ; Don't do logical operations with memory outputs
16699 ;
16700 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
16701 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
16702 ; the same decoder scheduling characteristics as the original.
16703
16704 (define_peephole2
16705   [(match_scratch:SI 2 "r")
16706    (parallel [(set (match_operand:SI 0 "memory_operand" "")
16707                    (match_operator:SI 3 "arith_or_logical_operator"
16708                      [(match_dup 0)
16709                       (match_operand:SI 1 "nonmemory_operand" "")]))
16710               (clobber (reg:CC FLAGS_REG))])]
16711   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
16712    /* Do not split stack checking probes.  */
16713    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
16714   [(set (match_dup 2) (match_dup 0))
16715    (parallel [(set (match_dup 2)
16716                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
16717               (clobber (reg:CC FLAGS_REG))])
16718    (set (match_dup 0) (match_dup 2))])
16719
16720 (define_peephole2
16721   [(match_scratch:SI 2 "r")
16722    (parallel [(set (match_operand:SI 0 "memory_operand" "")
16723                    (match_operator:SI 3 "arith_or_logical_operator"
16724                      [(match_operand:SI 1 "nonmemory_operand" "")
16725                       (match_dup 0)]))
16726               (clobber (reg:CC FLAGS_REG))])]
16727   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
16728    /* Do not split stack checking probes.  */
16729    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
16730   [(set (match_dup 2) (match_dup 0))
16731    (parallel [(set (match_dup 2)
16732                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16733               (clobber (reg:CC FLAGS_REG))])
16734    (set (match_dup 0) (match_dup 2))])
16735
16736 ;; Attempt to always use XOR for zeroing registers.
16737 (define_peephole2
16738   [(set (match_operand 0 "register_operand" "")
16739         (match_operand 1 "const0_operand" ""))]
16740   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
16741    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
16742    && GENERAL_REG_P (operands[0])
16743    && peep2_regno_dead_p (0, FLAGS_REG)"
16744   [(parallel [(set (match_dup 0) (const_int 0))
16745               (clobber (reg:CC FLAGS_REG))])]
16746   "operands[0] = gen_lowpart (word_mode, operands[0]);")
16747
16748 (define_peephole2
16749   [(set (strict_low_part (match_operand 0 "register_operand" ""))
16750         (const_int 0))]
16751   "(GET_MODE (operands[0]) == QImode
16752     || GET_MODE (operands[0]) == HImode)
16753    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
16754    && peep2_regno_dead_p (0, FLAGS_REG)"
16755   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
16756               (clobber (reg:CC FLAGS_REG))])])
16757
16758 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
16759 (define_peephole2
16760   [(set (match_operand:SWI248 0 "register_operand" "")
16761         (const_int -1))]
16762   "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
16763    && peep2_regno_dead_p (0, FLAGS_REG)"
16764   [(parallel [(set (match_dup 0) (const_int -1))
16765               (clobber (reg:CC FLAGS_REG))])]
16766 {
16767   if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
16768     operands[0] = gen_lowpart (SImode, operands[0]);
16769 })
16770
16771 ;; Attempt to convert simple lea to add/shift.
16772 ;; These can be created by move expanders.
16773
16774 (define_peephole2
16775   [(set (match_operand:SWI48 0 "register_operand" "")
16776         (plus:SWI48 (match_dup 0)
16777                     (match_operand:SWI48 1 "<nonmemory_operand>" "")))]
16778   "peep2_regno_dead_p (0, FLAGS_REG)"
16779   [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
16780               (clobber (reg:CC FLAGS_REG))])])
16781
16782 (define_peephole2
16783   [(set (match_operand:SI 0 "register_operand" "")
16784         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
16785                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
16786   "TARGET_64BIT
16787    && peep2_regno_dead_p (0, FLAGS_REG)
16788    && REGNO (operands[0]) == REGNO (operands[1])"
16789   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
16790               (clobber (reg:CC FLAGS_REG))])]
16791   "operands[2] = gen_lowpart (SImode, operands[2]);")
16792
16793 (define_peephole2
16794   [(set (match_operand:SWI48 0 "register_operand" "")
16795         (mult:SWI48 (match_dup 0)
16796                     (match_operand:SWI48 1 "const_int_operand" "")))]
16797   "exact_log2 (INTVAL (operands[1])) >= 0
16798    && peep2_regno_dead_p (0, FLAGS_REG)"
16799   [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
16800               (clobber (reg:CC FLAGS_REG))])]
16801   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
16802
16803 (define_peephole2
16804   [(set (match_operand:SI 0 "register_operand" "")
16805         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
16806                    (match_operand:DI 2 "const_int_operand" "")) 0))]
16807   "TARGET_64BIT
16808    && exact_log2 (INTVAL (operands[2])) >= 0
16809    && REGNO (operands[0]) == REGNO (operands[1])
16810    && peep2_regno_dead_p (0, FLAGS_REG)"
16811   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
16812               (clobber (reg:CC FLAGS_REG))])]
16813   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
16814
16815 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
16816 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
16817 ;; On many CPUs it is also faster, since special hardware to avoid esp
16818 ;; dependencies is present.
16819
16820 ;; While some of these conversions may be done using splitters, we use
16821 ;; peepholes in order to allow combine_stack_adjustments pass to see
16822 ;; nonobfuscated RTL.
16823
16824 ;; Convert prologue esp subtractions to push.
16825 ;; We need register to push.  In order to keep verify_flow_info happy we have
16826 ;; two choices
16827 ;; - use scratch and clobber it in order to avoid dependencies
16828 ;; - use already live register
16829 ;; We can't use the second way right now, since there is no reliable way how to
16830 ;; verify that given register is live.  First choice will also most likely in
16831 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
16832 ;; call clobbered registers are dead.  We may want to use base pointer as an
16833 ;; alternative when no register is available later.
16834
16835 (define_peephole2
16836   [(match_scratch:P 1 "r")
16837    (parallel [(set (reg:P SP_REG)
16838                    (plus:P (reg:P SP_REG)
16839                            (match_operand:P 0 "const_int_operand" "")))
16840               (clobber (reg:CC FLAGS_REG))
16841               (clobber (mem:BLK (scratch)))])]
16842   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
16843    && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
16844   [(clobber (match_dup 1))
16845    (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16846               (clobber (mem:BLK (scratch)))])])
16847
16848 (define_peephole2
16849   [(match_scratch:P 1 "r")
16850    (parallel [(set (reg:P SP_REG)
16851                    (plus:P (reg:P SP_REG)
16852                            (match_operand:P 0 "const_int_operand" "")))
16853               (clobber (reg:CC FLAGS_REG))
16854               (clobber (mem:BLK (scratch)))])]
16855   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
16856    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
16857   [(clobber (match_dup 1))
16858    (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16859    (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16860               (clobber (mem:BLK (scratch)))])])
16861
16862 ;; Convert esp subtractions to push.
16863 (define_peephole2
16864   [(match_scratch:P 1 "r")
16865    (parallel [(set (reg:P SP_REG)
16866                    (plus:P (reg:P SP_REG)
16867                            (match_operand:P 0 "const_int_operand" "")))
16868               (clobber (reg:CC FLAGS_REG))])]
16869   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
16870    && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
16871   [(clobber (match_dup 1))
16872    (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
16873
16874 (define_peephole2
16875   [(match_scratch:P 1 "r")
16876    (parallel [(set (reg:P SP_REG)
16877                    (plus:P (reg:P SP_REG)
16878                            (match_operand:P 0 "const_int_operand" "")))
16879               (clobber (reg:CC FLAGS_REG))])]
16880   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
16881    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
16882   [(clobber (match_dup 1))
16883    (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16884    (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
16885
16886 ;; Convert epilogue deallocator to pop.
16887 (define_peephole2
16888   [(match_scratch:P 1 "r")
16889    (parallel [(set (reg:P SP_REG)
16890                    (plus:P (reg:P SP_REG)
16891                            (match_operand:P 0 "const_int_operand" "")))
16892               (clobber (reg:CC FLAGS_REG))
16893               (clobber (mem:BLK (scratch)))])]
16894   "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
16895    && INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
16896   [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
16897               (clobber (mem:BLK (scratch)))])])
16898
16899 ;; Two pops case is tricky, since pop causes dependency
16900 ;; on destination register.  We use two registers if available.
16901 (define_peephole2
16902   [(match_scratch:P 1 "r")
16903    (match_scratch:P 2 "r")
16904    (parallel [(set (reg:P SP_REG)
16905                    (plus:P (reg:P SP_REG)
16906                            (match_operand:P 0 "const_int_operand" "")))
16907               (clobber (reg:CC FLAGS_REG))
16908               (clobber (mem:BLK (scratch)))])]
16909   "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
16910    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
16911   [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
16912               (clobber (mem:BLK (scratch)))])
16913    (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
16914
16915 (define_peephole2
16916   [(match_scratch:P 1 "r")
16917    (parallel [(set (reg:P SP_REG)
16918                    (plus:P (reg:P SP_REG)
16919                            (match_operand:P 0 "const_int_operand" "")))
16920               (clobber (reg:CC FLAGS_REG))
16921               (clobber (mem:BLK (scratch)))])]
16922   "optimize_insn_for_size_p ()
16923    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
16924   [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
16925               (clobber (mem:BLK (scratch)))])
16926    (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
16927
16928 ;; Convert esp additions to pop.
16929 (define_peephole2
16930   [(match_scratch:P 1 "r")
16931    (parallel [(set (reg:P SP_REG)
16932                    (plus:P (reg:P SP_REG)
16933                            (match_operand:P 0 "const_int_operand" "")))
16934               (clobber (reg:CC FLAGS_REG))])]
16935   "INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
16936   [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
16937
16938 ;; Two pops case is tricky, since pop causes dependency
16939 ;; on destination register.  We use two registers if available.
16940 (define_peephole2
16941   [(match_scratch:P 1 "r")
16942    (match_scratch:P 2 "r")
16943    (parallel [(set (reg:P SP_REG)
16944                    (plus:P (reg:P SP_REG)
16945                            (match_operand:P 0 "const_int_operand" "")))
16946               (clobber (reg:CC FLAGS_REG))])]
16947   "INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
16948   [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
16949    (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
16950
16951 (define_peephole2
16952   [(match_scratch:P 1 "r")
16953    (parallel [(set (reg:P SP_REG)
16954                    (plus:P (reg:P SP_REG)
16955                            (match_operand:P 0 "const_int_operand" "")))
16956               (clobber (reg:CC FLAGS_REG))])]
16957   "optimize_insn_for_size_p ()
16958    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
16959   [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
16960    (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
16961 \f
16962 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
16963 ;; required and register dies.  Similarly for 128 to -128.
16964 (define_peephole2
16965   [(set (match_operand 0 "flags_reg_operand" "")
16966         (match_operator 1 "compare_operator"
16967           [(match_operand 2 "register_operand" "")
16968            (match_operand 3 "const_int_operand" "")]))]
16969   "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
16970      && incdec_operand (operands[3], GET_MODE (operands[3])))
16971     || (!TARGET_FUSE_CMP_AND_BRANCH
16972         && INTVAL (operands[3]) == 128))
16973    && ix86_match_ccmode (insn, CCGCmode)
16974    && peep2_reg_dead_p (1, operands[2])"
16975   [(parallel [(set (match_dup 0)
16976                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
16977               (clobber (match_dup 2))])])
16978 \f
16979 ;; Convert imul by three, five and nine into lea
16980 (define_peephole2
16981   [(parallel
16982     [(set (match_operand:SWI48 0 "register_operand" "")
16983           (mult:SWI48 (match_operand:SWI48 1 "register_operand" "")
16984                       (match_operand:SWI48 2 "const_int_operand" "")))
16985      (clobber (reg:CC FLAGS_REG))])]
16986   "INTVAL (operands[2]) == 3
16987    || INTVAL (operands[2]) == 5
16988    || INTVAL (operands[2]) == 9"
16989   [(set (match_dup 0)
16990         (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
16991                     (match_dup 1)))]
16992   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
16993
16994 (define_peephole2
16995   [(parallel
16996     [(set (match_operand:SWI48 0 "register_operand" "")
16997           (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
16998                       (match_operand:SWI48 2 "const_int_operand" "")))
16999      (clobber (reg:CC FLAGS_REG))])]
17000   "optimize_insn_for_speed_p ()
17001    && (INTVAL (operands[2]) == 3
17002        || INTVAL (operands[2]) == 5
17003        || INTVAL (operands[2]) == 9)"
17004   [(set (match_dup 0) (match_dup 1))
17005    (set (match_dup 0)
17006         (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17007                     (match_dup 0)))]
17008   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17009
17010 ;; imul $32bit_imm, mem, reg is vector decoded, while
17011 ;; imul $32bit_imm, reg, reg is direct decoded.
17012 (define_peephole2
17013   [(match_scratch:SWI48 3 "r")
17014    (parallel [(set (match_operand:SWI48 0 "register_operand" "")
17015                    (mult:SWI48 (match_operand:SWI48 1 "memory_operand" "")
17016                                (match_operand:SWI48 2 "immediate_operand" "")))
17017               (clobber (reg:CC FLAGS_REG))])]
17018   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17019    && !satisfies_constraint_K (operands[2])"
17020   [(set (match_dup 3) (match_dup 1))
17021    (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17022               (clobber (reg:CC FLAGS_REG))])])
17023
17024 (define_peephole2
17025   [(match_scratch:SI 3 "r")
17026    (parallel [(set (match_operand:DI 0 "register_operand" "")
17027                    (zero_extend:DI
17028                      (mult:SI (match_operand:SI 1 "memory_operand" "")
17029                               (match_operand:SI 2 "immediate_operand" ""))))
17030               (clobber (reg:CC FLAGS_REG))])]
17031   "TARGET_64BIT
17032    && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17033    && !satisfies_constraint_K (operands[2])"
17034   [(set (match_dup 3) (match_dup 1))
17035    (parallel [(set (match_dup 0)
17036                    (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17037               (clobber (reg:CC FLAGS_REG))])])
17038
17039 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17040 ;; Convert it into imul reg, reg
17041 ;; It would be better to force assembler to encode instruction using long
17042 ;; immediate, but there is apparently no way to do so.
17043 (define_peephole2
17044   [(parallel [(set (match_operand:SWI248 0 "register_operand" "")
17045                    (mult:SWI248
17046                     (match_operand:SWI248 1 "nonimmediate_operand" "")
17047                     (match_operand:SWI248 2 "const_int_operand" "")))
17048               (clobber (reg:CC FLAGS_REG))])
17049    (match_scratch:SWI248 3 "r")]
17050   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17051    && satisfies_constraint_K (operands[2])"
17052   [(set (match_dup 3) (match_dup 2))
17053    (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17054               (clobber (reg:CC FLAGS_REG))])]
17055 {
17056   if (!rtx_equal_p (operands[0], operands[1]))
17057     emit_move_insn (operands[0], operands[1]);
17058 })
17059
17060 ;; After splitting up read-modify operations, array accesses with memory
17061 ;; operands might end up in form:
17062 ;;  sall    $2, %eax
17063 ;;  movl    4(%esp), %edx
17064 ;;  addl    %edx, %eax
17065 ;; instead of pre-splitting:
17066 ;;  sall    $2, %eax
17067 ;;  addl    4(%esp), %eax
17068 ;; Turn it into:
17069 ;;  movl    4(%esp), %edx
17070 ;;  leal    (%edx,%eax,4), %eax
17071
17072 (define_peephole2
17073   [(match_scratch:P 5 "r")
17074    (parallel [(set (match_operand 0 "register_operand" "")
17075                    (ashift (match_operand 1 "register_operand" "")
17076                            (match_operand 2 "const_int_operand" "")))
17077                (clobber (reg:CC FLAGS_REG))])
17078    (parallel [(set (match_operand 3 "register_operand" "")
17079                    (plus (match_dup 0)
17080                          (match_operand 4 "x86_64_general_operand" "")))
17081                    (clobber (reg:CC FLAGS_REG))])]
17082   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
17083    /* Validate MODE for lea.  */
17084    && ((!TARGET_PARTIAL_REG_STALL
17085         && (GET_MODE (operands[0]) == QImode
17086             || GET_MODE (operands[0]) == HImode))
17087        || GET_MODE (operands[0]) == SImode
17088        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17089    && (rtx_equal_p (operands[0], operands[3])
17090        || peep2_reg_dead_p (2, operands[0]))
17091    /* We reorder load and the shift.  */
17092    && !reg_overlap_mentioned_p (operands[0], operands[4])"
17093   [(set (match_dup 5) (match_dup 4))
17094    (set (match_dup 0) (match_dup 1))]
17095 {
17096   enum machine_mode mode = GET_MODE (operands[1]) == DImode ? DImode : SImode;
17097   int scale = 1 << INTVAL (operands[2]);
17098   rtx index = gen_lowpart (Pmode, operands[1]);
17099   rtx base = gen_lowpart (Pmode, operands[5]);
17100   rtx dest = gen_lowpart (mode, operands[3]);
17101
17102   operands[1] = gen_rtx_PLUS (Pmode, base,
17103                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
17104   operands[5] = base;
17105   if (mode != Pmode)
17106     {
17107       operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17108       operands[5] = gen_rtx_SUBREG (mode, operands[5], 0);
17109     }
17110   operands[0] = dest;
17111 })
17112 \f
17113 ;; Call-value patterns last so that the wildcard operand does not
17114 ;; disrupt insn-recog's switch tables.
17115
17116 (define_insn "*call_value_pop_0"
17117   [(set (match_operand 0 "" "")
17118         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17119               (match_operand:SI 2 "" "")))
17120    (set (reg:SI SP_REG)
17121         (plus:SI (reg:SI SP_REG)
17122                  (match_operand:SI 3 "immediate_operand" "")))]
17123   "!TARGET_64BIT"
17124 {
17125   if (SIBLING_CALL_P (insn))
17126     return "jmp\t%P1";
17127   else
17128     return "call\t%P1";
17129 }
17130   [(set_attr "type" "callv")])
17131
17132 (define_insn "*call_value_pop_1"
17133   [(set (match_operand 0 "" "")
17134         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17135               (match_operand:SI 2 "" "")))
17136    (set (reg:SI SP_REG)
17137         (plus:SI (reg:SI SP_REG)
17138                  (match_operand:SI 3 "immediate_operand" "i")))]
17139   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17140 {
17141   if (constant_call_address_operand (operands[1], Pmode))
17142     return "call\t%P1";
17143   return "call\t%A1";
17144 }
17145   [(set_attr "type" "callv")])
17146
17147 (define_insn "*sibcall_value_pop_1"
17148   [(set (match_operand 0 "" "")
17149         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17150               (match_operand:SI 2 "" "")))
17151    (set (reg:SI SP_REG)
17152         (plus:SI (reg:SI SP_REG)
17153                  (match_operand:SI 3 "immediate_operand" "i,i")))]
17154   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17155   "@
17156    jmp\t%P1
17157    jmp\t%A1"
17158   [(set_attr "type" "callv")])
17159
17160 (define_insn "*call_value_0"
17161   [(set (match_operand 0 "" "")
17162         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17163               (match_operand:SI 2 "" "")))]
17164   "!TARGET_64BIT"
17165 {
17166   if (SIBLING_CALL_P (insn))
17167     return "jmp\t%P1";
17168   else
17169     return "call\t%P1";
17170 }
17171   [(set_attr "type" "callv")])
17172
17173 (define_insn "*call_value_0_rex64"
17174   [(set (match_operand 0 "" "")
17175         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17176               (match_operand:DI 2 "const_int_operand" "")))]
17177   "TARGET_64BIT"
17178 {
17179   if (SIBLING_CALL_P (insn))
17180     return "jmp\t%P1";
17181   else
17182     return "call\t%P1";
17183 }
17184   [(set_attr "type" "callv")])
17185
17186 (define_insn "*call_value_0_rex64_ms_sysv"
17187   [(set (match_operand 0 "" "")
17188         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17189               (match_operand:DI 2 "const_int_operand" "")))
17190    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17191    (clobber (reg:TI XMM6_REG))
17192    (clobber (reg:TI XMM7_REG))
17193    (clobber (reg:TI XMM8_REG))
17194    (clobber (reg:TI XMM9_REG))
17195    (clobber (reg:TI XMM10_REG))
17196    (clobber (reg:TI XMM11_REG))
17197    (clobber (reg:TI XMM12_REG))
17198    (clobber (reg:TI XMM13_REG))
17199    (clobber (reg:TI XMM14_REG))
17200    (clobber (reg:TI XMM15_REG))
17201    (clobber (reg:DI SI_REG))
17202    (clobber (reg:DI DI_REG))]
17203   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17204 {
17205   if (SIBLING_CALL_P (insn))
17206     return "jmp\t%P1";
17207   else
17208     return "call\t%P1";
17209 }
17210   [(set_attr "type" "callv")])
17211
17212 (define_insn "*call_value_1"
17213   [(set (match_operand 0 "" "")
17214         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17215               (match_operand:SI 2 "" "")))]
17216   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17217 {
17218   if (constant_call_address_operand (operands[1], Pmode))
17219     return "call\t%P1";
17220   return "call\t%A1";
17221 }
17222   [(set_attr "type" "callv")])
17223
17224 (define_insn "*sibcall_value_1"
17225   [(set (match_operand 0 "" "")
17226         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17227               (match_operand:SI 2 "" "")))]
17228   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17229   "@
17230    jmp\t%P1
17231    jmp\t%A1"
17232   [(set_attr "type" "callv")])
17233
17234 (define_insn "*call_value_1_rex64"
17235   [(set (match_operand 0 "" "")
17236         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17237               (match_operand:DI 2 "" "")))]
17238   "TARGET_64BIT && !SIBLING_CALL_P (insn)
17239    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
17240 {
17241   if (constant_call_address_operand (operands[1], Pmode))
17242     return "call\t%P1";
17243   return "call\t%A1";
17244 }
17245   [(set_attr "type" "callv")])
17246
17247 (define_insn "*call_value_1_rex64_ms_sysv"
17248   [(set (match_operand 0 "" "")
17249         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17250               (match_operand:DI 2 "" "")))
17251    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17252    (clobber (reg:TI XMM6_REG))
17253    (clobber (reg:TI XMM7_REG))
17254    (clobber (reg:TI XMM8_REG))
17255    (clobber (reg:TI XMM9_REG))
17256    (clobber (reg:TI XMM10_REG))
17257    (clobber (reg:TI XMM11_REG))
17258    (clobber (reg:TI XMM12_REG))
17259    (clobber (reg:TI XMM13_REG))
17260    (clobber (reg:TI XMM14_REG))
17261    (clobber (reg:TI XMM15_REG))
17262    (clobber (reg:DI SI_REG))
17263    (clobber (reg:DI DI_REG))]
17264   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17265 {
17266   if (constant_call_address_operand (operands[1], Pmode))
17267     return "call\t%P1";
17268   return "call\t%A1";
17269 }
17270   [(set_attr "type" "callv")])
17271
17272 (define_insn "*call_value_1_rex64_large"
17273   [(set (match_operand 0 "" "")
17274         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
17275               (match_operand:DI 2 "" "")))]
17276   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17277   "call\t%A1"
17278   [(set_attr "type" "callv")])
17279
17280 (define_insn "*sibcall_value_1_rex64"
17281   [(set (match_operand 0 "" "")
17282         (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
17283               (match_operand:DI 2 "" "")))]
17284   "TARGET_64BIT && SIBLING_CALL_P (insn)"
17285   "@
17286    jmp\t%P1
17287    jmp\t%A1"
17288   [(set_attr "type" "callv")])
17289 \f
17290 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17291 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17292 ;; caught for use by garbage collectors and the like.  Using an insn that
17293 ;; maps to SIGILL makes it more likely the program will rightfully die.
17294 ;; Keeping with tradition, "6" is in honor of #UD.
17295 (define_insn "trap"
17296   [(trap_if (const_int 1) (const_int 6))]
17297   ""
17298   { return ASM_SHORT "0x0b0f"; }
17299   [(set_attr "length" "2")])
17300
17301 (define_expand "prefetch"
17302   [(prefetch (match_operand 0 "address_operand" "")
17303              (match_operand:SI 1 "const_int_operand" "")
17304              (match_operand:SI 2 "const_int_operand" ""))]
17305   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17306 {
17307   int rw = INTVAL (operands[1]);
17308   int locality = INTVAL (operands[2]);
17309
17310   gcc_assert (rw == 0 || rw == 1);
17311   gcc_assert (locality >= 0 && locality <= 3);
17312   gcc_assert (GET_MODE (operands[0]) == Pmode
17313               || GET_MODE (operands[0]) == VOIDmode);
17314
17315   /* Use 3dNOW prefetch in case we are asking for write prefetch not
17316      supported by SSE counterpart or the SSE prefetch is not available
17317      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
17318      of locality.  */
17319   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17320     operands[2] = GEN_INT (3);
17321   else
17322     operands[1] = const0_rtx;
17323 })
17324
17325 (define_insn "*prefetch_sse_<mode>"
17326   [(prefetch (match_operand:P 0 "address_operand" "p")
17327              (const_int 0)
17328              (match_operand:SI 1 "const_int_operand" ""))]
17329   "TARGET_PREFETCH_SSE"
17330 {
17331   static const char * const patterns[4] = {
17332    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17333   };
17334
17335   int locality = INTVAL (operands[1]);
17336   gcc_assert (locality >= 0 && locality <= 3);
17337
17338   return patterns[locality];
17339 }
17340   [(set_attr "type" "sse")
17341    (set_attr "atom_sse_attr" "prefetch")
17342    (set (attr "length_address")
17343         (symbol_ref "memory_address_length (operands[0])"))
17344    (set_attr "memory" "none")])
17345
17346 (define_insn "*prefetch_3dnow_<mode>"
17347   [(prefetch (match_operand:P 0 "address_operand" "p")
17348              (match_operand:SI 1 "const_int_operand" "n")
17349              (const_int 3))]
17350   "TARGET_3DNOW"
17351 {
17352   if (INTVAL (operands[1]) == 0)
17353     return "prefetch\t%a0";
17354   else
17355     return "prefetchw\t%a0";
17356 }
17357   [(set_attr "type" "mmx")
17358    (set (attr "length_address")
17359         (symbol_ref "memory_address_length (operands[0])"))
17360    (set_attr "memory" "none")])
17361
17362 (define_expand "stack_protect_set"
17363   [(match_operand 0 "memory_operand" "")
17364    (match_operand 1 "memory_operand" "")]
17365   ""
17366 {
17367 #ifdef TARGET_THREAD_SSP_OFFSET
17368   if (TARGET_64BIT)
17369     emit_insn (gen_stack_tls_protect_set_di (operands[0],
17370                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
17371   else
17372     emit_insn (gen_stack_tls_protect_set_si (operands[0],
17373                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
17374 #else
17375   if (TARGET_64BIT)
17376     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
17377   else
17378     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
17379 #endif
17380   DONE;
17381 })
17382
17383 (define_insn "stack_protect_set_si"
17384   [(set (match_operand:SI 0 "memory_operand" "=m")
17385         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
17386    (set (match_scratch:SI 2 "=&r") (const_int 0))
17387    (clobber (reg:CC FLAGS_REG))]
17388   ""
17389   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
17390   [(set_attr "type" "multi")])
17391
17392 (define_insn "stack_protect_set_di"
17393   [(set (match_operand:DI 0 "memory_operand" "=m")
17394         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
17395    (set (match_scratch:DI 2 "=&r") (const_int 0))
17396    (clobber (reg:CC FLAGS_REG))]
17397   "TARGET_64BIT"
17398   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17399   [(set_attr "type" "multi")])
17400
17401 (define_insn "stack_tls_protect_set_si"
17402   [(set (match_operand:SI 0 "memory_operand" "=m")
17403         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")]
17404                    UNSPEC_SP_TLS_SET))
17405    (set (match_scratch:SI 2 "=&r") (const_int 0))
17406    (clobber (reg:CC FLAGS_REG))]
17407   ""
17408   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
17409   [(set_attr "type" "multi")])
17410
17411 (define_insn "stack_tls_protect_set_di"
17412   [(set (match_operand:DI 0 "memory_operand" "=m")
17413         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")]
17414                    UNSPEC_SP_TLS_SET))
17415    (set (match_scratch:DI 2 "=&r") (const_int 0))
17416    (clobber (reg:CC FLAGS_REG))]
17417   "TARGET_64BIT"
17418   {
17419      /* The kernel uses a different segment register for performance reasons; a
17420         system call would not have to trash the userspace segment register,
17421         which would be expensive */
17422      if (ix86_cmodel != CM_KERNEL)
17423         return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
17424      else
17425         return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
17426   }
17427   [(set_attr "type" "multi")])
17428
17429 (define_expand "stack_protect_test"
17430   [(match_operand 0 "memory_operand" "")
17431    (match_operand 1 "memory_operand" "")
17432    (match_operand 2 "" "")]
17433   ""
17434 {
17435   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17436
17437 #ifdef TARGET_THREAD_SSP_OFFSET
17438   if (TARGET_64BIT)
17439     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
17440                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
17441   else
17442     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
17443                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
17444 #else
17445   if (TARGET_64BIT)
17446     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
17447   else
17448     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
17449 #endif
17450
17451   emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17452                                   flags, const0_rtx, operands[2]));
17453   DONE;
17454 })
17455
17456 (define_insn "stack_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 "memory_operand" "m")]
17460                     UNSPEC_SP_TEST))
17461    (clobber (match_scratch:SI 3 "=&r"))]
17462   ""
17463   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
17464   [(set_attr "type" "multi")])
17465
17466 (define_insn "stack_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 "memory_operand" "m")]
17470                     UNSPEC_SP_TEST))
17471    (clobber (match_scratch:DI 3 "=&r"))]
17472   "TARGET_64BIT"
17473   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
17474   [(set_attr "type" "multi")])
17475
17476 (define_insn "stack_tls_protect_test_si"
17477   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17478         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
17479                      (match_operand:SI 2 "const_int_operand" "i")]
17480                     UNSPEC_SP_TLS_TEST))
17481    (clobber (match_scratch:SI 3 "=r"))]
17482   ""
17483   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
17484   [(set_attr "type" "multi")])
17485
17486 (define_insn "stack_tls_protect_test_di"
17487   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17488         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
17489                      (match_operand:DI 2 "const_int_operand" "i")]
17490                     UNSPEC_SP_TLS_TEST))
17491    (clobber (match_scratch:DI 3 "=r"))]
17492   "TARGET_64BIT"
17493   {
17494      /* The kernel uses a different segment register for performance reasons; a
17495         system call would not have to trash the userspace segment register,
17496         which would be expensive */
17497      if (ix86_cmodel != CM_KERNEL)
17498         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
17499      else
17500         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
17501   }
17502   [(set_attr "type" "multi")])
17503
17504 (define_insn "sse4_2_crc32<mode>"
17505   [(set (match_operand:SI 0 "register_operand" "=r")
17506         (unspec:SI
17507           [(match_operand:SI 1 "register_operand" "0")
17508            (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17509           UNSPEC_CRC32))]
17510   "TARGET_SSE4_2 || TARGET_CRC32"
17511   "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17512   [(set_attr "type" "sselog1")
17513    (set_attr "prefix_rep" "1")
17514    (set_attr "prefix_extra" "1")
17515    (set (attr "prefix_data16")
17516      (if_then_else (match_operand:HI 2 "" "")
17517        (const_string "1")
17518        (const_string "*")))
17519    (set (attr "prefix_rex")
17520      (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
17521        (const_string "1")
17522        (const_string "*")))
17523    (set_attr "mode" "SI")])
17524
17525 (define_insn "sse4_2_crc32di"
17526   [(set (match_operand:DI 0 "register_operand" "=r")
17527         (unspec:DI
17528           [(match_operand:DI 1 "register_operand" "0")
17529            (match_operand:DI 2 "nonimmediate_operand" "rm")]
17530           UNSPEC_CRC32))]
17531   "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17532   "crc32{q}\t{%2, %0|%0, %2}"
17533   [(set_attr "type" "sselog1")
17534    (set_attr "prefix_rep" "1")
17535    (set_attr "prefix_extra" "1")
17536    (set_attr "mode" "DI")])
17537
17538 (define_expand "rdpmc"
17539   [(match_operand:DI 0 "register_operand" "")
17540    (match_operand:SI 1 "register_operand" "")]
17541   ""
17542 {
17543   rtx reg = gen_reg_rtx (DImode);
17544   rtx si;
17545
17546   /* Force operand 1 into ECX.  */
17547   rtx ecx = gen_rtx_REG (SImode, CX_REG);
17548   emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
17549   si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
17550                                 UNSPECV_RDPMC);
17551
17552   if (TARGET_64BIT)
17553     {
17554       rtvec vec = rtvec_alloc (2);
17555       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17556       rtx upper = gen_reg_rtx (DImode);
17557       rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17558                                         gen_rtvec (1, const0_rtx),
17559                                         UNSPECV_RDPMC);
17560       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
17561       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17562       emit_insn (load);
17563       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17564                                    NULL, 1, OPTAB_DIRECT);
17565       reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17566                                  OPTAB_DIRECT);
17567     }
17568   else
17569     emit_insn (gen_rtx_SET (VOIDmode, reg, si));
17570   emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17571   DONE;
17572 })
17573
17574 (define_insn "*rdpmc"
17575   [(set (match_operand:DI 0 "register_operand" "=A")
17576         (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17577                             UNSPECV_RDPMC))]
17578   "!TARGET_64BIT"
17579   "rdpmc"
17580   [(set_attr "type" "other")
17581    (set_attr "length" "2")])
17582
17583 (define_insn "*rdpmc_rex64"
17584   [(set (match_operand:DI 0 "register_operand" "=a")
17585         (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17586                             UNSPECV_RDPMC))
17587   (set (match_operand:DI 1 "register_operand" "=d")
17588        (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
17589   "TARGET_64BIT"
17590   "rdpmc"
17591   [(set_attr "type" "other")
17592    (set_attr "length" "2")])
17593
17594 (define_expand "rdtsc"
17595   [(set (match_operand:DI 0 "register_operand" "")
17596         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17597   ""
17598 {
17599   if (TARGET_64BIT)
17600     {
17601       rtvec vec = rtvec_alloc (2);
17602       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17603       rtx upper = gen_reg_rtx (DImode);
17604       rtx lower = gen_reg_rtx (DImode);
17605       rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
17606                                          gen_rtvec (1, const0_rtx),
17607                                          UNSPECV_RDTSC);
17608       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
17609       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
17610       emit_insn (load);
17611       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17612                                    NULL, 1, OPTAB_DIRECT);
17613       lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
17614                                    OPTAB_DIRECT);
17615       emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
17616       DONE;
17617     }
17618 })
17619
17620 (define_insn "*rdtsc"
17621   [(set (match_operand:DI 0 "register_operand" "=A")
17622         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17623   "!TARGET_64BIT"
17624   "rdtsc"
17625   [(set_attr "type" "other")
17626    (set_attr "length" "2")])
17627
17628 (define_insn "*rdtsc_rex64"
17629   [(set (match_operand:DI 0 "register_operand" "=a")
17630         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17631    (set (match_operand:DI 1 "register_operand" "=d")
17632         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17633   "TARGET_64BIT"
17634   "rdtsc"
17635   [(set_attr "type" "other")
17636    (set_attr "length" "2")])
17637
17638 (define_expand "rdtscp"
17639   [(match_operand:DI 0 "register_operand" "")
17640    (match_operand:SI 1 "memory_operand" "")]
17641   ""
17642 {
17643   rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17644                                     gen_rtvec (1, const0_rtx),
17645                                     UNSPECV_RDTSCP);
17646   rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
17647                                     gen_rtvec (1, const0_rtx),
17648                                     UNSPECV_RDTSCP);
17649   rtx reg = gen_reg_rtx (DImode);
17650   rtx tmp = gen_reg_rtx (SImode);
17651
17652   if (TARGET_64BIT)
17653     {
17654       rtvec vec = rtvec_alloc (3);
17655       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17656       rtx upper = gen_reg_rtx (DImode);
17657       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17658       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17659       RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
17660       emit_insn (load);
17661       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17662                                    NULL, 1, OPTAB_DIRECT);
17663       reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17664                                  OPTAB_DIRECT);
17665     }
17666   else
17667     {
17668       rtvec vec = rtvec_alloc (2);
17669       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17670       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17671       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
17672       emit_insn (load);
17673     }
17674   emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17675   emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
17676   DONE;
17677 })
17678
17679 (define_insn "*rdtscp"
17680   [(set (match_operand:DI 0 "register_operand" "=A")
17681         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17682    (set (match_operand:SI 1 "register_operand" "=c")
17683         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17684   "!TARGET_64BIT"
17685   "rdtscp"
17686   [(set_attr "type" "other")
17687    (set_attr "length" "3")])
17688
17689 (define_insn "*rdtscp_rex64"
17690   [(set (match_operand:DI 0 "register_operand" "=a")
17691         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17692    (set (match_operand:DI 1 "register_operand" "=d")
17693         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17694    (set (match_operand:SI 2 "register_operand" "=c")
17695         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17696   "TARGET_64BIT"
17697   "rdtscp"
17698   [(set_attr "type" "other")
17699    (set_attr "length" "3")])
17700
17701 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17702 ;;
17703 ;; LWP instructions
17704 ;;
17705 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17706
17707 (define_expand "lwp_llwpcb"
17708   [(unspec_volatile [(match_operand 0 "register_operand" "r")]
17709                     UNSPECV_LLWP_INTRINSIC)]
17710   "TARGET_LWP"
17711   "")
17712
17713 (define_insn "*lwp_llwpcb<mode>1"
17714   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
17715                     UNSPECV_LLWP_INTRINSIC)]
17716   "TARGET_LWP"
17717   "llwpcb\t%0"
17718   [(set_attr "type" "lwp")
17719    (set_attr "mode" "<MODE>")
17720    (set_attr "length" "5")])
17721
17722 (define_expand "lwp_slwpcb"
17723   [(set (match_operand 0 "register_operand" "=r")
17724         (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
17725   "TARGET_LWP"
17726   {
17727     if (TARGET_64BIT)
17728       emit_insn (gen_lwp_slwpcbdi (operands[0]));
17729     else
17730       emit_insn (gen_lwp_slwpcbsi (operands[0]));
17731     DONE;
17732   })
17733
17734 (define_insn "lwp_slwpcb<mode>"
17735   [(set (match_operand:P 0 "register_operand" "=r")
17736         (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
17737   "TARGET_LWP"
17738   "slwpcb\t%0"
17739   [(set_attr "type" "lwp")
17740    (set_attr "mode" "<MODE>")
17741    (set_attr "length" "5")])
17742
17743 (define_expand "lwp_lwpval<mode>3"
17744   [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
17745                      (match_operand:SI 2 "nonimmediate_operand" "rm")
17746                      (match_operand:SI 3 "const_int_operand" "i")]
17747                     UNSPECV_LWPVAL_INTRINSIC)]
17748   "TARGET_LWP"
17749   "/* Avoid unused variable warning.  */
17750    (void) operand0;")
17751
17752 (define_insn "*lwp_lwpval<mode>3_1"
17753   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
17754                      (match_operand:SI 1 "nonimmediate_operand" "rm")
17755                      (match_operand:SI 2 "const_int_operand" "i")]
17756                     UNSPECV_LWPVAL_INTRINSIC)]
17757   "TARGET_LWP"
17758   "lwpval\t{%2, %1, %0|%0, %1, %2}"
17759   [(set_attr "type" "lwp")
17760    (set_attr "mode" "<MODE>")
17761    (set (attr "length")
17762         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
17763
17764 (define_expand "lwp_lwpins<mode>3"
17765   [(set (reg:CCC FLAGS_REG)
17766         (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
17767                               (match_operand:SI 2 "nonimmediate_operand" "rm")
17768                               (match_operand:SI 3 "const_int_operand" "i")]
17769                              UNSPECV_LWPINS_INTRINSIC))
17770    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
17771         (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
17772   "TARGET_LWP"
17773   "")
17774
17775 (define_insn "*lwp_lwpins<mode>3_1"
17776   [(set (reg:CCC FLAGS_REG)
17777         (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
17778                               (match_operand:SI 1 "nonimmediate_operand" "rm")
17779                               (match_operand:SI 2 "const_int_operand" "i")]
17780                              UNSPECV_LWPINS_INTRINSIC))]
17781   "TARGET_LWP"
17782   "lwpins\t{%2, %1, %0|%0, %1, %2}"
17783   [(set_attr "type" "lwp")
17784    (set_attr "mode" "<MODE>")
17785    (set (attr "length")
17786         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
17787
17788 (define_insn "rdfsbase<mode>"
17789   [(set (match_operand:SWI48 0 "register_operand" "=r")
17790         (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDFSBASE))]
17791   "TARGET_64BIT && TARGET_FSGSBASE"
17792   "rdfsbase %0"
17793   [(set_attr "type" "other")
17794    (set_attr "prefix_extra" "2")])
17795
17796 (define_insn "rdgsbase<mode>"
17797   [(set (match_operand:SWI48 0 "register_operand" "=r")
17798         (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDGSBASE))]
17799   "TARGET_64BIT && TARGET_FSGSBASE"
17800   "rdgsbase %0"
17801   [(set_attr "type" "other")
17802    (set_attr "prefix_extra" "2")])
17803
17804 (define_insn "wrfsbase<mode>"
17805   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
17806                     UNSPECV_WRFSBASE)]
17807   "TARGET_64BIT && TARGET_FSGSBASE"
17808   "wrfsbase %0"
17809   [(set_attr "type" "other")
17810    (set_attr "prefix_extra" "2")])
17811
17812 (define_insn "wrgsbase<mode>"
17813   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
17814                     UNSPECV_WRGSBASE)]
17815   "TARGET_64BIT && TARGET_FSGSBASE"
17816   "wrgsbase %0"
17817   [(set_attr "type" "other")
17818    (set_attr "prefix_extra" "2")])
17819
17820 (define_expand "rdrand<mode>"
17821   [(set (match_operand:SWI248 0 "register_operand" "=r")
17822         (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))]
17823   "TARGET_RDRND"
17824 {
17825   rtx retry_label, insn, ccc;
17826
17827   retry_label = gen_label_rtx ();
17828
17829   emit_label (retry_label);
17830
17831   /* Generate rdrand.  */
17832   emit_insn (gen_rdrand<mode>_1 (operands[0]));
17833
17834   /* Retry if the carry flag isn't valid.  */
17835   ccc = gen_rtx_REG (CCCmode, FLAGS_REG);
17836   ccc = gen_rtx_EQ (VOIDmode, ccc, const0_rtx);
17837   ccc = gen_rtx_IF_THEN_ELSE (VOIDmode, ccc, pc_rtx,
17838                               gen_rtx_LABEL_REF (VOIDmode, retry_label));
17839   insn = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, ccc));
17840   JUMP_LABEL (insn) = retry_label;
17841
17842   DONE;
17843 })
17844
17845 (define_insn "rdrand<mode>_1"
17846   [(set (match_operand:SWI248 0 "register_operand" "=r")
17847         (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))]
17848   "TARGET_RDRND"
17849   "rdrand %0"
17850   [(set_attr "type" "other")
17851    (set_attr "prefix_extra" "1")])
17852
17853 (include "mmx.md")
17854 (include "sse.md")
17855 (include "sync.md")