OSDN Git Service

Replace unspec_volatile with unspec in split_stack_return.
[pf3gnuchains/gcc-fork.git] / gcc / config / i386 / i386.md
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
7 ;;
8 ;; This file is part of GCC.
9 ;;
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 3, or (at your option)
13 ;; any later version.
14 ;;
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 ;; GNU General Public License for more details.
19 ;;
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING3.  If not see
22 ;; <http://www.gnu.org/licenses/>.  */
23 ;;
24 ;; The original PO technology requires these to be ordered by speed,
25 ;; so that assigner will pick the fastest.
26 ;;
27 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
28 ;;
29 ;; The special asm out single letter directives following a '%' are:
30 ;; L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
31 ;; C -- print opcode suffix for set/cmov insn.
32 ;; c -- like C, but print reversed condition
33 ;; F,f -- likewise, but for floating-point.
34 ;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
35 ;;      otherwise nothing
36 ;; R -- print the prefix for register names.
37 ;; z -- print the opcode suffix for the size of the current operand.
38 ;; Z -- likewise, with special suffixes for x87 instructions.
39 ;; * -- print a star (in certain assembler syntax)
40 ;; A -- print an absolute memory reference.
41 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
42 ;; s -- print a shift double count, followed by the assemblers argument
43 ;;      delimiter.
44 ;; b -- print the QImode name of the register for the indicated operand.
45 ;;      %b0 would print %al if operands[0] is reg 0.
46 ;; w --  likewise, print the HImode name of the register.
47 ;; k --  likewise, print the SImode name of the register.
48 ;; q --  likewise, print the DImode name of the register.
49 ;; x --  likewise, print the V4SFmode name of the register.
50 ;; t --  likewise, print the V8SFmode name of the register.
51 ;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
52 ;; y -- print "st(0)" instead of "st" as a register.
53 ;; d -- print duplicated register operand for AVX instruction.
54 ;; D -- print condition for SSE cmp instruction.
55 ;; P -- if PIC, print an @PLT suffix.
56 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
57 ;; & -- print some in-use local-dynamic symbol name.
58 ;; H -- print a memory address offset by 8; used for sse high-parts
59 ;; Y -- print condition for XOP pcom* instruction.
60 ;; + -- print a branch hint as 'cs' or 'ds' prefix
61 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
62 ;; @ -- print a segment register of thread base pointer load
63
64 ;; UNSPEC usage:
65
66 (define_c_enum "unspec" [
67   ;; Relocation specifiers
68   UNSPEC_GOT
69   UNSPEC_GOTOFF
70   UNSPEC_GOTPCREL
71   UNSPEC_GOTTPOFF
72   UNSPEC_TPOFF
73   UNSPEC_NTPOFF
74   UNSPEC_DTPOFF
75   UNSPEC_GOTNTPOFF
76   UNSPEC_INDNTPOFF
77   UNSPEC_PLTOFF
78   UNSPEC_MACHOPIC_OFFSET
79
80   ;; Prologue support
81   UNSPEC_STACK_ALLOC
82   UNSPEC_SET_GOT
83   UNSPEC_REG_SAVE
84   UNSPEC_DEF_CFA
85   UNSPEC_SET_RIP
86   UNSPEC_SET_GOT_OFFSET
87   UNSPEC_MEMORY_BLOCKAGE
88   UNSPEC_STACK_CHECK
89
90   ;; TLS support
91   UNSPEC_TP
92   UNSPEC_TLS_GD
93   UNSPEC_TLS_LD_BASE
94   UNSPEC_TLSDESC
95
96   ;; Other random patterns
97   UNSPEC_SCAS
98   UNSPEC_FNSTSW
99   UNSPEC_SAHF
100   UNSPEC_PARITY
101   UNSPEC_FSTCW
102   UNSPEC_ADD_CARRY
103   UNSPEC_FLDCW
104   UNSPEC_REP
105   UNSPEC_LD_MPIC        ; load_macho_picbase
106   UNSPEC_TRUNC_NOOP
107   UNSPEC_DIV_ALREADY_SPLIT
108
109   ;; For SSE/MMX support:
110   UNSPEC_FIX_NOTRUNC
111   UNSPEC_MASKMOV
112   UNSPEC_MOVMSK
113   UNSPEC_MOVNT
114   UNSPEC_MOVU
115   UNSPEC_RCP
116   UNSPEC_RSQRT
117   UNSPEC_SFENCE
118   UNSPEC_PFRCP
119   UNSPEC_PFRCPIT1
120   UNSPEC_PFRCPIT2
121   UNSPEC_PFRSQRT
122   UNSPEC_PFRSQIT1
123   UNSPEC_MFENCE
124   UNSPEC_LFENCE
125   UNSPEC_PSADBW
126   UNSPEC_LDDQU
127   UNSPEC_MS_TO_SYSV_CALL
128
129   ;; Generic math support
130   UNSPEC_COPYSIGN
131   UNSPEC_IEEE_MIN       ; not commutative
132   UNSPEC_IEEE_MAX       ; not commutative
133
134   ;; x87 Floating point
135   UNSPEC_SIN
136   UNSPEC_COS
137   UNSPEC_FPATAN
138   UNSPEC_FYL2X
139   UNSPEC_FYL2XP1
140   UNSPEC_FRNDINT
141   UNSPEC_FIST
142   UNSPEC_F2XM1
143   UNSPEC_TAN
144   UNSPEC_FXAM
145
146   ;; x87 Rounding
147   UNSPEC_FRNDINT_FLOOR
148   UNSPEC_FRNDINT_CEIL
149   UNSPEC_FRNDINT_TRUNC
150   UNSPEC_FRNDINT_MASK_PM
151   UNSPEC_FIST_FLOOR
152   UNSPEC_FIST_CEIL
153
154   ;; x87 Double output FP
155   UNSPEC_SINCOS_COS
156   UNSPEC_SINCOS_SIN
157   UNSPEC_XTRACT_FRACT
158   UNSPEC_XTRACT_EXP
159   UNSPEC_FSCALE_FRACT
160   UNSPEC_FSCALE_EXP
161   UNSPEC_FPREM_F
162   UNSPEC_FPREM_U
163   UNSPEC_FPREM1_F
164   UNSPEC_FPREM1_U
165
166   UNSPEC_C2_FLAG
167   UNSPEC_FXAM_MEM
168
169   ;; SSP patterns
170   UNSPEC_SP_SET
171   UNSPEC_SP_TEST
172   UNSPEC_SP_TLS_SET
173   UNSPEC_SP_TLS_TEST
174
175   ;; SSSE3
176   UNSPEC_PSHUFB
177   UNSPEC_PSIGN
178   UNSPEC_PALIGNR
179
180   ;; For SSE4A support
181   UNSPEC_EXTRQI
182   UNSPEC_EXTRQ
183   UNSPEC_INSERTQI
184   UNSPEC_INSERTQ
185
186   ;; For SSE4.1 support
187   UNSPEC_BLENDV
188   UNSPEC_INSERTPS
189   UNSPEC_DP
190   UNSPEC_MOVNTDQA
191   UNSPEC_MPSADBW
192   UNSPEC_PHMINPOSUW
193   UNSPEC_PTEST
194   UNSPEC_ROUND
195
196   ;; For SSE4.2 support
197   UNSPEC_CRC32
198   UNSPEC_PCMPESTR
199   UNSPEC_PCMPISTR
200
201   ;; For FMA4 support
202   UNSPEC_FMADDSUB
203   UNSPEC_XOP_UNSIGNED_CMP
204   UNSPEC_XOP_TRUEFALSE
205   UNSPEC_XOP_PERMUTE
206   UNSPEC_FRCZ
207
208   ;; For AES support
209   UNSPEC_AESENC
210   UNSPEC_AESENCLAST
211   UNSPEC_AESDEC
212   UNSPEC_AESDECLAST
213   UNSPEC_AESIMC
214   UNSPEC_AESKEYGENASSIST
215
216   ;; For PCLMUL support
217   UNSPEC_PCLMUL
218
219   ;; For AVX support
220   UNSPEC_PCMP
221   UNSPEC_VPERMIL
222   UNSPEC_VPERMIL2
223   UNSPEC_VPERMIL2F128
224   UNSPEC_MASKLOAD
225   UNSPEC_MASKSTORE
226   UNSPEC_CAST
227   UNSPEC_VTESTP
228   UNSPEC_VCVTPH2PS
229   UNSPEC_VCVTPS2PH
230 ])
231
232 (define_c_enum "unspecv" [
233   UNSPECV_BLOCKAGE
234   UNSPECV_STACK_PROBE
235   UNSPECV_PROBE_STACK_RANGE
236   UNSPECV_EMMS
237   UNSPECV_LDMXCSR
238   UNSPECV_STMXCSR
239   UNSPECV_FEMMS
240   UNSPECV_CLFLUSH
241   UNSPECV_ALIGN
242   UNSPECV_MONITOR
243   UNSPECV_MWAIT
244   UNSPECV_CMPXCHG
245   UNSPECV_XCHG
246   UNSPECV_LOCK
247   UNSPECV_PROLOGUE_USE
248   UNSPECV_CLD
249   UNSPECV_NOPS
250   UNSPECV_VZEROALL
251   UNSPECV_VZEROUPPER
252   UNSPECV_RDTSC
253   UNSPECV_RDTSCP
254   UNSPECV_RDPMC
255   UNSPECV_LLWP_INTRINSIC
256   UNSPECV_SLWP_INTRINSIC
257   UNSPECV_LWPVAL_INTRINSIC
258   UNSPECV_LWPINS_INTRINSIC
259   UNSPECV_RDFSBASE
260   UNSPECV_RDGSBASE
261   UNSPECV_WRFSBASE
262   UNSPECV_WRGSBASE
263   UNSPECV_RDRAND
264 ])
265
266 ;; Constants to represent pcomtrue/pcomfalse variants
267 (define_constants
268   [(PCOM_FALSE                  0)
269    (PCOM_TRUE                   1)
270    (COM_FALSE_S                 2)
271    (COM_FALSE_P                 3)
272    (COM_TRUE_S                  4)
273    (COM_TRUE_P                  5)
274   ])
275
276 ;; Constants used in the XOP pperm instruction
277 (define_constants
278   [(PPERM_SRC                   0x00)   /* copy source */
279    (PPERM_INVERT                0x20)   /* invert source */
280    (PPERM_REVERSE               0x40)   /* bit reverse source */
281    (PPERM_REV_INV               0x60)   /* bit reverse & invert src */
282    (PPERM_ZERO                  0x80)   /* all 0's */
283    (PPERM_ONES                  0xa0)   /* all 1's */
284    (PPERM_SIGN                  0xc0)   /* propagate sign bit */
285    (PPERM_INV_SIGN              0xe0)   /* invert & propagate sign */
286    (PPERM_SRC1                  0x00)   /* use first source byte */
287    (PPERM_SRC2                  0x10)   /* use second source byte */
288    ])
289
290 ;; Registers by name.
291 (define_constants
292   [(AX_REG                       0)
293    (DX_REG                       1)
294    (CX_REG                       2)
295    (BX_REG                       3)
296    (SI_REG                       4)
297    (DI_REG                       5)
298    (BP_REG                       6)
299    (SP_REG                       7)
300    (ST0_REG                      8)
301    (ST1_REG                      9)
302    (ST2_REG                     10)
303    (ST3_REG                     11)
304    (ST4_REG                     12)
305    (ST5_REG                     13)
306    (ST6_REG                     14)
307    (ST7_REG                     15)
308    (FLAGS_REG                   17)
309    (FPSR_REG                    18)
310    (FPCR_REG                    19)
311    (XMM0_REG                    21)
312    (XMM1_REG                    22)
313    (XMM2_REG                    23)
314    (XMM3_REG                    24)
315    (XMM4_REG                    25)
316    (XMM5_REG                    26)
317    (XMM6_REG                    27)
318    (XMM7_REG                    28)
319    (MM0_REG                     29)
320    (MM1_REG                     30)
321    (MM2_REG                     31)
322    (MM3_REG                     32)
323    (MM4_REG                     33)
324    (MM5_REG                     34)
325    (MM6_REG                     35)
326    (MM7_REG                     36)
327    (R8_REG                      37)
328    (R9_REG                      38)
329    (R10_REG                     39)
330    (R11_REG                     40)
331    (R12_REG                     41)
332    (R13_REG                     42)
333    (XMM8_REG                    45)
334    (XMM9_REG                    46)
335    (XMM10_REG                   47)
336    (XMM11_REG                   48)
337    (XMM12_REG                   49)
338    (XMM13_REG                   50)
339    (XMM14_REG                   51)
340    (XMM15_REG                   52)
341   ])
342
343 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
344 ;; from i386.c.
345
346 ;; In C guard expressions, put expressions which may be compile-time
347 ;; constants first.  This allows for better optimization.  For
348 ;; example, write "TARGET_64BIT && reload_completed", not
349 ;; "reload_completed && TARGET_64BIT".
350
351 \f
352 ;; Processor type.
353 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,atom,
354                     generic64,amdfam10,bdver1"
355   (const (symbol_ref "ix86_schedule")))
356
357 ;; A basic instruction type.  Refinements due to arguments to be
358 ;; provided in other attributes.
359 (define_attr "type"
360   "other,multi,
361    alu,alu1,negnot,imov,imovx,lea,
362    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
363    icmp,test,ibr,setcc,icmov,
364    push,pop,call,callv,leave,
365    str,bitmanip,
366    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
367    sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
368    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
369    ssemuladd,sse4arg,lwp,
370    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
371   (const_string "other"))
372
373 ;; Main data type used by the insn
374 (define_attr "mode"
375   "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
376   (const_string "unknown"))
377
378 ;; The CPU unit operations uses.
379 (define_attr "unit" "integer,i387,sse,mmx,unknown"
380   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
381            (const_string "i387")
382          (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
383                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
384                           ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
385            (const_string "sse")
386          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
387            (const_string "mmx")
388          (eq_attr "type" "other")
389            (const_string "unknown")]
390          (const_string "integer")))
391
392 ;; The (bounding maximum) length of an instruction immediate.
393 (define_attr "length_immediate" ""
394   (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
395                           bitmanip")
396            (const_int 0)
397          (eq_attr "unit" "i387,sse,mmx")
398            (const_int 0)
399          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
400                           imul,icmp,push,pop")
401            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
402          (eq_attr "type" "imov,test")
403            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
404          (eq_attr "type" "call")
405            (if_then_else (match_operand 0 "constant_call_address_operand" "")
406              (const_int 4)
407              (const_int 0))
408          (eq_attr "type" "callv")
409            (if_then_else (match_operand 1 "constant_call_address_operand" "")
410              (const_int 4)
411              (const_int 0))
412          ;; We don't know the size before shorten_branches.  Expect
413          ;; the instruction to fit for better scheduling.
414          (eq_attr "type" "ibr")
415            (const_int 1)
416          ]
417          (symbol_ref "/* Update immediate_length and other attributes! */
418                       gcc_unreachable (),1")))
419
420 ;; The (bounding maximum) length of an instruction address.
421 (define_attr "length_address" ""
422   (cond [(eq_attr "type" "str,other,multi,fxch")
423            (const_int 0)
424          (and (eq_attr "type" "call")
425               (match_operand 0 "constant_call_address_operand" ""))
426              (const_int 0)
427          (and (eq_attr "type" "callv")
428               (match_operand 1 "constant_call_address_operand" ""))
429              (const_int 0)
430          ]
431          (symbol_ref "ix86_attr_length_address_default (insn)")))
432
433 ;; Set when length prefix is used.
434 (define_attr "prefix_data16" ""
435   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
436            (const_int 0)
437          (eq_attr "mode" "HI")
438            (const_int 1)
439          (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
440            (const_int 1)
441         ]
442         (const_int 0)))
443
444 ;; Set when string REP prefix is used.
445 (define_attr "prefix_rep" ""
446   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
447            (const_int 0)
448          (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
449            (const_int 1)
450         ]
451         (const_int 0)))
452
453 ;; Set when 0f opcode prefix is used.
454 (define_attr "prefix_0f" ""
455   (if_then_else
456     (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
457          (eq_attr "unit" "sse,mmx"))
458     (const_int 1)
459     (const_int 0)))
460
461 ;; Set when REX opcode prefix is used.
462 (define_attr "prefix_rex" ""
463   (cond [(eq (symbol_ref "TARGET_64BIT") (const_int 0))
464            (const_int 0)
465          (and (eq_attr "mode" "DI")
466               (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
467                    (eq_attr "unit" "!mmx")))
468            (const_int 1)
469          (and (eq_attr "mode" "QI")
470               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
471                   (const_int 0)))
472            (const_int 1)
473          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
474              (const_int 0))
475            (const_int 1)
476          (and (eq_attr "type" "imovx")
477               (match_operand:QI 1 "ext_QIreg_operand" ""))
478            (const_int 1)
479         ]
480         (const_int 0)))
481
482 ;; There are also additional prefixes in 3DNOW, SSSE3.
483 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
484 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
485 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
486 (define_attr "prefix_extra" ""
487   (cond [(eq_attr "type" "ssemuladd,sse4arg")
488            (const_int 2)
489          (eq_attr "type" "sseiadd1,ssecvt1")
490            (const_int 1)
491         ]
492         (const_int 0)))
493
494 ;; Prefix used: original, VEX or maybe VEX.
495 (define_attr "prefix" "orig,vex,maybe_vex"
496   (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
497     (const_string "vex")
498     (const_string "orig")))
499
500 ;; VEX W bit is used.
501 (define_attr "prefix_vex_w" "" (const_int 0))
502
503 ;; The length of VEX prefix
504 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
505 ;; 0f38/0f3a prefixes can't.  In i386.md 0f3[8a] is
506 ;; still prefix_0f 1, with prefix_extra 1.
507 (define_attr "length_vex" ""
508   (if_then_else (and (eq_attr "prefix_0f" "1")
509                      (eq_attr "prefix_extra" "0"))
510     (if_then_else (eq_attr "prefix_vex_w" "1")
511       (symbol_ref "ix86_attr_length_vex_default (insn, 1, 1)")
512       (symbol_ref "ix86_attr_length_vex_default (insn, 1, 0)"))
513     (if_then_else (eq_attr "prefix_vex_w" "1")
514       (symbol_ref "ix86_attr_length_vex_default (insn, 0, 1)")
515       (symbol_ref "ix86_attr_length_vex_default (insn, 0, 0)"))))
516
517 ;; Set when modrm byte is used.
518 (define_attr "modrm" ""
519   (cond [(eq_attr "type" "str,leave")
520            (const_int 0)
521          (eq_attr "unit" "i387")
522            (const_int 0)
523          (and (eq_attr "type" "incdec")
524               (and (eq (symbol_ref "TARGET_64BIT") (const_int 0))
525                    (ior (match_operand:SI 1 "register_operand" "")
526                         (match_operand:HI 1 "register_operand" ""))))
527            (const_int 0)
528          (and (eq_attr "type" "push")
529               (not (match_operand 1 "memory_operand" "")))
530            (const_int 0)
531          (and (eq_attr "type" "pop")
532               (not (match_operand 0 "memory_operand" "")))
533            (const_int 0)
534          (and (eq_attr "type" "imov")
535               (and (not (eq_attr "mode" "DI"))
536                    (ior (and (match_operand 0 "register_operand" "")
537                              (match_operand 1 "immediate_operand" ""))
538                         (ior (and (match_operand 0 "ax_reg_operand" "")
539                                   (match_operand 1 "memory_displacement_only_operand" ""))
540                              (and (match_operand 0 "memory_displacement_only_operand" "")
541                                   (match_operand 1 "ax_reg_operand" ""))))))
542            (const_int 0)
543          (and (eq_attr "type" "call")
544               (match_operand 0 "constant_call_address_operand" ""))
545              (const_int 0)
546          (and (eq_attr "type" "callv")
547               (match_operand 1 "constant_call_address_operand" ""))
548              (const_int 0)
549          (and (eq_attr "type" "alu,alu1,icmp,test")
550               (match_operand 0 "ax_reg_operand" ""))
551              (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
552          ]
553          (const_int 1)))
554
555 ;; The (bounding maximum) length of an instruction in bytes.
556 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
557 ;; Later we may want to split them and compute proper length as for
558 ;; other insns.
559 (define_attr "length" ""
560   (cond [(eq_attr "type" "other,multi,fistp,frndint")
561            (const_int 16)
562          (eq_attr "type" "fcmp")
563            (const_int 4)
564          (eq_attr "unit" "i387")
565            (plus (const_int 2)
566                  (plus (attr "prefix_data16")
567                        (attr "length_address")))
568          (ior (eq_attr "prefix" "vex")
569               (and (eq_attr "prefix" "maybe_vex")
570                     (ne (symbol_ref "TARGET_AVX") (const_int 0))))
571            (plus (attr "length_vex")
572                  (plus (attr "length_immediate")
573                        (plus (attr "modrm")
574                              (attr "length_address"))))]
575          (plus (plus (attr "modrm")
576                      (plus (attr "prefix_0f")
577                            (plus (attr "prefix_rex")
578                                  (plus (attr "prefix_extra")
579                                        (const_int 1)))))
580                (plus (attr "prefix_rep")
581                      (plus (attr "prefix_data16")
582                            (plus (attr "length_immediate")
583                                  (attr "length_address")))))))
584
585 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
586 ;; `store' if there is a simple memory reference therein, or `unknown'
587 ;; if the instruction is complex.
588
589 (define_attr "memory" "none,load,store,both,unknown"
590   (cond [(eq_attr "type" "other,multi,str,lwp")
591            (const_string "unknown")
592          (eq_attr "type" "lea,fcmov,fpspc")
593            (const_string "none")
594          (eq_attr "type" "fistp,leave")
595            (const_string "both")
596          (eq_attr "type" "frndint")
597            (const_string "load")
598          (eq_attr "type" "push")
599            (if_then_else (match_operand 1 "memory_operand" "")
600              (const_string "both")
601              (const_string "store"))
602          (eq_attr "type" "pop")
603            (if_then_else (match_operand 0 "memory_operand" "")
604              (const_string "both")
605              (const_string "load"))
606          (eq_attr "type" "setcc")
607            (if_then_else (match_operand 0 "memory_operand" "")
608              (const_string "store")
609              (const_string "none"))
610          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
611            (if_then_else (ior (match_operand 0 "memory_operand" "")
612                               (match_operand 1 "memory_operand" ""))
613              (const_string "load")
614              (const_string "none"))
615          (eq_attr "type" "ibr")
616            (if_then_else (match_operand 0 "memory_operand" "")
617              (const_string "load")
618              (const_string "none"))
619          (eq_attr "type" "call")
620            (if_then_else (match_operand 0 "constant_call_address_operand" "")
621              (const_string "none")
622              (const_string "load"))
623          (eq_attr "type" "callv")
624            (if_then_else (match_operand 1 "constant_call_address_operand" "")
625              (const_string "none")
626              (const_string "load"))
627          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
628               (match_operand 1 "memory_operand" ""))
629            (const_string "both")
630          (and (match_operand 0 "memory_operand" "")
631               (match_operand 1 "memory_operand" ""))
632            (const_string "both")
633          (match_operand 0 "memory_operand" "")
634            (const_string "store")
635          (match_operand 1 "memory_operand" "")
636            (const_string "load")
637          (and (eq_attr "type"
638                  "!alu1,negnot,ishift1,
639                    imov,imovx,icmp,test,bitmanip,
640                    fmov,fcmp,fsgn,
641                    sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
642                    sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
643               (match_operand 2 "memory_operand" ""))
644            (const_string "load")
645          (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
646               (match_operand 3 "memory_operand" ""))
647            (const_string "load")
648         ]
649         (const_string "none")))
650
651 ;; Indicates if an instruction has both an immediate and a displacement.
652
653 (define_attr "imm_disp" "false,true,unknown"
654   (cond [(eq_attr "type" "other,multi")
655            (const_string "unknown")
656          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
657               (and (match_operand 0 "memory_displacement_operand" "")
658                    (match_operand 1 "immediate_operand" "")))
659            (const_string "true")
660          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
661               (and (match_operand 0 "memory_displacement_operand" "")
662                    (match_operand 2 "immediate_operand" "")))
663            (const_string "true")
664         ]
665         (const_string "false")))
666
667 ;; Indicates if an FP operation has an integer source.
668
669 (define_attr "fp_int_src" "false,true"
670   (const_string "false"))
671
672 ;; Defines rounding mode of an FP operation.
673
674 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
675   (const_string "any"))
676
677 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
678 (define_attr "use_carry" "0,1" (const_string "0"))
679
680 ;; Define attribute to indicate unaligned ssemov insns
681 (define_attr "movu" "0,1" (const_string "0"))
682
683 ;; Describe a user's asm statement.
684 (define_asm_attributes
685   [(set_attr "length" "128")
686    (set_attr "type" "multi")])
687
688 (define_code_iterator plusminus [plus minus])
689
690 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
691
692 ;; Base name for define_insn
693 (define_code_attr plusminus_insn
694   [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
695    (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
696
697 ;; Base name for insn mnemonic.
698 (define_code_attr plusminus_mnemonic
699   [(plus "add") (ss_plus "adds") (us_plus "addus")
700    (minus "sub") (ss_minus "subs") (us_minus "subus")])
701 (define_code_attr plusminus_carry_mnemonic
702   [(plus "adc") (minus "sbb")])
703
704 ;; Mark commutative operators as such in constraints.
705 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
706                         (minus "") (ss_minus "") (us_minus "")])
707
708 ;; Mapping of signed max and min
709 (define_code_iterator smaxmin [smax smin])
710
711 ;; Mapping of unsigned max and min
712 (define_code_iterator umaxmin [umax umin])
713
714 ;; Base name for integer and FP insn mnemonic
715 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
716                               (umax "maxu") (umin "minu")])
717 (define_code_attr maxmin_float [(smax "max") (smin "min")])
718
719 ;; Mapping of logic operators
720 (define_code_iterator any_logic [and ior xor])
721 (define_code_iterator any_or [ior xor])
722
723 ;; Base name for insn mnemonic.
724 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
725
726 ;; Mapping of shift-right operators
727 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
728
729 ;; Base name for define_insn
730 (define_code_attr shiftrt_insn [(lshiftrt "lshr") (ashiftrt "ashr")])
731
732 ;; Base name for insn mnemonic.
733 (define_code_attr shiftrt [(lshiftrt "shr") (ashiftrt "sar")])
734
735 ;; Mapping of rotate operators
736 (define_code_iterator any_rotate [rotate rotatert])
737
738 ;; Base name for define_insn
739 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
740
741 ;; Base name for insn mnemonic.
742 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
743
744 ;; Mapping of abs neg operators
745 (define_code_iterator absneg [abs neg])
746
747 ;; Base name for x87 insn mnemonic.
748 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
749
750 ;; Used in signed and unsigned widening multiplications.
751 (define_code_iterator any_extend [sign_extend zero_extend])
752
753 ;; Various insn prefixes for signed and unsigned operations.
754 (define_code_attr u [(sign_extend "") (zero_extend "u")
755                      (div "") (udiv "u")])
756 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
757
758 ;; Used in signed and unsigned divisions.
759 (define_code_iterator any_div [div udiv])
760
761 ;; Instruction prefix for signed and unsigned operations.
762 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")
763                              (div "i") (udiv "")])
764
765 ;; 64bit single word integer modes.
766 (define_mode_iterator SWI1248x [QI HI SI DI])
767
768 ;; 64bit single word integer modes without QImode and HImode.
769 (define_mode_iterator SWI48x [SI DI])
770
771 ;; Single word integer modes.
772 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
773
774 ;; Single word integer modes without SImode and DImode.
775 (define_mode_iterator SWI12 [QI HI])
776
777 ;; Single word integer modes without DImode.
778 (define_mode_iterator SWI124 [QI HI SI])
779
780 ;; Single word integer modes without QImode and DImode.
781 (define_mode_iterator SWI24 [HI SI])
782
783 ;; Single word integer modes without QImode.
784 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
785
786 ;; Single word integer modes without QImode and HImode.
787 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
788
789 ;; All math-dependant single and double word integer modes.
790 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
791                              (HI "TARGET_HIMODE_MATH")
792                              SI DI (TI "TARGET_64BIT")])
793
794 ;; Math-dependant single word integer modes.
795 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
796                             (HI "TARGET_HIMODE_MATH")
797                             SI (DI "TARGET_64BIT")])
798
799 ;; Math-dependant single word integer modes without DImode.
800 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
801                                (HI "TARGET_HIMODE_MATH")
802                                SI])
803
804 ;; Math-dependant single word integer modes without QImode.
805 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
806                                SI (DI "TARGET_64BIT")])
807
808 ;; Double word integer modes.
809 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
810                            (TI "TARGET_64BIT")])
811
812 ;; Double word integer modes as mode attribute.
813 (define_mode_attr DWI [(SI "DI") (DI "TI")])
814 (define_mode_attr dwi [(SI "di") (DI "ti")])
815
816 ;; Half mode for double word integer modes.
817 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
818                             (DI "TARGET_64BIT")])
819
820 ;; Instruction suffix for integer modes.
821 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
822
823 ;; Pointer size prefix for integer modes (Intel asm dialect)
824 (define_mode_attr iptrsize [(QI "BYTE")
825                             (HI "WORD")
826                             (SI "DWORD")
827                             (DI "QWORD")])
828
829 ;; Register class for integer modes.
830 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
831
832 ;; Immediate operand constraint for integer modes.
833 (define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")])
834
835 ;; General operand constraint for word modes.
836 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "g") (DI "rme")])
837
838 ;; Immediate operand constraint for double integer modes.
839 (define_mode_attr di [(SI "iF") (DI "e")])
840
841 ;; Immediate operand constraint for shifts.
842 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
843
844 ;; General operand predicate for integer modes.
845 (define_mode_attr general_operand
846         [(QI "general_operand")
847          (HI "general_operand")
848          (SI "general_operand")
849          (DI "x86_64_general_operand")
850          (TI "x86_64_general_operand")])
851
852 ;; General sign/zero extend operand predicate for integer modes.
853 (define_mode_attr general_szext_operand
854         [(QI "general_operand")
855          (HI "general_operand")
856          (SI "general_operand")
857          (DI "x86_64_szext_general_operand")])
858
859 ;; Immediate operand predicate for integer modes.
860 (define_mode_attr immediate_operand
861         [(QI "immediate_operand")
862          (HI "immediate_operand")
863          (SI "immediate_operand")
864          (DI "x86_64_immediate_operand")])
865
866 ;; Nonmemory operand predicate for integer modes.
867 (define_mode_attr nonmemory_operand
868         [(QI "nonmemory_operand")
869          (HI "nonmemory_operand")
870          (SI "nonmemory_operand")
871          (DI "x86_64_nonmemory_operand")])
872
873 ;; Operand predicate for shifts.
874 (define_mode_attr shift_operand
875         [(QI "nonimmediate_operand")
876          (HI "nonimmediate_operand")
877          (SI "nonimmediate_operand")
878          (DI "shiftdi_operand")
879          (TI "register_operand")])
880
881 ;; Operand predicate for shift argument.
882 (define_mode_attr shift_immediate_operand
883         [(QI "const_1_to_31_operand")
884          (HI "const_1_to_31_operand")
885          (SI "const_1_to_31_operand")
886          (DI "const_1_to_63_operand")])
887
888 ;; Input operand predicate for arithmetic left shifts.
889 (define_mode_attr ashl_input_operand
890         [(QI "nonimmediate_operand")
891          (HI "nonimmediate_operand")
892          (SI "nonimmediate_operand")
893          (DI "ashldi_input_operand")
894          (TI "reg_or_pm1_operand")])
895
896 ;; SSE and x87 SFmode and DFmode floating point modes
897 (define_mode_iterator MODEF [SF DF])
898
899 ;; All x87 floating point modes
900 (define_mode_iterator X87MODEF [SF DF XF])
901
902 ;; All integer modes handled by x87 fisttp operator.
903 (define_mode_iterator X87MODEI [HI SI DI])
904
905 ;; All integer modes handled by integer x87 operators.
906 (define_mode_iterator X87MODEI12 [HI SI])
907
908 ;; All integer modes handled by SSE cvtts?2si* operators.
909 (define_mode_iterator SSEMODEI24 [SI DI])
910
911 ;; SSE asm suffix for floating point modes
912 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
913
914 ;; SSE vector mode corresponding to a scalar mode
915 (define_mode_attr ssevecmode
916   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
917
918 ;; Instruction suffix for REX 64bit operators.
919 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
920
921 ;; This mode iterator allows :P to be used for patterns that operate on
922 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
923 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
924 \f
925 ;; Scheduling descriptions
926
927 (include "pentium.md")
928 (include "ppro.md")
929 (include "k6.md")
930 (include "athlon.md")
931 (include "bdver1.md")
932 (include "geode.md")
933 (include "atom.md")
934
935 \f
936 ;; Operand and operator predicates and constraints
937
938 (include "predicates.md")
939 (include "constraints.md")
940
941 \f
942 ;; Compare and branch/compare and store instructions.
943
944 (define_expand "cbranch<mode>4"
945   [(set (reg:CC FLAGS_REG)
946         (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
947                     (match_operand:SDWIM 2 "<general_operand>" "")))
948    (set (pc) (if_then_else
949                (match_operator 0 "ordered_comparison_operator"
950                 [(reg:CC FLAGS_REG) (const_int 0)])
951                (label_ref (match_operand 3 "" ""))
952                (pc)))]
953   ""
954 {
955   if (MEM_P (operands[1]) && MEM_P (operands[2]))
956     operands[1] = force_reg (<MODE>mode, operands[1]);
957   ix86_expand_branch (GET_CODE (operands[0]),
958                       operands[1], operands[2], operands[3]);
959   DONE;
960 })
961
962 (define_expand "cstore<mode>4"
963   [(set (reg:CC FLAGS_REG)
964         (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
965                     (match_operand:SWIM 3 "<general_operand>" "")))
966    (set (match_operand:QI 0 "register_operand" "")
967         (match_operator 1 "ordered_comparison_operator"
968           [(reg:CC FLAGS_REG) (const_int 0)]))]
969   ""
970 {
971   if (MEM_P (operands[2]) && MEM_P (operands[3]))
972     operands[2] = force_reg (<MODE>mode, operands[2]);
973   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
974                      operands[2], operands[3]);
975   DONE;
976 })
977
978 (define_expand "cmp<mode>_1"
979   [(set (reg:CC FLAGS_REG)
980         (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
981                     (match_operand:SWI48 1 "<general_operand>" "")))])
982
983 (define_insn "*cmp<mode>_ccno_1"
984   [(set (reg FLAGS_REG)
985         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
986                  (match_operand:SWI 1 "const0_operand" "")))]
987   "ix86_match_ccmode (insn, CCNOmode)"
988   "@
989    test{<imodesuffix>}\t%0, %0
990    cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
991   [(set_attr "type" "test,icmp")
992    (set_attr "length_immediate" "0,1")
993    (set_attr "mode" "<MODE>")])
994
995 (define_insn "*cmp<mode>_1"
996   [(set (reg FLAGS_REG)
997         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
998                  (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
999   "ix86_match_ccmode (insn, CCmode)"
1000   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1001   [(set_attr "type" "icmp")
1002    (set_attr "mode" "<MODE>")])
1003
1004 (define_insn "*cmp<mode>_minus_1"
1005   [(set (reg FLAGS_REG)
1006         (compare
1007           (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1008                      (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1009           (const_int 0)))]
1010   "ix86_match_ccmode (insn, CCGOCmode)"
1011   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1012   [(set_attr "type" "icmp")
1013    (set_attr "mode" "<MODE>")])
1014
1015 (define_insn "*cmpqi_ext_1"
1016   [(set (reg FLAGS_REG)
1017         (compare
1018           (match_operand:QI 0 "general_operand" "Qm")
1019           (subreg:QI
1020             (zero_extract:SI
1021               (match_operand 1 "ext_register_operand" "Q")
1022               (const_int 8)
1023               (const_int 8)) 0)))]
1024   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1025   "cmp{b}\t{%h1, %0|%0, %h1}"
1026   [(set_attr "type" "icmp")
1027    (set_attr "mode" "QI")])
1028
1029 (define_insn "*cmpqi_ext_1_rex64"
1030   [(set (reg FLAGS_REG)
1031         (compare
1032           (match_operand:QI 0 "register_operand" "Q")
1033           (subreg:QI
1034             (zero_extract:SI
1035               (match_operand 1 "ext_register_operand" "Q")
1036               (const_int 8)
1037               (const_int 8)) 0)))]
1038   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1039   "cmp{b}\t{%h1, %0|%0, %h1}"
1040   [(set_attr "type" "icmp")
1041    (set_attr "mode" "QI")])
1042
1043 (define_insn "*cmpqi_ext_2"
1044   [(set (reg FLAGS_REG)
1045         (compare
1046           (subreg:QI
1047             (zero_extract:SI
1048               (match_operand 0 "ext_register_operand" "Q")
1049               (const_int 8)
1050               (const_int 8)) 0)
1051           (match_operand:QI 1 "const0_operand" "")))]
1052   "ix86_match_ccmode (insn, CCNOmode)"
1053   "test{b}\t%h0, %h0"
1054   [(set_attr "type" "test")
1055    (set_attr "length_immediate" "0")
1056    (set_attr "mode" "QI")])
1057
1058 (define_expand "cmpqi_ext_3"
1059   [(set (reg:CC FLAGS_REG)
1060         (compare:CC
1061           (subreg:QI
1062             (zero_extract:SI
1063               (match_operand 0 "ext_register_operand" "")
1064               (const_int 8)
1065               (const_int 8)) 0)
1066           (match_operand:QI 1 "immediate_operand" "")))])
1067
1068 (define_insn "*cmpqi_ext_3_insn"
1069   [(set (reg FLAGS_REG)
1070         (compare
1071           (subreg:QI
1072             (zero_extract:SI
1073               (match_operand 0 "ext_register_operand" "Q")
1074               (const_int 8)
1075               (const_int 8)) 0)
1076           (match_operand:QI 1 "general_operand" "Qmn")))]
1077   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1078   "cmp{b}\t{%1, %h0|%h0, %1}"
1079   [(set_attr "type" "icmp")
1080    (set_attr "modrm" "1")
1081    (set_attr "mode" "QI")])
1082
1083 (define_insn "*cmpqi_ext_3_insn_rex64"
1084   [(set (reg FLAGS_REG)
1085         (compare
1086           (subreg:QI
1087             (zero_extract:SI
1088               (match_operand 0 "ext_register_operand" "Q")
1089               (const_int 8)
1090               (const_int 8)) 0)
1091           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1092   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1093   "cmp{b}\t{%1, %h0|%h0, %1}"
1094   [(set_attr "type" "icmp")
1095    (set_attr "modrm" "1")
1096    (set_attr "mode" "QI")])
1097
1098 (define_insn "*cmpqi_ext_4"
1099   [(set (reg FLAGS_REG)
1100         (compare
1101           (subreg:QI
1102             (zero_extract:SI
1103               (match_operand 0 "ext_register_operand" "Q")
1104               (const_int 8)
1105               (const_int 8)) 0)
1106           (subreg:QI
1107             (zero_extract:SI
1108               (match_operand 1 "ext_register_operand" "Q")
1109               (const_int 8)
1110               (const_int 8)) 0)))]
1111   "ix86_match_ccmode (insn, CCmode)"
1112   "cmp{b}\t{%h1, %h0|%h0, %h1}"
1113   [(set_attr "type" "icmp")
1114    (set_attr "mode" "QI")])
1115
1116 ;; These implement float point compares.
1117 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1118 ;; which would allow mix and match FP modes on the compares.  Which is what
1119 ;; the old patterns did, but with many more of them.
1120
1121 (define_expand "cbranchxf4"
1122   [(set (reg:CC FLAGS_REG)
1123         (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1124                     (match_operand:XF 2 "nonmemory_operand" "")))
1125    (set (pc) (if_then_else
1126               (match_operator 0 "ix86_fp_comparison_operator"
1127                [(reg:CC FLAGS_REG)
1128                 (const_int 0)])
1129               (label_ref (match_operand 3 "" ""))
1130               (pc)))]
1131   "TARGET_80387"
1132 {
1133   ix86_expand_branch (GET_CODE (operands[0]),
1134                       operands[1], operands[2], operands[3]);
1135   DONE;
1136 })
1137
1138 (define_expand "cstorexf4"
1139   [(set (reg:CC FLAGS_REG)
1140         (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1141                     (match_operand:XF 3 "nonmemory_operand" "")))
1142    (set (match_operand:QI 0 "register_operand" "")
1143               (match_operator 1 "ix86_fp_comparison_operator"
1144                [(reg:CC FLAGS_REG)
1145                 (const_int 0)]))]
1146   "TARGET_80387"
1147 {
1148   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1149                      operands[2], operands[3]);
1150   DONE;
1151 })
1152
1153 (define_expand "cbranch<mode>4"
1154   [(set (reg:CC FLAGS_REG)
1155         (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1156                     (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1157    (set (pc) (if_then_else
1158               (match_operator 0 "ix86_fp_comparison_operator"
1159                [(reg:CC FLAGS_REG)
1160                 (const_int 0)])
1161               (label_ref (match_operand 3 "" ""))
1162               (pc)))]
1163   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1164 {
1165   ix86_expand_branch (GET_CODE (operands[0]),
1166                       operands[1], operands[2], operands[3]);
1167   DONE;
1168 })
1169
1170 (define_expand "cstore<mode>4"
1171   [(set (reg:CC FLAGS_REG)
1172         (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1173                     (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1174    (set (match_operand:QI 0 "register_operand" "")
1175               (match_operator 1 "ix86_fp_comparison_operator"
1176                [(reg:CC FLAGS_REG)
1177                 (const_int 0)]))]
1178   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1179 {
1180   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1181                      operands[2], operands[3]);
1182   DONE;
1183 })
1184
1185 (define_expand "cbranchcc4"
1186   [(set (pc) (if_then_else
1187               (match_operator 0 "comparison_operator"
1188                [(match_operand 1 "flags_reg_operand" "")
1189                 (match_operand 2 "const0_operand" "")])
1190               (label_ref (match_operand 3 "" ""))
1191               (pc)))]
1192   ""
1193 {
1194   ix86_expand_branch (GET_CODE (operands[0]),
1195                       operands[1], operands[2], operands[3]);
1196   DONE;
1197 })
1198
1199 (define_expand "cstorecc4"
1200   [(set (match_operand:QI 0 "register_operand" "")
1201               (match_operator 1 "comparison_operator"
1202                [(match_operand 2 "flags_reg_operand" "")
1203                 (match_operand 3 "const0_operand" "")]))]
1204   ""
1205 {
1206   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1207                      operands[2], operands[3]);
1208   DONE;
1209 })
1210
1211
1212 ;; FP compares, step 1:
1213 ;; Set the FP condition codes.
1214 ;;
1215 ;; CCFPmode     compare with exceptions
1216 ;; CCFPUmode    compare with no exceptions
1217
1218 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1219 ;; used to manage the reg stack popping would not be preserved.
1220
1221 (define_insn "*cmpfp_0"
1222   [(set (match_operand:HI 0 "register_operand" "=a")
1223         (unspec:HI
1224           [(compare:CCFP
1225              (match_operand 1 "register_operand" "f")
1226              (match_operand 2 "const0_operand" ""))]
1227         UNSPEC_FNSTSW))]
1228   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1229    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1230   "* return output_fp_compare (insn, operands, 0, 0);"
1231   [(set_attr "type" "multi")
1232    (set_attr "unit" "i387")
1233    (set (attr "mode")
1234      (cond [(match_operand:SF 1 "" "")
1235               (const_string "SF")
1236             (match_operand:DF 1 "" "")
1237               (const_string "DF")
1238            ]
1239            (const_string "XF")))])
1240
1241 (define_insn_and_split "*cmpfp_0_cc"
1242   [(set (reg:CCFP FLAGS_REG)
1243         (compare:CCFP
1244           (match_operand 1 "register_operand" "f")
1245           (match_operand 2 "const0_operand" "")))
1246    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1247   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1248    && TARGET_SAHF && !TARGET_CMOVE
1249    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1250   "#"
1251   "&& reload_completed"
1252   [(set (match_dup 0)
1253         (unspec:HI
1254           [(compare:CCFP (match_dup 1)(match_dup 2))]
1255         UNSPEC_FNSTSW))
1256    (set (reg:CC FLAGS_REG)
1257         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1258   ""
1259   [(set_attr "type" "multi")
1260    (set_attr "unit" "i387")
1261    (set (attr "mode")
1262      (cond [(match_operand:SF 1 "" "")
1263               (const_string "SF")
1264             (match_operand:DF 1 "" "")
1265               (const_string "DF")
1266            ]
1267            (const_string "XF")))])
1268
1269 (define_insn "*cmpfp_xf"
1270   [(set (match_operand:HI 0 "register_operand" "=a")
1271         (unspec:HI
1272           [(compare:CCFP
1273              (match_operand:XF 1 "register_operand" "f")
1274              (match_operand:XF 2 "register_operand" "f"))]
1275           UNSPEC_FNSTSW))]
1276   "TARGET_80387"
1277   "* return output_fp_compare (insn, operands, 0, 0);"
1278   [(set_attr "type" "multi")
1279    (set_attr "unit" "i387")
1280    (set_attr "mode" "XF")])
1281
1282 (define_insn_and_split "*cmpfp_xf_cc"
1283   [(set (reg:CCFP FLAGS_REG)
1284         (compare:CCFP
1285           (match_operand:XF 1 "register_operand" "f")
1286           (match_operand:XF 2 "register_operand" "f")))
1287    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1288   "TARGET_80387
1289    && TARGET_SAHF && !TARGET_CMOVE"
1290   "#"
1291   "&& reload_completed"
1292   [(set (match_dup 0)
1293         (unspec:HI
1294           [(compare:CCFP (match_dup 1)(match_dup 2))]
1295         UNSPEC_FNSTSW))
1296    (set (reg:CC FLAGS_REG)
1297         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1298   ""
1299   [(set_attr "type" "multi")
1300    (set_attr "unit" "i387")
1301    (set_attr "mode" "XF")])
1302
1303 (define_insn "*cmpfp_<mode>"
1304   [(set (match_operand:HI 0 "register_operand" "=a")
1305         (unspec:HI
1306           [(compare:CCFP
1307              (match_operand:MODEF 1 "register_operand" "f")
1308              (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1309           UNSPEC_FNSTSW))]
1310   "TARGET_80387"
1311   "* return output_fp_compare (insn, operands, 0, 0);"
1312   [(set_attr "type" "multi")
1313    (set_attr "unit" "i387")
1314    (set_attr "mode" "<MODE>")])
1315
1316 (define_insn_and_split "*cmpfp_<mode>_cc"
1317   [(set (reg:CCFP FLAGS_REG)
1318         (compare:CCFP
1319           (match_operand:MODEF 1 "register_operand" "f")
1320           (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1321    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1322   "TARGET_80387
1323    && TARGET_SAHF && !TARGET_CMOVE"
1324   "#"
1325   "&& reload_completed"
1326   [(set (match_dup 0)
1327         (unspec:HI
1328           [(compare:CCFP (match_dup 1)(match_dup 2))]
1329         UNSPEC_FNSTSW))
1330    (set (reg:CC FLAGS_REG)
1331         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1332   ""
1333   [(set_attr "type" "multi")
1334    (set_attr "unit" "i387")
1335    (set_attr "mode" "<MODE>")])
1336
1337 (define_insn "*cmpfp_u"
1338   [(set (match_operand:HI 0 "register_operand" "=a")
1339         (unspec:HI
1340           [(compare:CCFPU
1341              (match_operand 1 "register_operand" "f")
1342              (match_operand 2 "register_operand" "f"))]
1343           UNSPEC_FNSTSW))]
1344   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1345    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1346   "* return output_fp_compare (insn, operands, 0, 1);"
1347   [(set_attr "type" "multi")
1348    (set_attr "unit" "i387")
1349    (set (attr "mode")
1350      (cond [(match_operand:SF 1 "" "")
1351               (const_string "SF")
1352             (match_operand:DF 1 "" "")
1353               (const_string "DF")
1354            ]
1355            (const_string "XF")))])
1356
1357 (define_insn_and_split "*cmpfp_u_cc"
1358   [(set (reg:CCFPU FLAGS_REG)
1359         (compare:CCFPU
1360           (match_operand 1 "register_operand" "f")
1361           (match_operand 2 "register_operand" "f")))
1362    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1363   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1364    && TARGET_SAHF && !TARGET_CMOVE
1365    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1366   "#"
1367   "&& reload_completed"
1368   [(set (match_dup 0)
1369         (unspec:HI
1370           [(compare:CCFPU (match_dup 1)(match_dup 2))]
1371         UNSPEC_FNSTSW))
1372    (set (reg:CC FLAGS_REG)
1373         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1374   ""
1375   [(set_attr "type" "multi")
1376    (set_attr "unit" "i387")
1377    (set (attr "mode")
1378      (cond [(match_operand:SF 1 "" "")
1379               (const_string "SF")
1380             (match_operand:DF 1 "" "")
1381               (const_string "DF")
1382            ]
1383            (const_string "XF")))])
1384
1385 (define_insn "*cmpfp_<mode>"
1386   [(set (match_operand:HI 0 "register_operand" "=a")
1387         (unspec:HI
1388           [(compare:CCFP
1389              (match_operand 1 "register_operand" "f")
1390              (match_operator 3 "float_operator"
1391                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1392           UNSPEC_FNSTSW))]
1393   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1394    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1395    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1396   "* return output_fp_compare (insn, operands, 0, 0);"
1397   [(set_attr "type" "multi")
1398    (set_attr "unit" "i387")
1399    (set_attr "fp_int_src" "true")
1400    (set_attr "mode" "<MODE>")])
1401
1402 (define_insn_and_split "*cmpfp_<mode>_cc"
1403   [(set (reg:CCFP FLAGS_REG)
1404         (compare:CCFP
1405           (match_operand 1 "register_operand" "f")
1406           (match_operator 3 "float_operator"
1407             [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1408    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1409   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1410    && TARGET_SAHF && !TARGET_CMOVE
1411    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1412    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1413   "#"
1414   "&& reload_completed"
1415   [(set (match_dup 0)
1416         (unspec:HI
1417           [(compare:CCFP
1418              (match_dup 1)
1419              (match_op_dup 3 [(match_dup 2)]))]
1420         UNSPEC_FNSTSW))
1421    (set (reg:CC FLAGS_REG)
1422         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1423   ""
1424   [(set_attr "type" "multi")
1425    (set_attr "unit" "i387")
1426    (set_attr "fp_int_src" "true")
1427    (set_attr "mode" "<MODE>")])
1428
1429 ;; FP compares, step 2
1430 ;; Move the fpsw to ax.
1431
1432 (define_insn "x86_fnstsw_1"
1433   [(set (match_operand:HI 0 "register_operand" "=a")
1434         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1435   "TARGET_80387"
1436   "fnstsw\t%0"
1437   [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1438    (set_attr "mode" "SI")
1439    (set_attr "unit" "i387")])
1440
1441 ;; FP compares, step 3
1442 ;; Get ax into flags, general case.
1443
1444 (define_insn "x86_sahf_1"
1445   [(set (reg:CC FLAGS_REG)
1446         (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1447                    UNSPEC_SAHF))]
1448   "TARGET_SAHF"
1449 {
1450 #ifndef HAVE_AS_IX86_SAHF
1451   if (TARGET_64BIT)
1452     return ASM_BYTE "0x9e";
1453   else
1454 #endif
1455   return "sahf";
1456 }
1457   [(set_attr "length" "1")
1458    (set_attr "athlon_decode" "vector")
1459    (set_attr "amdfam10_decode" "direct")
1460    (set_attr "bdver1_decode" "direct")
1461    (set_attr "mode" "SI")])
1462
1463 ;; Pentium Pro can do steps 1 through 3 in one go.
1464 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1465 (define_insn "*cmpfp_i_mixed"
1466   [(set (reg:CCFP FLAGS_REG)
1467         (compare:CCFP (match_operand 0 "register_operand" "f,x")
1468                       (match_operand 1 "nonimmediate_operand" "f,xm")))]
1469   "TARGET_MIX_SSE_I387
1470    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1471    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1472   "* return output_fp_compare (insn, operands, 1, 0);"
1473   [(set_attr "type" "fcmp,ssecomi")
1474    (set_attr "prefix" "orig,maybe_vex")
1475    (set (attr "mode")
1476      (if_then_else (match_operand:SF 1 "" "")
1477         (const_string "SF")
1478         (const_string "DF")))
1479    (set (attr "prefix_rep")
1480         (if_then_else (eq_attr "type" "ssecomi")
1481                       (const_string "0")
1482                       (const_string "*")))
1483    (set (attr "prefix_data16")
1484         (cond [(eq_attr "type" "fcmp")
1485                  (const_string "*")
1486                (eq_attr "mode" "DF")
1487                  (const_string "1")
1488               ]
1489               (const_string "0")))
1490    (set_attr "athlon_decode" "vector")
1491    (set_attr "amdfam10_decode" "direct")
1492    (set_attr "bdver1_decode" "double")])
1493
1494 (define_insn "*cmpfp_i_sse"
1495   [(set (reg:CCFP FLAGS_REG)
1496         (compare:CCFP (match_operand 0 "register_operand" "x")
1497                       (match_operand 1 "nonimmediate_operand" "xm")))]
1498   "TARGET_SSE_MATH
1499    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1500    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1501   "* return output_fp_compare (insn, operands, 1, 0);"
1502   [(set_attr "type" "ssecomi")
1503    (set_attr "prefix" "maybe_vex")
1504    (set (attr "mode")
1505      (if_then_else (match_operand:SF 1 "" "")
1506         (const_string "SF")
1507         (const_string "DF")))
1508    (set_attr "prefix_rep" "0")
1509    (set (attr "prefix_data16")
1510         (if_then_else (eq_attr "mode" "DF")
1511                       (const_string "1")
1512                       (const_string "0")))
1513    (set_attr "athlon_decode" "vector")
1514    (set_attr "amdfam10_decode" "direct")
1515    (set_attr "bdver1_decode" "double")])
1516
1517 (define_insn "*cmpfp_i_i387"
1518   [(set (reg:CCFP FLAGS_REG)
1519         (compare:CCFP (match_operand 0 "register_operand" "f")
1520                       (match_operand 1 "register_operand" "f")))]
1521   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1522    && TARGET_CMOVE
1523    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1524    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1525   "* return output_fp_compare (insn, operands, 1, 0);"
1526   [(set_attr "type" "fcmp")
1527    (set (attr "mode")
1528      (cond [(match_operand:SF 1 "" "")
1529               (const_string "SF")
1530             (match_operand:DF 1 "" "")
1531               (const_string "DF")
1532            ]
1533            (const_string "XF")))
1534    (set_attr "athlon_decode" "vector")
1535    (set_attr "amdfam10_decode" "direct")
1536    (set_attr "bdver1_decode" "double")])
1537
1538 (define_insn "*cmpfp_iu_mixed"
1539   [(set (reg:CCFPU FLAGS_REG)
1540         (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1541                        (match_operand 1 "nonimmediate_operand" "f,xm")))]
1542   "TARGET_MIX_SSE_I387
1543    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1544    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1545   "* return output_fp_compare (insn, operands, 1, 1);"
1546   [(set_attr "type" "fcmp,ssecomi")
1547    (set_attr "prefix" "orig,maybe_vex")
1548    (set (attr "mode")
1549      (if_then_else (match_operand:SF 1 "" "")
1550         (const_string "SF")
1551         (const_string "DF")))
1552    (set (attr "prefix_rep")
1553         (if_then_else (eq_attr "type" "ssecomi")
1554                       (const_string "0")
1555                       (const_string "*")))
1556    (set (attr "prefix_data16")
1557         (cond [(eq_attr "type" "fcmp")
1558                  (const_string "*")
1559                (eq_attr "mode" "DF")
1560                  (const_string "1")
1561               ]
1562               (const_string "0")))
1563    (set_attr "athlon_decode" "vector")
1564    (set_attr "amdfam10_decode" "direct")
1565    (set_attr "bdver1_decode" "double")])
1566
1567 (define_insn "*cmpfp_iu_sse"
1568   [(set (reg:CCFPU FLAGS_REG)
1569         (compare:CCFPU (match_operand 0 "register_operand" "x")
1570                        (match_operand 1 "nonimmediate_operand" "xm")))]
1571   "TARGET_SSE_MATH
1572    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1573    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1574   "* return output_fp_compare (insn, operands, 1, 1);"
1575   [(set_attr "type" "ssecomi")
1576    (set_attr "prefix" "maybe_vex")
1577    (set (attr "mode")
1578      (if_then_else (match_operand:SF 1 "" "")
1579         (const_string "SF")
1580         (const_string "DF")))
1581    (set_attr "prefix_rep" "0")
1582    (set (attr "prefix_data16")
1583         (if_then_else (eq_attr "mode" "DF")
1584                       (const_string "1")
1585                       (const_string "0")))
1586    (set_attr "athlon_decode" "vector")
1587    (set_attr "amdfam10_decode" "direct")
1588    (set_attr "bdver1_decode" "double")])
1589
1590 (define_insn "*cmpfp_iu_387"
1591   [(set (reg:CCFPU FLAGS_REG)
1592         (compare:CCFPU (match_operand 0 "register_operand" "f")
1593                        (match_operand 1 "register_operand" "f")))]
1594   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1595    && TARGET_CMOVE
1596    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1597    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1598   "* return output_fp_compare (insn, operands, 1, 1);"
1599   [(set_attr "type" "fcmp")
1600    (set (attr "mode")
1601      (cond [(match_operand:SF 1 "" "")
1602               (const_string "SF")
1603             (match_operand:DF 1 "" "")
1604               (const_string "DF")
1605            ]
1606            (const_string "XF")))
1607    (set_attr "athlon_decode" "vector")
1608    (set_attr "amdfam10_decode" "direct")
1609    (set_attr "bdver1_decode" "direct")])
1610 \f
1611 ;; Push/pop instructions.
1612
1613 (define_insn "*push<mode>2"
1614   [(set (match_operand:DWI 0 "push_operand" "=<")
1615         (match_operand:DWI 1 "general_no_elim_operand" "riF*m"))]
1616   ""
1617   "#")
1618
1619 (define_split
1620   [(set (match_operand:TI 0 "push_operand" "")
1621         (match_operand:TI 1 "general_operand" ""))]
1622   "TARGET_64BIT && reload_completed
1623    && !SSE_REG_P (operands[1])"
1624   [(const_int 0)]
1625   "ix86_split_long_move (operands); DONE;")
1626
1627 (define_insn "*pushdi2_rex64"
1628   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1629         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1630   "TARGET_64BIT"
1631   "@
1632    push{q}\t%1
1633    #"
1634   [(set_attr "type" "push,multi")
1635    (set_attr "mode" "DI")])
1636
1637 ;; Convert impossible pushes of immediate to existing instructions.
1638 ;; First try to get scratch register and go through it.  In case this
1639 ;; fails, push sign extended lower part first and then overwrite
1640 ;; upper part by 32bit move.
1641 (define_peephole2
1642   [(match_scratch:DI 2 "r")
1643    (set (match_operand:DI 0 "push_operand" "")
1644         (match_operand:DI 1 "immediate_operand" ""))]
1645   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1646    && !x86_64_immediate_operand (operands[1], DImode)"
1647   [(set (match_dup 2) (match_dup 1))
1648    (set (match_dup 0) (match_dup 2))])
1649
1650 ;; We need to define this as both peepholer and splitter for case
1651 ;; peephole2 pass is not run.
1652 ;; "&& 1" is needed to keep it from matching the previous pattern.
1653 (define_peephole2
1654   [(set (match_operand:DI 0 "push_operand" "")
1655         (match_operand:DI 1 "immediate_operand" ""))]
1656   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1657    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1658   [(set (match_dup 0) (match_dup 1))
1659    (set (match_dup 2) (match_dup 3))]
1660 {
1661   split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1662
1663   operands[1] = gen_lowpart (DImode, operands[2]);
1664   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1665                                                    GEN_INT (4)));
1666 })
1667
1668 (define_split
1669   [(set (match_operand:DI 0 "push_operand" "")
1670         (match_operand:DI 1 "immediate_operand" ""))]
1671   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1672                     ? epilogue_completed : reload_completed)
1673    && !symbolic_operand (operands[1], DImode)
1674    && !x86_64_immediate_operand (operands[1], DImode)"
1675   [(set (match_dup 0) (match_dup 1))
1676    (set (match_dup 2) (match_dup 3))]
1677 {
1678   split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1679
1680   operands[1] = gen_lowpart (DImode, operands[2]);
1681   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1682                                                    GEN_INT (4)));
1683 })
1684
1685 (define_split
1686   [(set (match_operand:DI 0 "push_operand" "")
1687         (match_operand:DI 1 "general_operand" ""))]
1688   "!TARGET_64BIT && reload_completed
1689    && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1690   [(const_int 0)]
1691   "ix86_split_long_move (operands); DONE;")
1692
1693 (define_insn "*pushsi2"
1694   [(set (match_operand:SI 0 "push_operand" "=<")
1695         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1696   "!TARGET_64BIT"
1697   "push{l}\t%1"
1698   [(set_attr "type" "push")
1699    (set_attr "mode" "SI")])
1700
1701 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1702 ;; "push a byte/word".  But actually we use pushl, which has the effect
1703 ;; of rounding the amount pushed up to a word.
1704
1705 ;; For TARGET_64BIT we always round up to 8 bytes.
1706 (define_insn "*push<mode>2_rex64"
1707   [(set (match_operand:SWI124 0 "push_operand" "=X")
1708         (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1709   "TARGET_64BIT"
1710   "push{q}\t%q1"
1711   [(set_attr "type" "push")
1712    (set_attr "mode" "DI")])
1713
1714 (define_insn "*push<mode>2"
1715   [(set (match_operand:SWI12 0 "push_operand" "=X")
1716         (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1717   "!TARGET_64BIT"
1718   "push{l}\t%k1"
1719   [(set_attr "type" "push")
1720    (set_attr "mode" "SI")])
1721
1722 (define_insn "*push<mode>2_prologue"
1723   [(set (match_operand:P 0 "push_operand" "=<")
1724         (match_operand:P 1 "general_no_elim_operand" "r<i>*m"))
1725    (clobber (mem:BLK (scratch)))]
1726   ""
1727   "push{<imodesuffix>}\t%1"
1728   [(set_attr "type" "push")
1729    (set_attr "mode" "<MODE>")])
1730
1731 (define_insn "*pop<mode>1"
1732   [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1733         (match_operand:P 1 "pop_operand" ">"))]
1734   ""
1735   "pop{<imodesuffix>}\t%0"
1736   [(set_attr "type" "pop")
1737    (set_attr "mode" "<MODE>")])
1738
1739 (define_insn "*pop<mode>1_epilogue"
1740   [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1741         (match_operand:P 1 "pop_operand" ">"))
1742    (clobber (mem:BLK (scratch)))]
1743   ""
1744   "pop{<imodesuffix>}\t%0"
1745   [(set_attr "type" "pop")
1746    (set_attr "mode" "<MODE>")])
1747 \f
1748 ;; Move instructions.
1749
1750 (define_expand "movoi"
1751   [(set (match_operand:OI 0 "nonimmediate_operand" "")
1752         (match_operand:OI 1 "general_operand" ""))]
1753   "TARGET_AVX"
1754   "ix86_expand_move (OImode, operands); DONE;")
1755
1756 (define_expand "movti"
1757   [(set (match_operand:TI 0 "nonimmediate_operand" "")
1758         (match_operand:TI 1 "nonimmediate_operand" ""))]
1759   "TARGET_64BIT || TARGET_SSE"
1760 {
1761   if (TARGET_64BIT)
1762     ix86_expand_move (TImode, operands);
1763   else if (push_operand (operands[0], TImode))
1764     ix86_expand_push (TImode, operands[1]);
1765   else
1766     ix86_expand_vector_move (TImode, operands);
1767   DONE;
1768 })
1769
1770 ;; This expands to what emit_move_complex would generate if we didn't
1771 ;; have a movti pattern.  Having this avoids problems with reload on
1772 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1773 ;; to have around all the time.
1774 (define_expand "movcdi"
1775   [(set (match_operand:CDI 0 "nonimmediate_operand" "")
1776         (match_operand:CDI 1 "general_operand" ""))]
1777   ""
1778 {
1779   if (push_operand (operands[0], CDImode))
1780     emit_move_complex_push (CDImode, operands[0], operands[1]);
1781   else
1782     emit_move_complex_parts (operands[0], operands[1]);
1783   DONE;
1784 })
1785
1786 (define_expand "mov<mode>"
1787   [(set (match_operand:SWI1248x 0 "nonimmediate_operand" "")
1788         (match_operand:SWI1248x 1 "general_operand" ""))]
1789   ""
1790   "ix86_expand_move (<MODE>mode, operands); DONE;")
1791
1792 (define_insn "*mov<mode>_xor"
1793   [(set (match_operand:SWI48 0 "register_operand" "=r")
1794         (match_operand:SWI48 1 "const0_operand" ""))
1795    (clobber (reg:CC FLAGS_REG))]
1796   "reload_completed"
1797   "xor{l}\t%k0, %k0"
1798   [(set_attr "type" "alu1")
1799    (set_attr "mode" "SI")
1800    (set_attr "length_immediate" "0")])
1801
1802 (define_insn "*mov<mode>_or"
1803   [(set (match_operand:SWI48 0 "register_operand" "=r")
1804         (match_operand:SWI48 1 "const_int_operand" ""))
1805    (clobber (reg:CC FLAGS_REG))]
1806   "reload_completed
1807    && operands[1] == constm1_rtx"
1808   "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1809   [(set_attr "type" "alu1")
1810    (set_attr "mode" "<MODE>")
1811    (set_attr "length_immediate" "1")])
1812
1813 (define_insn "*movoi_internal_avx"
1814   [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
1815         (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
1816   "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1817 {
1818   switch (which_alternative)
1819     {
1820     case 0:
1821       return "vxorps\t%0, %0, %0";
1822     case 1:
1823     case 2:
1824       if (misaligned_operand (operands[0], OImode)
1825           || misaligned_operand (operands[1], OImode))
1826         return "vmovdqu\t{%1, %0|%0, %1}";
1827       else
1828         return "vmovdqa\t{%1, %0|%0, %1}";
1829     default:
1830       gcc_unreachable ();
1831     }
1832 }
1833   [(set_attr "type" "sselog1,ssemov,ssemov")
1834    (set_attr "prefix" "vex")
1835    (set_attr "mode" "OI")])
1836
1837 (define_insn "*movti_internal_rex64"
1838   [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
1839         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
1840   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1841 {
1842   switch (which_alternative)
1843     {
1844     case 0:
1845     case 1:
1846       return "#";
1847     case 2:
1848       if (get_attr_mode (insn) == MODE_V4SF)
1849         return "%vxorps\t%0, %d0";
1850       else
1851         return "%vpxor\t%0, %d0";
1852     case 3:
1853     case 4:
1854       /* TDmode values are passed as TImode on the stack.  Moving them
1855          to stack may result in unaligned memory access.  */
1856       if (misaligned_operand (operands[0], TImode)
1857           || misaligned_operand (operands[1], TImode))
1858         {
1859           if (get_attr_mode (insn) == MODE_V4SF)
1860             return "%vmovups\t{%1, %0|%0, %1}";
1861          else
1862            return "%vmovdqu\t{%1, %0|%0, %1}";
1863         }
1864       else
1865         {
1866           if (get_attr_mode (insn) == MODE_V4SF)
1867             return "%vmovaps\t{%1, %0|%0, %1}";
1868          else
1869            return "%vmovdqa\t{%1, %0|%0, %1}";
1870         }
1871     default:
1872       gcc_unreachable ();
1873     }
1874 }
1875   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1876    (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1877    (set (attr "mode")
1878         (cond [(eq_attr "alternative" "2,3")
1879                  (if_then_else
1880                    (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1881                        (const_int 0))
1882                    (const_string "V4SF")
1883                    (const_string "TI"))
1884                (eq_attr "alternative" "4")
1885                  (if_then_else
1886                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
1887                             (const_int 0))
1888                         (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1889                             (const_int 0)))
1890                    (const_string "V4SF")
1891                    (const_string "TI"))]
1892                (const_string "DI")))])
1893
1894 (define_split
1895   [(set (match_operand:TI 0 "nonimmediate_operand" "")
1896         (match_operand:TI 1 "general_operand" ""))]
1897   "reload_completed
1898    && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1899   [(const_int 0)]
1900   "ix86_split_long_move (operands); DONE;")
1901
1902 (define_insn "*movti_internal_sse"
1903   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
1904         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
1905   "TARGET_SSE && !TARGET_64BIT
1906    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1907 {
1908   switch (which_alternative)
1909     {
1910     case 0:
1911       if (get_attr_mode (insn) == MODE_V4SF)
1912         return "%vxorps\t%0, %d0";
1913       else
1914         return "%vpxor\t%0, %d0";
1915     case 1:
1916     case 2:
1917       /* TDmode values are passed as TImode on the stack.  Moving them
1918          to stack may result in unaligned memory access.  */
1919       if (misaligned_operand (operands[0], TImode)
1920           || misaligned_operand (operands[1], TImode))
1921         {
1922           if (get_attr_mode (insn) == MODE_V4SF)
1923             return "%vmovups\t{%1, %0|%0, %1}";
1924          else
1925            return "%vmovdqu\t{%1, %0|%0, %1}";
1926         }
1927       else
1928         {
1929           if (get_attr_mode (insn) == MODE_V4SF)
1930             return "%vmovaps\t{%1, %0|%0, %1}";
1931          else
1932            return "%vmovdqa\t{%1, %0|%0, %1}";
1933         }
1934     default:
1935       gcc_unreachable ();
1936     }
1937 }
1938   [(set_attr "type" "sselog1,ssemov,ssemov")
1939    (set_attr "prefix" "maybe_vex")
1940    (set (attr "mode")
1941         (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1942                     (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1943                         (const_int 0)))
1944                  (const_string "V4SF")
1945                (and (eq_attr "alternative" "2")
1946                     (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
1947                         (const_int 0)))
1948                  (const_string "V4SF")]
1949               (const_string "TI")))])
1950
1951 (define_insn "*movdi_internal_rex64"
1952   [(set (match_operand:DI 0 "nonimmediate_operand"
1953           "=r,r  ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
1954         (match_operand:DI 1 "general_operand"
1955           "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r   ,m  ,C ,*x,*Yi,*x,r  ,m ,*Ym,*x"))]
1956   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1957 {
1958   switch (get_attr_type (insn))
1959     {
1960     case TYPE_SSECVT:
1961       if (SSE_REG_P (operands[0]))
1962         return "movq2dq\t{%1, %0|%0, %1}";
1963       else
1964         return "movdq2q\t{%1, %0|%0, %1}";
1965
1966     case TYPE_SSEMOV:
1967       if (TARGET_AVX)
1968         {
1969           if (get_attr_mode (insn) == MODE_TI)
1970             return "vmovdqa\t{%1, %0|%0, %1}";
1971           else
1972             return "vmovq\t{%1, %0|%0, %1}";
1973         }
1974
1975       if (get_attr_mode (insn) == MODE_TI)
1976         return "movdqa\t{%1, %0|%0, %1}";
1977       /* FALLTHRU */
1978
1979     case TYPE_MMXMOV:
1980       /* Moves from and into integer register is done using movd
1981          opcode with REX prefix.  */
1982       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1983         return "movd\t{%1, %0|%0, %1}";
1984       return "movq\t{%1, %0|%0, %1}";
1985
1986     case TYPE_SSELOG1:
1987       return "%vpxor\t%0, %d0";
1988
1989     case TYPE_MMX:
1990       return "pxor\t%0, %0";
1991
1992     case TYPE_MULTI:
1993       return "#";
1994
1995     case TYPE_LEA:
1996       return "lea{q}\t{%a1, %0|%0, %a1}";
1997
1998     default:
1999       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2000       if (get_attr_mode (insn) == MODE_SI)
2001         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2002       else if (which_alternative == 2)
2003         return "movabs{q}\t{%1, %0|%0, %1}";
2004       else
2005         return "mov{q}\t{%1, %0|%0, %1}";
2006     }
2007 }
2008   [(set (attr "type")
2009      (cond [(eq_attr "alternative" "5")
2010               (const_string "mmx")
2011             (eq_attr "alternative" "6,7,8,9,10")
2012               (const_string "mmxmov")
2013             (eq_attr "alternative" "11")
2014               (const_string "sselog1")
2015             (eq_attr "alternative" "12,13,14,15,16")
2016               (const_string "ssemov")
2017             (eq_attr "alternative" "17,18")
2018               (const_string "ssecvt")
2019             (eq_attr "alternative" "4")
2020               (const_string "multi")
2021             (match_operand:DI 1 "pic_32bit_operand" "")
2022               (const_string "lea")
2023            ]
2024            (const_string "imov")))
2025    (set (attr "modrm")
2026      (if_then_else
2027        (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2028          (const_string "0")
2029          (const_string "*")))
2030    (set (attr "length_immediate")
2031      (if_then_else
2032        (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2033          (const_string "8")
2034          (const_string "*")))
2035    (set_attr "prefix_rex" "*,*,*,*,*,*,*,1,*,1,*,*,*,*,*,*,*,*,*")
2036    (set_attr "prefix_data16" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,1,*,*,*")
2037    (set (attr "prefix")
2038      (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
2039        (const_string "maybe_vex")
2040        (const_string "orig")))
2041    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2042
2043 ;; Convert impossible stores of immediate to existing instructions.
2044 ;; First try to get scratch register and go through it.  In case this
2045 ;; fails, move by 32bit parts.
2046 (define_peephole2
2047   [(match_scratch:DI 2 "r")
2048    (set (match_operand:DI 0 "memory_operand" "")
2049         (match_operand:DI 1 "immediate_operand" ""))]
2050   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2051    && !x86_64_immediate_operand (operands[1], DImode)"
2052   [(set (match_dup 2) (match_dup 1))
2053    (set (match_dup 0) (match_dup 2))])
2054
2055 ;; We need to define this as both peepholer and splitter for case
2056 ;; peephole2 pass is not run.
2057 ;; "&& 1" is needed to keep it from matching the previous pattern.
2058 (define_peephole2
2059   [(set (match_operand:DI 0 "memory_operand" "")
2060         (match_operand:DI 1 "immediate_operand" ""))]
2061   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2062    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2063   [(set (match_dup 2) (match_dup 3))
2064    (set (match_dup 4) (match_dup 5))]
2065   "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2066
2067 (define_split
2068   [(set (match_operand:DI 0 "memory_operand" "")
2069         (match_operand:DI 1 "immediate_operand" ""))]
2070   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2071                     ? epilogue_completed : reload_completed)
2072    && !symbolic_operand (operands[1], DImode)
2073    && !x86_64_immediate_operand (operands[1], DImode)"
2074   [(set (match_dup 2) (match_dup 3))
2075    (set (match_dup 4) (match_dup 5))]
2076   "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2077
2078 (define_insn "*movdi_internal"
2079   [(set (match_operand:DI 0 "nonimmediate_operand"
2080                         "=r  ,o  ,*y,m*y,*y,*Y2,m  ,*Y2,*Y2,*x,m ,*x,*x")
2081         (match_operand:DI 1 "general_operand"
2082                         "riFo,riF,C ,*y ,m ,C  ,*Y2,*Y2,m  ,C ,*x,*x,m "))]
2083   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2084   "@
2085    #
2086    #
2087    pxor\t%0, %0
2088    movq\t{%1, %0|%0, %1}
2089    movq\t{%1, %0|%0, %1}
2090    %vpxor\t%0, %d0
2091    %vmovq\t{%1, %0|%0, %1}
2092    %vmovdqa\t{%1, %0|%0, %1}
2093    %vmovq\t{%1, %0|%0, %1}
2094    xorps\t%0, %0
2095    movlps\t{%1, %0|%0, %1}
2096    movaps\t{%1, %0|%0, %1}
2097    movlps\t{%1, %0|%0, %1}"
2098   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2099    (set (attr "prefix")
2100      (if_then_else (eq_attr "alternative" "5,6,7,8")
2101        (const_string "vex")
2102        (const_string "orig")))
2103    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2104
2105 (define_split
2106   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2107         (match_operand:DI 1 "general_operand" ""))]
2108   "!TARGET_64BIT && reload_completed
2109    && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2110    && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2111   [(const_int 0)]
2112   "ix86_split_long_move (operands); DONE;")
2113
2114 (define_insn "*movsi_internal"
2115   [(set (match_operand:SI 0 "nonimmediate_operand"
2116                         "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2117         (match_operand:SI 1 "general_operand"
2118                         "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r   ,m "))]
2119   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2120 {
2121   switch (get_attr_type (insn))
2122     {
2123     case TYPE_SSELOG1:
2124       if (get_attr_mode (insn) == MODE_TI)
2125         return "%vpxor\t%0, %d0";
2126       return "%vxorps\t%0, %d0";
2127
2128     case TYPE_SSEMOV:
2129       switch (get_attr_mode (insn))
2130         {
2131         case MODE_TI:
2132           return "%vmovdqa\t{%1, %0|%0, %1}";
2133         case MODE_V4SF:
2134           return "%vmovaps\t{%1, %0|%0, %1}";
2135         case MODE_SI:
2136           return "%vmovd\t{%1, %0|%0, %1}";
2137         case MODE_SF:
2138           return "%vmovss\t{%1, %0|%0, %1}";
2139         default:
2140           gcc_unreachable ();
2141         }
2142
2143     case TYPE_MMX:
2144       return "pxor\t%0, %0";
2145
2146     case TYPE_MMXMOV:
2147       if (get_attr_mode (insn) == MODE_DI)
2148         return "movq\t{%1, %0|%0, %1}";
2149       return "movd\t{%1, %0|%0, %1}";
2150
2151     case TYPE_LEA:
2152       return "lea{l}\t{%a1, %0|%0, %a1}";
2153
2154     default:
2155       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2156       return "mov{l}\t{%1, %0|%0, %1}";
2157     }
2158 }
2159   [(set (attr "type")
2160      (cond [(eq_attr "alternative" "2")
2161               (const_string "mmx")
2162             (eq_attr "alternative" "3,4,5")
2163               (const_string "mmxmov")
2164             (eq_attr "alternative" "6")
2165               (const_string "sselog1")
2166             (eq_attr "alternative" "7,8,9,10,11")
2167               (const_string "ssemov")
2168             (match_operand:DI 1 "pic_32bit_operand" "")
2169               (const_string "lea")
2170            ]
2171            (const_string "imov")))
2172    (set (attr "prefix")
2173      (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2174        (const_string "orig")
2175        (const_string "maybe_vex")))
2176    (set (attr "prefix_data16")
2177      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2178        (const_string "1")
2179        (const_string "*")))
2180    (set (attr "mode")
2181      (cond [(eq_attr "alternative" "2,3")
2182               (const_string "DI")
2183             (eq_attr "alternative" "6,7")
2184               (if_then_else
2185                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2186                 (const_string "V4SF")
2187                 (const_string "TI"))
2188             (and (eq_attr "alternative" "8,9,10,11")
2189                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
2190               (const_string "SF")
2191            ]
2192            (const_string "SI")))])
2193
2194 (define_insn "*movhi_internal"
2195   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2196         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2197   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2198 {
2199   switch (get_attr_type (insn))
2200     {
2201     case TYPE_IMOVX:
2202       /* movzwl is faster than movw on p2 due to partial word stalls,
2203          though not as fast as an aligned movl.  */
2204       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2205     default:
2206       if (get_attr_mode (insn) == MODE_SI)
2207         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2208       else
2209         return "mov{w}\t{%1, %0|%0, %1}";
2210     }
2211 }
2212   [(set (attr "type")
2213      (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
2214                 (const_int 0))
2215               (const_string "imov")
2216             (and (eq_attr "alternative" "0")
2217                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2218                           (const_int 0))
2219                       (eq (symbol_ref "TARGET_HIMODE_MATH")
2220                           (const_int 0))))
2221               (const_string "imov")
2222             (and (eq_attr "alternative" "1,2")
2223                  (match_operand:HI 1 "aligned_operand" ""))
2224               (const_string "imov")
2225             (and (ne (symbol_ref "TARGET_MOVX")
2226                      (const_int 0))
2227                  (eq_attr "alternative" "0,2"))
2228               (const_string "imovx")
2229            ]
2230            (const_string "imov")))
2231     (set (attr "mode")
2232       (cond [(eq_attr "type" "imovx")
2233                (const_string "SI")
2234              (and (eq_attr "alternative" "1,2")
2235                   (match_operand:HI 1 "aligned_operand" ""))
2236                (const_string "SI")
2237              (and (eq_attr "alternative" "0")
2238                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2239                            (const_int 0))
2240                        (eq (symbol_ref "TARGET_HIMODE_MATH")
2241                            (const_int 0))))
2242                (const_string "SI")
2243             ]
2244             (const_string "HI")))])
2245
2246 ;; Situation is quite tricky about when to choose full sized (SImode) move
2247 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
2248 ;; partial register dependency machines (such as AMD Athlon), where QImode
2249 ;; moves issue extra dependency and for partial register stalls machines
2250 ;; that don't use QImode patterns (and QImode move cause stall on the next
2251 ;; instruction).
2252 ;;
2253 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2254 ;; register stall machines with, where we use QImode instructions, since
2255 ;; partial register stall can be caused there.  Then we use movzx.
2256 (define_insn "*movqi_internal"
2257   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2258         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
2259   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2260 {
2261   switch (get_attr_type (insn))
2262     {
2263     case TYPE_IMOVX:
2264       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2265       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2266     default:
2267       if (get_attr_mode (insn) == MODE_SI)
2268         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2269       else
2270         return "mov{b}\t{%1, %0|%0, %1}";
2271     }
2272 }
2273   [(set (attr "type")
2274      (cond [(and (eq_attr "alternative" "5")
2275                  (not (match_operand:QI 1 "aligned_operand" "")))
2276               (const_string "imovx")
2277             (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2278                 (const_int 0))
2279               (const_string "imov")
2280             (and (eq_attr "alternative" "3")
2281                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2282                           (const_int 0))
2283                       (eq (symbol_ref "TARGET_QIMODE_MATH")
2284                           (const_int 0))))
2285               (const_string "imov")
2286             (eq_attr "alternative" "3,5")
2287               (const_string "imovx")
2288             (and (ne (symbol_ref "TARGET_MOVX")
2289                      (const_int 0))
2290                  (eq_attr "alternative" "2"))
2291               (const_string "imovx")
2292            ]
2293            (const_string "imov")))
2294    (set (attr "mode")
2295       (cond [(eq_attr "alternative" "3,4,5")
2296                (const_string "SI")
2297              (eq_attr "alternative" "6")
2298                (const_string "QI")
2299              (eq_attr "type" "imovx")
2300                (const_string "SI")
2301              (and (eq_attr "type" "imov")
2302                   (and (eq_attr "alternative" "0,1")
2303                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
2304                                 (const_int 0))
2305                             (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2306                                      (const_int 0))
2307                                  (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2308                                      (const_int 0))))))
2309                (const_string "SI")
2310              ;; Avoid partial register stalls when not using QImode arithmetic
2311              (and (eq_attr "type" "imov")
2312                   (and (eq_attr "alternative" "0,1")
2313                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
2314                                 (const_int 0))
2315                             (eq (symbol_ref "TARGET_QIMODE_MATH")
2316                                 (const_int 0)))))
2317                (const_string "SI")
2318            ]
2319            (const_string "QI")))])
2320
2321 ;; Stores and loads of ax to arbitrary constant address.
2322 ;; We fake an second form of instruction to force reload to load address
2323 ;; into register when rax is not available
2324 (define_insn "*movabs<mode>_1"
2325   [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2326         (match_operand:SWI1248x 1 "nonmemory_operand" "a,er"))]
2327   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2328   "@
2329    movabs{<imodesuffix>}\t{%1, %P0|%P0, %1}
2330    mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2331   [(set_attr "type" "imov")
2332    (set_attr "modrm" "0,*")
2333    (set_attr "length_address" "8,0")
2334    (set_attr "length_immediate" "0,*")
2335    (set_attr "memory" "store")
2336    (set_attr "mode" "<MODE>")])
2337
2338 (define_insn "*movabs<mode>_2"
2339   [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2340         (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2341   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2342   "@
2343    movabs{<imodesuffix>}\t{%P1, %0|%0, %P1}
2344    mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2345   [(set_attr "type" "imov")
2346    (set_attr "modrm" "0,*")
2347    (set_attr "length_address" "8,0")
2348    (set_attr "length_immediate" "0")
2349    (set_attr "memory" "load")
2350    (set_attr "mode" "<MODE>")])
2351
2352 (define_insn "*swap<mode>"
2353   [(set (match_operand:SWI48 0 "register_operand" "+r")
2354         (match_operand:SWI48 1 "register_operand" "+r"))
2355    (set (match_dup 1)
2356         (match_dup 0))]
2357   ""
2358   "xchg{<imodesuffix>}\t%1, %0"
2359   [(set_attr "type" "imov")
2360    (set_attr "mode" "<MODE>")
2361    (set_attr "pent_pair" "np")
2362    (set_attr "athlon_decode" "vector")
2363    (set_attr "amdfam10_decode" "double")
2364    (set_attr "bdver1_decode" "double")])
2365
2366 (define_insn "*swap<mode>_1"
2367   [(set (match_operand:SWI12 0 "register_operand" "+r")
2368         (match_operand:SWI12 1 "register_operand" "+r"))
2369    (set (match_dup 1)
2370         (match_dup 0))]
2371   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2372   "xchg{l}\t%k1, %k0"
2373   [(set_attr "type" "imov")
2374    (set_attr "mode" "SI")
2375    (set_attr "pent_pair" "np")
2376    (set_attr "athlon_decode" "vector")
2377    (set_attr "amdfam10_decode" "double")
2378    (set_attr "bdver1_decode" "double")])
2379
2380 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2381 ;; is disabled for AMDFAM10
2382 (define_insn "*swap<mode>_2"
2383   [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2384         (match_operand:SWI12 1 "register_operand" "+<r>"))
2385    (set (match_dup 1)
2386         (match_dup 0))]
2387   "TARGET_PARTIAL_REG_STALL"
2388   "xchg{<imodesuffix>}\t%1, %0"
2389   [(set_attr "type" "imov")
2390    (set_attr "mode" "<MODE>")
2391    (set_attr "pent_pair" "np")
2392    (set_attr "athlon_decode" "vector")])
2393
2394 (define_expand "movstrict<mode>"
2395   [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand" ""))
2396         (match_operand:SWI12 1 "general_operand" ""))]
2397   ""
2398 {
2399   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2400     FAIL;
2401   /* Don't generate memory->memory moves, go through a register */
2402   if (MEM_P (operands[0]) && MEM_P (operands[1]))
2403     operands[1] = force_reg (<MODE>mode, operands[1]);
2404 })
2405
2406 (define_insn "*movstrict<mode>_1"
2407   [(set (strict_low_part
2408           (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2409         (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2410   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2411    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2412   "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2413   [(set_attr "type" "imov")
2414    (set_attr "mode" "<MODE>")])
2415
2416 (define_insn "*movstrict<mode>_xor"
2417   [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2418         (match_operand:SWI12 1 "const0_operand" ""))
2419    (clobber (reg:CC FLAGS_REG))]
2420   "reload_completed"
2421   "xor{<imodesuffix>}\t%0, %0"
2422   [(set_attr "type" "alu1")
2423    (set_attr "mode" "<MODE>")
2424    (set_attr "length_immediate" "0")])
2425
2426 (define_insn "*mov<mode>_extv_1"
2427   [(set (match_operand:SWI24 0 "register_operand" "=R")
2428         (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2429                             (const_int 8)
2430                             (const_int 8)))]
2431   ""
2432   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2433   [(set_attr "type" "imovx")
2434    (set_attr "mode" "SI")])
2435
2436 (define_insn "*movqi_extv_1_rex64"
2437   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2438         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2439                          (const_int 8)
2440                          (const_int 8)))]
2441   "TARGET_64BIT"
2442 {
2443   switch (get_attr_type (insn))
2444     {
2445     case TYPE_IMOVX:
2446       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2447     default:
2448       return "mov{b}\t{%h1, %0|%0, %h1}";
2449     }
2450 }
2451   [(set (attr "type")
2452      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2453                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2454                              (ne (symbol_ref "TARGET_MOVX")
2455                                  (const_int 0))))
2456         (const_string "imovx")
2457         (const_string "imov")))
2458    (set (attr "mode")
2459      (if_then_else (eq_attr "type" "imovx")
2460         (const_string "SI")
2461         (const_string "QI")))])
2462
2463 (define_insn "*movqi_extv_1"
2464   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2465         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2466                          (const_int 8)
2467                          (const_int 8)))]
2468   "!TARGET_64BIT"
2469 {
2470   switch (get_attr_type (insn))
2471     {
2472     case TYPE_IMOVX:
2473       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2474     default:
2475       return "mov{b}\t{%h1, %0|%0, %h1}";
2476     }
2477 }
2478   [(set (attr "type")
2479      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2480                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2481                              (ne (symbol_ref "TARGET_MOVX")
2482                                  (const_int 0))))
2483         (const_string "imovx")
2484         (const_string "imov")))
2485    (set (attr "mode")
2486      (if_then_else (eq_attr "type" "imovx")
2487         (const_string "SI")
2488         (const_string "QI")))])
2489
2490 (define_insn "*mov<mode>_extzv_1"
2491   [(set (match_operand:SWI48 0 "register_operand" "=R")
2492         (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2493                             (const_int 8)
2494                             (const_int 8)))]
2495   ""
2496   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2497   [(set_attr "type" "imovx")
2498    (set_attr "mode" "SI")])
2499
2500 (define_insn "*movqi_extzv_2_rex64"
2501   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2502         (subreg:QI
2503           (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2504                            (const_int 8)
2505                            (const_int 8)) 0))]
2506   "TARGET_64BIT"
2507 {
2508   switch (get_attr_type (insn))
2509     {
2510     case TYPE_IMOVX:
2511       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2512     default:
2513       return "mov{b}\t{%h1, %0|%0, %h1}";
2514     }
2515 }
2516   [(set (attr "type")
2517      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2518                         (ne (symbol_ref "TARGET_MOVX")
2519                             (const_int 0)))
2520         (const_string "imovx")
2521         (const_string "imov")))
2522    (set (attr "mode")
2523      (if_then_else (eq_attr "type" "imovx")
2524         (const_string "SI")
2525         (const_string "QI")))])
2526
2527 (define_insn "*movqi_extzv_2"
2528   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2529         (subreg:QI
2530           (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2531                            (const_int 8)
2532                            (const_int 8)) 0))]
2533   "!TARGET_64BIT"
2534 {
2535   switch (get_attr_type (insn))
2536     {
2537     case TYPE_IMOVX:
2538       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2539     default:
2540       return "mov{b}\t{%h1, %0|%0, %h1}";
2541     }
2542 }
2543   [(set (attr "type")
2544      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2545                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2546                              (ne (symbol_ref "TARGET_MOVX")
2547                                  (const_int 0))))
2548         (const_string "imovx")
2549         (const_string "imov")))
2550    (set (attr "mode")
2551      (if_then_else (eq_attr "type" "imovx")
2552         (const_string "SI")
2553         (const_string "QI")))])
2554
2555 (define_expand "mov<mode>_insv_1"
2556   [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "")
2557                             (const_int 8)
2558                             (const_int 8))
2559         (match_operand:SWI48 1 "nonmemory_operand" ""))])
2560
2561 (define_insn "*mov<mode>_insv_1_rex64"
2562   [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2563                              (const_int 8)
2564                              (const_int 8))
2565         (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2566   "TARGET_64BIT"
2567   "mov{b}\t{%b1, %h0|%h0, %b1}"
2568   [(set_attr "type" "imov")
2569    (set_attr "mode" "QI")])
2570
2571 (define_insn "*movsi_insv_1"
2572   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2573                          (const_int 8)
2574                          (const_int 8))
2575         (match_operand:SI 1 "general_operand" "Qmn"))]
2576   "!TARGET_64BIT"
2577   "mov{b}\t{%b1, %h0|%h0, %b1}"
2578   [(set_attr "type" "imov")
2579    (set_attr "mode" "QI")])
2580
2581 (define_insn "*movqi_insv_2"
2582   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2583                          (const_int 8)
2584                          (const_int 8))
2585         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2586                      (const_int 8)))]
2587   ""
2588   "mov{b}\t{%h1, %h0|%h0, %h1}"
2589   [(set_attr "type" "imov")
2590    (set_attr "mode" "QI")])
2591 \f
2592 ;; Floating point push instructions.
2593
2594 (define_insn "*pushtf"
2595   [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2596         (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2597   "TARGET_SSE2"
2598 {
2599   /* This insn should be already split before reg-stack.  */
2600   gcc_unreachable ();
2601 }
2602   [(set_attr "type" "multi")
2603    (set_attr "unit" "sse,*,*")
2604    (set_attr "mode" "TF,SI,SI")])
2605
2606 (define_split
2607   [(set (match_operand:TF 0 "push_operand" "")
2608         (match_operand:TF 1 "sse_reg_operand" ""))]
2609   "TARGET_SSE2 && reload_completed"
2610   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2611    (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2612
2613 (define_split
2614   [(set (match_operand:TF 0 "push_operand" "")
2615         (match_operand:TF 1 "general_operand" ""))]
2616   "TARGET_SSE2 && reload_completed
2617    && !SSE_REG_P (operands[1])"
2618   [(const_int 0)]
2619   "ix86_split_long_move (operands); DONE;")
2620
2621 (define_insn "*pushxf"
2622   [(set (match_operand:XF 0 "push_operand" "=<,<")
2623         (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2624   "optimize_function_for_speed_p (cfun)"
2625 {
2626   /* This insn should be already split before reg-stack.  */
2627   gcc_unreachable ();
2628 }
2629   [(set_attr "type" "multi")
2630    (set_attr "unit" "i387,*")
2631    (set_attr "mode" "XF,SI")])
2632
2633 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2634 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2635 ;; Pushing using integer instructions is longer except for constants
2636 ;; and direct memory references (assuming that any given constant is pushed
2637 ;; only once, but this ought to be handled elsewhere).
2638
2639 (define_insn "*pushxf_nointeger"
2640   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2641         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2642   "optimize_function_for_size_p (cfun)"
2643 {
2644   /* This insn should be already split before reg-stack.  */
2645   gcc_unreachable ();
2646 }
2647   [(set_attr "type" "multi")
2648    (set_attr "unit" "i387,*,*")
2649    (set_attr "mode" "XF,SI,SI")])
2650
2651 (define_split
2652   [(set (match_operand:XF 0 "push_operand" "")
2653         (match_operand:XF 1 "fp_register_operand" ""))]
2654   "reload_completed"
2655   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2656    (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2657   "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2658
2659 (define_split
2660   [(set (match_operand:XF 0 "push_operand" "")
2661         (match_operand:XF 1 "general_operand" ""))]
2662   "reload_completed
2663    && !FP_REG_P (operands[1])"
2664   [(const_int 0)]
2665   "ix86_split_long_move (operands); DONE;")
2666
2667 (define_insn "*pushdf"
2668   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2669         (match_operand:DF 1 "general_no_elim_operand" "f,rFo,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,DF")])
2678
2679 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2680 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2681 ;; On the average, pushdf using integers can be still shorter.  Allow this
2682 ;; pattern for optimize_size too.
2683
2684 (define_insn "*pushdf_nointeger"
2685   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2686         (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2687   "!(TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES)"
2688 {
2689   /* This insn should be already split before reg-stack.  */
2690   gcc_unreachable ();
2691 }
2692   [(set_attr "type" "multi")
2693    (set_attr "unit" "i387,*,*,*")
2694    (set_attr "mode" "DF,SI,SI,DF")])
2695
2696 ;; %%% Kill this when call knows how to work this out.
2697 (define_split
2698   [(set (match_operand:DF 0 "push_operand" "")
2699         (match_operand:DF 1 "any_fp_register_operand" ""))]
2700   "reload_completed"
2701   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2702    (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2703
2704 (define_split
2705   [(set (match_operand:DF 0 "push_operand" "")
2706         (match_operand:DF 1 "general_operand" ""))]
2707   "reload_completed
2708    && !ANY_FP_REG_P (operands[1])"
2709   [(const_int 0)]
2710   "ix86_split_long_move (operands); DONE;")
2711
2712 (define_insn "*pushsf_rex64"
2713   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2714         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2715   "TARGET_64BIT"
2716 {
2717   /* Anything else should be already split before reg-stack.  */
2718   gcc_assert (which_alternative == 1);
2719   return "push{q}\t%q1";
2720 }
2721   [(set_attr "type" "multi,push,multi")
2722    (set_attr "unit" "i387,*,*")
2723    (set_attr "mode" "SF,DI,SF")])
2724
2725 (define_insn "*pushsf"
2726   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2727         (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2728   "!TARGET_64BIT"
2729 {
2730   /* Anything else should be already split before reg-stack.  */
2731   gcc_assert (which_alternative == 1);
2732   return "push{l}\t%1";
2733 }
2734   [(set_attr "type" "multi,push,multi")
2735    (set_attr "unit" "i387,*,*")
2736    (set_attr "mode" "SF,SI,SF")])
2737
2738 (define_split
2739   [(set (match_operand:SF 0 "push_operand" "")
2740         (match_operand:SF 1 "memory_operand" ""))]
2741   "reload_completed
2742    && MEM_P (operands[1])
2743    && (operands[2] = find_constant_src (insn))"
2744   [(set (match_dup 0)
2745         (match_dup 2))])
2746
2747 ;; %%% Kill this when call knows how to work this out.
2748 (define_split
2749   [(set (match_operand:SF 0 "push_operand" "")
2750         (match_operand:SF 1 "any_fp_register_operand" ""))]
2751   "reload_completed"
2752   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2753    (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2754   "operands[2] = GEN_INT (-GET_MODE_SIZE (<MODE>mode));")
2755 \f
2756 ;; Floating point move instructions.
2757
2758 (define_expand "movtf"
2759   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2760         (match_operand:TF 1 "nonimmediate_operand" ""))]
2761   "TARGET_SSE2"
2762 {
2763   ix86_expand_move (TFmode, operands);
2764   DONE;
2765 })
2766
2767 (define_expand "mov<mode>"
2768   [(set (match_operand:X87MODEF 0 "nonimmediate_operand" "")
2769         (match_operand:X87MODEF 1 "general_operand" ""))]
2770   ""
2771   "ix86_expand_move (<MODE>mode, operands); DONE;")
2772
2773 (define_insn "*movtf_internal"
2774   [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
2775         (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
2776   "TARGET_SSE2
2777    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2778 {
2779   switch (which_alternative)
2780     {
2781     case 0:
2782     case 1:
2783       if (get_attr_mode (insn) == MODE_V4SF)
2784         return "%vmovaps\t{%1, %0|%0, %1}";
2785       else
2786         return "%vmovdqa\t{%1, %0|%0, %1}";
2787     case 2:
2788       if (get_attr_mode (insn) == MODE_V4SF)
2789         return "%vxorps\t%0, %d0";
2790       else
2791         return "%vpxor\t%0, %d0";
2792     case 3:
2793     case 4:
2794         return "#";
2795     default:
2796       gcc_unreachable ();
2797     }
2798 }
2799   [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
2800    (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2801    (set (attr "mode")
2802         (cond [(eq_attr "alternative" "0,2")
2803                  (if_then_else
2804                    (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2805                        (const_int 0))
2806                    (const_string "V4SF")
2807                    (const_string "TI"))
2808                (eq_attr "alternative" "1")
2809                  (if_then_else
2810                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2811                             (const_int 0))
2812                         (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2813                             (const_int 0)))
2814                    (const_string "V4SF")
2815                    (const_string "TI"))]
2816                (const_string "DI")))])
2817
2818 (define_split
2819   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2820         (match_operand:TF 1 "general_operand" ""))]
2821   "reload_completed
2822    && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
2823   [(const_int 0)]
2824   "ix86_split_long_move (operands); DONE;")
2825
2826 (define_insn "*movxf_internal"
2827   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
2828         (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
2829   "optimize_function_for_speed_p (cfun)
2830    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2831    && (reload_in_progress || reload_completed
2832        || GET_CODE (operands[1]) != CONST_DOUBLE
2833        || memory_operand (operands[0], XFmode))"
2834 {
2835   switch (which_alternative)
2836     {
2837     case 0:
2838     case 1:
2839       return output_387_reg_move (insn, operands);
2840
2841     case 2:
2842       return standard_80387_constant_opcode (operands[1]);
2843
2844     case 3: case 4:
2845       return "#";
2846
2847     default:
2848       gcc_unreachable ();
2849     }
2850 }
2851   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2852    (set_attr "mode" "XF,XF,XF,SI,SI")])
2853
2854 ;; Do not use integer registers when optimizing for size
2855 (define_insn "*movxf_internal_nointeger"
2856   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2857         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2858   "optimize_function_for_size_p (cfun)
2859    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2860    && (reload_in_progress || reload_completed
2861        || standard_80387_constant_p (operands[1])
2862        || GET_CODE (operands[1]) != CONST_DOUBLE
2863        || memory_operand (operands[0], XFmode))"
2864 {
2865   switch (which_alternative)
2866     {
2867     case 0:
2868     case 1:
2869       return output_387_reg_move (insn, operands);
2870
2871     case 2:
2872       return standard_80387_constant_opcode (operands[1]);
2873
2874     case 3: case 4:
2875       return "#";
2876     default:
2877       gcc_unreachable ();
2878     }
2879 }
2880   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2881    (set_attr "mode" "XF,XF,XF,SI,SI")])
2882
2883 (define_split
2884   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2885         (match_operand:XF 1 "general_operand" ""))]
2886   "reload_completed
2887    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2888    && ! (FP_REG_P (operands[0]) ||
2889          (GET_CODE (operands[0]) == SUBREG
2890           && FP_REG_P (SUBREG_REG (operands[0]))))
2891    && ! (FP_REG_P (operands[1]) ||
2892          (GET_CODE (operands[1]) == SUBREG
2893           && FP_REG_P (SUBREG_REG (operands[1]))))"
2894   [(const_int 0)]
2895   "ix86_split_long_move (operands); DONE;")
2896
2897 (define_insn "*movdf_internal_rex64"
2898   [(set (match_operand:DF 0 "nonimmediate_operand"
2899                 "=f,m,f,r  ,m ,Y2*x,Y2*x,Y2*x,m   ,Yi,r ")
2900         (match_operand:DF 1 "general_operand"
2901                 "fm,f,G,rmF,Fr,C   ,Y2*x,m   ,Y2*x,r ,Yi"))]
2902   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2903    && (reload_in_progress || reload_completed
2904        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2905        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
2906            && optimize_function_for_size_p (cfun)
2907            && standard_80387_constant_p (operands[1]))
2908        || GET_CODE (operands[1]) != CONST_DOUBLE
2909        || memory_operand (operands[0], DFmode))"
2910 {
2911   switch (which_alternative)
2912     {
2913     case 0:
2914     case 1:
2915       return output_387_reg_move (insn, operands);
2916
2917     case 2:
2918       return standard_80387_constant_opcode (operands[1]);
2919
2920     case 3:
2921     case 4:
2922       return "#";
2923
2924     case 5:
2925       switch (get_attr_mode (insn))
2926         {
2927         case MODE_V4SF:
2928           return "%vxorps\t%0, %d0";
2929         case MODE_V2DF:
2930           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2931             return "%vxorps\t%0, %d0";
2932           else
2933             return "%vxorpd\t%0, %d0";
2934         case MODE_TI:
2935           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2936             return "%vxorps\t%0, %d0";
2937           else
2938             return "%vpxor\t%0, %d0";
2939         default:
2940           gcc_unreachable ();
2941         }
2942     case 6:
2943     case 7:
2944     case 8:
2945       switch (get_attr_mode (insn))
2946         {
2947         case MODE_V4SF:
2948           return "%vmovaps\t{%1, %0|%0, %1}";
2949         case MODE_V2DF:
2950           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2951             return "%vmovaps\t{%1, %0|%0, %1}";
2952           else
2953             return "%vmovapd\t{%1, %0|%0, %1}";
2954         case MODE_TI:
2955           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2956             return "%vmovaps\t{%1, %0|%0, %1}";
2957           else
2958             return "%vmovdqa\t{%1, %0|%0, %1}";
2959         case MODE_DI:
2960           return "%vmovq\t{%1, %0|%0, %1}";
2961         case MODE_DF:
2962           if (TARGET_AVX)
2963             {
2964               if (REG_P (operands[0]) && REG_P (operands[1]))
2965                 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
2966               else
2967                 return "vmovsd\t{%1, %0|%0, %1}";
2968             }
2969           else
2970             return "movsd\t{%1, %0|%0, %1}";
2971         case MODE_V1DF:
2972           return "%vmovlpd\t{%1, %d0|%d0, %1}";
2973         case MODE_V2SF:
2974           return "%vmovlps\t{%1, %d0|%d0, %1}";
2975         default:
2976           gcc_unreachable ();
2977         }
2978
2979     case 9:
2980     case 10:
2981     return "%vmovd\t{%1, %0|%0, %1}";
2982
2983     default:
2984       gcc_unreachable();
2985     }
2986 }
2987   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
2988    (set (attr "prefix")
2989      (if_then_else (eq_attr "alternative" "0,1,2,3,4")
2990        (const_string "orig")
2991        (const_string "maybe_vex")))
2992    (set (attr "prefix_data16")
2993      (if_then_else (eq_attr "mode" "V1DF")
2994        (const_string "1")
2995        (const_string "*")))
2996    (set (attr "mode")
2997         (cond [(eq_attr "alternative" "0,1,2")
2998                  (const_string "DF")
2999                (eq_attr "alternative" "3,4,9,10")
3000                  (const_string "DI")
3001
3002                /* For SSE1, we have many fewer alternatives.  */
3003                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3004                  (cond [(eq_attr "alternative" "5,6")
3005                           (const_string "V4SF")
3006                        ]
3007                    (const_string "V2SF"))
3008
3009                /* xorps is one byte shorter.  */
3010                (eq_attr "alternative" "5")
3011                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3012                             (const_int 0))
3013                           (const_string "V4SF")
3014                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3015                             (const_int 0))
3016                           (const_string "TI")
3017                        ]
3018                        (const_string "V2DF"))
3019
3020                /* For architectures resolving dependencies on
3021                   whole SSE registers use APD move to break dependency
3022                   chains, otherwise use short move to avoid extra work.
3023
3024                   movaps encodes one byte shorter.  */
3025                (eq_attr "alternative" "6")
3026                  (cond
3027                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3028                         (const_int 0))
3029                       (const_string "V4SF")
3030                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3031                         (const_int 0))
3032                       (const_string "V2DF")
3033                    ]
3034                    (const_string "DF"))
3035                /* For architectures resolving dependencies on register
3036                   parts we may avoid extra work to zero out upper part
3037                   of register.  */
3038                (eq_attr "alternative" "7")
3039                  (if_then_else
3040                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3041                        (const_int 0))
3042                    (const_string "V1DF")
3043                    (const_string "DF"))
3044               ]
3045               (const_string "DF")))])
3046
3047 (define_insn "*movdf_internal"
3048   [(set (match_operand:DF 0 "nonimmediate_operand"
3049                 "=f,m,f,r  ,o ,Y2*x,Y2*x,Y2*x,m   ")
3050         (match_operand:DF 1 "general_operand"
3051                 "fm,f,G,roF,Fr,C   ,Y2*x,m   ,Y2*x"))]
3052   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3053    && optimize_function_for_speed_p (cfun)
3054    && TARGET_INTEGER_DFMODE_MOVES
3055    && (reload_in_progress || reload_completed
3056        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3057        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3058            && optimize_function_for_size_p (cfun)
3059            && standard_80387_constant_p (operands[1]))
3060        || GET_CODE (operands[1]) != CONST_DOUBLE
3061        || memory_operand (operands[0], DFmode))"
3062 {
3063   switch (which_alternative)
3064     {
3065     case 0:
3066     case 1:
3067       return output_387_reg_move (insn, operands);
3068
3069     case 2:
3070       return standard_80387_constant_opcode (operands[1]);
3071
3072     case 3:
3073     case 4:
3074       return "#";
3075
3076     case 5:
3077       switch (get_attr_mode (insn))
3078         {
3079         case MODE_V4SF:
3080           return "xorps\t%0, %0";
3081         case MODE_V2DF:
3082           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3083             return "xorps\t%0, %0";
3084           else
3085             return "xorpd\t%0, %0";
3086         case MODE_TI:
3087           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3088             return "xorps\t%0, %0";
3089           else
3090             return "pxor\t%0, %0";
3091         default:
3092           gcc_unreachable ();
3093         }
3094     case 6:
3095     case 7:
3096     case 8:
3097       switch (get_attr_mode (insn))
3098         {
3099         case MODE_V4SF:
3100           return "movaps\t{%1, %0|%0, %1}";
3101         case MODE_V2DF:
3102           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3103             return "movaps\t{%1, %0|%0, %1}";
3104           else
3105             return "movapd\t{%1, %0|%0, %1}";
3106         case MODE_TI:
3107           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3108             return "movaps\t{%1, %0|%0, %1}";
3109           else
3110             return "movdqa\t{%1, %0|%0, %1}";
3111         case MODE_DI:
3112           return "movq\t{%1, %0|%0, %1}";
3113         case MODE_DF:
3114           return "movsd\t{%1, %0|%0, %1}";
3115         case MODE_V1DF:
3116           return "movlpd\t{%1, %0|%0, %1}";
3117         case MODE_V2SF:
3118           return "movlps\t{%1, %0|%0, %1}";
3119         default:
3120           gcc_unreachable ();
3121         }
3122
3123     default:
3124       gcc_unreachable();
3125     }
3126 }
3127   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3128    (set (attr "prefix_data16")
3129      (if_then_else (eq_attr "mode" "V1DF")
3130        (const_string "1")
3131        (const_string "*")))
3132    (set (attr "mode")
3133         (cond [(eq_attr "alternative" "0,1,2")
3134                  (const_string "DF")
3135                (eq_attr "alternative" "3,4")
3136                  (const_string "SI")
3137
3138                /* For SSE1, we have many fewer alternatives.  */
3139                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3140                  (cond [(eq_attr "alternative" "5,6")
3141                           (const_string "V4SF")
3142                        ]
3143                    (const_string "V2SF"))
3144
3145                /* xorps is one byte shorter.  */
3146                (eq_attr "alternative" "5")
3147                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3148                             (const_int 0))
3149                           (const_string "V4SF")
3150                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3151                             (const_int 0))
3152                           (const_string "TI")
3153                        ]
3154                        (const_string "V2DF"))
3155
3156                /* For architectures resolving dependencies on
3157                   whole SSE registers use APD move to break dependency
3158                   chains, otherwise use short move to avoid extra work.
3159
3160                   movaps encodes one byte shorter.  */
3161                (eq_attr "alternative" "6")
3162                  (cond
3163                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3164                         (const_int 0))
3165                       (const_string "V4SF")
3166                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3167                         (const_int 0))
3168                       (const_string "V2DF")
3169                    ]
3170                    (const_string "DF"))
3171                /* For architectures resolving dependencies on register
3172                   parts we may avoid extra work to zero out upper part
3173                   of register.  */
3174                (eq_attr "alternative" "7")
3175                  (if_then_else
3176                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3177                        (const_int 0))
3178                    (const_string "V1DF")
3179                    (const_string "DF"))
3180               ]
3181               (const_string "DF")))])
3182
3183 ;; Moving is usually shorter when only FP registers are used. This separate
3184 ;; movdf pattern avoids the use of integer registers for FP operations
3185 ;; when optimizing for size.
3186
3187 (define_insn "*movdf_internal_nointeger"
3188   [(set (match_operand:DF 0 "nonimmediate_operand"
3189                         "=f,m,f,*r  ,o  ,Y2*x,Y2*x,Y2*x ,m  ")
3190         (match_operand:DF 1 "general_operand"
3191                         "fm,f,G,*roF,*Fr,C   ,Y2*x,mY2*x,Y2*x"))]
3192   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3193    && ((optimize_function_for_size_p (cfun)
3194        || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
3195    && (reload_in_progress || reload_completed
3196        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3197        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3198            && optimize_function_for_size_p (cfun)
3199            && !memory_operand (operands[0], DFmode)
3200            && standard_80387_constant_p (operands[1]))
3201        || GET_CODE (operands[1]) != CONST_DOUBLE
3202        || ((optimize_function_for_size_p (cfun)
3203             || !TARGET_MEMORY_MISMATCH_STALL
3204             || reload_in_progress || reload_completed)
3205            && memory_operand (operands[0], DFmode)))"
3206 {
3207   switch (which_alternative)
3208     {
3209     case 0:
3210     case 1:
3211       return output_387_reg_move (insn, operands);
3212
3213     case 2:
3214       return standard_80387_constant_opcode (operands[1]);
3215
3216     case 3:
3217     case 4:
3218       return "#";
3219
3220     case 5:
3221       switch (get_attr_mode (insn))
3222         {
3223         case MODE_V4SF:
3224           return "%vxorps\t%0, %d0";
3225         case MODE_V2DF:
3226           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3227             return "%vxorps\t%0, %d0";
3228           else
3229             return "%vxorpd\t%0, %d0";
3230         case MODE_TI:
3231           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3232             return "%vxorps\t%0, %d0";
3233           else
3234             return "%vpxor\t%0, %d0";
3235         default:
3236           gcc_unreachable ();
3237         }
3238     case 6:
3239     case 7:
3240     case 8:
3241       switch (get_attr_mode (insn))
3242         {
3243         case MODE_V4SF:
3244           return "%vmovaps\t{%1, %0|%0, %1}";
3245         case MODE_V2DF:
3246           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3247             return "%vmovaps\t{%1, %0|%0, %1}";
3248           else
3249             return "%vmovapd\t{%1, %0|%0, %1}";
3250         case MODE_TI:
3251           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3252             return "%vmovaps\t{%1, %0|%0, %1}";
3253           else
3254             return "%vmovdqa\t{%1, %0|%0, %1}";
3255         case MODE_DI:
3256           return "%vmovq\t{%1, %0|%0, %1}";
3257         case MODE_DF:
3258           if (TARGET_AVX)
3259             {
3260               if (REG_P (operands[0]) && REG_P (operands[1]))
3261                 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3262               else
3263                 return "vmovsd\t{%1, %0|%0, %1}";
3264             }
3265           else
3266             return "movsd\t{%1, %0|%0, %1}";
3267         case MODE_V1DF:
3268           if (TARGET_AVX)
3269             {
3270               if (REG_P (operands[0]))
3271                 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
3272               else
3273                 return "vmovlpd\t{%1, %0|%0, %1}";
3274             }
3275           else
3276             return "movlpd\t{%1, %0|%0, %1}";
3277         case MODE_V2SF:
3278           if (TARGET_AVX)
3279             {
3280               if (REG_P (operands[0]))
3281                 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
3282               else
3283                 return "vmovlps\t{%1, %0|%0, %1}";
3284             }
3285           else
3286             return "movlps\t{%1, %0|%0, %1}";
3287         default:
3288           gcc_unreachable ();
3289         }
3290
3291     default:
3292       gcc_unreachable ();
3293     }
3294 }
3295   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3296    (set (attr "prefix")
3297      (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3298        (const_string "orig")
3299        (const_string "maybe_vex")))
3300    (set (attr "prefix_data16")
3301      (if_then_else (eq_attr "mode" "V1DF")
3302        (const_string "1")
3303        (const_string "*")))
3304    (set (attr "mode")
3305         (cond [(eq_attr "alternative" "0,1,2")
3306                  (const_string "DF")
3307                (eq_attr "alternative" "3,4")
3308                  (const_string "SI")
3309
3310                /* For SSE1, we have many fewer alternatives.  */
3311                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3312                  (cond [(eq_attr "alternative" "5,6")
3313                           (const_string "V4SF")
3314                        ]
3315                    (const_string "V2SF"))
3316
3317                /* xorps is one byte shorter.  */
3318                (eq_attr "alternative" "5")
3319                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3320                             (const_int 0))
3321                           (const_string "V4SF")
3322                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3323                             (const_int 0))
3324                           (const_string "TI")
3325                        ]
3326                        (const_string "V2DF"))
3327
3328                /* For architectures resolving dependencies on
3329                   whole SSE registers use APD move to break dependency
3330                   chains, otherwise use short move to avoid extra work.
3331
3332                   movaps encodes one byte shorter.  */
3333                (eq_attr "alternative" "6")
3334                  (cond
3335                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3336                         (const_int 0))
3337                       (const_string "V4SF")
3338                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3339                         (const_int 0))
3340                       (const_string "V2DF")
3341                    ]
3342                    (const_string "DF"))
3343                /* For architectures resolving dependencies on register
3344                   parts we may avoid extra work to zero out upper part
3345                   of register.  */
3346                (eq_attr "alternative" "7")
3347                  (if_then_else
3348                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3349                        (const_int 0))
3350                    (const_string "V1DF")
3351                    (const_string "DF"))
3352               ]
3353               (const_string "DF")))])
3354
3355 (define_split
3356   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3357         (match_operand:DF 1 "general_operand" ""))]
3358   "reload_completed
3359    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3360    && ! (ANY_FP_REG_P (operands[0]) ||
3361          (GET_CODE (operands[0]) == SUBREG
3362           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3363    && ! (ANY_FP_REG_P (operands[1]) ||
3364          (GET_CODE (operands[1]) == SUBREG
3365           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3366   [(const_int 0)]
3367   "ix86_split_long_move (operands); DONE;")
3368
3369 (define_insn "*movsf_internal"
3370   [(set (match_operand:SF 0 "nonimmediate_operand"
3371           "=f,m,f,r  ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3372         (match_operand:SF 1 "general_operand"
3373           "fm,f,G,rmF,Fr,C,x,xm,x,m  ,*y,*y ,r  ,Yi,r   ,*Ym"))]
3374   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3375    && (reload_in_progress || reload_completed
3376        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3377        || (!TARGET_SSE_MATH && optimize_function_for_size_p (cfun)
3378            && standard_80387_constant_p (operands[1]))
3379        || GET_CODE (operands[1]) != CONST_DOUBLE
3380        || memory_operand (operands[0], SFmode))"
3381 {
3382   switch (which_alternative)
3383     {
3384     case 0:
3385     case 1:
3386       return output_387_reg_move (insn, operands);
3387
3388     case 2:
3389       return standard_80387_constant_opcode (operands[1]);
3390
3391     case 3:
3392     case 4:
3393       return "mov{l}\t{%1, %0|%0, %1}";
3394     case 5:
3395       if (get_attr_mode (insn) == MODE_TI)
3396         return "%vpxor\t%0, %d0";
3397       else
3398         return "%vxorps\t%0, %d0";
3399     case 6:
3400       if (get_attr_mode (insn) == MODE_V4SF)
3401         return "%vmovaps\t{%1, %0|%0, %1}";
3402       else
3403         return "%vmovss\t{%1, %d0|%d0, %1}";
3404     case 7:
3405       if (TARGET_AVX)
3406         return REG_P (operands[1]) ? "vmovss\t{%1, %0, %0|%0, %0, %1}"
3407                                    : "vmovss\t{%1, %0|%0, %1}";
3408       else
3409         return "movss\t{%1, %0|%0, %1}";
3410     case 8:
3411       return "%vmovss\t{%1, %0|%0, %1}";
3412
3413     case 9: case 10: case 14: case 15:
3414       return "movd\t{%1, %0|%0, %1}";
3415     case 12: case 13:
3416       return "%vmovd\t{%1, %0|%0, %1}";
3417
3418     case 11:
3419       return "movq\t{%1, %0|%0, %1}";
3420
3421     default:
3422       gcc_unreachable ();
3423     }
3424 }
3425   [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
3426    (set (attr "prefix")
3427      (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3428        (const_string "maybe_vex")
3429        (const_string "orig")))
3430    (set (attr "mode")
3431         (cond [(eq_attr "alternative" "3,4,9,10")
3432                  (const_string "SI")
3433                (eq_attr "alternative" "5")
3434                  (if_then_else
3435                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3436                                  (const_int 0))
3437                              (ne (symbol_ref "TARGET_SSE2")
3438                                  (const_int 0)))
3439                         (eq (symbol_ref "optimize_function_for_size_p (cfun)")
3440                             (const_int 0)))
3441                    (const_string "TI")
3442                    (const_string "V4SF"))
3443                /* For architectures resolving dependencies on
3444                   whole SSE registers use APS move to break dependency
3445                   chains, otherwise use short move to avoid extra work.
3446
3447                   Do the same for architectures resolving dependencies on
3448                   the parts.  While in DF mode it is better to always handle
3449                   just register parts, the SF mode is different due to lack
3450                   of instructions to load just part of the register.  It is
3451                   better to maintain the whole registers in single format
3452                   to avoid problems on using packed logical operations.  */
3453                (eq_attr "alternative" "6")
3454                  (if_then_else
3455                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3456                             (const_int 0))
3457                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3458                             (const_int 0)))
3459                    (const_string "V4SF")
3460                    (const_string "SF"))
3461                (eq_attr "alternative" "11")
3462                  (const_string "DI")]
3463                (const_string "SF")))])
3464
3465 (define_split
3466   [(set (match_operand 0 "register_operand" "")
3467         (match_operand 1 "memory_operand" ""))]
3468   "reload_completed
3469    && MEM_P (operands[1])
3470    && (GET_MODE (operands[0]) == TFmode
3471        || GET_MODE (operands[0]) == XFmode
3472        || GET_MODE (operands[0]) == DFmode
3473        || GET_MODE (operands[0]) == SFmode)
3474    && (operands[2] = find_constant_src (insn))"
3475   [(set (match_dup 0) (match_dup 2))]
3476 {
3477   rtx c = operands[2];
3478   rtx r = operands[0];
3479
3480   if (GET_CODE (r) == SUBREG)
3481     r = SUBREG_REG (r);
3482
3483   if (SSE_REG_P (r))
3484     {
3485       if (!standard_sse_constant_p (c))
3486         FAIL;
3487     }
3488   else if (FP_REG_P (r))
3489     {
3490       if (!standard_80387_constant_p (c))
3491         FAIL;
3492     }
3493   else if (MMX_REG_P (r))
3494     FAIL;
3495 })
3496
3497 (define_split
3498   [(set (match_operand 0 "register_operand" "")
3499         (float_extend (match_operand 1 "memory_operand" "")))]
3500   "reload_completed
3501    && MEM_P (operands[1])
3502    && (GET_MODE (operands[0]) == TFmode
3503        || GET_MODE (operands[0]) == XFmode
3504        || GET_MODE (operands[0]) == DFmode
3505        || GET_MODE (operands[0]) == SFmode)
3506    && (operands[2] = find_constant_src (insn))"
3507   [(set (match_dup 0) (match_dup 2))]
3508 {
3509   rtx c = operands[2];
3510   rtx r = operands[0];
3511
3512   if (GET_CODE (r) == SUBREG)
3513     r = SUBREG_REG (r);
3514
3515   if (SSE_REG_P (r))
3516     {
3517       if (!standard_sse_constant_p (c))
3518         FAIL;
3519     }
3520   else if (FP_REG_P (r))
3521     {
3522       if (!standard_80387_constant_p (c))
3523         FAIL;
3524     }
3525   else if (MMX_REG_P (r))
3526     FAIL;
3527 })
3528
3529 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3530 (define_split
3531   [(set (match_operand:X87MODEF 0 "register_operand" "")
3532         (match_operand:X87MODEF 1 "immediate_operand" ""))]
3533   "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3534    && (standard_80387_constant_p (operands[1]) == 8
3535        || standard_80387_constant_p (operands[1]) == 9)"
3536   [(set (match_dup 0)(match_dup 1))
3537    (set (match_dup 0)
3538         (neg:X87MODEF (match_dup 0)))]
3539 {
3540   REAL_VALUE_TYPE r;
3541
3542   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3543   if (real_isnegzero (&r))
3544     operands[1] = CONST0_RTX (<MODE>mode);
3545   else
3546     operands[1] = CONST1_RTX (<MODE>mode);
3547 })
3548
3549 (define_insn "swapxf"
3550   [(set (match_operand:XF 0 "register_operand" "+f")
3551         (match_operand:XF 1 "register_operand" "+f"))
3552    (set (match_dup 1)
3553         (match_dup 0))]
3554   "TARGET_80387"
3555 {
3556   if (STACK_TOP_P (operands[0]))
3557     return "fxch\t%1";
3558   else
3559     return "fxch\t%0";
3560 }
3561   [(set_attr "type" "fxch")
3562    (set_attr "mode" "XF")])
3563
3564 (define_insn "*swap<mode>"
3565   [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3566         (match_operand:MODEF 1 "fp_register_operand" "+f"))
3567    (set (match_dup 1)
3568         (match_dup 0))]
3569   "TARGET_80387 || reload_completed"
3570 {
3571   if (STACK_TOP_P (operands[0]))
3572     return "fxch\t%1";
3573   else
3574     return "fxch\t%0";
3575 }
3576   [(set_attr "type" "fxch")
3577    (set_attr "mode" "<MODE>")])
3578 \f
3579 ;; Zero extension instructions
3580
3581 (define_expand "zero_extendsidi2"
3582   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3583         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3584   ""
3585 {
3586   if (!TARGET_64BIT)
3587     {
3588       emit_insn (gen_zero_extendsidi2_1 (operands[0], operands[1]));
3589       DONE;
3590     }
3591 })
3592
3593 (define_insn "*zero_extendsidi2_rex64"
3594   [(set (match_operand:DI 0 "nonimmediate_operand"  "=r,o,?*Ym,?*y,?*Yi,*Y2")
3595         (zero_extend:DI
3596          (match_operand:SI 1 "nonimmediate_operand" "rm,0,r   ,m  ,r   ,m")))]
3597   "TARGET_64BIT"
3598   "@
3599    mov\t{%k1, %k0|%k0, %k1}
3600    #
3601    movd\t{%1, %0|%0, %1}
3602    movd\t{%1, %0|%0, %1}
3603    %vmovd\t{%1, %0|%0, %1}
3604    %vmovd\t{%1, %0|%0, %1}"
3605   [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3606    (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3607    (set_attr "prefix_0f" "0,*,*,*,*,*")
3608    (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3609
3610 (define_split
3611   [(set (match_operand:DI 0 "memory_operand" "")
3612         (zero_extend:DI (match_dup 0)))]
3613   "TARGET_64BIT"
3614   [(set (match_dup 4) (const_int 0))]
3615   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3616
3617 ;; %%% Kill me once multi-word ops are sane.
3618 (define_insn "zero_extendsidi2_1"
3619   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3620         (zero_extend:DI
3621          (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r   ,m  ,r   ,m")))
3622    (clobber (reg:CC FLAGS_REG))]
3623   "!TARGET_64BIT"
3624   "@
3625    #
3626    #
3627    #
3628    movd\t{%1, %0|%0, %1}
3629    movd\t{%1, %0|%0, %1}
3630    %vmovd\t{%1, %0|%0, %1}
3631    %vmovd\t{%1, %0|%0, %1}"
3632   [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3633    (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3634    (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3635
3636 (define_split
3637   [(set (match_operand:DI 0 "register_operand" "")
3638         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3639    (clobber (reg:CC FLAGS_REG))]
3640   "!TARGET_64BIT && reload_completed
3641    && true_regnum (operands[0]) == true_regnum (operands[1])"
3642   [(set (match_dup 4) (const_int 0))]
3643   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3644
3645 (define_split
3646   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3647         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3648    (clobber (reg:CC FLAGS_REG))]
3649   "!TARGET_64BIT && reload_completed
3650    && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3651   [(set (match_dup 3) (match_dup 1))
3652    (set (match_dup 4) (const_int 0))]
3653   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3654
3655 (define_insn "zero_extend<mode>di2"
3656   [(set (match_operand:DI 0 "register_operand" "=r")
3657         (zero_extend:DI
3658          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3659   "TARGET_64BIT"
3660   "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3661   [(set_attr "type" "imovx")
3662    (set_attr "mode" "SI")])
3663
3664 (define_expand "zero_extendhisi2"
3665   [(set (match_operand:SI 0 "register_operand" "")
3666         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3667   ""
3668 {
3669   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3670     {
3671       operands[1] = force_reg (HImode, operands[1]);
3672       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3673       DONE;
3674     }
3675 })
3676
3677 (define_insn_and_split "zero_extendhisi2_and"
3678   [(set (match_operand:SI 0 "register_operand" "=r")
3679         (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3680    (clobber (reg:CC FLAGS_REG))]
3681   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3682   "#"
3683   "&& reload_completed"
3684   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3685               (clobber (reg:CC FLAGS_REG))])]
3686   ""
3687   [(set_attr "type" "alu1")
3688    (set_attr "mode" "SI")])
3689
3690 (define_insn "*zero_extendhisi2_movzwl"
3691   [(set (match_operand:SI 0 "register_operand" "=r")
3692         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3693   "!TARGET_ZERO_EXTEND_WITH_AND
3694    || optimize_function_for_size_p (cfun)"
3695   "movz{wl|x}\t{%1, %0|%0, %1}"
3696   [(set_attr "type" "imovx")
3697    (set_attr "mode" "SI")])
3698
3699 (define_expand "zero_extendqi<mode>2"
3700   [(parallel
3701     [(set (match_operand:SWI24 0 "register_operand" "")
3702           (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3703      (clobber (reg:CC FLAGS_REG))])])
3704
3705 (define_insn "*zero_extendqi<mode>2_and"
3706   [(set (match_operand:SWI24 0 "register_operand" "=r,?&q")
3707         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3708    (clobber (reg:CC FLAGS_REG))]
3709   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3710   "#"
3711   [(set_attr "type" "alu1")
3712    (set_attr "mode" "<MODE>")])
3713
3714 ;; When source and destination does not overlap, clear destination
3715 ;; first and then do the movb
3716 (define_split
3717   [(set (match_operand:SWI24 0 "register_operand" "")
3718         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3719    (clobber (reg:CC FLAGS_REG))]
3720   "reload_completed
3721    && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3722    && ANY_QI_REG_P (operands[0])
3723    && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3724    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3725   [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3726 {
3727   operands[2] = gen_lowpart (QImode, operands[0]);
3728   ix86_expand_clear (operands[0]);
3729 })
3730
3731 (define_insn "*zero_extendqi<mode>2_movzbl_and"
3732   [(set (match_operand:SWI24 0 "register_operand" "=r,r")
3733         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3734    (clobber (reg:CC FLAGS_REG))]
3735   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3736   "#"
3737   [(set_attr "type" "imovx,alu1")
3738    (set_attr "mode" "<MODE>")])
3739
3740 ;; For the movzbl case strip only the clobber
3741 (define_split
3742   [(set (match_operand:SWI24 0 "register_operand" "")
3743         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3744    (clobber (reg:CC FLAGS_REG))]
3745   "reload_completed
3746    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3747    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3748   [(set (match_dup 0)
3749         (zero_extend:SWI24 (match_dup 1)))])
3750
3751 ; zero extend to SImode to avoid partial register stalls
3752 (define_insn "*zero_extendqi<mode>2_movzbl"
3753   [(set (match_operand:SWI24 0 "register_operand" "=r")
3754         (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3755   "reload_completed
3756    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
3757   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3758   [(set_attr "type" "imovx")
3759    (set_attr "mode" "SI")])
3760
3761 ;; Rest is handled by single and.
3762 (define_split
3763   [(set (match_operand:SWI24 0 "register_operand" "")
3764         (zero_extend:SWI24 (match_operand:QI 1 "register_operand" "")))
3765    (clobber (reg:CC FLAGS_REG))]
3766   "reload_completed
3767    && true_regnum (operands[0]) == true_regnum (operands[1])"
3768   [(parallel [(set (match_dup 0) (and:SWI24 (match_dup 0) (const_int 255)))
3769               (clobber (reg:CC FLAGS_REG))])])
3770 \f
3771 ;; Sign extension instructions
3772
3773 (define_expand "extendsidi2"
3774   [(set (match_operand:DI 0 "register_operand" "")
3775         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3776   ""
3777 {
3778   if (!TARGET_64BIT)
3779     {
3780       emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3781       DONE;
3782     }
3783 })
3784
3785 (define_insn "*extendsidi2_rex64"
3786   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3787         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3788   "TARGET_64BIT"
3789   "@
3790    {cltq|cdqe}
3791    movs{lq|x}\t{%1, %0|%0, %1}"
3792   [(set_attr "type" "imovx")
3793    (set_attr "mode" "DI")
3794    (set_attr "prefix_0f" "0")
3795    (set_attr "modrm" "0,1")])
3796
3797 (define_insn "extendsidi2_1"
3798   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3799         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3800    (clobber (reg:CC FLAGS_REG))
3801    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3802   "!TARGET_64BIT"
3803   "#")
3804
3805 ;; Extend to memory case when source register does 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     && dead_or_set_p (insn, operands[1])
3813     && !reg_mentioned_p (operands[1], operands[0]))"
3814   [(set (match_dup 3) (match_dup 1))
3815    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3816               (clobber (reg:CC FLAGS_REG))])
3817    (set (match_dup 4) (match_dup 1))]
3818   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3819
3820 ;; Extend to memory case when source register does not die.
3821 (define_split
3822   [(set (match_operand:DI 0 "memory_operand" "")
3823         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3824    (clobber (reg:CC FLAGS_REG))
3825    (clobber (match_operand:SI 2 "register_operand" ""))]
3826   "reload_completed"
3827   [(const_int 0)]
3828 {
3829   split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3830
3831   emit_move_insn (operands[3], operands[1]);
3832
3833   /* Generate a cltd if possible and doing so it profitable.  */
3834   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3835       && true_regnum (operands[1]) == AX_REG
3836       && true_regnum (operands[2]) == DX_REG)
3837     {
3838       emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3839     }
3840   else
3841     {
3842       emit_move_insn (operands[2], operands[1]);
3843       emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3844     }
3845   emit_move_insn (operands[4], operands[2]);
3846   DONE;
3847 })
3848
3849 ;; Extend to register case.  Optimize case where source and destination
3850 ;; registers match and cases where we can use cltd.
3851 (define_split
3852   [(set (match_operand:DI 0 "register_operand" "")
3853         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3854    (clobber (reg:CC FLAGS_REG))
3855    (clobber (match_scratch:SI 2 ""))]
3856   "reload_completed"
3857   [(const_int 0)]
3858 {
3859   split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3860
3861   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3862     emit_move_insn (operands[3], operands[1]);
3863
3864   /* Generate a cltd if possible and doing so it profitable.  */
3865   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3866       && true_regnum (operands[3]) == AX_REG
3867       && true_regnum (operands[4]) == DX_REG)
3868     {
3869       emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3870       DONE;
3871     }
3872
3873   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3874     emit_move_insn (operands[4], operands[1]);
3875
3876   emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3877   DONE;
3878 })
3879
3880 (define_insn "extend<mode>di2"
3881   [(set (match_operand:DI 0 "register_operand" "=r")
3882         (sign_extend:DI
3883          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3884   "TARGET_64BIT"
3885   "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3886   [(set_attr "type" "imovx")
3887    (set_attr "mode" "DI")])
3888
3889 (define_insn "extendhisi2"
3890   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3891         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3892   ""
3893 {
3894   switch (get_attr_prefix_0f (insn))
3895     {
3896     case 0:
3897       return "{cwtl|cwde}";
3898     default:
3899       return "movs{wl|x}\t{%1, %0|%0, %1}";
3900     }
3901 }
3902   [(set_attr "type" "imovx")
3903    (set_attr "mode" "SI")
3904    (set (attr "prefix_0f")
3905      ;; movsx is short decodable while cwtl is vector decoded.
3906      (if_then_else (and (eq_attr "cpu" "!k6")
3907                         (eq_attr "alternative" "0"))
3908         (const_string "0")
3909         (const_string "1")))
3910    (set (attr "modrm")
3911      (if_then_else (eq_attr "prefix_0f" "0")
3912         (const_string "0")
3913         (const_string "1")))])
3914
3915 (define_insn "*extendhisi2_zext"
3916   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3917         (zero_extend:DI
3918          (sign_extend:SI
3919           (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3920   "TARGET_64BIT"
3921 {
3922   switch (get_attr_prefix_0f (insn))
3923     {
3924     case 0:
3925       return "{cwtl|cwde}";
3926     default:
3927       return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3928     }
3929 }
3930   [(set_attr "type" "imovx")
3931    (set_attr "mode" "SI")
3932    (set (attr "prefix_0f")
3933      ;; movsx is short decodable while cwtl is vector decoded.
3934      (if_then_else (and (eq_attr "cpu" "!k6")
3935                         (eq_attr "alternative" "0"))
3936         (const_string "0")
3937         (const_string "1")))
3938    (set (attr "modrm")
3939      (if_then_else (eq_attr "prefix_0f" "0")
3940         (const_string "0")
3941         (const_string "1")))])
3942
3943 (define_insn "extendqisi2"
3944   [(set (match_operand:SI 0 "register_operand" "=r")
3945         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3946   ""
3947   "movs{bl|x}\t{%1, %0|%0, %1}"
3948    [(set_attr "type" "imovx")
3949     (set_attr "mode" "SI")])
3950
3951 (define_insn "*extendqisi2_zext"
3952   [(set (match_operand:DI 0 "register_operand" "=r")
3953         (zero_extend:DI
3954           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3955   "TARGET_64BIT"
3956   "movs{bl|x}\t{%1, %k0|%k0, %1}"
3957    [(set_attr "type" "imovx")
3958     (set_attr "mode" "SI")])
3959
3960 (define_insn "extendqihi2"
3961   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3962         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3963   ""
3964 {
3965   switch (get_attr_prefix_0f (insn))
3966     {
3967     case 0:
3968       return "{cbtw|cbw}";
3969     default:
3970       return "movs{bw|x}\t{%1, %0|%0, %1}";
3971     }
3972 }
3973   [(set_attr "type" "imovx")
3974    (set_attr "mode" "HI")
3975    (set (attr "prefix_0f")
3976      ;; movsx is short decodable while cwtl is vector decoded.
3977      (if_then_else (and (eq_attr "cpu" "!k6")
3978                         (eq_attr "alternative" "0"))
3979         (const_string "0")
3980         (const_string "1")))
3981    (set (attr "modrm")
3982      (if_then_else (eq_attr "prefix_0f" "0")
3983         (const_string "0")
3984         (const_string "1")))])
3985 \f
3986 ;; Conversions between float and double.
3987
3988 ;; These are all no-ops in the model used for the 80387.
3989 ;; So just emit moves.
3990
3991 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3992 (define_split
3993   [(set (match_operand:DF 0 "push_operand" "")
3994         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3995   "reload_completed"
3996   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3997    (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3998
3999 (define_split
4000   [(set (match_operand:XF 0 "push_operand" "")
4001         (float_extend:XF (match_operand:MODEF 1 "fp_register_operand" "")))]
4002   "reload_completed"
4003   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4004    (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4005   "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
4006
4007 (define_expand "extendsfdf2"
4008   [(set (match_operand:DF 0 "nonimmediate_operand" "")
4009         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
4010   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4011 {
4012   /* ??? Needed for compress_float_constant since all fp constants
4013      are LEGITIMATE_CONSTANT_P.  */
4014   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4015     {
4016       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4017           && standard_80387_constant_p (operands[1]) > 0)
4018         {
4019           operands[1] = simplify_const_unary_operation
4020             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4021           emit_move_insn_1 (operands[0], operands[1]);
4022           DONE;
4023         }
4024       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4025     }
4026 })
4027
4028 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4029    cvtss2sd:
4030       unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4031       cvtps2pd xmm2,xmm1
4032    We do the conversion post reload to avoid producing of 128bit spills
4033    that might lead to ICE on 32bit target.  The sequence unlikely combine
4034    anyway.  */
4035 (define_split
4036   [(set (match_operand:DF 0 "register_operand" "")
4037         (float_extend:DF
4038           (match_operand:SF 1 "nonimmediate_operand" "")))]
4039   "TARGET_USE_VECTOR_FP_CONVERTS
4040    && optimize_insn_for_speed_p ()
4041    && reload_completed && SSE_REG_P (operands[0])"
4042    [(set (match_dup 2)
4043          (float_extend:V2DF
4044            (vec_select:V2SF
4045              (match_dup 3)
4046              (parallel [(const_int 0) (const_int 1)]))))]
4047 {
4048   operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4049   operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4050   /* Use movss for loading from memory, unpcklps reg, reg for registers.
4051      Try to avoid move when unpacking can be done in source.  */
4052   if (REG_P (operands[1]))
4053     {
4054       /* If it is unsafe to overwrite upper half of source, we need
4055          to move to destination and unpack there.  */
4056       if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4057            || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4058           && true_regnum (operands[0]) != true_regnum (operands[1]))
4059         {
4060           rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4061           emit_move_insn (tmp, operands[1]);
4062         }
4063       else
4064         operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4065       emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4066                                              operands[3]));
4067     }
4068   else
4069     emit_insn (gen_vec_setv4sf_0 (operands[3],
4070                                   CONST0_RTX (V4SFmode), operands[1]));
4071 })
4072
4073 (define_insn "*extendsfdf2_mixed"
4074   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4075         (float_extend:DF
4076           (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4077   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4078 {
4079   switch (which_alternative)
4080     {
4081     case 0:
4082     case 1:
4083       return output_387_reg_move (insn, operands);
4084
4085     case 2:
4086       return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4087
4088     default:
4089       gcc_unreachable ();
4090     }
4091 }
4092   [(set_attr "type" "fmov,fmov,ssecvt")
4093    (set_attr "prefix" "orig,orig,maybe_vex")
4094    (set_attr "mode" "SF,XF,DF")])
4095
4096 (define_insn "*extendsfdf2_sse"
4097   [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4098         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4099   "TARGET_SSE2 && TARGET_SSE_MATH"
4100   "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4101   [(set_attr "type" "ssecvt")
4102    (set_attr "prefix" "maybe_vex")
4103    (set_attr "mode" "DF")])
4104
4105 (define_insn "*extendsfdf2_i387"
4106   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4107         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4108   "TARGET_80387"
4109   "* return output_387_reg_move (insn, operands);"
4110   [(set_attr "type" "fmov")
4111    (set_attr "mode" "SF,XF")])
4112
4113 (define_expand "extend<mode>xf2"
4114   [(set (match_operand:XF 0 "nonimmediate_operand" "")
4115         (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4116   "TARGET_80387"
4117 {
4118   /* ??? Needed for compress_float_constant since all fp constants
4119      are LEGITIMATE_CONSTANT_P.  */
4120   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4121     {
4122       if (standard_80387_constant_p (operands[1]) > 0)
4123         {
4124           operands[1] = simplify_const_unary_operation
4125             (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4126           emit_move_insn_1 (operands[0], operands[1]);
4127           DONE;
4128         }
4129       operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4130     }
4131 })
4132
4133 (define_insn "*extend<mode>xf2_i387"
4134   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4135         (float_extend:XF
4136           (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4137   "TARGET_80387"
4138   "* return output_387_reg_move (insn, operands);"
4139   [(set_attr "type" "fmov")
4140    (set_attr "mode" "<MODE>,XF")])
4141
4142 ;; %%% This seems bad bad news.
4143 ;; This cannot output into an f-reg because there is no way to be sure
4144 ;; of truncating in that case.  Otherwise this is just like a simple move
4145 ;; insn.  So we pretend we can output to a reg in order to get better
4146 ;; register preferencing, but we really use a stack slot.
4147
4148 ;; Conversion from DFmode to SFmode.
4149
4150 (define_expand "truncdfsf2"
4151   [(set (match_operand:SF 0 "nonimmediate_operand" "")
4152         (float_truncate:SF
4153           (match_operand:DF 1 "nonimmediate_operand" "")))]
4154   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4155 {
4156   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4157     ;
4158   else if (flag_unsafe_math_optimizations)
4159     ;
4160   else
4161     {
4162       enum ix86_stack_slot slot = (virtuals_instantiated
4163                                    ? SLOT_TEMP
4164                                    : SLOT_VIRTUAL);
4165       rtx temp = assign_386_stack_local (SFmode, slot);
4166       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4167       DONE;
4168     }
4169 })
4170
4171 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4172    cvtsd2ss:
4173       unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4174       cvtpd2ps xmm2,xmm1
4175    We do the conversion post reload to avoid producing of 128bit spills
4176    that might lead to ICE on 32bit target.  The sequence unlikely combine
4177    anyway.  */
4178 (define_split
4179   [(set (match_operand:SF 0 "register_operand" "")
4180         (float_truncate:SF
4181           (match_operand:DF 1 "nonimmediate_operand" "")))]
4182   "TARGET_USE_VECTOR_FP_CONVERTS
4183    && optimize_insn_for_speed_p ()
4184    && reload_completed && SSE_REG_P (operands[0])"
4185    [(set (match_dup 2)
4186          (vec_concat:V4SF
4187            (float_truncate:V2SF
4188              (match_dup 4))
4189            (match_dup 3)))]
4190 {
4191   operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4192   operands[3] = CONST0_RTX (V2SFmode);
4193   operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4194   /* Use movsd for loading from memory, unpcklpd for registers.
4195      Try to avoid move when unpacking can be done in source, or SSE3
4196      movddup is available.  */
4197   if (REG_P (operands[1]))
4198     {
4199       if (!TARGET_SSE3
4200           && true_regnum (operands[0]) != true_regnum (operands[1])
4201           && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4202               || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4203         {
4204           rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4205           emit_move_insn (tmp, operands[1]);
4206           operands[1] = tmp;
4207         }
4208       else if (!TARGET_SSE3)
4209         operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4210       emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4211     }
4212   else
4213     emit_insn (gen_sse2_loadlpd (operands[4],
4214                                  CONST0_RTX (V2DFmode), operands[1]));
4215 })
4216
4217 (define_expand "truncdfsf2_with_temp"
4218   [(parallel [(set (match_operand:SF 0 "" "")
4219                    (float_truncate:SF (match_operand:DF 1 "" "")))
4220               (clobber (match_operand:SF 2 "" ""))])])
4221
4222 (define_insn "*truncdfsf_fast_mixed"
4223   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm,x")
4224         (float_truncate:SF
4225           (match_operand:DF 1 "nonimmediate_operand" "f  ,xm")))]
4226   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4227 {
4228   switch (which_alternative)
4229     {
4230     case 0:
4231       return output_387_reg_move (insn, operands);
4232     case 1:
4233       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4234     default:
4235       gcc_unreachable ();
4236     }
4237 }
4238   [(set_attr "type" "fmov,ssecvt")
4239    (set_attr "prefix" "orig,maybe_vex")
4240    (set_attr "mode" "SF")])
4241
4242 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4243 ;; because nothing we do here is unsafe.
4244 (define_insn "*truncdfsf_fast_sse"
4245   [(set (match_operand:SF 0 "nonimmediate_operand"   "=x")
4246         (float_truncate:SF
4247           (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4248   "TARGET_SSE2 && TARGET_SSE_MATH"
4249   "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4250   [(set_attr "type" "ssecvt")
4251    (set_attr "prefix" "maybe_vex")
4252    (set_attr "mode" "SF")])
4253
4254 (define_insn "*truncdfsf_fast_i387"
4255   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
4256         (float_truncate:SF
4257           (match_operand:DF 1 "nonimmediate_operand" "f")))]
4258   "TARGET_80387 && flag_unsafe_math_optimizations"
4259   "* return output_387_reg_move (insn, operands);"
4260   [(set_attr "type" "fmov")
4261    (set_attr "mode" "SF")])
4262
4263 (define_insn "*truncdfsf_mixed"
4264   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,Y2 ,?f,?x,?*r")
4265         (float_truncate:SF
4266           (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4267    (clobber (match_operand:SF 2 "memory_operand"     "=X,X  ,m ,m ,m"))]
4268   "TARGET_MIX_SSE_I387"
4269 {
4270   switch (which_alternative)
4271     {
4272     case 0:
4273       return output_387_reg_move (insn, operands);
4274     case 1:
4275       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4276
4277     default:
4278       return "#";
4279     }
4280 }
4281   [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4282    (set_attr "unit" "*,*,i387,i387,i387")
4283    (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4284    (set_attr "mode" "SF")])
4285
4286 (define_insn "*truncdfsf_i387"
4287   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?f,?x,?*r")
4288         (float_truncate:SF
4289           (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4290    (clobber (match_operand:SF 2 "memory_operand"     "=X,m ,m ,m"))]
4291   "TARGET_80387"
4292 {
4293   switch (which_alternative)
4294     {
4295     case 0:
4296       return output_387_reg_move (insn, operands);
4297
4298     default:
4299       return "#";
4300     }
4301 }
4302   [(set_attr "type" "fmov,multi,multi,multi")
4303    (set_attr "unit" "*,i387,i387,i387")
4304    (set_attr "mode" "SF")])
4305
4306 (define_insn "*truncdfsf2_i387_1"
4307   [(set (match_operand:SF 0 "memory_operand" "=m")
4308         (float_truncate:SF
4309           (match_operand:DF 1 "register_operand" "f")))]
4310   "TARGET_80387
4311    && !(TARGET_SSE2 && TARGET_SSE_MATH)
4312    && !TARGET_MIX_SSE_I387"
4313   "* return output_387_reg_move (insn, operands);"
4314   [(set_attr "type" "fmov")
4315    (set_attr "mode" "SF")])
4316
4317 (define_split
4318   [(set (match_operand:SF 0 "register_operand" "")
4319         (float_truncate:SF
4320          (match_operand:DF 1 "fp_register_operand" "")))
4321    (clobber (match_operand 2 "" ""))]
4322   "reload_completed"
4323   [(set (match_dup 2) (match_dup 1))
4324    (set (match_dup 0) (match_dup 2))]
4325   "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4326
4327 ;; Conversion from XFmode to {SF,DF}mode
4328
4329 (define_expand "truncxf<mode>2"
4330   [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4331                    (float_truncate:MODEF
4332                      (match_operand:XF 1 "register_operand" "")))
4333               (clobber (match_dup 2))])]
4334   "TARGET_80387"
4335 {
4336   if (flag_unsafe_math_optimizations)
4337     {
4338       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4339       emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4340       if (reg != operands[0])
4341         emit_move_insn (operands[0], reg);
4342       DONE;
4343     }
4344   else
4345     {
4346       enum ix86_stack_slot slot = (virtuals_instantiated
4347                                    ? SLOT_TEMP
4348                                    : SLOT_VIRTUAL);
4349       operands[2] = assign_386_stack_local (<MODE>mode, slot);
4350     }
4351 })
4352
4353 (define_insn "*truncxfsf2_mixed"
4354   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4355         (float_truncate:SF
4356           (match_operand:XF 1 "register_operand"   "f ,f ,f ,f")))
4357    (clobber (match_operand:SF 2 "memory_operand"   "=X,m ,m ,m"))]
4358   "TARGET_80387"
4359 {
4360   gcc_assert (!which_alternative);
4361   return output_387_reg_move (insn, operands);
4362 }
4363   [(set_attr "type" "fmov,multi,multi,multi")
4364    (set_attr "unit" "*,i387,i387,i387")
4365    (set_attr "mode" "SF")])
4366
4367 (define_insn "*truncxfdf2_mixed"
4368   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4369         (float_truncate:DF
4370           (match_operand:XF 1 "register_operand"   "f ,f ,f  ,f")))
4371    (clobber (match_operand:DF 2 "memory_operand"   "=X,m ,m  ,m"))]
4372   "TARGET_80387"
4373 {
4374   gcc_assert (!which_alternative);
4375   return output_387_reg_move (insn, operands);
4376 }
4377   [(set_attr "type" "fmov,multi,multi,multi")
4378    (set_attr "unit" "*,i387,i387,i387")
4379    (set_attr "mode" "DF")])
4380
4381 (define_insn "truncxf<mode>2_i387_noop"
4382   [(set (match_operand:MODEF 0 "register_operand" "=f")
4383         (float_truncate:MODEF
4384           (match_operand:XF 1 "register_operand" "f")))]
4385   "TARGET_80387 && flag_unsafe_math_optimizations"
4386   "* return output_387_reg_move (insn, operands);"
4387   [(set_attr "type" "fmov")
4388    (set_attr "mode" "<MODE>")])
4389
4390 (define_insn "*truncxf<mode>2_i387"
4391   [(set (match_operand:MODEF 0 "memory_operand" "=m")
4392         (float_truncate:MODEF
4393           (match_operand:XF 1 "register_operand" "f")))]
4394   "TARGET_80387"
4395   "* return output_387_reg_move (insn, operands);"
4396   [(set_attr "type" "fmov")
4397    (set_attr "mode" "<MODE>")])
4398
4399 (define_split
4400   [(set (match_operand:MODEF 0 "register_operand" "")
4401         (float_truncate:MODEF
4402           (match_operand:XF 1 "register_operand" "")))
4403    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4404   "TARGET_80387 && reload_completed"
4405   [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4406    (set (match_dup 0) (match_dup 2))])
4407
4408 (define_split
4409   [(set (match_operand:MODEF 0 "memory_operand" "")
4410         (float_truncate:MODEF
4411           (match_operand:XF 1 "register_operand" "")))
4412    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4413   "TARGET_80387"
4414   [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4415 \f
4416 ;; Signed conversion to DImode.
4417
4418 (define_expand "fix_truncxfdi2"
4419   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4420                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4421               (clobber (reg:CC FLAGS_REG))])]
4422   "TARGET_80387"
4423 {
4424   if (TARGET_FISTTP)
4425    {
4426      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4427      DONE;
4428    }
4429 })
4430
4431 (define_expand "fix_trunc<mode>di2"
4432   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4433                    (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4434               (clobber (reg:CC FLAGS_REG))])]
4435   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4436 {
4437   if (TARGET_FISTTP
4438       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4439    {
4440      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4441      DONE;
4442    }
4443   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4444    {
4445      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4446      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4447      if (out != operands[0])
4448         emit_move_insn (operands[0], out);
4449      DONE;
4450    }
4451 })
4452
4453 ;; Signed conversion to SImode.
4454
4455 (define_expand "fix_truncxfsi2"
4456   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4457                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4458               (clobber (reg:CC FLAGS_REG))])]
4459   "TARGET_80387"
4460 {
4461   if (TARGET_FISTTP)
4462    {
4463      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4464      DONE;
4465    }
4466 })
4467
4468 (define_expand "fix_trunc<mode>si2"
4469   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4470                    (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4471               (clobber (reg:CC FLAGS_REG))])]
4472   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4473 {
4474   if (TARGET_FISTTP
4475       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4476    {
4477      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4478      DONE;
4479    }
4480   if (SSE_FLOAT_MODE_P (<MODE>mode))
4481    {
4482      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4483      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4484      if (out != operands[0])
4485         emit_move_insn (operands[0], out);
4486      DONE;
4487    }
4488 })
4489
4490 ;; Signed conversion to HImode.
4491
4492 (define_expand "fix_trunc<mode>hi2"
4493   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4494                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4495               (clobber (reg:CC FLAGS_REG))])]
4496   "TARGET_80387
4497    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4498 {
4499   if (TARGET_FISTTP)
4500    {
4501      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4502      DONE;
4503    }
4504 })
4505
4506 ;; Unsigned conversion to SImode.
4507
4508 (define_expand "fixuns_trunc<mode>si2"
4509   [(parallel
4510     [(set (match_operand:SI 0 "register_operand" "")
4511           (unsigned_fix:SI
4512             (match_operand:MODEF 1 "nonimmediate_operand" "")))
4513      (use (match_dup 2))
4514      (clobber (match_scratch:<ssevecmode> 3 ""))
4515      (clobber (match_scratch:<ssevecmode> 4 ""))])]
4516   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4517 {
4518   enum machine_mode mode = <MODE>mode;
4519   enum machine_mode vecmode = <ssevecmode>mode;
4520   REAL_VALUE_TYPE TWO31r;
4521   rtx two31;
4522
4523   if (optimize_insn_for_size_p ())
4524     FAIL;
4525
4526   real_ldexp (&TWO31r, &dconst1, 31);
4527   two31 = const_double_from_real_value (TWO31r, mode);
4528   two31 = ix86_build_const_vector (vecmode, true, two31);
4529   operands[2] = force_reg (vecmode, two31);
4530 })
4531
4532 (define_insn_and_split "*fixuns_trunc<mode>_1"
4533   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4534         (unsigned_fix:SI
4535           (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4536    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
4537    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4538    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4539   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4540    && optimize_function_for_speed_p (cfun)"
4541   "#"
4542   "&& reload_completed"
4543   [(const_int 0)]
4544 {
4545   ix86_split_convert_uns_si_sse (operands);
4546   DONE;
4547 })
4548
4549 ;; Unsigned conversion to HImode.
4550 ;; Without these patterns, we'll try the unsigned SI conversion which
4551 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4552
4553 (define_expand "fixuns_trunc<mode>hi2"
4554   [(set (match_dup 2)
4555         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4556    (set (match_operand:HI 0 "nonimmediate_operand" "")
4557         (subreg:HI (match_dup 2) 0))]
4558   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4559   "operands[2] = gen_reg_rtx (SImode);")
4560
4561 ;; When SSE is available, it is always faster to use it!
4562 (define_insn "fix_trunc<mode>di_sse"
4563   [(set (match_operand:DI 0 "register_operand" "=r,r")
4564         (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4565   "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4566    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4567   "%vcvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4568   [(set_attr "type" "sseicvt")
4569    (set_attr "prefix" "maybe_vex")
4570    (set_attr "prefix_rex" "1")
4571    (set_attr "mode" "<MODE>")
4572    (set_attr "athlon_decode" "double,vector")
4573    (set_attr "amdfam10_decode" "double,double")
4574    (set_attr "bdver1_decode" "double,double")])
4575
4576 (define_insn "fix_trunc<mode>si_sse"
4577   [(set (match_operand:SI 0 "register_operand" "=r,r")
4578         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4579   "SSE_FLOAT_MODE_P (<MODE>mode)
4580    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4581   "%vcvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4582   [(set_attr "type" "sseicvt")
4583    (set_attr "prefix" "maybe_vex")
4584    (set_attr "mode" "<MODE>")
4585    (set_attr "athlon_decode" "double,vector")
4586    (set_attr "amdfam10_decode" "double,double")
4587    (set_attr "bdver1_decode" "double,double")])
4588
4589 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4590 (define_peephole2
4591   [(set (match_operand:MODEF 0 "register_operand" "")
4592         (match_operand:MODEF 1 "memory_operand" ""))
4593    (set (match_operand:SSEMODEI24 2 "register_operand" "")
4594         (fix:SSEMODEI24 (match_dup 0)))]
4595   "TARGET_SHORTEN_X87_SSE
4596    && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4597    && peep2_reg_dead_p (2, operands[0])"
4598   [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))])
4599
4600 ;; Avoid vector decoded forms of the instruction.
4601 (define_peephole2
4602   [(match_scratch:DF 2 "Y2")
4603    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4604         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4605   "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4606   [(set (match_dup 2) (match_dup 1))
4607    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))])
4608
4609 (define_peephole2
4610   [(match_scratch:SF 2 "x")
4611    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4612         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4613   "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4614   [(set (match_dup 2) (match_dup 1))
4615    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))])
4616
4617 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4618   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4619         (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4620   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4621    && TARGET_FISTTP
4622    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4623          && (TARGET_64BIT || <MODE>mode != DImode))
4624         && TARGET_SSE_MATH)
4625    && can_create_pseudo_p ()"
4626   "#"
4627   "&& 1"
4628   [(const_int 0)]
4629 {
4630   if (memory_operand (operands[0], VOIDmode))
4631     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4632   else
4633     {
4634       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4635       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4636                                                             operands[1],
4637                                                             operands[2]));
4638     }
4639   DONE;
4640 }
4641   [(set_attr "type" "fisttp")
4642    (set_attr "mode" "<MODE>")])
4643
4644 (define_insn "fix_trunc<mode>_i387_fisttp"
4645   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4646         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4647    (clobber (match_scratch:XF 2 "=&1f"))]
4648   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4649    && TARGET_FISTTP
4650    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4651          && (TARGET_64BIT || <MODE>mode != DImode))
4652         && TARGET_SSE_MATH)"
4653   "* return output_fix_trunc (insn, operands, 1);"
4654   [(set_attr "type" "fisttp")
4655    (set_attr "mode" "<MODE>")])
4656
4657 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4658   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4659         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4660    (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
4661    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4662   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4663    && TARGET_FISTTP
4664    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4665         && (TARGET_64BIT || <MODE>mode != DImode))
4666         && TARGET_SSE_MATH)"
4667   "#"
4668   [(set_attr "type" "fisttp")
4669    (set_attr "mode" "<MODE>")])
4670
4671 (define_split
4672   [(set (match_operand:X87MODEI 0 "register_operand" "")
4673         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4674    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4675    (clobber (match_scratch 3 ""))]
4676   "reload_completed"
4677   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4678               (clobber (match_dup 3))])
4679    (set (match_dup 0) (match_dup 2))])
4680
4681 (define_split
4682   [(set (match_operand:X87MODEI 0 "memory_operand" "")
4683         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4684    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4685    (clobber (match_scratch 3 ""))]
4686   "reload_completed"
4687   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4688               (clobber (match_dup 3))])])
4689
4690 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4691 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4692 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4693 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4694 ;; function in i386.c.
4695 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4696   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4697         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4698    (clobber (reg:CC FLAGS_REG))]
4699   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4700    && !TARGET_FISTTP
4701    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4702          && (TARGET_64BIT || <MODE>mode != DImode))
4703    && can_create_pseudo_p ()"
4704   "#"
4705   "&& 1"
4706   [(const_int 0)]
4707 {
4708   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4709
4710   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4711   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4712   if (memory_operand (operands[0], VOIDmode))
4713     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4714                                          operands[2], operands[3]));
4715   else
4716     {
4717       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4718       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4719                                                      operands[2], operands[3],
4720                                                      operands[4]));
4721     }
4722   DONE;
4723 }
4724   [(set_attr "type" "fistp")
4725    (set_attr "i387_cw" "trunc")
4726    (set_attr "mode" "<MODE>")])
4727
4728 (define_insn "fix_truncdi_i387"
4729   [(set (match_operand:DI 0 "memory_operand" "=m")
4730         (fix:DI (match_operand 1 "register_operand" "f")))
4731    (use (match_operand:HI 2 "memory_operand" "m"))
4732    (use (match_operand:HI 3 "memory_operand" "m"))
4733    (clobber (match_scratch:XF 4 "=&1f"))]
4734   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4735    && !TARGET_FISTTP
4736    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4737   "* return output_fix_trunc (insn, operands, 0);"
4738   [(set_attr "type" "fistp")
4739    (set_attr "i387_cw" "trunc")
4740    (set_attr "mode" "DI")])
4741
4742 (define_insn "fix_truncdi_i387_with_temp"
4743   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4744         (fix:DI (match_operand 1 "register_operand" "f,f")))
4745    (use (match_operand:HI 2 "memory_operand" "m,m"))
4746    (use (match_operand:HI 3 "memory_operand" "m,m"))
4747    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4748    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4749   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4750    && !TARGET_FISTTP
4751    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4752   "#"
4753   [(set_attr "type" "fistp")
4754    (set_attr "i387_cw" "trunc")
4755    (set_attr "mode" "DI")])
4756
4757 (define_split
4758   [(set (match_operand:DI 0 "register_operand" "")
4759         (fix:DI (match_operand 1 "register_operand" "")))
4760    (use (match_operand:HI 2 "memory_operand" ""))
4761    (use (match_operand:HI 3 "memory_operand" ""))
4762    (clobber (match_operand:DI 4 "memory_operand" ""))
4763    (clobber (match_scratch 5 ""))]
4764   "reload_completed"
4765   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4766               (use (match_dup 2))
4767               (use (match_dup 3))
4768               (clobber (match_dup 5))])
4769    (set (match_dup 0) (match_dup 4))])
4770
4771 (define_split
4772   [(set (match_operand:DI 0 "memory_operand" "")
4773         (fix:DI (match_operand 1 "register_operand" "")))
4774    (use (match_operand:HI 2 "memory_operand" ""))
4775    (use (match_operand:HI 3 "memory_operand" ""))
4776    (clobber (match_operand:DI 4 "memory_operand" ""))
4777    (clobber (match_scratch 5 ""))]
4778   "reload_completed"
4779   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4780               (use (match_dup 2))
4781               (use (match_dup 3))
4782               (clobber (match_dup 5))])])
4783
4784 (define_insn "fix_trunc<mode>_i387"
4785   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4786         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4787    (use (match_operand:HI 2 "memory_operand" "m"))
4788    (use (match_operand:HI 3 "memory_operand" "m"))]
4789   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4790    && !TARGET_FISTTP
4791    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4792   "* return output_fix_trunc (insn, operands, 0);"
4793   [(set_attr "type" "fistp")
4794    (set_attr "i387_cw" "trunc")
4795    (set_attr "mode" "<MODE>")])
4796
4797 (define_insn "fix_trunc<mode>_i387_with_temp"
4798   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4799         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4800    (use (match_operand:HI 2 "memory_operand" "m,m"))
4801    (use (match_operand:HI 3 "memory_operand" "m,m"))
4802    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
4803   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4804    && !TARGET_FISTTP
4805    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4806   "#"
4807   [(set_attr "type" "fistp")
4808    (set_attr "i387_cw" "trunc")
4809    (set_attr "mode" "<MODE>")])
4810
4811 (define_split
4812   [(set (match_operand:X87MODEI12 0 "register_operand" "")
4813         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4814    (use (match_operand:HI 2 "memory_operand" ""))
4815    (use (match_operand:HI 3 "memory_operand" ""))
4816    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4817   "reload_completed"
4818   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4819               (use (match_dup 2))
4820               (use (match_dup 3))])
4821    (set (match_dup 0) (match_dup 4))])
4822
4823 (define_split
4824   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4825         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4826    (use (match_operand:HI 2 "memory_operand" ""))
4827    (use (match_operand:HI 3 "memory_operand" ""))
4828    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4829   "reload_completed"
4830   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4831               (use (match_dup 2))
4832               (use (match_dup 3))])])
4833
4834 (define_insn "x86_fnstcw_1"
4835   [(set (match_operand:HI 0 "memory_operand" "=m")
4836         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4837   "TARGET_80387"
4838   "fnstcw\t%0"
4839   [(set (attr "length")
4840         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4841    (set_attr "mode" "HI")
4842    (set_attr "unit" "i387")
4843    (set_attr "bdver1_decode" "vector")])
4844
4845 (define_insn "x86_fldcw_1"
4846   [(set (reg:HI FPCR_REG)
4847         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4848   "TARGET_80387"
4849   "fldcw\t%0"
4850   [(set (attr "length")
4851         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4852    (set_attr "mode" "HI")
4853    (set_attr "unit" "i387")
4854    (set_attr "athlon_decode" "vector")
4855    (set_attr "amdfam10_decode" "vector")
4856    (set_attr "bdver1_decode" "vector")])
4857 \f
4858 ;; Conversion between fixed point and floating point.
4859
4860 ;; Even though we only accept memory inputs, the backend _really_
4861 ;; wants to be able to do this between registers.
4862
4863 (define_expand "floathi<mode>2"
4864   [(set (match_operand:X87MODEF 0 "register_operand" "")
4865         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4866   "TARGET_80387
4867    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4868        || TARGET_MIX_SSE_I387)")
4869
4870 ;; Pre-reload splitter to add memory clobber to the pattern.
4871 (define_insn_and_split "*floathi<mode>2_1"
4872   [(set (match_operand:X87MODEF 0 "register_operand" "")
4873         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4874   "TARGET_80387
4875    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4876        || TARGET_MIX_SSE_I387)
4877    && can_create_pseudo_p ()"
4878   "#"
4879   "&& 1"
4880   [(parallel [(set (match_dup 0)
4881               (float:X87MODEF (match_dup 1)))
4882    (clobber (match_dup 2))])]
4883   "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4884
4885 (define_insn "*floathi<mode>2_i387_with_temp"
4886   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4887         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4888   (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
4889   "TARGET_80387
4890    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4891        || TARGET_MIX_SSE_I387)"
4892   "#"
4893   [(set_attr "type" "fmov,multi")
4894    (set_attr "mode" "<MODE>")
4895    (set_attr "unit" "*,i387")
4896    (set_attr "fp_int_src" "true")])
4897
4898 (define_insn "*floathi<mode>2_i387"
4899   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4900         (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4901   "TARGET_80387
4902    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4903        || TARGET_MIX_SSE_I387)"
4904   "fild%Z1\t%1"
4905   [(set_attr "type" "fmov")
4906    (set_attr "mode" "<MODE>")
4907    (set_attr "fp_int_src" "true")])
4908
4909 (define_split
4910   [(set (match_operand:X87MODEF 0 "register_operand" "")
4911         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4912    (clobber (match_operand:HI 2 "memory_operand" ""))]
4913   "TARGET_80387
4914    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4915        || TARGET_MIX_SSE_I387)
4916    && reload_completed"
4917   [(set (match_dup 2) (match_dup 1))
4918    (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4919
4920 (define_split
4921   [(set (match_operand:X87MODEF 0 "register_operand" "")
4922         (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
4923    (clobber (match_operand:HI 2 "memory_operand" ""))]
4924    "TARGET_80387
4925     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4926         || TARGET_MIX_SSE_I387)
4927     && reload_completed"
4928   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4929
4930 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
4931   [(set (match_operand:X87MODEF 0 "register_operand" "")
4932         (float:X87MODEF
4933           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
4934   "TARGET_80387
4935    || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4936        && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4937 {
4938   if (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4939         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4940       && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode))
4941     {
4942       rtx reg = gen_reg_rtx (XFmode);
4943       rtx insn;
4944
4945       emit_insn (gen_float<SSEMODEI24:mode>xf2 (reg, operands[1]));
4946
4947       if (<X87MODEF:MODE>mode == SFmode)
4948         insn = gen_truncxfsf2 (operands[0], reg);
4949       else if (<X87MODEF:MODE>mode == DFmode)
4950         insn = gen_truncxfdf2 (operands[0], reg);
4951       else
4952         gcc_unreachable ();
4953
4954       emit_insn (insn);
4955       DONE;
4956     }
4957 })
4958
4959 ;; Pre-reload splitter to add memory clobber to the pattern.
4960 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
4961   [(set (match_operand:X87MODEF 0 "register_operand" "")
4962         (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
4963   "((TARGET_80387
4964      && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
4965      && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4966            && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4967          || TARGET_MIX_SSE_I387))
4968     || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4969         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4970         && ((<SSEMODEI24:MODE>mode == SImode
4971              && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4972              && optimize_function_for_speed_p (cfun)
4973              && flag_trapping_math)
4974             || !(TARGET_INTER_UNIT_CONVERSIONS
4975                  || optimize_function_for_size_p (cfun)))))
4976    && can_create_pseudo_p ()"
4977   "#"
4978   "&& 1"
4979   [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4980               (clobber (match_dup 2))])]
4981 {
4982   operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
4983
4984   /* Avoid store forwarding (partial memory) stall penalty
4985      by passing DImode value through XMM registers.  */
4986   if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
4987       && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4988       && optimize_function_for_speed_p (cfun))
4989     {
4990       emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4991                                                             operands[1],
4992                                                             operands[2]));
4993       DONE;
4994     }
4995 })
4996
4997 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4998   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4999         (float:MODEF
5000           (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
5001    (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
5002   "TARGET_SSE2 && TARGET_MIX_SSE_I387
5003    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5004   "#"
5005   [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
5006    (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
5007    (set_attr "unit" "*,i387,*,*,*")
5008    (set_attr "athlon_decode" "*,*,double,direct,double")
5009    (set_attr "amdfam10_decode" "*,*,vector,double,double")
5010    (set_attr "bdver1_decode" "*,*,double,direct,double")
5011    (set_attr "fp_int_src" "true")])
5012
5013 (define_insn "*floatsi<mode>2_vector_mixed"
5014   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5015         (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
5016   "TARGET_SSE2 && TARGET_MIX_SSE_I387
5017    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5018   "@
5019    fild%Z1\t%1
5020    #"
5021   [(set_attr "type" "fmov,sseicvt")
5022    (set_attr "mode" "<MODE>,<ssevecmode>")
5023    (set_attr "unit" "i387,*")
5024    (set_attr "athlon_decode" "*,direct")
5025    (set_attr "amdfam10_decode" "*,double")
5026    (set_attr "bdver1_decode" "*,direct")
5027    (set_attr "fp_int_src" "true")])
5028
5029 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
5030   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
5031         (float:MODEF
5032           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
5033   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
5034   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5035    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
5036   "#"
5037   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5038    (set_attr "mode" "<MODEF:MODE>")
5039    (set_attr "unit" "*,i387,*,*")
5040    (set_attr "athlon_decode" "*,*,double,direct")
5041    (set_attr "amdfam10_decode" "*,*,vector,double")
5042    (set_attr "bdver1_decode" "*,*,double,direct")
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 "bdver1_decode" "*,double,direct")
5096    (set_attr "fp_int_src" "true")])
5097
5098 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5099   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5100         (float:MODEF
5101           (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5102   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5103    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5104    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5105   "@
5106    fild%Z1\t%1
5107    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5108   [(set_attr "type" "fmov,sseicvt")
5109    (set_attr "prefix" "orig,maybe_vex")
5110    (set_attr "mode" "<MODEF:MODE>")
5111    (set (attr "prefix_rex")
5112      (if_then_else
5113        (and (eq_attr "prefix" "maybe_vex")
5114             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5115        (const_string "1")
5116        (const_string "*")))
5117    (set_attr "athlon_decode" "*,direct")
5118    (set_attr "amdfam10_decode" "*,double")
5119    (set_attr "bdver1_decode" "*,direct")
5120    (set_attr "fp_int_src" "true")])
5121
5122 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5123   [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5124         (float:MODEF
5125           (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5126    (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5127   "TARGET_SSE2 && TARGET_SSE_MATH
5128    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5129   "#"
5130   [(set_attr "type" "sseicvt")
5131    (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5132    (set_attr "athlon_decode" "double,direct,double")
5133    (set_attr "amdfam10_decode" "vector,double,double")
5134    (set_attr "bdver1_decode" "double,direct,double")
5135    (set_attr "fp_int_src" "true")])
5136
5137 (define_insn "*floatsi<mode>2_vector_sse"
5138   [(set (match_operand:MODEF 0 "register_operand" "=x")
5139         (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5140   "TARGET_SSE2 && TARGET_SSE_MATH
5141    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5142   "#"
5143   [(set_attr "type" "sseicvt")
5144    (set_attr "mode" "<MODE>")
5145    (set_attr "athlon_decode" "direct")
5146    (set_attr "amdfam10_decode" "double")
5147    (set_attr "bdver1_decode" "direct")
5148    (set_attr "fp_int_src" "true")])
5149
5150 (define_split
5151   [(set (match_operand:MODEF 0 "register_operand" "")
5152         (float:MODEF (match_operand:SI 1 "register_operand" "")))
5153    (clobber (match_operand:SI 2 "memory_operand" ""))]
5154   "TARGET_SSE2 && TARGET_SSE_MATH
5155    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5156    && reload_completed
5157    && (SSE_REG_P (operands[0])
5158        || (GET_CODE (operands[0]) == SUBREG
5159            && SSE_REG_P (operands[0])))"
5160   [(const_int 0)]
5161 {
5162   rtx op1 = operands[1];
5163
5164   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5165                                      <MODE>mode, 0);
5166   if (GET_CODE (op1) == SUBREG)
5167     op1 = SUBREG_REG (op1);
5168
5169   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5170     {
5171       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5172       emit_insn (gen_sse2_loadld (operands[4],
5173                                   CONST0_RTX (V4SImode), operands[1]));
5174     }
5175   /* We can ignore possible trapping value in the
5176      high part of SSE register for non-trapping math. */
5177   else if (SSE_REG_P (op1) && !flag_trapping_math)
5178     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5179   else
5180     {
5181       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5182       emit_move_insn (operands[2], operands[1]);
5183       emit_insn (gen_sse2_loadld (operands[4],
5184                                   CONST0_RTX (V4SImode), operands[2]));
5185     }
5186   emit_insn
5187     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5188   DONE;
5189 })
5190
5191 (define_split
5192   [(set (match_operand:MODEF 0 "register_operand" "")
5193         (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5194    (clobber (match_operand:SI 2 "memory_operand" ""))]
5195   "TARGET_SSE2 && TARGET_SSE_MATH
5196    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5197    && reload_completed
5198    && (SSE_REG_P (operands[0])
5199        || (GET_CODE (operands[0]) == SUBREG
5200            && SSE_REG_P (operands[0])))"
5201   [(const_int 0)]
5202 {
5203   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5204                                      <MODE>mode, 0);
5205   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5206
5207   emit_insn (gen_sse2_loadld (operands[4],
5208                               CONST0_RTX (V4SImode), operands[1]));
5209   emit_insn
5210     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5211   DONE;
5212 })
5213
5214 (define_split
5215   [(set (match_operand:MODEF 0 "register_operand" "")
5216         (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5217   "TARGET_SSE2 && TARGET_SSE_MATH
5218    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5219    && reload_completed
5220    && (SSE_REG_P (operands[0])
5221        || (GET_CODE (operands[0]) == SUBREG
5222            && SSE_REG_P (operands[0])))"
5223   [(const_int 0)]
5224 {
5225   rtx op1 = operands[1];
5226
5227   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5228                                      <MODE>mode, 0);
5229   if (GET_CODE (op1) == SUBREG)
5230     op1 = SUBREG_REG (op1);
5231
5232   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5233     {
5234       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5235       emit_insn (gen_sse2_loadld (operands[4],
5236                                   CONST0_RTX (V4SImode), operands[1]));
5237     }
5238   /* We can ignore possible trapping value in the
5239      high part of SSE register for non-trapping math. */
5240   else if (SSE_REG_P (op1) && !flag_trapping_math)
5241     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5242   else
5243     gcc_unreachable ();
5244   emit_insn
5245     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5246   DONE;
5247 })
5248
5249 (define_split
5250   [(set (match_operand:MODEF 0 "register_operand" "")
5251         (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5252   "TARGET_SSE2 && TARGET_SSE_MATH
5253    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5254    && reload_completed
5255    && (SSE_REG_P (operands[0])
5256        || (GET_CODE (operands[0]) == SUBREG
5257            && SSE_REG_P (operands[0])))"
5258   [(const_int 0)]
5259 {
5260   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5261                                      <MODE>mode, 0);
5262   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5263
5264   emit_insn (gen_sse2_loadld (operands[4],
5265                               CONST0_RTX (V4SImode), operands[1]));
5266   emit_insn
5267     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5268   DONE;
5269 })
5270
5271 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5272   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5273         (float:MODEF
5274           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5275   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5276   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5277    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5278   "#"
5279   [(set_attr "type" "sseicvt")
5280    (set_attr "mode" "<MODEF:MODE>")
5281    (set_attr "athlon_decode" "double,direct")
5282    (set_attr "amdfam10_decode" "vector,double")
5283    (set_attr "bdver1_decode" "double,direct")
5284    (set_attr "fp_int_src" "true")])
5285
5286 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5287   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5288         (float:MODEF
5289           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5290   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5291    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5292    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5293   "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5294   [(set_attr "type" "sseicvt")
5295    (set_attr "prefix" "maybe_vex")
5296    (set_attr "mode" "<MODEF:MODE>")
5297    (set (attr "prefix_rex")
5298      (if_then_else
5299        (and (eq_attr "prefix" "maybe_vex")
5300             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5301        (const_string "1")
5302        (const_string "*")))
5303    (set_attr "athlon_decode" "double,direct")
5304    (set_attr "amdfam10_decode" "vector,double")
5305    (set_attr "bdver1_decode" "double,direct")
5306    (set_attr "fp_int_src" "true")])
5307
5308 (define_split
5309   [(set (match_operand:MODEF 0 "register_operand" "")
5310         (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5311    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5312   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5313    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5314    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5315    && reload_completed
5316    && (SSE_REG_P (operands[0])
5317        || (GET_CODE (operands[0]) == SUBREG
5318            && SSE_REG_P (operands[0])))"
5319   [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5320
5321 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5322   [(set (match_operand:MODEF 0 "register_operand" "=x")
5323         (float:MODEF
5324           (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5325   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5326    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5327    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5328   "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5329   [(set_attr "type" "sseicvt")
5330    (set_attr "prefix" "maybe_vex")
5331    (set_attr "mode" "<MODEF:MODE>")
5332    (set (attr "prefix_rex")
5333      (if_then_else
5334        (and (eq_attr "prefix" "maybe_vex")
5335             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5336        (const_string "1")
5337        (const_string "*")))
5338    (set_attr "athlon_decode" "direct")
5339    (set_attr "amdfam10_decode" "double")
5340    (set_attr "bdver1_decode" "direct")
5341    (set_attr "fp_int_src" "true")])
5342
5343 (define_split
5344   [(set (match_operand:MODEF 0 "register_operand" "")
5345         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5346    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5347   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5348    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5349    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5350    && reload_completed
5351    && (SSE_REG_P (operands[0])
5352        || (GET_CODE (operands[0]) == SUBREG
5353            && SSE_REG_P (operands[0])))"
5354   [(set (match_dup 2) (match_dup 1))
5355    (set (match_dup 0) (float:MODEF (match_dup 2)))])
5356
5357 (define_split
5358   [(set (match_operand:MODEF 0 "register_operand" "")
5359         (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5360    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5361   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5362    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5363    && reload_completed
5364    && (SSE_REG_P (operands[0])
5365        || (GET_CODE (operands[0]) == SUBREG
5366            && SSE_REG_P (operands[0])))"
5367   [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5368
5369 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5370   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5371         (float:X87MODEF
5372           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5373   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5374   "TARGET_80387
5375    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5376   "@
5377    fild%Z1\t%1
5378    #"
5379   [(set_attr "type" "fmov,multi")
5380    (set_attr "mode" "<X87MODEF:MODE>")
5381    (set_attr "unit" "*,i387")
5382    (set_attr "fp_int_src" "true")])
5383
5384 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5385   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5386         (float:X87MODEF
5387           (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5388   "TARGET_80387
5389    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5390   "fild%Z1\t%1"
5391   [(set_attr "type" "fmov")
5392    (set_attr "mode" "<X87MODEF:MODE>")
5393    (set_attr "fp_int_src" "true")])
5394
5395 (define_split
5396   [(set (match_operand:X87MODEF 0 "register_operand" "")
5397         (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5398    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5399   "TARGET_80387
5400    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5401    && reload_completed
5402    && FP_REG_P (operands[0])"
5403   [(set (match_dup 2) (match_dup 1))
5404    (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5405
5406 (define_split
5407   [(set (match_operand:X87MODEF 0 "register_operand" "")
5408         (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5409    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5410   "TARGET_80387
5411    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5412    && reload_completed
5413    && FP_REG_P (operands[0])"
5414   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5415
5416 ;; Avoid store forwarding (partial memory) stall penalty
5417 ;; by passing DImode value through XMM registers.  */
5418
5419 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5420   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5421         (float:X87MODEF
5422           (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5423    (clobber (match_scratch:V4SI 3 "=X,x"))
5424    (clobber (match_scratch:V4SI 4 "=X,x"))
5425    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5426   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5427    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5428    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5429   "#"
5430   [(set_attr "type" "multi")
5431    (set_attr "mode" "<X87MODEF:MODE>")
5432    (set_attr "unit" "i387")
5433    (set_attr "fp_int_src" "true")])
5434
5435 (define_split
5436   [(set (match_operand:X87MODEF 0 "register_operand" "")
5437         (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5438    (clobber (match_scratch:V4SI 3 ""))
5439    (clobber (match_scratch:V4SI 4 ""))
5440    (clobber (match_operand:DI 2 "memory_operand" ""))]
5441   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5442    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5443    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5444    && reload_completed
5445    && FP_REG_P (operands[0])"
5446   [(set (match_dup 2) (match_dup 3))
5447    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5448 {
5449   /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5450      Assemble the 64-bit DImode value in an xmm register.  */
5451   emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5452                               gen_rtx_SUBREG (SImode, operands[1], 0)));
5453   emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5454                               gen_rtx_SUBREG (SImode, operands[1], 4)));
5455   emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5456                                          operands[4]));
5457
5458   operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5459 })
5460
5461 (define_split
5462   [(set (match_operand:X87MODEF 0 "register_operand" "")
5463         (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5464    (clobber (match_scratch:V4SI 3 ""))
5465    (clobber (match_scratch:V4SI 4 ""))
5466    (clobber (match_operand:DI 2 "memory_operand" ""))]
5467   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5468    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5469    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5470    && reload_completed
5471    && FP_REG_P (operands[0])"
5472   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5473
5474 ;; Avoid store forwarding (partial memory) stall penalty by extending
5475 ;; SImode value to DImode through XMM register instead of pushing two
5476 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5477 ;; targets benefit from this optimization. Also note that fild
5478 ;; loads from memory only.
5479
5480 (define_insn "*floatunssi<mode>2_1"
5481   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5482         (unsigned_float:X87MODEF
5483           (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5484    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5485    (clobber (match_scratch:SI 3 "=X,x"))]
5486   "!TARGET_64BIT
5487    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5488    && TARGET_SSE"
5489   "#"
5490   [(set_attr "type" "multi")
5491    (set_attr "mode" "<MODE>")])
5492
5493 (define_split
5494   [(set (match_operand:X87MODEF 0 "register_operand" "")
5495         (unsigned_float:X87MODEF
5496           (match_operand:SI 1 "register_operand" "")))
5497    (clobber (match_operand:DI 2 "memory_operand" ""))
5498    (clobber (match_scratch:SI 3 ""))]
5499   "!TARGET_64BIT
5500    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5501    && TARGET_SSE
5502    && reload_completed"
5503   [(set (match_dup 2) (match_dup 1))
5504    (set (match_dup 0)
5505         (float:X87MODEF (match_dup 2)))]
5506   "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5507
5508 (define_split
5509   [(set (match_operand:X87MODEF 0 "register_operand" "")
5510         (unsigned_float:X87MODEF
5511           (match_operand:SI 1 "memory_operand" "")))
5512    (clobber (match_operand:DI 2 "memory_operand" ""))
5513    (clobber (match_scratch:SI 3 ""))]
5514   "!TARGET_64BIT
5515    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5516    && TARGET_SSE
5517    && reload_completed"
5518   [(set (match_dup 2) (match_dup 3))
5519    (set (match_dup 0)
5520         (float:X87MODEF (match_dup 2)))]
5521 {
5522   emit_move_insn (operands[3], operands[1]);
5523   operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5524 })
5525
5526 (define_expand "floatunssi<mode>2"
5527   [(parallel
5528      [(set (match_operand:X87MODEF 0 "register_operand" "")
5529            (unsigned_float:X87MODEF
5530              (match_operand:SI 1 "nonimmediate_operand" "")))
5531       (clobber (match_dup 2))
5532       (clobber (match_scratch:SI 3 ""))])]
5533   "!TARGET_64BIT
5534    && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5535         && TARGET_SSE)
5536        || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5537 {
5538   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5539     {
5540       ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5541       DONE;
5542     }
5543   else
5544     {
5545       enum ix86_stack_slot slot = (virtuals_instantiated
5546                                    ? SLOT_TEMP
5547                                    : SLOT_VIRTUAL);
5548       operands[2] = assign_386_stack_local (DImode, slot);
5549     }
5550 })
5551
5552 (define_expand "floatunsdisf2"
5553   [(use (match_operand:SF 0 "register_operand" ""))
5554    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5555   "TARGET_64BIT && TARGET_SSE_MATH"
5556   "x86_emit_floatuns (operands); DONE;")
5557
5558 (define_expand "floatunsdidf2"
5559   [(use (match_operand:DF 0 "register_operand" ""))
5560    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5561   "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5562    && TARGET_SSE2 && TARGET_SSE_MATH"
5563 {
5564   if (TARGET_64BIT)
5565     x86_emit_floatuns (operands);
5566   else
5567     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5568   DONE;
5569 })
5570 \f
5571 ;; Add instructions
5572
5573 (define_expand "add<mode>3"
5574   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5575         (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5576                     (match_operand:SDWIM 2 "<general_operand>" "")))]
5577   ""
5578   "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5579
5580 (define_insn_and_split "*add<dwi>3_doubleword"
5581   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5582         (plus:<DWI>
5583           (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5584           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5585    (clobber (reg:CC FLAGS_REG))]
5586   "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5587   "#"
5588   "reload_completed"
5589   [(parallel [(set (reg:CC FLAGS_REG)
5590                    (unspec:CC [(match_dup 1) (match_dup 2)]
5591                               UNSPEC_ADD_CARRY))
5592               (set (match_dup 0)
5593                    (plus:DWIH (match_dup 1) (match_dup 2)))])
5594    (parallel [(set (match_dup 3)
5595                    (plus:DWIH
5596                      (match_dup 4)
5597                      (plus:DWIH
5598                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5599                        (match_dup 5))))
5600               (clobber (reg:CC FLAGS_REG))])]
5601   "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5602
5603 (define_insn "*add<mode>3_cc"
5604   [(set (reg:CC FLAGS_REG)
5605         (unspec:CC
5606           [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5607            (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5608           UNSPEC_ADD_CARRY))
5609    (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5610         (plus:SWI48 (match_dup 1) (match_dup 2)))]
5611   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5612   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5613   [(set_attr "type" "alu")
5614    (set_attr "mode" "<MODE>")])
5615
5616 (define_insn "addqi3_cc"
5617   [(set (reg:CC FLAGS_REG)
5618         (unspec:CC
5619           [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5620            (match_operand:QI 2 "general_operand" "qn,qm")]
5621           UNSPEC_ADD_CARRY))
5622    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5623         (plus:QI (match_dup 1) (match_dup 2)))]
5624   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5625   "add{b}\t{%2, %0|%0, %2}"
5626   [(set_attr "type" "alu")
5627    (set_attr "mode" "QI")])
5628
5629 (define_insn "*lea_1"
5630   [(set (match_operand:P 0 "register_operand" "=r")
5631         (match_operand:P 1 "no_seg_address_operand" "p"))]
5632   ""
5633   "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
5634   [(set_attr "type" "lea")
5635    (set_attr "mode" "<MODE>")])
5636
5637 (define_insn "*lea_2"
5638   [(set (match_operand:SI 0 "register_operand" "=r")
5639         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5640   "TARGET_64BIT"
5641   "lea{l}\t{%a1, %0|%0, %a1}"
5642   [(set_attr "type" "lea")
5643    (set_attr "mode" "SI")])
5644
5645 (define_insn "*lea_2_zext"
5646   [(set (match_operand:DI 0 "register_operand" "=r")
5647         (zero_extend:DI
5648           (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5649   "TARGET_64BIT"
5650   "lea{l}\t{%a1, %k0|%k0, %a1}"
5651   [(set_attr "type" "lea")
5652    (set_attr "mode" "SI")])
5653
5654 (define_insn "*add<mode>_1"
5655   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5656         (plus:SWI48
5657           (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5658           (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,0,l<i>")))
5659    (clobber (reg:CC FLAGS_REG))]
5660   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5661 {
5662   switch (get_attr_type (insn))
5663     {
5664     case TYPE_LEA:
5665       return "#";
5666
5667     case TYPE_INCDEC:
5668       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5669       if (operands[2] == const1_rtx)
5670         return "inc{<imodesuffix>}\t%0";
5671       else
5672         {
5673           gcc_assert (operands[2] == constm1_rtx);
5674           return "dec{<imodesuffix>}\t%0";
5675         }
5676
5677     default:
5678       /* For most processors, ADD is faster than LEA.  This alternative
5679          was added to use ADD as much as possible.  */
5680       if (which_alternative == 2)
5681         {
5682           rtx tmp;
5683           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5684         }
5685         
5686       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5687       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5688         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5689
5690       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5691     }
5692 }
5693   [(set (attr "type")
5694      (cond [(eq_attr "alternative" "3")
5695               (const_string "lea")
5696             (match_operand:SWI48 2 "incdec_operand" "")
5697               (const_string "incdec")
5698            ]
5699            (const_string "alu")))
5700    (set (attr "length_immediate")
5701       (if_then_else
5702         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5703         (const_string "1")
5704         (const_string "*")))
5705    (set_attr "mode" "<MODE>")])
5706
5707 ;; It may seem that nonimmediate operand is proper one for operand 1.
5708 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5709 ;; we take care in ix86_binary_operator_ok to not allow two memory
5710 ;; operands so proper swapping will be done in reload.  This allow
5711 ;; patterns constructed from addsi_1 to match.
5712
5713 (define_insn "*addsi_1_zext"
5714   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5715         (zero_extend:DI
5716           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5717                    (match_operand:SI 2 "general_operand" "g,0,li"))))
5718    (clobber (reg:CC FLAGS_REG))]
5719   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5720 {
5721   switch (get_attr_type (insn))
5722     {
5723     case TYPE_LEA:
5724       return "#";
5725
5726     case TYPE_INCDEC:
5727       if (operands[2] == const1_rtx)
5728         return "inc{l}\t%k0";
5729       else
5730         {
5731           gcc_assert (operands[2] == constm1_rtx);
5732           return "dec{l}\t%k0";
5733         }
5734
5735     default:
5736       /* For most processors, ADD is faster than LEA.  This alternative
5737          was added to use ADD as much as possible.  */
5738       if (which_alternative == 1)
5739         {
5740           rtx tmp;
5741           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5742         }
5743
5744       if (x86_maybe_negate_const_int (&operands[2], SImode))
5745         return "sub{l}\t{%2, %k0|%k0, %2}";
5746
5747       return "add{l}\t{%2, %k0|%k0, %2}";
5748     }
5749 }
5750   [(set (attr "type")
5751      (cond [(eq_attr "alternative" "2")
5752               (const_string "lea")
5753             (match_operand:SI 2 "incdec_operand" "")
5754               (const_string "incdec")
5755            ]
5756            (const_string "alu")))
5757    (set (attr "length_immediate")
5758       (if_then_else
5759         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5760         (const_string "1")
5761         (const_string "*")))
5762    (set_attr "mode" "SI")])
5763
5764 (define_insn "*addhi_1"
5765   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5766         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5767                  (match_operand:HI 2 "general_operand" "rn,rm")))
5768    (clobber (reg:CC FLAGS_REG))]
5769   "TARGET_PARTIAL_REG_STALL
5770    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5771 {
5772   switch (get_attr_type (insn))
5773     {
5774     case TYPE_INCDEC:
5775       if (operands[2] == const1_rtx)
5776         return "inc{w}\t%0";
5777       else
5778         {
5779           gcc_assert (operands[2] == constm1_rtx);
5780           return "dec{w}\t%0";
5781         }
5782
5783     default:
5784       if (x86_maybe_negate_const_int (&operands[2], HImode))
5785         return "sub{w}\t{%2, %0|%0, %2}";
5786
5787       return "add{w}\t{%2, %0|%0, %2}";
5788     }
5789 }
5790   [(set (attr "type")
5791      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5792         (const_string "incdec")
5793         (const_string "alu")))
5794    (set (attr "length_immediate")
5795       (if_then_else
5796         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5797         (const_string "1")
5798         (const_string "*")))
5799    (set_attr "mode" "HI")])
5800
5801 (define_insn "*addhi_1_lea"
5802   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm,r,r")
5803         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,r")
5804                  (match_operand:HI 2 "general_operand" "rmn,rn,0,ln")))
5805    (clobber (reg:CC FLAGS_REG))]
5806   "!TARGET_PARTIAL_REG_STALL
5807    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5808 {
5809   switch (get_attr_type (insn))
5810     {
5811     case TYPE_LEA:
5812       return "#";
5813
5814     case TYPE_INCDEC:
5815       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5816       if (operands[2] == const1_rtx)
5817         return "inc{w}\t%0";
5818       else
5819         {
5820           gcc_assert (operands[2] == constm1_rtx);
5821           return "dec{w}\t%0";
5822         }
5823
5824     default:
5825       /* For most processors, ADD is faster than LEA.  This alternative
5826          was added to use ADD as much as possible.  */
5827       if (which_alternative == 2)
5828         {
5829           rtx tmp;
5830           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5831         }
5832
5833       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5834       if (x86_maybe_negate_const_int (&operands[2], HImode))
5835         return "sub{w}\t{%2, %0|%0, %2}";
5836
5837       return "add{w}\t{%2, %0|%0, %2}";
5838     }
5839 }
5840   [(set (attr "type")
5841      (cond [(eq_attr "alternative" "3")
5842               (const_string "lea")
5843             (match_operand:HI 2 "incdec_operand" "")
5844               (const_string "incdec")
5845            ]
5846            (const_string "alu")))
5847    (set (attr "length_immediate")
5848       (if_then_else
5849         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5850         (const_string "1")
5851         (const_string "*")))
5852    (set_attr "mode" "HI,HI,HI,SI")])
5853
5854 ;; %%% Potential partial reg stall on alternative 2.  What to do?
5855 (define_insn "*addqi_1"
5856   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
5857         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
5858                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
5859    (clobber (reg:CC FLAGS_REG))]
5860   "TARGET_PARTIAL_REG_STALL
5861    && ix86_binary_operator_ok (PLUS, QImode, operands)"
5862 {
5863   int widen = (which_alternative == 2);
5864   switch (get_attr_type (insn))
5865     {
5866     case TYPE_INCDEC:
5867       if (operands[2] == const1_rtx)
5868         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5869       else
5870         {
5871           gcc_assert (operands[2] == constm1_rtx);
5872           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5873         }
5874
5875     default:
5876       if (x86_maybe_negate_const_int (&operands[2], QImode))
5877         {
5878           if (widen)
5879             return "sub{l}\t{%2, %k0|%k0, %2}";
5880           else
5881             return "sub{b}\t{%2, %0|%0, %2}";
5882         }
5883       if (widen)
5884         return "add{l}\t{%k2, %k0|%k0, %k2}";
5885       else
5886         return "add{b}\t{%2, %0|%0, %2}";
5887     }
5888 }
5889   [(set (attr "type")
5890      (if_then_else (match_operand:QI 2 "incdec_operand" "")
5891         (const_string "incdec")
5892         (const_string "alu")))
5893    (set (attr "length_immediate")
5894       (if_then_else
5895         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5896         (const_string "1")
5897         (const_string "*")))
5898    (set_attr "mode" "QI,QI,SI")])
5899
5900 ;; %%% Potential partial reg stall on alternatives 3 and 4.  What to do?
5901 (define_insn "*addqi_1_lea"
5902   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,q,r,r,r")
5903         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,r")
5904                  (match_operand:QI 2 "general_operand" "qmn,qn,0,rn,0,ln")))
5905    (clobber (reg:CC FLAGS_REG))]
5906   "!TARGET_PARTIAL_REG_STALL
5907    && ix86_binary_operator_ok (PLUS, QImode, operands)"
5908 {
5909   int widen = (which_alternative == 3 || which_alternative == 4);
5910
5911   switch (get_attr_type (insn))
5912     {
5913     case TYPE_LEA:
5914       return "#";
5915
5916     case TYPE_INCDEC:
5917       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5918       if (operands[2] == const1_rtx)
5919         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5920       else
5921         {
5922           gcc_assert (operands[2] == constm1_rtx);
5923           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5924         }
5925
5926     default:
5927       /* For most processors, ADD is faster than LEA.  These alternatives
5928          were added to use ADD as much as possible.  */
5929       if (which_alternative == 2 || which_alternative == 4)
5930         {
5931           rtx tmp;
5932           tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5933         }
5934
5935       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5936       if (x86_maybe_negate_const_int (&operands[2], QImode))
5937         {
5938           if (widen)
5939             return "sub{l}\t{%2, %k0|%k0, %2}";
5940           else
5941             return "sub{b}\t{%2, %0|%0, %2}";
5942         }
5943       if (widen)
5944         return "add{l}\t{%k2, %k0|%k0, %k2}";
5945       else
5946         return "add{b}\t{%2, %0|%0, %2}";
5947     }
5948 }
5949   [(set (attr "type")
5950      (cond [(eq_attr "alternative" "5")
5951               (const_string "lea")
5952             (match_operand:QI 2 "incdec_operand" "")
5953               (const_string "incdec")
5954            ]
5955            (const_string "alu")))
5956    (set (attr "length_immediate")
5957       (if_then_else
5958         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5959         (const_string "1")
5960         (const_string "*")))
5961    (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5962
5963 (define_insn "*addqi_1_slp"
5964   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5965         (plus:QI (match_dup 0)
5966                  (match_operand:QI 1 "general_operand" "qn,qnm")))
5967    (clobber (reg:CC FLAGS_REG))]
5968   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5969    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5970 {
5971   switch (get_attr_type (insn))
5972     {
5973     case TYPE_INCDEC:
5974       if (operands[1] == const1_rtx)
5975         return "inc{b}\t%0";
5976       else
5977         {
5978           gcc_assert (operands[1] == constm1_rtx);
5979           return "dec{b}\t%0";
5980         }
5981
5982     default:
5983       if (x86_maybe_negate_const_int (&operands[1], QImode))
5984         return "sub{b}\t{%1, %0|%0, %1}";
5985
5986       return "add{b}\t{%1, %0|%0, %1}";
5987     }
5988 }
5989   [(set (attr "type")
5990      (if_then_else (match_operand:QI 1 "incdec_operand" "")
5991         (const_string "incdec")
5992         (const_string "alu1")))
5993    (set (attr "memory")
5994      (if_then_else (match_operand 1 "memory_operand" "")
5995         (const_string "load")
5996         (const_string "none")))
5997    (set_attr "mode" "QI")])
5998
5999 ;; Convert lea to the lea pattern to avoid flags dependency.
6000 (define_split
6001   [(set (match_operand 0 "register_operand" "")
6002         (plus (match_operand 1 "register_operand" "")
6003               (match_operand 2 "nonmemory_operand" "")))
6004    (clobber (reg:CC FLAGS_REG))]
6005   "reload_completed && ix86_lea_for_add_ok (insn, operands)" 
6006   [(const_int 0)]
6007 {
6008   rtx pat;
6009   enum machine_mode mode = GET_MODE (operands[0]);
6010
6011   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
6012      may confuse gen_lowpart.  */
6013   if (mode != Pmode)
6014     {
6015       operands[1] = gen_lowpart (Pmode, operands[1]);
6016       operands[2] = gen_lowpart (Pmode, operands[2]);
6017     }
6018
6019   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
6020
6021   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6022     operands[0] = gen_lowpart (SImode, operands[0]);
6023
6024   if (TARGET_64BIT && mode != Pmode)
6025     pat = gen_rtx_SUBREG (SImode, pat, 0);
6026
6027   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6028   DONE;
6029 })
6030
6031 ;; Convert lea to the lea pattern to avoid flags dependency.
6032 ;; ??? This pattern handles immediate operands that do not satisfy immediate
6033 ;; operand predicate (LEGITIMATE_CONSTANT_P) in the previous pattern.
6034 (define_split
6035   [(set (match_operand:DI 0 "register_operand" "")
6036         (plus:DI (match_operand:DI 1 "register_operand" "")
6037                  (match_operand:DI 2 "x86_64_immediate_operand" "")))
6038    (clobber (reg:CC FLAGS_REG))]
6039   "TARGET_64BIT && reload_completed 
6040    && true_regnum (operands[0]) != true_regnum (operands[1])"
6041   [(set (match_dup 0)
6042         (plus:DI (match_dup 1) (match_dup 2)))])
6043
6044 ;; Convert lea to the lea pattern to avoid flags dependency.
6045 (define_split
6046   [(set (match_operand:DI 0 "register_operand" "")
6047         (zero_extend:DI
6048           (plus:SI (match_operand:SI 1 "register_operand" "")
6049                    (match_operand:SI 2 "nonmemory_operand" ""))))
6050    (clobber (reg:CC FLAGS_REG))]
6051   "TARGET_64BIT && reload_completed
6052    && ix86_lea_for_add_ok (insn, operands)"
6053   [(set (match_dup 0)
6054         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
6055 {
6056   operands[1] = gen_lowpart (DImode, operands[1]);
6057   operands[2] = gen_lowpart (DImode, operands[2]);
6058 })
6059
6060 (define_insn "*add<mode>_2"
6061   [(set (reg FLAGS_REG)
6062         (compare
6063           (plus:SWI
6064             (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6065             (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
6066           (const_int 0)))
6067    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
6068         (plus:SWI (match_dup 1) (match_dup 2)))]
6069   "ix86_match_ccmode (insn, CCGOCmode)
6070    && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6071 {
6072   switch (get_attr_type (insn))
6073     {
6074     case TYPE_INCDEC:
6075       if (operands[2] == const1_rtx)
6076         return "inc{<imodesuffix>}\t%0";
6077       else
6078         {
6079           gcc_assert (operands[2] == constm1_rtx);
6080           return "dec{<imodesuffix>}\t%0";
6081         }
6082
6083     default:
6084       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6085         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6086
6087       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6088     }
6089 }
6090   [(set (attr "type")
6091      (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6092         (const_string "incdec")
6093         (const_string "alu")))
6094    (set (attr "length_immediate")
6095       (if_then_else
6096         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6097         (const_string "1")
6098         (const_string "*")))
6099    (set_attr "mode" "<MODE>")])
6100
6101 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6102 (define_insn "*addsi_2_zext"
6103   [(set (reg FLAGS_REG)
6104         (compare
6105           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6106                    (match_operand:SI 2 "general_operand" "g"))
6107           (const_int 0)))
6108    (set (match_operand:DI 0 "register_operand" "=r")
6109         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6110   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6111    && ix86_binary_operator_ok (PLUS, SImode, operands)"
6112 {
6113   switch (get_attr_type (insn))
6114     {
6115     case TYPE_INCDEC:
6116       if (operands[2] == const1_rtx)
6117         return "inc{l}\t%k0";
6118       else
6119         {
6120           gcc_assert (operands[2] == constm1_rtx);
6121           return "dec{l}\t%k0";
6122         }
6123
6124     default:
6125       if (x86_maybe_negate_const_int (&operands[2], SImode))
6126         return "sub{l}\t{%2, %k0|%k0, %2}";
6127
6128       return "add{l}\t{%2, %k0|%k0, %2}";
6129     }
6130 }
6131   [(set (attr "type")
6132      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6133         (const_string "incdec")
6134         (const_string "alu")))
6135    (set (attr "length_immediate")
6136       (if_then_else
6137         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6138         (const_string "1")
6139         (const_string "*")))
6140    (set_attr "mode" "SI")])
6141
6142 (define_insn "*add<mode>_3"
6143   [(set (reg FLAGS_REG)
6144         (compare
6145           (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>"))
6146           (match_operand:SWI 1 "nonimmediate_operand" "%0")))
6147    (clobber (match_scratch:SWI 0 "=<r>"))]
6148   "ix86_match_ccmode (insn, CCZmode)
6149    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6150 {
6151   switch (get_attr_type (insn))
6152     {
6153     case TYPE_INCDEC:
6154       if (operands[2] == const1_rtx)
6155         return "inc{<imodesuffix>}\t%0";
6156       else
6157         {
6158           gcc_assert (operands[2] == constm1_rtx);
6159           return "dec{<imodesuffix>}\t%0";
6160         }
6161
6162     default:
6163       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6164         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6165
6166       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6167     }
6168 }
6169   [(set (attr "type")
6170      (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6171         (const_string "incdec")
6172         (const_string "alu")))
6173    (set (attr "length_immediate")
6174       (if_then_else
6175         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6176         (const_string "1")
6177         (const_string "*")))
6178    (set_attr "mode" "<MODE>")])
6179
6180 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6181 (define_insn "*addsi_3_zext"
6182   [(set (reg FLAGS_REG)
6183         (compare
6184           (neg:SI (match_operand:SI 2 "general_operand" "g"))
6185           (match_operand:SI 1 "nonimmediate_operand" "%0")))
6186    (set (match_operand:DI 0 "register_operand" "=r")
6187         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6188   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6189    && ix86_binary_operator_ok (PLUS, SImode, operands)"
6190 {
6191   switch (get_attr_type (insn))
6192     {
6193     case TYPE_INCDEC:
6194       if (operands[2] == const1_rtx)
6195         return "inc{l}\t%k0";
6196       else
6197         {
6198           gcc_assert (operands[2] == constm1_rtx);
6199           return "dec{l}\t%k0";
6200         }
6201
6202     default:
6203       if (x86_maybe_negate_const_int (&operands[2], SImode))
6204         return "sub{l}\t{%2, %k0|%k0, %2}";
6205
6206       return "add{l}\t{%2, %k0|%k0, %2}";
6207     }
6208 }
6209   [(set (attr "type")
6210      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6211         (const_string "incdec")
6212         (const_string "alu")))
6213    (set (attr "length_immediate")
6214       (if_then_else
6215         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6216         (const_string "1")
6217         (const_string "*")))
6218    (set_attr "mode" "SI")])
6219
6220 ; For comparisons against 1, -1 and 128, we may generate better code
6221 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6222 ; is matched then.  We can't accept general immediate, because for
6223 ; case of overflows,  the result is messed up.
6224 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6225 ; only for comparisons not depending on it.
6226
6227 (define_insn "*adddi_4"
6228   [(set (reg FLAGS_REG)
6229         (compare
6230           (match_operand:DI 1 "nonimmediate_operand" "0")
6231           (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6232    (clobber (match_scratch:DI 0 "=rm"))]
6233   "TARGET_64BIT
6234    && ix86_match_ccmode (insn, CCGCmode)"
6235 {
6236   switch (get_attr_type (insn))
6237     {
6238     case TYPE_INCDEC:
6239       if (operands[2] == constm1_rtx)
6240         return "inc{q}\t%0";
6241       else
6242         {
6243           gcc_assert (operands[2] == const1_rtx);
6244           return "dec{q}\t%0";
6245         }
6246
6247     default:
6248       if (x86_maybe_negate_const_int (&operands[2], DImode))
6249         return "add{q}\t{%2, %0|%0, %2}";
6250
6251       return "sub{q}\t{%2, %0|%0, %2}";
6252     }
6253 }
6254   [(set (attr "type")
6255      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6256         (const_string "incdec")
6257         (const_string "alu")))
6258    (set (attr "length_immediate")
6259       (if_then_else
6260         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6261         (const_string "1")
6262         (const_string "*")))
6263    (set_attr "mode" "DI")])
6264
6265 ; For comparisons against 1, -1 and 128, we may generate better code
6266 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6267 ; is matched then.  We can't accept general immediate, because for
6268 ; case of overflows,  the result is messed up.
6269 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6270 ; only for comparisons not depending on it.
6271
6272 (define_insn "*add<mode>_4"
6273   [(set (reg FLAGS_REG)
6274         (compare
6275           (match_operand:SWI124 1 "nonimmediate_operand" "0")
6276           (match_operand:SWI124 2 "const_int_operand" "n")))
6277    (clobber (match_scratch:SWI124 0 "=<r>m"))]
6278   "ix86_match_ccmode (insn, CCGCmode)"
6279 {
6280   switch (get_attr_type (insn))
6281     {
6282     case TYPE_INCDEC:
6283       if (operands[2] == constm1_rtx)
6284         return "inc{<imodesuffix>}\t%0";
6285       else
6286         {
6287           gcc_assert (operands[2] == const1_rtx);
6288           return "dec{<imodesuffix>}\t%0";
6289         }
6290
6291     default:
6292       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6293         return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6294
6295       return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6296     }
6297 }
6298   [(set (attr "type")
6299      (if_then_else (match_operand:<MODE> 2 "incdec_operand" "")
6300         (const_string "incdec")
6301         (const_string "alu")))
6302    (set (attr "length_immediate")
6303       (if_then_else
6304         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6305         (const_string "1")
6306         (const_string "*")))
6307    (set_attr "mode" "<MODE>")])
6308
6309 (define_insn "*add<mode>_5"
6310   [(set (reg FLAGS_REG)
6311         (compare
6312           (plus:SWI
6313             (match_operand:SWI 1 "nonimmediate_operand" "%0")
6314             (match_operand:SWI 2 "<general_operand>" "<g>"))
6315           (const_int 0)))
6316    (clobber (match_scratch:SWI 0 "=<r>"))]
6317   "ix86_match_ccmode (insn, CCGOCmode)
6318    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6319 {
6320   switch (get_attr_type (insn))
6321     {
6322     case TYPE_INCDEC:
6323       if (operands[2] == const1_rtx)
6324         return "inc{<imodesuffix>}\t%0";
6325       else
6326         {
6327           gcc_assert (operands[2] == constm1_rtx);
6328           return "dec{<imodesuffix>}\t%0";
6329         }
6330
6331     default:
6332       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6333         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6334
6335       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6336     }
6337 }
6338   [(set (attr "type")
6339      (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6340         (const_string "incdec")
6341         (const_string "alu")))
6342    (set (attr "length_immediate")
6343       (if_then_else
6344         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6345         (const_string "1")
6346         (const_string "*")))
6347    (set_attr "mode" "<MODE>")])
6348
6349 (define_insn "*addqi_ext_1_rex64"
6350   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6351                          (const_int 8)
6352                          (const_int 8))
6353         (plus:SI
6354           (zero_extract:SI
6355             (match_operand 1 "ext_register_operand" "0")
6356             (const_int 8)
6357             (const_int 8))
6358           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6359    (clobber (reg:CC FLAGS_REG))]
6360   "TARGET_64BIT"
6361 {
6362   switch (get_attr_type (insn))
6363     {
6364     case TYPE_INCDEC:
6365       if (operands[2] == const1_rtx)
6366         return "inc{b}\t%h0";
6367       else
6368         {
6369           gcc_assert (operands[2] == constm1_rtx);
6370           return "dec{b}\t%h0";
6371         }
6372
6373     default:
6374       return "add{b}\t{%2, %h0|%h0, %2}";
6375     }
6376 }
6377   [(set (attr "type")
6378      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6379         (const_string "incdec")
6380         (const_string "alu")))
6381    (set_attr "modrm" "1")
6382    (set_attr "mode" "QI")])
6383
6384 (define_insn "addqi_ext_1"
6385   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6386                          (const_int 8)
6387                          (const_int 8))
6388         (plus:SI
6389           (zero_extract:SI
6390             (match_operand 1 "ext_register_operand" "0")
6391             (const_int 8)
6392             (const_int 8))
6393           (match_operand:QI 2 "general_operand" "Qmn")))
6394    (clobber (reg:CC FLAGS_REG))]
6395   "!TARGET_64BIT"
6396 {
6397   switch (get_attr_type (insn))
6398     {
6399     case TYPE_INCDEC:
6400       if (operands[2] == const1_rtx)
6401         return "inc{b}\t%h0";
6402       else
6403         {
6404           gcc_assert (operands[2] == constm1_rtx);
6405           return "dec{b}\t%h0";
6406         }
6407
6408     default:
6409       return "add{b}\t{%2, %h0|%h0, %2}";
6410     }
6411 }
6412   [(set (attr "type")
6413      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6414         (const_string "incdec")
6415         (const_string "alu")))
6416    (set_attr "modrm" "1")
6417    (set_attr "mode" "QI")])
6418
6419 (define_insn "*addqi_ext_2"
6420   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6421                          (const_int 8)
6422                          (const_int 8))
6423         (plus:SI
6424           (zero_extract:SI
6425             (match_operand 1 "ext_register_operand" "%0")
6426             (const_int 8)
6427             (const_int 8))
6428           (zero_extract:SI
6429             (match_operand 2 "ext_register_operand" "Q")
6430             (const_int 8)
6431             (const_int 8))))
6432    (clobber (reg:CC FLAGS_REG))]
6433   ""
6434   "add{b}\t{%h2, %h0|%h0, %h2}"
6435   [(set_attr "type" "alu")
6436    (set_attr "mode" "QI")])
6437
6438 ;; The lea patterns for non-Pmodes needs to be matched by
6439 ;; several insns converted to real lea by splitters.
6440
6441 (define_insn_and_split "*lea_general_1"
6442   [(set (match_operand 0 "register_operand" "=r")
6443         (plus (plus (match_operand 1 "index_register_operand" "l")
6444                     (match_operand 2 "register_operand" "r"))
6445               (match_operand 3 "immediate_operand" "i")))]
6446   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6447     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6448    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6449    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6450    && GET_MODE (operands[0]) == GET_MODE (operands[2])
6451    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6452        || GET_MODE (operands[3]) == VOIDmode)"
6453   "#"
6454   "&& reload_completed"
6455   [(const_int 0)]
6456 {
6457   rtx pat;
6458   operands[0] = gen_lowpart (SImode, operands[0]);
6459   operands[1] = gen_lowpart (Pmode, operands[1]);
6460   operands[2] = gen_lowpart (Pmode, operands[2]);
6461   operands[3] = gen_lowpart (Pmode, operands[3]);
6462   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
6463                       operands[3]);
6464   if (Pmode != SImode)
6465     pat = gen_rtx_SUBREG (SImode, pat, 0);
6466   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6467   DONE;
6468 }
6469   [(set_attr "type" "lea")
6470    (set_attr "mode" "SI")])
6471
6472 (define_insn_and_split "*lea_general_1_zext"
6473   [(set (match_operand:DI 0 "register_operand" "=r")
6474         (zero_extend:DI
6475           (plus:SI (plus:SI
6476                      (match_operand:SI 1 "index_register_operand" "l")
6477                      (match_operand:SI 2 "register_operand" "r"))
6478                    (match_operand:SI 3 "immediate_operand" "i"))))]
6479   "TARGET_64BIT"
6480   "#"
6481   "&& reload_completed"
6482   [(set (match_dup 0)
6483         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
6484                                                      (match_dup 2))
6485                                             (match_dup 3)) 0)))]
6486 {
6487   operands[1] = gen_lowpart (Pmode, operands[1]);
6488   operands[2] = gen_lowpart (Pmode, operands[2]);
6489   operands[3] = gen_lowpart (Pmode, operands[3]);
6490 }
6491   [(set_attr "type" "lea")
6492    (set_attr "mode" "SI")])
6493
6494 (define_insn_and_split "*lea_general_2"
6495   [(set (match_operand 0 "register_operand" "=r")
6496         (plus (mult (match_operand 1 "index_register_operand" "l")
6497                     (match_operand 2 "const248_operand" "i"))
6498               (match_operand 3 "nonmemory_operand" "ri")))]
6499   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6500     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6501    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6502    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6503    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6504        || GET_MODE (operands[3]) == VOIDmode)"
6505   "#"
6506   "&& reload_completed"
6507   [(const_int 0)]
6508 {
6509   rtx pat;
6510   operands[0] = gen_lowpart (SImode, operands[0]);
6511   operands[1] = gen_lowpart (Pmode, operands[1]);
6512   operands[3] = gen_lowpart (Pmode, operands[3]);
6513   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
6514                       operands[3]);
6515   if (Pmode != SImode)
6516     pat = gen_rtx_SUBREG (SImode, pat, 0);
6517   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6518   DONE;
6519 }
6520   [(set_attr "type" "lea")
6521    (set_attr "mode" "SI")])
6522
6523 (define_insn_and_split "*lea_general_2_zext"
6524   [(set (match_operand:DI 0 "register_operand" "=r")
6525         (zero_extend:DI
6526           (plus:SI (mult:SI
6527                      (match_operand:SI 1 "index_register_operand" "l")
6528                      (match_operand:SI 2 "const248_operand" "n"))
6529                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
6530   "TARGET_64BIT"
6531   "#"
6532   "&& reload_completed"
6533   [(set (match_dup 0)
6534         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
6535                                                      (match_dup 2))
6536                                             (match_dup 3)) 0)))]
6537 {
6538   operands[1] = gen_lowpart (Pmode, operands[1]);
6539   operands[3] = gen_lowpart (Pmode, operands[3]);
6540 }
6541   [(set_attr "type" "lea")
6542    (set_attr "mode" "SI")])
6543
6544 (define_insn_and_split "*lea_general_3"
6545   [(set (match_operand 0 "register_operand" "=r")
6546         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6547                           (match_operand 2 "const248_operand" "i"))
6548                     (match_operand 3 "register_operand" "r"))
6549               (match_operand 4 "immediate_operand" "i")))]
6550   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6551     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6552    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6553    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6554    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6555   "#"
6556   "&& reload_completed"
6557   [(const_int 0)]
6558 {
6559   rtx pat;
6560   operands[0] = gen_lowpart (SImode, operands[0]);
6561   operands[1] = gen_lowpart (Pmode, operands[1]);
6562   operands[3] = gen_lowpart (Pmode, operands[3]);
6563   operands[4] = gen_lowpart (Pmode, operands[4]);
6564   pat = gen_rtx_PLUS (Pmode,
6565                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
6566                                                          operands[2]),
6567                                     operands[3]),
6568                       operands[4]);
6569   if (Pmode != SImode)
6570     pat = gen_rtx_SUBREG (SImode, pat, 0);
6571   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6572   DONE;
6573 }
6574   [(set_attr "type" "lea")
6575    (set_attr "mode" "SI")])
6576
6577 (define_insn_and_split "*lea_general_3_zext"
6578   [(set (match_operand:DI 0 "register_operand" "=r")
6579         (zero_extend:DI
6580           (plus:SI (plus:SI
6581                      (mult:SI
6582                        (match_operand:SI 1 "index_register_operand" "l")
6583                        (match_operand:SI 2 "const248_operand" "n"))
6584                      (match_operand:SI 3 "register_operand" "r"))
6585                    (match_operand:SI 4 "immediate_operand" "i"))))]
6586   "TARGET_64BIT"
6587   "#"
6588   "&& reload_completed"
6589   [(set (match_dup 0)
6590         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
6591                                                               (match_dup 2))
6592                                                      (match_dup 3))
6593                                             (match_dup 4)) 0)))]
6594 {
6595   operands[1] = gen_lowpart (Pmode, operands[1]);
6596   operands[3] = gen_lowpart (Pmode, operands[3]);
6597   operands[4] = gen_lowpart (Pmode, operands[4]);
6598 }
6599   [(set_attr "type" "lea")
6600    (set_attr "mode" "SI")])
6601 \f
6602 ;; Subtract instructions
6603
6604 (define_expand "sub<mode>3"
6605   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
6606         (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6607                      (match_operand:SDWIM 2 "<general_operand>" "")))]
6608   ""
6609   "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6610
6611 (define_insn_and_split "*sub<dwi>3_doubleword"
6612   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6613         (minus:<DWI>
6614           (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6615           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6616    (clobber (reg:CC FLAGS_REG))]
6617   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6618   "#"
6619   "reload_completed"
6620   [(parallel [(set (reg:CC FLAGS_REG)
6621                    (compare:CC (match_dup 1) (match_dup 2)))
6622               (set (match_dup 0)
6623                    (minus:DWIH (match_dup 1) (match_dup 2)))])
6624    (parallel [(set (match_dup 3)
6625                    (minus:DWIH
6626                      (match_dup 4)
6627                      (plus:DWIH
6628                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6629                        (match_dup 5))))
6630               (clobber (reg:CC FLAGS_REG))])]
6631   "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6632
6633 (define_insn "*sub<mode>_1"
6634   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6635         (minus:SWI
6636           (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6637           (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6638    (clobber (reg:CC FLAGS_REG))]
6639   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6640   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6641   [(set_attr "type" "alu")
6642    (set_attr "mode" "<MODE>")])
6643
6644 (define_insn "*subsi_1_zext"
6645   [(set (match_operand:DI 0 "register_operand" "=r")
6646         (zero_extend:DI
6647           (minus:SI (match_operand:SI 1 "register_operand" "0")
6648                     (match_operand:SI 2 "general_operand" "g"))))
6649    (clobber (reg:CC FLAGS_REG))]
6650   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6651   "sub{l}\t{%2, %k0|%k0, %2}"
6652   [(set_attr "type" "alu")
6653    (set_attr "mode" "SI")])
6654
6655 (define_insn "*subqi_1_slp"
6656   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6657         (minus:QI (match_dup 0)
6658                   (match_operand:QI 1 "general_operand" "qn,qm")))
6659    (clobber (reg:CC FLAGS_REG))]
6660   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6661    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6662   "sub{b}\t{%1, %0|%0, %1}"
6663   [(set_attr "type" "alu1")
6664    (set_attr "mode" "QI")])
6665
6666 (define_insn "*sub<mode>_2"
6667   [(set (reg FLAGS_REG)
6668         (compare
6669           (minus:SWI
6670             (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6671             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6672           (const_int 0)))
6673    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6674         (minus:SWI (match_dup 1) (match_dup 2)))]
6675   "ix86_match_ccmode (insn, CCGOCmode)
6676    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6677   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6678   [(set_attr "type" "alu")
6679    (set_attr "mode" "<MODE>")])
6680
6681 (define_insn "*subsi_2_zext"
6682   [(set (reg FLAGS_REG)
6683         (compare
6684           (minus:SI (match_operand:SI 1 "register_operand" "0")
6685                     (match_operand:SI 2 "general_operand" "g"))
6686           (const_int 0)))
6687    (set (match_operand:DI 0 "register_operand" "=r")
6688         (zero_extend:DI
6689           (minus:SI (match_dup 1)
6690                     (match_dup 2))))]
6691   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6692    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6693   "sub{l}\t{%2, %k0|%k0, %2}"
6694   [(set_attr "type" "alu")
6695    (set_attr "mode" "SI")])
6696
6697 (define_insn "*sub<mode>_3"
6698   [(set (reg FLAGS_REG)
6699         (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6700                  (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6701    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6702         (minus:SWI (match_dup 1) (match_dup 2)))]
6703   "ix86_match_ccmode (insn, CCmode)
6704    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6705   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6706   [(set_attr "type" "alu")
6707    (set_attr "mode" "<MODE>")])
6708
6709 (define_insn "*subsi_3_zext"
6710   [(set (reg FLAGS_REG)
6711         (compare (match_operand:SI 1 "register_operand" "0")
6712                  (match_operand:SI 2 "general_operand" "g")))
6713    (set (match_operand:DI 0 "register_operand" "=r")
6714         (zero_extend:DI
6715           (minus:SI (match_dup 1)
6716                     (match_dup 2))))]
6717   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6718    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6719   "sub{l}\t{%2, %1|%1, %2}"
6720   [(set_attr "type" "alu")
6721    (set_attr "mode" "SI")])
6722 \f
6723 ;; Add with carry and subtract with borrow
6724
6725 (define_expand "<plusminus_insn><mode>3_carry"
6726   [(parallel
6727     [(set (match_operand:SWI 0 "nonimmediate_operand" "")
6728           (plusminus:SWI
6729             (match_operand:SWI 1 "nonimmediate_operand" "")
6730             (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6731                        [(match_operand 3 "flags_reg_operand" "")
6732                         (const_int 0)])
6733                       (match_operand:SWI 2 "<general_operand>" ""))))
6734      (clobber (reg:CC FLAGS_REG))])]
6735   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6736
6737 (define_insn "*<plusminus_insn><mode>3_carry"
6738   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6739         (plusminus:SWI
6740           (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6741           (plus:SWI
6742             (match_operator 3 "ix86_carry_flag_operator"
6743              [(reg FLAGS_REG) (const_int 0)])
6744             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6745    (clobber (reg:CC FLAGS_REG))]
6746   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6747   "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6748   [(set_attr "type" "alu")
6749    (set_attr "use_carry" "1")
6750    (set_attr "pent_pair" "pu")
6751    (set_attr "mode" "<MODE>")])
6752
6753 (define_insn "*addsi3_carry_zext"
6754   [(set (match_operand:DI 0 "register_operand" "=r")
6755         (zero_extend:DI
6756           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6757                    (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6758                              [(reg FLAGS_REG) (const_int 0)])
6759                             (match_operand:SI 2 "general_operand" "g")))))
6760    (clobber (reg:CC FLAGS_REG))]
6761   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6762   "adc{l}\t{%2, %k0|%k0, %2}"
6763   [(set_attr "type" "alu")
6764    (set_attr "use_carry" "1")
6765    (set_attr "pent_pair" "pu")
6766    (set_attr "mode" "SI")])
6767
6768 (define_insn "*subsi3_carry_zext"
6769   [(set (match_operand:DI 0 "register_operand" "=r")
6770         (zero_extend:DI
6771           (minus:SI (match_operand:SI 1 "register_operand" "0")
6772                     (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6773                               [(reg FLAGS_REG) (const_int 0)])
6774                              (match_operand:SI 2 "general_operand" "g")))))
6775    (clobber (reg:CC FLAGS_REG))]
6776   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6777   "sbb{l}\t{%2, %k0|%k0, %2}"
6778   [(set_attr "type" "alu")
6779    (set_attr "pent_pair" "pu")
6780    (set_attr "mode" "SI")])
6781 \f
6782 ;; Overflow setting add and subtract instructions
6783
6784 (define_insn "*add<mode>3_cconly_overflow"
6785   [(set (reg:CCC FLAGS_REG)
6786         (compare:CCC
6787           (plus:SWI
6788             (match_operand:SWI 1 "nonimmediate_operand" "%0")
6789             (match_operand:SWI 2 "<general_operand>" "<g>"))
6790           (match_dup 1)))
6791    (clobber (match_scratch:SWI 0 "=<r>"))]
6792   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6793   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6794   [(set_attr "type" "alu")
6795    (set_attr "mode" "<MODE>")])
6796
6797 (define_insn "*sub<mode>3_cconly_overflow"
6798   [(set (reg:CCC FLAGS_REG)
6799         (compare:CCC
6800           (minus:SWI
6801             (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6802             (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6803           (match_dup 0)))]
6804   ""
6805   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6806   [(set_attr "type" "icmp")
6807    (set_attr "mode" "<MODE>")])
6808
6809 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6810   [(set (reg:CCC FLAGS_REG)
6811         (compare:CCC
6812             (plusminus:SWI
6813                 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6814                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6815             (match_dup 1)))
6816    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6817         (plusminus:SWI (match_dup 1) (match_dup 2)))]
6818   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6819   "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6820   [(set_attr "type" "alu")
6821    (set_attr "mode" "<MODE>")])
6822
6823 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6824   [(set (reg:CCC FLAGS_REG)
6825         (compare:CCC
6826           (plusminus:SI
6827             (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6828             (match_operand:SI 2 "general_operand" "g"))
6829           (match_dup 1)))
6830    (set (match_operand:DI 0 "register_operand" "=r")
6831         (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6832   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6833   "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6834   [(set_attr "type" "alu")
6835    (set_attr "mode" "SI")])
6836
6837 ;; The patterns that match these are at the end of this file.
6838
6839 (define_expand "<plusminus_insn>xf3"
6840   [(set (match_operand:XF 0 "register_operand" "")
6841         (plusminus:XF
6842           (match_operand:XF 1 "register_operand" "")
6843           (match_operand:XF 2 "register_operand" "")))]
6844   "TARGET_80387")
6845
6846 (define_expand "<plusminus_insn><mode>3"
6847   [(set (match_operand:MODEF 0 "register_operand" "")
6848         (plusminus:MODEF
6849           (match_operand:MODEF 1 "register_operand" "")
6850           (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6851   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6852     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6853 \f
6854 ;; Multiply instructions
6855
6856 (define_expand "mul<mode>3"
6857   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
6858                    (mult:SWIM248
6859                      (match_operand:SWIM248 1 "register_operand" "")
6860                      (match_operand:SWIM248 2 "<general_operand>" "")))
6861               (clobber (reg:CC FLAGS_REG))])])
6862
6863 (define_expand "mulqi3"
6864   [(parallel [(set (match_operand:QI 0 "register_operand" "")
6865                    (mult:QI
6866                      (match_operand:QI 1 "register_operand" "")
6867                      (match_operand:QI 2 "nonimmediate_operand" "")))
6868               (clobber (reg:CC FLAGS_REG))])]
6869   "TARGET_QIMODE_MATH")
6870
6871 ;; On AMDFAM10
6872 ;; IMUL reg32/64, reg32/64, imm8        Direct
6873 ;; IMUL reg32/64, mem32/64, imm8        VectorPath
6874 ;; IMUL reg32/64, reg32/64, imm32       Direct
6875 ;; IMUL reg32/64, mem32/64, imm32       VectorPath
6876 ;; IMUL reg32/64, reg32/64              Direct
6877 ;; IMUL reg32/64, mem32/64              Direct
6878 ;;
6879 ;; On BDVER1, all above IMULs use DirectPath
6880
6881 (define_insn "*mul<mode>3_1"
6882   [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6883         (mult:SWI48
6884           (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6885           (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6886    (clobber (reg:CC FLAGS_REG))]
6887   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6888   "@
6889    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6890    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6891    imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6892   [(set_attr "type" "imul")
6893    (set_attr "prefix_0f" "0,0,1")
6894    (set (attr "athlon_decode")
6895         (cond [(eq_attr "cpu" "athlon")
6896                   (const_string "vector")
6897                (eq_attr "alternative" "1")
6898                   (const_string "vector")
6899                (and (eq_attr "alternative" "2")
6900                     (match_operand 1 "memory_operand" ""))
6901                   (const_string "vector")]
6902               (const_string "direct")))
6903    (set (attr "amdfam10_decode")
6904         (cond [(and (eq_attr "alternative" "0,1")
6905                     (match_operand 1 "memory_operand" ""))
6906                   (const_string "vector")]
6907               (const_string "direct")))
6908    (set_attr "bdver1_decode" "direct")
6909    (set_attr "mode" "<MODE>")])
6910
6911 (define_insn "*mulsi3_1_zext"
6912   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6913         (zero_extend:DI
6914           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6915                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
6916    (clobber (reg:CC FLAGS_REG))]
6917   "TARGET_64BIT
6918    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6919   "@
6920    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6921    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6922    imul{l}\t{%2, %k0|%k0, %2}"
6923   [(set_attr "type" "imul")
6924    (set_attr "prefix_0f" "0,0,1")
6925    (set (attr "athlon_decode")
6926         (cond [(eq_attr "cpu" "athlon")
6927                   (const_string "vector")
6928                (eq_attr "alternative" "1")
6929                   (const_string "vector")
6930                (and (eq_attr "alternative" "2")
6931                     (match_operand 1 "memory_operand" ""))
6932                   (const_string "vector")]
6933               (const_string "direct")))
6934    (set (attr "amdfam10_decode")
6935         (cond [(and (eq_attr "alternative" "0,1")
6936                     (match_operand 1 "memory_operand" ""))
6937                   (const_string "vector")]
6938               (const_string "direct")))
6939    (set_attr "bdver1_decode" "direct")
6940    (set_attr "mode" "SI")])
6941
6942 ;; On AMDFAM10
6943 ;; IMUL reg16, reg16, imm8      VectorPath
6944 ;; IMUL reg16, mem16, imm8      VectorPath
6945 ;; IMUL reg16, reg16, imm16     VectorPath
6946 ;; IMUL reg16, mem16, imm16     VectorPath
6947 ;; IMUL reg16, reg16            Direct
6948 ;; IMUL reg16, mem16            Direct
6949 ;;
6950 ;; On BDVER1, all HI MULs use DoublePath
6951
6952 (define_insn "*mulhi3_1"
6953   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6954         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6955                  (match_operand:HI 2 "general_operand" "K,n,mr")))
6956    (clobber (reg:CC FLAGS_REG))]
6957   "TARGET_HIMODE_MATH
6958    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6959   "@
6960    imul{w}\t{%2, %1, %0|%0, %1, %2}
6961    imul{w}\t{%2, %1, %0|%0, %1, %2}
6962    imul{w}\t{%2, %0|%0, %2}"
6963   [(set_attr "type" "imul")
6964    (set_attr "prefix_0f" "0,0,1")
6965    (set (attr "athlon_decode")
6966         (cond [(eq_attr "cpu" "athlon")
6967                   (const_string "vector")
6968                (eq_attr "alternative" "1,2")
6969                   (const_string "vector")]
6970               (const_string "direct")))
6971    (set (attr "amdfam10_decode")
6972         (cond [(eq_attr "alternative" "0,1")
6973                   (const_string "vector")]
6974               (const_string "direct")))
6975    (set_attr "bdver1_decode" "double")
6976    (set_attr "mode" "HI")])
6977
6978 ;;On AMDFAM10 and BDVER1
6979 ;; MUL reg8     Direct
6980 ;; MUL mem8     Direct
6981
6982 (define_insn "*mulqi3_1"
6983   [(set (match_operand:QI 0 "register_operand" "=a")
6984         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6985                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
6986    (clobber (reg:CC FLAGS_REG))]
6987   "TARGET_QIMODE_MATH
6988    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6989   "mul{b}\t%2"
6990   [(set_attr "type" "imul")
6991    (set_attr "length_immediate" "0")
6992    (set (attr "athlon_decode")
6993      (if_then_else (eq_attr "cpu" "athlon")
6994         (const_string "vector")
6995         (const_string "direct")))
6996    (set_attr "amdfam10_decode" "direct")
6997    (set_attr "bdver1_decode" "direct")
6998    (set_attr "mode" "QI")])
6999
7000 (define_expand "<u>mul<mode><dwi>3"
7001   [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
7002                    (mult:<DWI>
7003                      (any_extend:<DWI>
7004                        (match_operand:DWIH 1 "nonimmediate_operand" ""))
7005                      (any_extend:<DWI>
7006                        (match_operand:DWIH 2 "register_operand" ""))))
7007               (clobber (reg:CC FLAGS_REG))])])
7008
7009 (define_expand "<u>mulqihi3"
7010   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7011                    (mult:HI
7012                      (any_extend:HI
7013                        (match_operand:QI 1 "nonimmediate_operand" ""))
7014                      (any_extend:HI
7015                        (match_operand:QI 2 "register_operand" ""))))
7016               (clobber (reg:CC FLAGS_REG))])]
7017   "TARGET_QIMODE_MATH")
7018
7019 (define_insn "*<u>mul<mode><dwi>3_1"
7020   [(set (match_operand:<DWI> 0 "register_operand" "=A")
7021         (mult:<DWI>
7022           (any_extend:<DWI>
7023             (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
7024           (any_extend:<DWI>
7025             (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7026    (clobber (reg:CC FLAGS_REG))]
7027   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7028   "<sgnprefix>mul{<imodesuffix>}\t%2"
7029   [(set_attr "type" "imul")
7030    (set_attr "length_immediate" "0")
7031    (set (attr "athlon_decode")
7032      (if_then_else (eq_attr "cpu" "athlon")
7033         (const_string "vector")
7034         (const_string "double")))
7035    (set_attr "amdfam10_decode" "double")
7036    (set_attr "bdver1_decode" "direct")
7037    (set_attr "mode" "<MODE>")])
7038
7039 (define_insn "*<u>mulqihi3_1"
7040   [(set (match_operand:HI 0 "register_operand" "=a")
7041         (mult:HI
7042           (any_extend:HI
7043             (match_operand:QI 1 "nonimmediate_operand" "%0"))
7044           (any_extend:HI
7045             (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7046    (clobber (reg:CC FLAGS_REG))]
7047   "TARGET_QIMODE_MATH
7048    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7049   "<sgnprefix>mul{b}\t%2"
7050   [(set_attr "type" "imul")
7051    (set_attr "length_immediate" "0")
7052    (set (attr "athlon_decode")
7053      (if_then_else (eq_attr "cpu" "athlon")
7054         (const_string "vector")
7055         (const_string "direct")))
7056    (set_attr "amdfam10_decode" "direct")
7057    (set_attr "bdver1_decode" "direct")
7058    (set_attr "mode" "QI")])
7059
7060 (define_expand "<s>mul<mode>3_highpart"
7061   [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
7062                    (truncate:SWI48
7063                      (lshiftrt:<DWI>
7064                        (mult:<DWI>
7065                          (any_extend:<DWI>
7066                            (match_operand:SWI48 1 "nonimmediate_operand" ""))
7067                          (any_extend:<DWI>
7068                            (match_operand:SWI48 2 "register_operand" "")))
7069                        (match_dup 4))))
7070               (clobber (match_scratch:SWI48 3 ""))
7071               (clobber (reg:CC FLAGS_REG))])]
7072   ""
7073   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7074
7075 (define_insn "*<s>muldi3_highpart_1"
7076   [(set (match_operand:DI 0 "register_operand" "=d")
7077         (truncate:DI
7078           (lshiftrt:TI
7079             (mult:TI
7080               (any_extend:TI
7081                 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7082               (any_extend:TI
7083                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7084             (const_int 64))))
7085    (clobber (match_scratch:DI 3 "=1"))
7086    (clobber (reg:CC FLAGS_REG))]
7087   "TARGET_64BIT
7088    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7089   "<sgnprefix>mul{q}\t%2"
7090   [(set_attr "type" "imul")
7091    (set_attr "length_immediate" "0")
7092    (set (attr "athlon_decode")
7093      (if_then_else (eq_attr "cpu" "athlon")
7094         (const_string "vector")
7095         (const_string "double")))
7096    (set_attr "amdfam10_decode" "double")
7097    (set_attr "bdver1_decode" "direct")
7098    (set_attr "mode" "DI")])
7099
7100 (define_insn "*<s>mulsi3_highpart_1"
7101   [(set (match_operand:SI 0 "register_operand" "=d")
7102         (truncate:SI
7103           (lshiftrt:DI
7104             (mult:DI
7105               (any_extend:DI
7106                 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7107               (any_extend:DI
7108                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7109             (const_int 32))))
7110    (clobber (match_scratch:SI 3 "=1"))
7111    (clobber (reg:CC FLAGS_REG))]
7112   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7113   "<sgnprefix>mul{l}\t%2"
7114   [(set_attr "type" "imul")
7115    (set_attr "length_immediate" "0")
7116    (set (attr "athlon_decode")
7117      (if_then_else (eq_attr "cpu" "athlon")
7118         (const_string "vector")
7119         (const_string "double")))
7120    (set_attr "amdfam10_decode" "double")
7121    (set_attr "bdver1_decode" "direct")
7122    (set_attr "mode" "SI")])
7123
7124 (define_insn "*<s>mulsi3_highpart_zext"
7125   [(set (match_operand:DI 0 "register_operand" "=d")
7126         (zero_extend:DI (truncate:SI
7127           (lshiftrt:DI
7128             (mult:DI (any_extend:DI
7129                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7130                      (any_extend:DI
7131                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7132             (const_int 32)))))
7133    (clobber (match_scratch:SI 3 "=1"))
7134    (clobber (reg:CC FLAGS_REG))]
7135   "TARGET_64BIT
7136    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7137   "<sgnprefix>mul{l}\t%2"
7138   [(set_attr "type" "imul")
7139    (set_attr "length_immediate" "0")
7140    (set (attr "athlon_decode")
7141      (if_then_else (eq_attr "cpu" "athlon")
7142         (const_string "vector")
7143         (const_string "double")))
7144    (set_attr "amdfam10_decode" "double")
7145    (set_attr "bdver1_decode" "direct")
7146    (set_attr "mode" "SI")])
7147
7148 ;; The patterns that match these are at the end of this file.
7149
7150 (define_expand "mulxf3"
7151   [(set (match_operand:XF 0 "register_operand" "")
7152         (mult:XF (match_operand:XF 1 "register_operand" "")
7153                  (match_operand:XF 2 "register_operand" "")))]
7154   "TARGET_80387")
7155
7156 (define_expand "mul<mode>3"
7157   [(set (match_operand:MODEF 0 "register_operand" "")
7158         (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
7159                     (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7160   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7161     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7162 \f
7163 ;; Divide instructions
7164
7165 ;; The patterns that match these are at the end of this file.
7166
7167 (define_expand "divxf3"
7168   [(set (match_operand:XF 0 "register_operand" "")
7169         (div:XF (match_operand:XF 1 "register_operand" "")
7170                 (match_operand:XF 2 "register_operand" "")))]
7171   "TARGET_80387")
7172
7173 (define_expand "divdf3"
7174   [(set (match_operand:DF 0 "register_operand" "")
7175         (div:DF (match_operand:DF 1 "register_operand" "")
7176                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7177    "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7178     || (TARGET_SSE2 && TARGET_SSE_MATH)")
7179
7180 (define_expand "divsf3"
7181   [(set (match_operand:SF 0 "register_operand" "")
7182         (div:SF (match_operand:SF 1 "register_operand" "")
7183                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7184   "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7185     || TARGET_SSE_MATH"
7186 {
7187   if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
7188       && flag_finite_math_only && !flag_trapping_math
7189       && flag_unsafe_math_optimizations)
7190     {
7191       ix86_emit_swdivsf (operands[0], operands[1],
7192                          operands[2], SFmode);
7193       DONE;
7194     }
7195 })
7196 \f
7197 ;; Divmod instructions.
7198
7199 (define_expand "divmod<mode>4"
7200   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7201                    (div:SWIM248
7202                      (match_operand:SWIM248 1 "register_operand" "")
7203                      (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7204               (set (match_operand:SWIM248 3 "register_operand" "")
7205                    (mod:SWIM248 (match_dup 1) (match_dup 2)))
7206               (clobber (reg:CC FLAGS_REG))])])
7207
7208 ;; Split with 8bit unsigned divide:
7209 ;;      if (dividend an divisor are in [0-255])
7210 ;;         use 8bit unsigned integer divide
7211 ;;       else
7212 ;;         use original integer divide
7213 (define_split
7214   [(set (match_operand:SWI48 0 "register_operand" "")
7215         (div:SWI48 (match_operand:SWI48 2 "register_operand" "")
7216                     (match_operand:SWI48 3 "nonimmediate_operand" "")))
7217    (set (match_operand:SWI48 1 "register_operand" "")
7218         (mod:SWI48 (match_dup 2) (match_dup 3)))
7219    (clobber (reg:CC FLAGS_REG))]
7220   "TARGET_USE_8BIT_IDIV
7221    && TARGET_QIMODE_MATH
7222    && can_create_pseudo_p ()
7223    && !optimize_insn_for_size_p ()"
7224   [(const_int 0)]
7225   "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7226
7227 (define_insn_and_split "divmod<mode>4_1"
7228   [(set (match_operand:SWI48 0 "register_operand" "=a")
7229         (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7230                    (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7231    (set (match_operand:SWI48 1 "register_operand" "=&d")
7232         (mod:SWI48 (match_dup 2) (match_dup 3)))
7233    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7234    (clobber (reg:CC FLAGS_REG))]
7235   ""
7236   "#"
7237   "reload_completed"
7238   [(parallel [(set (match_dup 1)
7239                    (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7240               (clobber (reg:CC FLAGS_REG))])
7241    (parallel [(set (match_dup 0)
7242                    (div:SWI48 (match_dup 2) (match_dup 3)))
7243               (set (match_dup 1)
7244                    (mod:SWI48 (match_dup 2) (match_dup 3)))
7245               (use (match_dup 1))
7246               (clobber (reg:CC FLAGS_REG))])]
7247 {
7248   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7249
7250   if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7251     operands[4] = operands[2];
7252   else
7253     {
7254       /* Avoid use of cltd in favor of a mov+shift.  */
7255       emit_move_insn (operands[1], operands[2]);
7256       operands[4] = operands[1];
7257     }
7258 }
7259   [(set_attr "type" "multi")
7260    (set_attr "mode" "<MODE>")])
7261
7262 (define_insn_and_split "*divmod<mode>4"
7263   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7264         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7265                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7266    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7267         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7268    (clobber (reg:CC FLAGS_REG))]
7269   ""
7270   "#"
7271   "reload_completed"
7272   [(parallel [(set (match_dup 1)
7273                    (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7274               (clobber (reg:CC FLAGS_REG))])
7275    (parallel [(set (match_dup 0)
7276                    (div:SWIM248 (match_dup 2) (match_dup 3)))
7277               (set (match_dup 1)
7278                    (mod:SWIM248 (match_dup 2) (match_dup 3)))
7279               (use (match_dup 1))
7280               (clobber (reg:CC FLAGS_REG))])]
7281 {
7282   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7283
7284   if (<MODE>mode != HImode
7285       && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7286     operands[4] = operands[2];
7287   else
7288     {
7289       /* Avoid use of cltd in favor of a mov+shift.  */
7290       emit_move_insn (operands[1], operands[2]);
7291       operands[4] = operands[1];
7292     }
7293 }
7294   [(set_attr "type" "multi")
7295    (set_attr "mode" "<MODE>")])
7296
7297 (define_insn "*divmod<mode>4_noext"
7298   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7299         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7300                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7301    (set (match_operand:SWIM248 1 "register_operand" "=d")
7302         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7303    (use (match_operand:SWIM248 4 "register_operand" "1"))
7304    (clobber (reg:CC FLAGS_REG))]
7305   ""
7306   "idiv{<imodesuffix>}\t%3"
7307   [(set_attr "type" "idiv")
7308    (set_attr "mode" "<MODE>")])
7309
7310 (define_expand "divmodqi4"
7311   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7312                    (div:QI
7313                      (match_operand:QI 1 "register_operand" "")
7314                      (match_operand:QI 2 "nonimmediate_operand" "")))
7315               (set (match_operand:QI 3 "register_operand" "")
7316                    (mod:QI (match_dup 1) (match_dup 2)))
7317               (clobber (reg:CC FLAGS_REG))])]
7318   "TARGET_QIMODE_MATH"
7319 {
7320   rtx div, mod, insn;
7321   rtx tmp0, tmp1;
7322   
7323   tmp0 = gen_reg_rtx (HImode);
7324   tmp1 = gen_reg_rtx (HImode);
7325
7326   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is
7327      in AX.  */
7328   emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7329   emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7330
7331   /* Extract remainder from AH.  */
7332   tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7333   insn = emit_move_insn (operands[3], tmp1);
7334
7335   mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7336   set_unique_reg_note (insn, REG_EQUAL, mod);
7337
7338   /* Extract quotient from AL.  */
7339   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7340
7341   div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7342   set_unique_reg_note (insn, REG_EQUAL, div);
7343
7344   DONE;
7345 })
7346
7347 ;; Divide AX by r/m8, with result stored in
7348 ;; AL <- Quotient
7349 ;; AH <- Remainder
7350 ;; Change div/mod to HImode and extend the second argument to HImode
7351 ;; so that mode of div/mod matches with mode of arguments.  Otherwise
7352 ;; combine may fail.
7353 (define_insn "divmodhiqi3"
7354   [(set (match_operand:HI 0 "register_operand" "=a")
7355         (ior:HI
7356           (ashift:HI
7357             (zero_extend:HI
7358               (truncate:QI
7359                 (mod:HI (match_operand:HI 1 "register_operand" "0")
7360                         (sign_extend:HI
7361                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7362             (const_int 8))
7363           (zero_extend:HI
7364             (truncate:QI
7365               (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7366    (clobber (reg:CC FLAGS_REG))]
7367   "TARGET_QIMODE_MATH"
7368   "idiv{b}\t%2"
7369   [(set_attr "type" "idiv")
7370    (set_attr "mode" "QI")])
7371
7372 (define_expand "udivmod<mode>4"
7373   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7374                    (udiv:SWIM248
7375                      (match_operand:SWIM248 1 "register_operand" "")
7376                      (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7377               (set (match_operand:SWIM248 3 "register_operand" "")
7378                    (umod:SWIM248 (match_dup 1) (match_dup 2)))
7379               (clobber (reg:CC FLAGS_REG))])])
7380
7381 ;; Split with 8bit unsigned divide:
7382 ;;      if (dividend an divisor are in [0-255])
7383 ;;         use 8bit unsigned integer divide
7384 ;;       else
7385 ;;         use original integer divide
7386 (define_split
7387   [(set (match_operand:SWI48 0 "register_operand" "")
7388         (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "")
7389                     (match_operand:SWI48 3 "nonimmediate_operand" "")))
7390    (set (match_operand:SWI48 1 "register_operand" "")
7391         (umod:SWI48 (match_dup 2) (match_dup 3)))
7392    (clobber (reg:CC FLAGS_REG))]
7393   "TARGET_USE_8BIT_IDIV
7394    && TARGET_QIMODE_MATH
7395    && can_create_pseudo_p ()
7396    && !optimize_insn_for_size_p ()"
7397   [(const_int 0)]
7398   "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7399
7400 (define_insn_and_split "udivmod<mode>4_1"
7401   [(set (match_operand:SWI48 0 "register_operand" "=a")
7402         (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7403                     (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7404    (set (match_operand:SWI48 1 "register_operand" "=&d")
7405         (umod:SWI48 (match_dup 2) (match_dup 3)))
7406    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7407    (clobber (reg:CC FLAGS_REG))]
7408   ""
7409   "#"
7410   "reload_completed"
7411   [(set (match_dup 1) (const_int 0))
7412    (parallel [(set (match_dup 0)
7413                    (udiv:SWI48 (match_dup 2) (match_dup 3)))
7414               (set (match_dup 1)
7415                    (umod:SWI48 (match_dup 2) (match_dup 3)))
7416               (use (match_dup 1))
7417               (clobber (reg:CC FLAGS_REG))])]
7418   ""
7419   [(set_attr "type" "multi")
7420    (set_attr "mode" "<MODE>")])
7421
7422 (define_insn_and_split "*udivmod<mode>4"
7423   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7424         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7425                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7426    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7427         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7428    (clobber (reg:CC FLAGS_REG))]
7429   ""
7430   "#"
7431   "reload_completed"
7432   [(set (match_dup 1) (const_int 0))
7433    (parallel [(set (match_dup 0)
7434                    (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7435               (set (match_dup 1)
7436                    (umod:SWIM248 (match_dup 2) (match_dup 3)))
7437               (use (match_dup 1))
7438               (clobber (reg:CC FLAGS_REG))])]
7439   ""
7440   [(set_attr "type" "multi")
7441    (set_attr "mode" "<MODE>")])
7442
7443 (define_insn "*udivmod<mode>4_noext"
7444   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7445         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7446                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7447    (set (match_operand:SWIM248 1 "register_operand" "=d")
7448         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7449    (use (match_operand:SWIM248 4 "register_operand" "1"))
7450    (clobber (reg:CC FLAGS_REG))]
7451   ""
7452   "div{<imodesuffix>}\t%3"
7453   [(set_attr "type" "idiv")
7454    (set_attr "mode" "<MODE>")])
7455
7456 (define_expand "udivmodqi4"
7457   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7458                    (udiv:QI
7459                      (match_operand:QI 1 "register_operand" "")
7460                      (match_operand:QI 2 "nonimmediate_operand" "")))
7461               (set (match_operand:QI 3 "register_operand" "")
7462                    (umod:QI (match_dup 1) (match_dup 2)))
7463               (clobber (reg:CC FLAGS_REG))])]
7464   "TARGET_QIMODE_MATH"
7465 {
7466   rtx div, mod, insn;
7467   rtx tmp0, tmp1;
7468   
7469   tmp0 = gen_reg_rtx (HImode);
7470   tmp1 = gen_reg_rtx (HImode);
7471
7472   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is
7473      in AX.  */
7474   emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7475   emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7476
7477   /* Extract remainder from AH.  */
7478   tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7479   tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7480   insn = emit_move_insn (operands[3], tmp1);
7481
7482   mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7483   set_unique_reg_note (insn, REG_EQUAL, mod);
7484
7485   /* Extract quotient from AL.  */
7486   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7487
7488   div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7489   set_unique_reg_note (insn, REG_EQUAL, div);
7490
7491   DONE;
7492 })
7493
7494 (define_insn "udivmodhiqi3"
7495   [(set (match_operand:HI 0 "register_operand" "=a")
7496         (ior:HI
7497           (ashift:HI
7498             (zero_extend:HI
7499               (truncate:QI
7500                 (mod:HI (match_operand:HI 1 "register_operand" "0")
7501                         (zero_extend:HI
7502                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7503             (const_int 8))
7504           (zero_extend:HI
7505             (truncate:QI
7506               (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7507    (clobber (reg:CC FLAGS_REG))]
7508   "TARGET_QIMODE_MATH"
7509   "div{b}\t%2"
7510   [(set_attr "type" "idiv")
7511    (set_attr "mode" "QI")])
7512
7513 ;; We cannot use div/idiv for double division, because it causes
7514 ;; "division by zero" on the overflow and that's not what we expect
7515 ;; from truncate.  Because true (non truncating) double division is
7516 ;; never generated, we can't create this insn anyway.
7517 ;
7518 ;(define_insn ""
7519 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7520 ;       (truncate:SI
7521 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7522 ;                  (zero_extend:DI
7523 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7524 ;   (set (match_operand:SI 3 "register_operand" "=d")
7525 ;       (truncate:SI
7526 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7527 ;   (clobber (reg:CC FLAGS_REG))]
7528 ;  ""
7529 ;  "div{l}\t{%2, %0|%0, %2}"
7530 ;  [(set_attr "type" "idiv")])
7531 \f
7532 ;;- Logical AND instructions
7533
7534 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7535 ;; Note that this excludes ah.
7536
7537 (define_expand "testsi_ccno_1"
7538   [(set (reg:CCNO FLAGS_REG)
7539         (compare:CCNO
7540           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7541                   (match_operand:SI 1 "nonmemory_operand" ""))
7542           (const_int 0)))])
7543
7544 (define_expand "testqi_ccz_1"
7545   [(set (reg:CCZ FLAGS_REG)
7546         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7547                              (match_operand:QI 1 "nonmemory_operand" ""))
7548                  (const_int 0)))])
7549
7550 (define_expand "testdi_ccno_1"
7551   [(set (reg:CCNO FLAGS_REG)
7552         (compare:CCNO
7553           (and:DI (match_operand:DI 0 "nonimmediate_operand" "")
7554                   (match_operand:DI 1 "x86_64_szext_general_operand" ""))
7555           (const_int 0)))]
7556   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7557
7558 (define_insn "*testdi_1"
7559   [(set (reg FLAGS_REG)
7560         (compare
7561          (and:DI
7562           (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7563           (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7564          (const_int 0)))]
7565   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7566    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7567   "@
7568    test{l}\t{%k1, %k0|%k0, %k1}
7569    test{l}\t{%k1, %k0|%k0, %k1}
7570    test{q}\t{%1, %0|%0, %1}
7571    test{q}\t{%1, %0|%0, %1}
7572    test{q}\t{%1, %0|%0, %1}"
7573   [(set_attr "type" "test")
7574    (set_attr "modrm" "0,1,0,1,1")
7575    (set_attr "mode" "SI,SI,DI,DI,DI")])
7576
7577 (define_insn "*testqi_1_maybe_si"
7578   [(set (reg FLAGS_REG)
7579         (compare
7580           (and:QI
7581             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7582             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7583           (const_int 0)))]
7584    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7585     && ix86_match_ccmode (insn,
7586                          CONST_INT_P (operands[1])
7587                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7588 {
7589   if (which_alternative == 3)
7590     {
7591       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7592         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7593       return "test{l}\t{%1, %k0|%k0, %1}";
7594     }
7595   return "test{b}\t{%1, %0|%0, %1}";
7596 }
7597   [(set_attr "type" "test")
7598    (set_attr "modrm" "0,1,1,1")
7599    (set_attr "mode" "QI,QI,QI,SI")
7600    (set_attr "pent_pair" "uv,np,uv,np")])
7601
7602 (define_insn "*test<mode>_1"
7603   [(set (reg FLAGS_REG)
7604         (compare
7605          (and:SWI124
7606           (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7607           (match_operand:SWI124 1 "general_operand" "<i>,<i>,<r><i>"))
7608          (const_int 0)))]
7609   "ix86_match_ccmode (insn, CCNOmode)
7610    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7611   "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7612   [(set_attr "type" "test")
7613    (set_attr "modrm" "0,1,1")
7614    (set_attr "mode" "<MODE>")
7615    (set_attr "pent_pair" "uv,np,uv")])
7616
7617 (define_expand "testqi_ext_ccno_0"
7618   [(set (reg:CCNO FLAGS_REG)
7619         (compare:CCNO
7620           (and:SI
7621             (zero_extract:SI
7622               (match_operand 0 "ext_register_operand" "")
7623               (const_int 8)
7624               (const_int 8))
7625             (match_operand 1 "const_int_operand" ""))
7626           (const_int 0)))])
7627
7628 (define_insn "*testqi_ext_0"
7629   [(set (reg FLAGS_REG)
7630         (compare
7631           (and:SI
7632             (zero_extract:SI
7633               (match_operand 0 "ext_register_operand" "Q")
7634               (const_int 8)
7635               (const_int 8))
7636             (match_operand 1 "const_int_operand" "n"))
7637           (const_int 0)))]
7638   "ix86_match_ccmode (insn, CCNOmode)"
7639   "test{b}\t{%1, %h0|%h0, %1}"
7640   [(set_attr "type" "test")
7641    (set_attr "mode" "QI")
7642    (set_attr "length_immediate" "1")
7643    (set_attr "modrm" "1")
7644    (set_attr "pent_pair" "np")])
7645
7646 (define_insn "*testqi_ext_1_rex64"
7647   [(set (reg FLAGS_REG)
7648         (compare
7649           (and:SI
7650             (zero_extract:SI
7651               (match_operand 0 "ext_register_operand" "Q")
7652               (const_int 8)
7653               (const_int 8))
7654             (zero_extend:SI
7655               (match_operand:QI 1 "register_operand" "Q")))
7656           (const_int 0)))]
7657   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7658   "test{b}\t{%1, %h0|%h0, %1}"
7659   [(set_attr "type" "test")
7660    (set_attr "mode" "QI")])
7661
7662 (define_insn "*testqi_ext_1"
7663   [(set (reg FLAGS_REG)
7664         (compare
7665           (and:SI
7666             (zero_extract:SI
7667               (match_operand 0 "ext_register_operand" "Q")
7668               (const_int 8)
7669               (const_int 8))
7670             (zero_extend:SI
7671               (match_operand:QI 1 "general_operand" "Qm")))
7672           (const_int 0)))]
7673   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7674   "test{b}\t{%1, %h0|%h0, %1}"
7675   [(set_attr "type" "test")
7676    (set_attr "mode" "QI")])
7677
7678 (define_insn "*testqi_ext_2"
7679   [(set (reg FLAGS_REG)
7680         (compare
7681           (and:SI
7682             (zero_extract:SI
7683               (match_operand 0 "ext_register_operand" "Q")
7684               (const_int 8)
7685               (const_int 8))
7686             (zero_extract:SI
7687               (match_operand 1 "ext_register_operand" "Q")
7688               (const_int 8)
7689               (const_int 8)))
7690           (const_int 0)))]
7691   "ix86_match_ccmode (insn, CCNOmode)"
7692   "test{b}\t{%h1, %h0|%h0, %h1}"
7693   [(set_attr "type" "test")
7694    (set_attr "mode" "QI")])
7695
7696 (define_insn "*testqi_ext_3_rex64"
7697   [(set (reg FLAGS_REG)
7698         (compare (zero_extract:DI
7699                    (match_operand 0 "nonimmediate_operand" "rm")
7700                    (match_operand:DI 1 "const_int_operand" "")
7701                    (match_operand:DI 2 "const_int_operand" ""))
7702                  (const_int 0)))]
7703   "TARGET_64BIT
7704    && ix86_match_ccmode (insn, CCNOmode)
7705    && INTVAL (operands[1]) > 0
7706    && INTVAL (operands[2]) >= 0
7707    /* Ensure that resulting mask is zero or sign extended operand.  */
7708    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7709        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7710            && INTVAL (operands[1]) > 32))
7711    && (GET_MODE (operands[0]) == SImode
7712        || GET_MODE (operands[0]) == DImode
7713        || GET_MODE (operands[0]) == HImode
7714        || GET_MODE (operands[0]) == QImode)"
7715   "#")
7716
7717 ;; Combine likes to form bit extractions for some tests.  Humor it.
7718 (define_insn "*testqi_ext_3"
7719   [(set (reg FLAGS_REG)
7720         (compare (zero_extract:SI
7721                    (match_operand 0 "nonimmediate_operand" "rm")
7722                    (match_operand:SI 1 "const_int_operand" "")
7723                    (match_operand:SI 2 "const_int_operand" ""))
7724                  (const_int 0)))]
7725   "ix86_match_ccmode (insn, CCNOmode)
7726    && INTVAL (operands[1]) > 0
7727    && INTVAL (operands[2]) >= 0
7728    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7729    && (GET_MODE (operands[0]) == SImode
7730        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7731        || GET_MODE (operands[0]) == HImode
7732        || GET_MODE (operands[0]) == QImode)"
7733   "#")
7734
7735 (define_split
7736   [(set (match_operand 0 "flags_reg_operand" "")
7737         (match_operator 1 "compare_operator"
7738           [(zero_extract
7739              (match_operand 2 "nonimmediate_operand" "")
7740              (match_operand 3 "const_int_operand" "")
7741              (match_operand 4 "const_int_operand" ""))
7742            (const_int 0)]))]
7743   "ix86_match_ccmode (insn, CCNOmode)"
7744   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7745 {
7746   rtx val = operands[2];
7747   HOST_WIDE_INT len = INTVAL (operands[3]);
7748   HOST_WIDE_INT pos = INTVAL (operands[4]);
7749   HOST_WIDE_INT mask;
7750   enum machine_mode mode, submode;
7751
7752   mode = GET_MODE (val);
7753   if (MEM_P (val))
7754     {
7755       /* ??? Combine likes to put non-volatile mem extractions in QImode
7756          no matter the size of the test.  So find a mode that works.  */
7757       if (! MEM_VOLATILE_P (val))
7758         {
7759           mode = smallest_mode_for_size (pos + len, MODE_INT);
7760           val = adjust_address (val, mode, 0);
7761         }
7762     }
7763   else if (GET_CODE (val) == SUBREG
7764            && (submode = GET_MODE (SUBREG_REG (val)),
7765                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7766            && pos + len <= GET_MODE_BITSIZE (submode)
7767            && GET_MODE_CLASS (submode) == MODE_INT)
7768     {
7769       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
7770       mode = submode;
7771       val = SUBREG_REG (val);
7772     }
7773   else if (mode == HImode && pos + len <= 8)
7774     {
7775       /* Small HImode tests can be converted to QImode.  */
7776       mode = QImode;
7777       val = gen_lowpart (QImode, val);
7778     }
7779
7780   if (len == HOST_BITS_PER_WIDE_INT)
7781     mask = -1;
7782   else
7783     mask = ((HOST_WIDE_INT)1 << len) - 1;
7784   mask <<= pos;
7785
7786   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7787 })
7788
7789 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7790 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7791 ;; this is relatively important trick.
7792 ;; Do the conversion only post-reload to avoid limiting of the register class
7793 ;; to QI regs.
7794 (define_split
7795   [(set (match_operand 0 "flags_reg_operand" "")
7796         (match_operator 1 "compare_operator"
7797           [(and (match_operand 2 "register_operand" "")
7798                 (match_operand 3 "const_int_operand" ""))
7799            (const_int 0)]))]
7800    "reload_completed
7801     && QI_REG_P (operands[2])
7802     && GET_MODE (operands[2]) != QImode
7803     && ((ix86_match_ccmode (insn, CCZmode)
7804          && !(INTVAL (operands[3]) & ~(255 << 8)))
7805         || (ix86_match_ccmode (insn, CCNOmode)
7806             && !(INTVAL (operands[3]) & ~(127 << 8))))"
7807   [(set (match_dup 0)
7808         (match_op_dup 1
7809           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7810                    (match_dup 3))
7811            (const_int 0)]))]
7812   "operands[2] = gen_lowpart (SImode, operands[2]);
7813    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7814
7815 (define_split
7816   [(set (match_operand 0 "flags_reg_operand" "")
7817         (match_operator 1 "compare_operator"
7818           [(and (match_operand 2 "nonimmediate_operand" "")
7819                 (match_operand 3 "const_int_operand" ""))
7820            (const_int 0)]))]
7821    "reload_completed
7822     && GET_MODE (operands[2]) != QImode
7823     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7824     && ((ix86_match_ccmode (insn, CCZmode)
7825          && !(INTVAL (operands[3]) & ~255))
7826         || (ix86_match_ccmode (insn, CCNOmode)
7827             && !(INTVAL (operands[3]) & ~127)))"
7828   [(set (match_dup 0)
7829         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7830                          (const_int 0)]))]
7831   "operands[2] = gen_lowpart (QImode, operands[2]);
7832    operands[3] = gen_lowpart (QImode, operands[3]);")
7833
7834 ;; %%% This used to optimize known byte-wide and operations to memory,
7835 ;; and sometimes to QImode registers.  If this is considered useful,
7836 ;; it should be done with splitters.
7837
7838 (define_expand "and<mode>3"
7839   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
7840         (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
7841                   (match_operand:SWIM 2 "<general_szext_operand>" "")))]
7842   ""
7843   "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
7844
7845 (define_insn "*anddi_1"
7846   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7847         (and:DI
7848          (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7849          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7850    (clobber (reg:CC FLAGS_REG))]
7851   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7852 {
7853   switch (get_attr_type (insn))
7854     {
7855     case TYPE_IMOVX:
7856       {
7857         enum machine_mode mode;
7858
7859         gcc_assert (CONST_INT_P (operands[2]));
7860         if (INTVAL (operands[2]) == 0xff)
7861           mode = QImode;
7862         else
7863           {
7864             gcc_assert (INTVAL (operands[2]) == 0xffff);
7865             mode = HImode;
7866           }
7867
7868         operands[1] = gen_lowpart (mode, operands[1]);
7869         if (mode == QImode)
7870           return "movz{bl|x}\t{%1, %k0|%k0, %1}";
7871         else
7872           return "movz{wl|x}\t{%1, %k0|%k0, %1}";
7873       }
7874
7875     default:
7876       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7877       if (get_attr_mode (insn) == MODE_SI)
7878         return "and{l}\t{%k2, %k0|%k0, %k2}";
7879       else
7880         return "and{q}\t{%2, %0|%0, %2}";
7881     }
7882 }
7883   [(set_attr "type" "alu,alu,alu,imovx")
7884    (set_attr "length_immediate" "*,*,*,0")
7885    (set (attr "prefix_rex")
7886      (if_then_else
7887        (and (eq_attr "type" "imovx")
7888             (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7889                  (match_operand 1 "ext_QIreg_nomode_operand" "")))
7890        (const_string "1")
7891        (const_string "*")))
7892    (set_attr "mode" "SI,DI,DI,SI")])
7893
7894 (define_insn "*andsi_1"
7895   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7896         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7897                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
7898    (clobber (reg:CC FLAGS_REG))]
7899   "ix86_binary_operator_ok (AND, SImode, operands)"
7900 {
7901   switch (get_attr_type (insn))
7902     {
7903     case TYPE_IMOVX:
7904       {
7905         enum machine_mode mode;
7906
7907         gcc_assert (CONST_INT_P (operands[2]));
7908         if (INTVAL (operands[2]) == 0xff)
7909           mode = QImode;
7910         else
7911           {
7912             gcc_assert (INTVAL (operands[2]) == 0xffff);
7913             mode = HImode;
7914           }
7915
7916         operands[1] = gen_lowpart (mode, operands[1]);
7917         if (mode == QImode)
7918           return "movz{bl|x}\t{%1, %0|%0, %1}";
7919         else
7920           return "movz{wl|x}\t{%1, %0|%0, %1}";
7921       }
7922
7923     default:
7924       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7925       return "and{l}\t{%2, %0|%0, %2}";
7926     }
7927 }
7928   [(set_attr "type" "alu,alu,imovx")
7929    (set (attr "prefix_rex")
7930      (if_then_else
7931        (and (eq_attr "type" "imovx")
7932             (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7933                  (match_operand 1 "ext_QIreg_nomode_operand" "")))
7934        (const_string "1")
7935        (const_string "*")))
7936    (set_attr "length_immediate" "*,*,0")
7937    (set_attr "mode" "SI")])
7938
7939 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7940 (define_insn "*andsi_1_zext"
7941   [(set (match_operand:DI 0 "register_operand" "=r")
7942         (zero_extend:DI
7943           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7944                   (match_operand:SI 2 "general_operand" "g"))))
7945    (clobber (reg:CC FLAGS_REG))]
7946   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7947   "and{l}\t{%2, %k0|%k0, %2}"
7948   [(set_attr "type" "alu")
7949    (set_attr "mode" "SI")])
7950
7951 (define_insn "*andhi_1"
7952   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
7953         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7954                 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7955    (clobber (reg:CC FLAGS_REG))]
7956   "ix86_binary_operator_ok (AND, HImode, operands)"
7957 {
7958   switch (get_attr_type (insn))
7959     {
7960     case TYPE_IMOVX:
7961       gcc_assert (CONST_INT_P (operands[2]));
7962       gcc_assert (INTVAL (operands[2]) == 0xff);
7963       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
7964
7965     default:
7966       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7967
7968       return "and{w}\t{%2, %0|%0, %2}";
7969     }
7970 }
7971   [(set_attr "type" "alu,alu,imovx")
7972    (set_attr "length_immediate" "*,*,0")
7973    (set (attr "prefix_rex")
7974      (if_then_else
7975        (and (eq_attr "type" "imovx")
7976             (match_operand 1 "ext_QIreg_nomode_operand" ""))
7977        (const_string "1")
7978        (const_string "*")))
7979    (set_attr "mode" "HI,HI,SI")])
7980
7981 ;; %%% Potential partial reg stall on alternative 2.  What to do?
7982 (define_insn "*andqi_1"
7983   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7984         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7985                 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7986    (clobber (reg:CC FLAGS_REG))]
7987   "ix86_binary_operator_ok (AND, QImode, operands)"
7988   "@
7989    and{b}\t{%2, %0|%0, %2}
7990    and{b}\t{%2, %0|%0, %2}
7991    and{l}\t{%k2, %k0|%k0, %k2}"
7992   [(set_attr "type" "alu")
7993    (set_attr "mode" "QI,QI,SI")])
7994
7995 (define_insn "*andqi_1_slp"
7996   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7997         (and:QI (match_dup 0)
7998                 (match_operand:QI 1 "general_operand" "qn,qmn")))
7999    (clobber (reg:CC FLAGS_REG))]
8000   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8001    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8002   "and{b}\t{%1, %0|%0, %1}"
8003   [(set_attr "type" "alu1")
8004    (set_attr "mode" "QI")])
8005
8006 (define_split
8007   [(set (match_operand 0 "register_operand" "")
8008         (and (match_dup 0)
8009              (const_int -65536)))
8010    (clobber (reg:CC FLAGS_REG))]
8011   "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
8012     || optimize_function_for_size_p (cfun)"
8013   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8014   "operands[1] = gen_lowpart (HImode, operands[0]);")
8015
8016 (define_split
8017   [(set (match_operand 0 "ext_register_operand" "")
8018         (and (match_dup 0)
8019              (const_int -256)))
8020    (clobber (reg:CC FLAGS_REG))]
8021   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8022    && reload_completed"
8023   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8024   "operands[1] = gen_lowpart (QImode, operands[0]);")
8025
8026 (define_split
8027   [(set (match_operand 0 "ext_register_operand" "")
8028         (and (match_dup 0)
8029              (const_int -65281)))
8030    (clobber (reg:CC FLAGS_REG))]
8031   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8032    && reload_completed"
8033   [(parallel [(set (zero_extract:SI (match_dup 0)
8034                                     (const_int 8)
8035                                     (const_int 8))
8036                    (xor:SI
8037                      (zero_extract:SI (match_dup 0)
8038                                       (const_int 8)
8039                                       (const_int 8))
8040                      (zero_extract:SI (match_dup 0)
8041                                       (const_int 8)
8042                                       (const_int 8))))
8043               (clobber (reg:CC FLAGS_REG))])]
8044   "operands[0] = gen_lowpart (SImode, operands[0]);")
8045
8046 (define_insn "*anddi_2"
8047   [(set (reg FLAGS_REG)
8048         (compare
8049          (and:DI
8050           (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8051           (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8052          (const_int 0)))
8053    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8054         (and:DI (match_dup 1) (match_dup 2)))]
8055   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8056    && ix86_binary_operator_ok (AND, DImode, operands)"
8057   "@
8058    and{l}\t{%k2, %k0|%k0, %k2}
8059    and{q}\t{%2, %0|%0, %2}
8060    and{q}\t{%2, %0|%0, %2}"
8061   [(set_attr "type" "alu")
8062    (set_attr "mode" "SI,DI,DI")])
8063
8064 (define_insn "*andqi_2_maybe_si"
8065   [(set (reg FLAGS_REG)
8066         (compare (and:QI
8067                   (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8068                   (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8069                  (const_int 0)))
8070    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8071         (and:QI (match_dup 1) (match_dup 2)))]
8072   "ix86_binary_operator_ok (AND, QImode, operands)
8073    && ix86_match_ccmode (insn,
8074                          CONST_INT_P (operands[2])
8075                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8076 {
8077   if (which_alternative == 2)
8078     {
8079       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8080         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8081       return "and{l}\t{%2, %k0|%k0, %2}";
8082     }
8083   return "and{b}\t{%2, %0|%0, %2}";
8084 }
8085   [(set_attr "type" "alu")
8086    (set_attr "mode" "QI,QI,SI")])
8087
8088 (define_insn "*and<mode>_2"
8089   [(set (reg FLAGS_REG)
8090         (compare (and:SWI124
8091                   (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8092                   (match_operand:SWI124 2 "general_operand" "<g>,<r><i>"))
8093                  (const_int 0)))
8094    (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8095         (and:SWI124 (match_dup 1) (match_dup 2)))]
8096   "ix86_match_ccmode (insn, CCNOmode)
8097    && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8098   "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8099   [(set_attr "type" "alu")
8100    (set_attr "mode" "<MODE>")])
8101
8102 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8103 (define_insn "*andsi_2_zext"
8104   [(set (reg FLAGS_REG)
8105         (compare (and:SI
8106                   (match_operand:SI 1 "nonimmediate_operand" "%0")
8107                   (match_operand:SI 2 "general_operand" "g"))
8108                  (const_int 0)))
8109    (set (match_operand:DI 0 "register_operand" "=r")
8110         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8111   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8112    && ix86_binary_operator_ok (AND, SImode, operands)"
8113   "and{l}\t{%2, %k0|%k0, %2}"
8114   [(set_attr "type" "alu")
8115    (set_attr "mode" "SI")])
8116
8117 (define_insn "*andqi_2_slp"
8118   [(set (reg FLAGS_REG)
8119         (compare (and:QI
8120                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8121                    (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8122                  (const_int 0)))
8123    (set (strict_low_part (match_dup 0))
8124         (and:QI (match_dup 0) (match_dup 1)))]
8125   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8126    && ix86_match_ccmode (insn, CCNOmode)
8127    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8128   "and{b}\t{%1, %0|%0, %1}"
8129   [(set_attr "type" "alu1")
8130    (set_attr "mode" "QI")])
8131
8132 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8133 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8134 ;; for a QImode operand, which of course failed.
8135 (define_insn "andqi_ext_0"
8136   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8137                          (const_int 8)
8138                          (const_int 8))
8139         (and:SI
8140           (zero_extract:SI
8141             (match_operand 1 "ext_register_operand" "0")
8142             (const_int 8)
8143             (const_int 8))
8144           (match_operand 2 "const_int_operand" "n")))
8145    (clobber (reg:CC FLAGS_REG))]
8146   ""
8147   "and{b}\t{%2, %h0|%h0, %2}"
8148   [(set_attr "type" "alu")
8149    (set_attr "length_immediate" "1")
8150    (set_attr "modrm" "1")
8151    (set_attr "mode" "QI")])
8152
8153 ;; Generated by peephole translating test to and.  This shows up
8154 ;; often in fp comparisons.
8155 (define_insn "*andqi_ext_0_cc"
8156   [(set (reg FLAGS_REG)
8157         (compare
8158           (and:SI
8159             (zero_extract:SI
8160               (match_operand 1 "ext_register_operand" "0")
8161               (const_int 8)
8162               (const_int 8))
8163             (match_operand 2 "const_int_operand" "n"))
8164           (const_int 0)))
8165    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8166                          (const_int 8)
8167                          (const_int 8))
8168         (and:SI
8169           (zero_extract:SI
8170             (match_dup 1)
8171             (const_int 8)
8172             (const_int 8))
8173           (match_dup 2)))]
8174   "ix86_match_ccmode (insn, CCNOmode)"
8175   "and{b}\t{%2, %h0|%h0, %2}"
8176   [(set_attr "type" "alu")
8177    (set_attr "length_immediate" "1")
8178    (set_attr "modrm" "1")
8179    (set_attr "mode" "QI")])
8180
8181 (define_insn "*andqi_ext_1_rex64"
8182   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8183                          (const_int 8)
8184                          (const_int 8))
8185         (and:SI
8186           (zero_extract:SI
8187             (match_operand 1 "ext_register_operand" "0")
8188             (const_int 8)
8189             (const_int 8))
8190           (zero_extend:SI
8191             (match_operand 2 "ext_register_operand" "Q"))))
8192    (clobber (reg:CC FLAGS_REG))]
8193   "TARGET_64BIT"
8194   "and{b}\t{%2, %h0|%h0, %2}"
8195   [(set_attr "type" "alu")
8196    (set_attr "length_immediate" "0")
8197    (set_attr "mode" "QI")])
8198
8199 (define_insn "*andqi_ext_1"
8200   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8201                          (const_int 8)
8202                          (const_int 8))
8203         (and:SI
8204           (zero_extract:SI
8205             (match_operand 1 "ext_register_operand" "0")
8206             (const_int 8)
8207             (const_int 8))
8208           (zero_extend:SI
8209             (match_operand:QI 2 "general_operand" "Qm"))))
8210    (clobber (reg:CC FLAGS_REG))]
8211   "!TARGET_64BIT"
8212   "and{b}\t{%2, %h0|%h0, %2}"
8213   [(set_attr "type" "alu")
8214    (set_attr "length_immediate" "0")
8215    (set_attr "mode" "QI")])
8216
8217 (define_insn "*andqi_ext_2"
8218   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8219                          (const_int 8)
8220                          (const_int 8))
8221         (and:SI
8222           (zero_extract:SI
8223             (match_operand 1 "ext_register_operand" "%0")
8224             (const_int 8)
8225             (const_int 8))
8226           (zero_extract:SI
8227             (match_operand 2 "ext_register_operand" "Q")
8228             (const_int 8)
8229             (const_int 8))))
8230    (clobber (reg:CC FLAGS_REG))]
8231   ""
8232   "and{b}\t{%h2, %h0|%h0, %h2}"
8233   [(set_attr "type" "alu")
8234    (set_attr "length_immediate" "0")
8235    (set_attr "mode" "QI")])
8236
8237 ;; Convert wide AND instructions with immediate operand to shorter QImode
8238 ;; equivalents when possible.
8239 ;; Don't do the splitting with memory operands, since it introduces risk
8240 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8241 ;; for size, but that can (should?) be handled by generic code instead.
8242 (define_split
8243   [(set (match_operand 0 "register_operand" "")
8244         (and (match_operand 1 "register_operand" "")
8245              (match_operand 2 "const_int_operand" "")))
8246    (clobber (reg:CC FLAGS_REG))]
8247    "reload_completed
8248     && QI_REG_P (operands[0])
8249     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8250     && !(~INTVAL (operands[2]) & ~(255 << 8))
8251     && GET_MODE (operands[0]) != QImode"
8252   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8253                    (and:SI (zero_extract:SI (match_dup 1)
8254                                             (const_int 8) (const_int 8))
8255                            (match_dup 2)))
8256               (clobber (reg:CC FLAGS_REG))])]
8257   "operands[0] = gen_lowpart (SImode, operands[0]);
8258    operands[1] = gen_lowpart (SImode, operands[1]);
8259    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8260
8261 ;; Since AND can be encoded with sign extended immediate, this is only
8262 ;; profitable when 7th bit is not set.
8263 (define_split
8264   [(set (match_operand 0 "register_operand" "")
8265         (and (match_operand 1 "general_operand" "")
8266              (match_operand 2 "const_int_operand" "")))
8267    (clobber (reg:CC FLAGS_REG))]
8268    "reload_completed
8269     && ANY_QI_REG_P (operands[0])
8270     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8271     && !(~INTVAL (operands[2]) & ~255)
8272     && !(INTVAL (operands[2]) & 128)
8273     && GET_MODE (operands[0]) != QImode"
8274   [(parallel [(set (strict_low_part (match_dup 0))
8275                    (and:QI (match_dup 1)
8276                            (match_dup 2)))
8277               (clobber (reg:CC FLAGS_REG))])]
8278   "operands[0] = gen_lowpart (QImode, operands[0]);
8279    operands[1] = gen_lowpart (QImode, operands[1]);
8280    operands[2] = gen_lowpart (QImode, operands[2]);")
8281 \f
8282 ;; Logical inclusive and exclusive OR instructions
8283
8284 ;; %%% This used to optimize known byte-wide and operations to memory.
8285 ;; If this is considered useful, it should be done with splitters.
8286
8287 (define_expand "<code><mode>3"
8288   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8289         (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8290                      (match_operand:SWIM 2 "<general_operand>" "")))]
8291   ""
8292   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8293
8294 (define_insn "*<code><mode>_1"
8295   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8296         (any_or:SWI248
8297          (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8298          (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8299    (clobber (reg:CC FLAGS_REG))]
8300   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8301   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8302   [(set_attr "type" "alu")
8303    (set_attr "mode" "<MODE>")])
8304
8305 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8306 (define_insn "*<code>qi_1"
8307   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8308         (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8309                    (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8310    (clobber (reg:CC FLAGS_REG))]
8311   "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8312   "@
8313    <logic>{b}\t{%2, %0|%0, %2}
8314    <logic>{b}\t{%2, %0|%0, %2}
8315    <logic>{l}\t{%k2, %k0|%k0, %k2}"
8316   [(set_attr "type" "alu")
8317    (set_attr "mode" "QI,QI,SI")])
8318
8319 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8320 (define_insn "*<code>si_1_zext"
8321   [(set (match_operand:DI 0 "register_operand" "=r")
8322         (zero_extend:DI
8323          (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8324                     (match_operand:SI 2 "general_operand" "g"))))
8325    (clobber (reg:CC FLAGS_REG))]
8326   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8327   "<logic>{l}\t{%2, %k0|%k0, %2}"
8328   [(set_attr "type" "alu")
8329    (set_attr "mode" "SI")])
8330
8331 (define_insn "*<code>si_1_zext_imm"
8332   [(set (match_operand:DI 0 "register_operand" "=r")
8333         (any_or:DI
8334          (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8335          (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8336    (clobber (reg:CC FLAGS_REG))]
8337   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8338   "<logic>{l}\t{%2, %k0|%k0, %2}"
8339   [(set_attr "type" "alu")
8340    (set_attr "mode" "SI")])
8341
8342 (define_insn "*<code>qi_1_slp"
8343   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8344         (any_or:QI (match_dup 0)
8345                    (match_operand:QI 1 "general_operand" "qmn,qn")))
8346    (clobber (reg:CC FLAGS_REG))]
8347   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8348    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8349   "<logic>{b}\t{%1, %0|%0, %1}"
8350   [(set_attr "type" "alu1")
8351    (set_attr "mode" "QI")])
8352
8353 (define_insn "*<code><mode>_2"
8354   [(set (reg FLAGS_REG)
8355         (compare (any_or:SWI
8356                   (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8357                   (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8358                  (const_int 0)))
8359    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8360         (any_or:SWI (match_dup 1) (match_dup 2)))]
8361   "ix86_match_ccmode (insn, CCNOmode)
8362    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8363   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8364   [(set_attr "type" "alu")
8365    (set_attr "mode" "<MODE>")])
8366
8367 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8368 ;; ??? Special case for immediate operand is missing - it is tricky.
8369 (define_insn "*<code>si_2_zext"
8370   [(set (reg FLAGS_REG)
8371         (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8372                             (match_operand:SI 2 "general_operand" "g"))
8373                  (const_int 0)))
8374    (set (match_operand:DI 0 "register_operand" "=r")
8375         (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8376   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8377    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8378   "<logic>{l}\t{%2, %k0|%k0, %2}"
8379   [(set_attr "type" "alu")
8380    (set_attr "mode" "SI")])
8381
8382 (define_insn "*<code>si_2_zext_imm"
8383   [(set (reg FLAGS_REG)
8384         (compare (any_or:SI
8385                   (match_operand:SI 1 "nonimmediate_operand" "%0")
8386                   (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8387                  (const_int 0)))
8388    (set (match_operand:DI 0 "register_operand" "=r")
8389         (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8390   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8391    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8392   "<logic>{l}\t{%2, %k0|%k0, %2}"
8393   [(set_attr "type" "alu")
8394    (set_attr "mode" "SI")])
8395
8396 (define_insn "*<code>qi_2_slp"
8397   [(set (reg FLAGS_REG)
8398         (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8399                             (match_operand:QI 1 "general_operand" "qmn,qn"))
8400                  (const_int 0)))
8401    (set (strict_low_part (match_dup 0))
8402         (any_or:QI (match_dup 0) (match_dup 1)))]
8403   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8404    && ix86_match_ccmode (insn, CCNOmode)
8405    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8406   "<logic>{b}\t{%1, %0|%0, %1}"
8407   [(set_attr "type" "alu1")
8408    (set_attr "mode" "QI")])
8409
8410 (define_insn "*<code><mode>_3"
8411   [(set (reg FLAGS_REG)
8412         (compare (any_or:SWI
8413                   (match_operand:SWI 1 "nonimmediate_operand" "%0")
8414                   (match_operand:SWI 2 "<general_operand>" "<g>"))
8415                  (const_int 0)))
8416    (clobber (match_scratch:SWI 0 "=<r>"))]
8417   "ix86_match_ccmode (insn, CCNOmode)
8418    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8419   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8420   [(set_attr "type" "alu")
8421    (set_attr "mode" "<MODE>")])
8422
8423 (define_insn "*<code>qi_ext_0"
8424   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8425                          (const_int 8)
8426                          (const_int 8))
8427         (any_or:SI
8428           (zero_extract:SI
8429             (match_operand 1 "ext_register_operand" "0")
8430             (const_int 8)
8431             (const_int 8))
8432           (match_operand 2 "const_int_operand" "n")))
8433    (clobber (reg:CC FLAGS_REG))]
8434   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8435   "<logic>{b}\t{%2, %h0|%h0, %2}"
8436   [(set_attr "type" "alu")
8437    (set_attr "length_immediate" "1")
8438    (set_attr "modrm" "1")
8439    (set_attr "mode" "QI")])
8440
8441 (define_insn "*<code>qi_ext_1_rex64"
8442   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8443                          (const_int 8)
8444                          (const_int 8))
8445         (any_or:SI
8446           (zero_extract:SI
8447             (match_operand 1 "ext_register_operand" "0")
8448             (const_int 8)
8449             (const_int 8))
8450           (zero_extend:SI
8451             (match_operand 2 "ext_register_operand" "Q"))))
8452    (clobber (reg:CC FLAGS_REG))]
8453   "TARGET_64BIT
8454    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8455   "<logic>{b}\t{%2, %h0|%h0, %2}"
8456   [(set_attr "type" "alu")
8457    (set_attr "length_immediate" "0")
8458    (set_attr "mode" "QI")])
8459
8460 (define_insn "*<code>qi_ext_1"
8461   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8462                          (const_int 8)
8463                          (const_int 8))
8464         (any_or:SI
8465           (zero_extract:SI
8466             (match_operand 1 "ext_register_operand" "0")
8467             (const_int 8)
8468             (const_int 8))
8469           (zero_extend:SI
8470             (match_operand:QI 2 "general_operand" "Qm"))))
8471    (clobber (reg:CC FLAGS_REG))]
8472   "!TARGET_64BIT
8473    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8474   "<logic>{b}\t{%2, %h0|%h0, %2}"
8475   [(set_attr "type" "alu")
8476    (set_attr "length_immediate" "0")
8477    (set_attr "mode" "QI")])
8478
8479 (define_insn "*<code>qi_ext_2"
8480   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8481                          (const_int 8)
8482                          (const_int 8))
8483         (any_or:SI
8484           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8485                            (const_int 8)
8486                            (const_int 8))
8487           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8488                            (const_int 8)
8489                            (const_int 8))))
8490    (clobber (reg:CC FLAGS_REG))]
8491   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8492   "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8493   [(set_attr "type" "alu")
8494    (set_attr "length_immediate" "0")
8495    (set_attr "mode" "QI")])
8496
8497 (define_split
8498   [(set (match_operand 0 "register_operand" "")
8499         (any_or (match_operand 1 "register_operand" "")
8500                 (match_operand 2 "const_int_operand" "")))
8501    (clobber (reg:CC FLAGS_REG))]
8502    "reload_completed
8503     && QI_REG_P (operands[0])
8504     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8505     && !(INTVAL (operands[2]) & ~(255 << 8))
8506     && GET_MODE (operands[0]) != QImode"
8507   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8508                    (any_or:SI (zero_extract:SI (match_dup 1)
8509                                                (const_int 8) (const_int 8))
8510                               (match_dup 2)))
8511               (clobber (reg:CC FLAGS_REG))])]
8512   "operands[0] = gen_lowpart (SImode, operands[0]);
8513    operands[1] = gen_lowpart (SImode, operands[1]);
8514    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8515
8516 ;; Since OR can be encoded with sign extended immediate, this is only
8517 ;; profitable when 7th bit is set.
8518 (define_split
8519   [(set (match_operand 0 "register_operand" "")
8520         (any_or (match_operand 1 "general_operand" "")
8521                 (match_operand 2 "const_int_operand" "")))
8522    (clobber (reg:CC FLAGS_REG))]
8523    "reload_completed
8524     && ANY_QI_REG_P (operands[0])
8525     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8526     && !(INTVAL (operands[2]) & ~255)
8527     && (INTVAL (operands[2]) & 128)
8528     && GET_MODE (operands[0]) != QImode"
8529   [(parallel [(set (strict_low_part (match_dup 0))
8530                    (any_or:QI (match_dup 1)
8531                               (match_dup 2)))
8532               (clobber (reg:CC FLAGS_REG))])]
8533   "operands[0] = gen_lowpart (QImode, operands[0]);
8534    operands[1] = gen_lowpart (QImode, operands[1]);
8535    operands[2] = gen_lowpart (QImode, operands[2]);")
8536
8537 (define_expand "xorqi_cc_ext_1"
8538   [(parallel [
8539      (set (reg:CCNO FLAGS_REG)
8540           (compare:CCNO
8541             (xor:SI
8542               (zero_extract:SI
8543                 (match_operand 1 "ext_register_operand" "")
8544                 (const_int 8)
8545                 (const_int 8))
8546               (match_operand:QI 2 "general_operand" ""))
8547             (const_int 0)))
8548      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8549                            (const_int 8)
8550                            (const_int 8))
8551           (xor:SI
8552             (zero_extract:SI
8553              (match_dup 1)
8554              (const_int 8)
8555              (const_int 8))
8556             (match_dup 2)))])])
8557
8558 (define_insn "*xorqi_cc_ext_1_rex64"
8559   [(set (reg FLAGS_REG)
8560         (compare
8561           (xor:SI
8562             (zero_extract:SI
8563               (match_operand 1 "ext_register_operand" "0")
8564               (const_int 8)
8565               (const_int 8))
8566             (match_operand:QI 2 "nonmemory_operand" "Qn"))
8567           (const_int 0)))
8568    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8569                          (const_int 8)
8570                          (const_int 8))
8571         (xor:SI
8572           (zero_extract:SI
8573            (match_dup 1)
8574            (const_int 8)
8575            (const_int 8))
8576           (match_dup 2)))]
8577   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8578   "xor{b}\t{%2, %h0|%h0, %2}"
8579   [(set_attr "type" "alu")
8580    (set_attr "modrm" "1")
8581    (set_attr "mode" "QI")])
8582
8583 (define_insn "*xorqi_cc_ext_1"
8584   [(set (reg FLAGS_REG)
8585         (compare
8586           (xor:SI
8587             (zero_extract:SI
8588               (match_operand 1 "ext_register_operand" "0")
8589               (const_int 8)
8590               (const_int 8))
8591             (match_operand:QI 2 "general_operand" "qmn"))
8592           (const_int 0)))
8593    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8594                          (const_int 8)
8595                          (const_int 8))
8596         (xor:SI
8597           (zero_extract:SI
8598            (match_dup 1)
8599            (const_int 8)
8600            (const_int 8))
8601           (match_dup 2)))]
8602   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8603   "xor{b}\t{%2, %h0|%h0, %2}"
8604   [(set_attr "type" "alu")
8605    (set_attr "modrm" "1")
8606    (set_attr "mode" "QI")])
8607 \f
8608 ;; Negation instructions
8609
8610 (define_expand "neg<mode>2"
8611   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
8612         (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
8613   ""
8614   "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8615
8616 (define_insn_and_split "*neg<dwi>2_doubleword"
8617   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8618         (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8619    (clobber (reg:CC FLAGS_REG))]
8620   "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8621   "#"
8622   "reload_completed"
8623   [(parallel
8624     [(set (reg:CCZ FLAGS_REG)
8625           (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8626      (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8627    (parallel
8628     [(set (match_dup 2)
8629           (plus:DWIH (match_dup 3)
8630                      (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8631                                 (const_int 0))))
8632      (clobber (reg:CC FLAGS_REG))])
8633    (parallel
8634     [(set (match_dup 2)
8635           (neg:DWIH (match_dup 2)))
8636      (clobber (reg:CC FLAGS_REG))])]
8637   "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8638
8639 (define_insn "*neg<mode>2_1"
8640   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8641         (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8642    (clobber (reg:CC FLAGS_REG))]
8643   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8644   "neg{<imodesuffix>}\t%0"
8645   [(set_attr "type" "negnot")
8646    (set_attr "mode" "<MODE>")])
8647
8648 ;; Combine is quite creative about this pattern.
8649 (define_insn "*negsi2_1_zext"
8650   [(set (match_operand:DI 0 "register_operand" "=r")
8651         (lshiftrt:DI
8652           (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8653                              (const_int 32)))
8654         (const_int 32)))
8655    (clobber (reg:CC FLAGS_REG))]
8656   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8657   "neg{l}\t%k0"
8658   [(set_attr "type" "negnot")
8659    (set_attr "mode" "SI")])
8660
8661 ;; The problem with neg is that it does not perform (compare x 0),
8662 ;; it really performs (compare 0 x), which leaves us with the zero
8663 ;; flag being the only useful item.
8664
8665 (define_insn "*neg<mode>2_cmpz"
8666   [(set (reg:CCZ FLAGS_REG)
8667         (compare:CCZ
8668           (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8669                    (const_int 0)))
8670    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8671         (neg:SWI (match_dup 1)))]
8672   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8673   "neg{<imodesuffix>}\t%0"
8674   [(set_attr "type" "negnot")
8675    (set_attr "mode" "<MODE>")])
8676
8677 (define_insn "*negsi2_cmpz_zext"
8678   [(set (reg:CCZ FLAGS_REG)
8679         (compare:CCZ
8680           (lshiftrt:DI
8681             (neg:DI (ashift:DI
8682                       (match_operand:DI 1 "register_operand" "0")
8683                       (const_int 32)))
8684             (const_int 32))
8685           (const_int 0)))
8686    (set (match_operand:DI 0 "register_operand" "=r")
8687         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8688                                         (const_int 32)))
8689                      (const_int 32)))]
8690   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8691   "neg{l}\t%k0"
8692   [(set_attr "type" "negnot")
8693    (set_attr "mode" "SI")])
8694
8695 ;; Changing of sign for FP values is doable using integer unit too.
8696
8697 (define_expand "<code><mode>2"
8698   [(set (match_operand:X87MODEF 0 "register_operand" "")
8699         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
8700   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8701   "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8702
8703 (define_insn "*absneg<mode>2_mixed"
8704   [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8705         (match_operator:MODEF 3 "absneg_operator"
8706           [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8707    (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8708    (clobber (reg:CC FLAGS_REG))]
8709   "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8710   "#")
8711
8712 (define_insn "*absneg<mode>2_sse"
8713   [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8714         (match_operator:MODEF 3 "absneg_operator"
8715           [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8716    (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8717    (clobber (reg:CC FLAGS_REG))]
8718   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8719   "#")
8720
8721 (define_insn "*absneg<mode>2_i387"
8722   [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8723         (match_operator:X87MODEF 3 "absneg_operator"
8724           [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8725    (use (match_operand 2 "" ""))
8726    (clobber (reg:CC FLAGS_REG))]
8727   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8728   "#")
8729
8730 (define_expand "<code>tf2"
8731   [(set (match_operand:TF 0 "register_operand" "")
8732         (absneg:TF (match_operand:TF 1 "register_operand" "")))]
8733   "TARGET_SSE2"
8734   "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8735
8736 (define_insn "*absnegtf2_sse"
8737   [(set (match_operand:TF 0 "register_operand" "=x,x")
8738         (match_operator:TF 3 "absneg_operator"
8739           [(match_operand:TF 1 "register_operand" "0,x")]))
8740    (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8741    (clobber (reg:CC FLAGS_REG))]
8742   "TARGET_SSE2"
8743   "#")
8744
8745 ;; Splitters for fp abs and neg.
8746
8747 (define_split
8748   [(set (match_operand 0 "fp_register_operand" "")
8749         (match_operator 1 "absneg_operator" [(match_dup 0)]))
8750    (use (match_operand 2 "" ""))
8751    (clobber (reg:CC FLAGS_REG))]
8752   "reload_completed"
8753   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8754
8755 (define_split
8756   [(set (match_operand 0 "register_operand" "")
8757         (match_operator 3 "absneg_operator"
8758           [(match_operand 1 "register_operand" "")]))
8759    (use (match_operand 2 "nonimmediate_operand" ""))
8760    (clobber (reg:CC FLAGS_REG))]
8761   "reload_completed && SSE_REG_P (operands[0])"
8762   [(set (match_dup 0) (match_dup 3))]
8763 {
8764   enum machine_mode mode = GET_MODE (operands[0]);
8765   enum machine_mode vmode = GET_MODE (operands[2]);
8766   rtx tmp;
8767
8768   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8769   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8770   if (operands_match_p (operands[0], operands[2]))
8771     {
8772       tmp = operands[1];
8773       operands[1] = operands[2];
8774       operands[2] = tmp;
8775     }
8776   if (GET_CODE (operands[3]) == ABS)
8777     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8778   else
8779     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8780   operands[3] = tmp;
8781 })
8782
8783 (define_split
8784   [(set (match_operand:SF 0 "register_operand" "")
8785         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8786    (use (match_operand:V4SF 2 "" ""))
8787    (clobber (reg:CC FLAGS_REG))]
8788   "reload_completed"
8789   [(parallel [(set (match_dup 0) (match_dup 1))
8790               (clobber (reg:CC FLAGS_REG))])]
8791 {
8792   rtx tmp;
8793   operands[0] = gen_lowpart (SImode, operands[0]);
8794   if (GET_CODE (operands[1]) == ABS)
8795     {
8796       tmp = gen_int_mode (0x7fffffff, SImode);
8797       tmp = gen_rtx_AND (SImode, operands[0], tmp);
8798     }
8799   else
8800     {
8801       tmp = gen_int_mode (0x80000000, SImode);
8802       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8803     }
8804   operands[1] = tmp;
8805 })
8806
8807 (define_split
8808   [(set (match_operand:DF 0 "register_operand" "")
8809         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8810    (use (match_operand 2 "" ""))
8811    (clobber (reg:CC FLAGS_REG))]
8812   "reload_completed"
8813   [(parallel [(set (match_dup 0) (match_dup 1))
8814               (clobber (reg:CC FLAGS_REG))])]
8815 {
8816   rtx tmp;
8817   if (TARGET_64BIT)
8818     {
8819       tmp = gen_lowpart (DImode, operands[0]);
8820       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8821       operands[0] = tmp;
8822
8823       if (GET_CODE (operands[1]) == ABS)
8824         tmp = const0_rtx;
8825       else
8826         tmp = gen_rtx_NOT (DImode, tmp);
8827     }
8828   else
8829     {
8830       operands[0] = gen_highpart (SImode, operands[0]);
8831       if (GET_CODE (operands[1]) == ABS)
8832         {
8833           tmp = gen_int_mode (0x7fffffff, SImode);
8834           tmp = gen_rtx_AND (SImode, operands[0], tmp);
8835         }
8836       else
8837         {
8838           tmp = gen_int_mode (0x80000000, SImode);
8839           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8840         }
8841     }
8842   operands[1] = tmp;
8843 })
8844
8845 (define_split
8846   [(set (match_operand:XF 0 "register_operand" "")
8847         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8848    (use (match_operand 2 "" ""))
8849    (clobber (reg:CC FLAGS_REG))]
8850   "reload_completed"
8851   [(parallel [(set (match_dup 0) (match_dup 1))
8852               (clobber (reg:CC FLAGS_REG))])]
8853 {
8854   rtx tmp;
8855   operands[0] = gen_rtx_REG (SImode,
8856                              true_regnum (operands[0])
8857                              + (TARGET_64BIT ? 1 : 2));
8858   if (GET_CODE (operands[1]) == ABS)
8859     {
8860       tmp = GEN_INT (0x7fff);
8861       tmp = gen_rtx_AND (SImode, operands[0], tmp);
8862     }
8863   else
8864     {
8865       tmp = GEN_INT (0x8000);
8866       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8867     }
8868   operands[1] = tmp;
8869 })
8870
8871 ;; Conditionalize these after reload. If they match before reload, we
8872 ;; lose the clobber and ability to use integer instructions.
8873
8874 (define_insn "*<code><mode>2_1"
8875   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8876         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8877   "TARGET_80387
8878    && (reload_completed
8879        || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8880   "f<absneg_mnemonic>"
8881   [(set_attr "type" "fsgn")
8882    (set_attr "mode" "<MODE>")])
8883
8884 (define_insn "*<code>extendsfdf2"
8885   [(set (match_operand:DF 0 "register_operand" "=f")
8886         (absneg:DF (float_extend:DF
8887                      (match_operand:SF 1 "register_operand" "0"))))]
8888   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8889   "f<absneg_mnemonic>"
8890   [(set_attr "type" "fsgn")
8891    (set_attr "mode" "DF")])
8892
8893 (define_insn "*<code>extendsfxf2"
8894   [(set (match_operand:XF 0 "register_operand" "=f")
8895         (absneg:XF (float_extend:XF
8896                      (match_operand:SF 1 "register_operand" "0"))))]
8897   "TARGET_80387"
8898   "f<absneg_mnemonic>"
8899   [(set_attr "type" "fsgn")
8900    (set_attr "mode" "XF")])
8901
8902 (define_insn "*<code>extenddfxf2"
8903   [(set (match_operand:XF 0 "register_operand" "=f")
8904         (absneg:XF (float_extend:XF
8905                      (match_operand:DF 1 "register_operand" "0"))))]
8906   "TARGET_80387"
8907   "f<absneg_mnemonic>"
8908   [(set_attr "type" "fsgn")
8909    (set_attr "mode" "XF")])
8910
8911 ;; Copysign instructions
8912
8913 (define_mode_iterator CSGNMODE [SF DF TF])
8914 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8915
8916 (define_expand "copysign<mode>3"
8917   [(match_operand:CSGNMODE 0 "register_operand" "")
8918    (match_operand:CSGNMODE 1 "nonmemory_operand" "")
8919    (match_operand:CSGNMODE 2 "register_operand" "")]
8920   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8921    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8922   "ix86_expand_copysign (operands); DONE;")
8923
8924 (define_insn_and_split "copysign<mode>3_const"
8925   [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8926         (unspec:CSGNMODE
8927           [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8928            (match_operand:CSGNMODE 2 "register_operand" "0")
8929            (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8930           UNSPEC_COPYSIGN))]
8931   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8932    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8933   "#"
8934   "&& reload_completed"
8935   [(const_int 0)]
8936   "ix86_split_copysign_const (operands); DONE;")
8937
8938 (define_insn "copysign<mode>3_var"
8939   [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8940         (unspec:CSGNMODE
8941           [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8942            (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8943            (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8944            (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8945           UNSPEC_COPYSIGN))
8946    (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8947   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8948    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8949   "#")
8950
8951 (define_split
8952   [(set (match_operand:CSGNMODE 0 "register_operand" "")
8953         (unspec:CSGNMODE
8954           [(match_operand:CSGNMODE 2 "register_operand" "")
8955            (match_operand:CSGNMODE 3 "register_operand" "")
8956            (match_operand:<CSGNVMODE> 4 "" "")
8957            (match_operand:<CSGNVMODE> 5 "" "")]
8958           UNSPEC_COPYSIGN))
8959    (clobber (match_scratch:<CSGNVMODE> 1 ""))]
8960   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8961     || (TARGET_SSE2 && (<MODE>mode == TFmode)))
8962    && reload_completed"
8963   [(const_int 0)]
8964   "ix86_split_copysign_var (operands); DONE;")
8965 \f
8966 ;; One complement instructions
8967
8968 (define_expand "one_cmpl<mode>2"
8969   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8970         (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
8971   ""
8972   "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8973
8974 (define_insn "*one_cmpl<mode>2_1"
8975   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8976         (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8977   "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8978   "not{<imodesuffix>}\t%0"
8979   [(set_attr "type" "negnot")
8980    (set_attr "mode" "<MODE>")])
8981
8982 ;; %%% Potential partial reg stall on alternative 1.  What to do?
8983 (define_insn "*one_cmplqi2_1"
8984   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8985         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8986   "ix86_unary_operator_ok (NOT, QImode, operands)"
8987   "@
8988    not{b}\t%0
8989    not{l}\t%k0"
8990   [(set_attr "type" "negnot")
8991    (set_attr "mode" "QI,SI")])
8992
8993 ;; ??? Currently never generated - xor is used instead.
8994 (define_insn "*one_cmplsi2_1_zext"
8995   [(set (match_operand:DI 0 "register_operand" "=r")
8996         (zero_extend:DI
8997           (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8998   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8999   "not{l}\t%k0"
9000   [(set_attr "type" "negnot")
9001    (set_attr "mode" "SI")])
9002
9003 (define_insn "*one_cmpl<mode>2_2"
9004   [(set (reg FLAGS_REG)
9005         (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9006                  (const_int 0)))
9007    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9008         (not:SWI (match_dup 1)))]
9009   "ix86_match_ccmode (insn, CCNOmode)
9010    && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9011   "#"
9012   [(set_attr "type" "alu1")
9013    (set_attr "mode" "<MODE>")])
9014
9015 (define_split
9016   [(set (match_operand 0 "flags_reg_operand" "")
9017         (match_operator 2 "compare_operator"
9018           [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
9019            (const_int 0)]))
9020    (set (match_operand:SWI 1 "nonimmediate_operand" "")
9021         (not:SWI (match_dup 3)))]
9022   "ix86_match_ccmode (insn, CCNOmode)"
9023   [(parallel [(set (match_dup 0)
9024                    (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9025                                     (const_int 0)]))
9026               (set (match_dup 1)
9027                    (xor:SWI (match_dup 3) (const_int -1)))])])
9028
9029 ;; ??? Currently never generated - xor is used instead.
9030 (define_insn "*one_cmplsi2_2_zext"
9031   [(set (reg FLAGS_REG)
9032         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9033                  (const_int 0)))
9034    (set (match_operand:DI 0 "register_operand" "=r")
9035         (zero_extend:DI (not:SI (match_dup 1))))]
9036   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9037    && ix86_unary_operator_ok (NOT, SImode, operands)"
9038   "#"
9039   [(set_attr "type" "alu1")
9040    (set_attr "mode" "SI")])
9041
9042 (define_split
9043   [(set (match_operand 0 "flags_reg_operand" "")
9044         (match_operator 2 "compare_operator"
9045           [(not:SI (match_operand:SI 3 "register_operand" ""))
9046            (const_int 0)]))
9047    (set (match_operand:DI 1 "register_operand" "")
9048         (zero_extend:DI (not:SI (match_dup 3))))]
9049   "ix86_match_ccmode (insn, CCNOmode)"
9050   [(parallel [(set (match_dup 0)
9051                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9052                                     (const_int 0)]))
9053               (set (match_dup 1)
9054                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
9055 \f
9056 ;; Shift instructions
9057
9058 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9059 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
9060 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9061 ;; from the assembler input.
9062 ;;
9063 ;; This instruction shifts the target reg/mem as usual, but instead of
9064 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
9065 ;; is a left shift double, bits are taken from the high order bits of
9066 ;; reg, else if the insn is a shift right double, bits are taken from the
9067 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
9068 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9069 ;;
9070 ;; Since sh[lr]d does not change the `reg' operand, that is done
9071 ;; separately, making all shifts emit pairs of shift double and normal
9072 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
9073 ;; support a 63 bit shift, each shift where the count is in a reg expands
9074 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9075 ;;
9076 ;; If the shift count is a constant, we need never emit more than one
9077 ;; shift pair, instead using moves and sign extension for counts greater
9078 ;; than 31.
9079
9080 (define_expand "ashl<mode>3"
9081   [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9082         (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
9083                       (match_operand:QI 2 "nonmemory_operand" "")))]
9084   ""
9085   "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9086
9087 (define_insn "*ashl<mode>3_doubleword"
9088   [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9089         (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9090                     (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9091    (clobber (reg:CC FLAGS_REG))]
9092   ""
9093   "#"
9094   [(set_attr "type" "multi")])
9095
9096 (define_split
9097   [(set (match_operand:DWI 0 "register_operand" "")
9098         (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
9099                     (match_operand:QI 2 "nonmemory_operand" "")))
9100    (clobber (reg:CC FLAGS_REG))]
9101   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9102   [(const_int 0)]
9103   "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9104
9105 ;; By default we don't ask for a scratch register, because when DWImode
9106 ;; values are manipulated, registers are already at a premium.  But if
9107 ;; we have one handy, we won't turn it away.
9108
9109 (define_peephole2
9110   [(match_scratch:DWIH 3 "r")
9111    (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9112                    (ashift:<DWI>
9113                      (match_operand:<DWI> 1 "nonmemory_operand" "")
9114                      (match_operand:QI 2 "nonmemory_operand" "")))
9115               (clobber (reg:CC FLAGS_REG))])
9116    (match_dup 3)]
9117   "TARGET_CMOVE"
9118   [(const_int 0)]
9119   "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9120
9121 (define_insn "x86_64_shld"
9122   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9123         (ior:DI (ashift:DI (match_dup 0)
9124                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
9125                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9126                   (minus:QI (const_int 64) (match_dup 2)))))
9127    (clobber (reg:CC FLAGS_REG))]
9128   "TARGET_64BIT"
9129   "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9130   [(set_attr "type" "ishift")
9131    (set_attr "prefix_0f" "1")
9132    (set_attr "mode" "DI")
9133    (set_attr "athlon_decode" "vector")
9134    (set_attr "amdfam10_decode" "vector")
9135    (set_attr "bdver1_decode" "vector")])
9136
9137 (define_insn "x86_shld"
9138   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9139         (ior:SI (ashift:SI (match_dup 0)
9140                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
9141                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9142                   (minus:QI (const_int 32) (match_dup 2)))))
9143    (clobber (reg:CC FLAGS_REG))]
9144   ""
9145   "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9146   [(set_attr "type" "ishift")
9147    (set_attr "prefix_0f" "1")
9148    (set_attr "mode" "SI")
9149    (set_attr "pent_pair" "np")
9150    (set_attr "athlon_decode" "vector")
9151    (set_attr "amdfam10_decode" "vector")
9152    (set_attr "bdver1_decode" "vector")])
9153
9154 (define_expand "x86_shift<mode>_adj_1"
9155   [(set (reg:CCZ FLAGS_REG)
9156         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
9157                              (match_dup 4))
9158                      (const_int 0)))
9159    (set (match_operand:SWI48 0 "register_operand" "")
9160         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9161                             (match_operand:SWI48 1 "register_operand" "")
9162                             (match_dup 0)))
9163    (set (match_dup 1)
9164         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9165                             (match_operand:SWI48 3 "register_operand" "r")
9166                             (match_dup 1)))]
9167   "TARGET_CMOVE"
9168   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9169
9170 (define_expand "x86_shift<mode>_adj_2"
9171   [(use (match_operand:SWI48 0 "register_operand" ""))
9172    (use (match_operand:SWI48 1 "register_operand" ""))
9173    (use (match_operand:QI 2 "register_operand" ""))]
9174   ""
9175 {
9176   rtx label = gen_label_rtx ();
9177   rtx tmp;
9178
9179   emit_insn (gen_testqi_ccz_1 (operands[2],
9180                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9181
9182   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9183   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9184   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9185                               gen_rtx_LABEL_REF (VOIDmode, label),
9186                               pc_rtx);
9187   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9188   JUMP_LABEL (tmp) = label;
9189
9190   emit_move_insn (operands[0], operands[1]);
9191   ix86_expand_clear (operands[1]);
9192
9193   emit_label (label);
9194   LABEL_NUSES (label) = 1;
9195
9196   DONE;
9197 })
9198
9199 ;; Avoid useless masking of count operand.
9200 (define_insn_and_split "*ashl<mode>3_mask"
9201   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9202         (ashift:SWI48
9203           (match_operand:SWI48 1 "nonimmediate_operand" "0")
9204           (subreg:QI
9205             (and:SI
9206               (match_operand:SI 2 "nonimmediate_operand" "c")
9207               (match_operand:SI 3 "const_int_operand" "n")) 0)))
9208    (clobber (reg:CC FLAGS_REG))]
9209   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9210    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9211       == GET_MODE_BITSIZE (<MODE>mode)-1"
9212   "#"
9213   "&& 1"
9214   [(parallel [(set (match_dup 0)
9215                    (ashift:SWI48 (match_dup 1) (match_dup 2)))
9216               (clobber (reg:CC FLAGS_REG))])]
9217 {
9218   if (can_create_pseudo_p ())
9219     operands [2] = force_reg (SImode, operands[2]);
9220
9221   operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9222 }
9223   [(set_attr "type" "ishift")
9224    (set_attr "mode" "<MODE>")])
9225
9226 (define_insn "*ashl<mode>3_1"
9227   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9228         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l")
9229                       (match_operand:QI 2 "nonmemory_operand" "c<S>,M")))
9230    (clobber (reg:CC FLAGS_REG))]
9231   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9232 {
9233   switch (get_attr_type (insn))
9234     {
9235     case TYPE_LEA:
9236       return "#";
9237
9238     case TYPE_ALU:
9239       gcc_assert (operands[2] == const1_rtx);
9240       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9241       return "add{<imodesuffix>}\t%0, %0";
9242
9243     default:
9244       if (operands[2] == const1_rtx
9245           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9246         return "sal{<imodesuffix>}\t%0";
9247       else
9248         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9249     }
9250 }
9251   [(set (attr "type")
9252      (cond [(eq_attr "alternative" "1")
9253               (const_string "lea")
9254             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9255                           (const_int 0))
9256                       (match_operand 0 "register_operand" ""))
9257                  (match_operand 2 "const1_operand" ""))
9258               (const_string "alu")
9259            ]
9260            (const_string "ishift")))
9261    (set (attr "length_immediate")
9262      (if_then_else
9263        (ior (eq_attr "type" "alu")
9264             (and (eq_attr "type" "ishift")
9265                  (and (match_operand 2 "const1_operand" "")
9266                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9267                           (const_int 0)))))
9268        (const_string "0")
9269        (const_string "*")))
9270    (set_attr "mode" "<MODE>")])
9271
9272 (define_insn "*ashlsi3_1_zext"
9273   [(set (match_operand:DI 0 "register_operand" "=r,r")
9274         (zero_extend:DI
9275           (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
9276                      (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
9277    (clobber (reg:CC FLAGS_REG))]
9278   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9279 {
9280   switch (get_attr_type (insn))
9281     {
9282     case TYPE_LEA:
9283       return "#";
9284
9285     case TYPE_ALU:
9286       gcc_assert (operands[2] == const1_rtx);
9287       return "add{l}\t%k0, %k0";
9288
9289     default:
9290       if (operands[2] == const1_rtx
9291           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9292         return "sal{l}\t%k0";
9293       else
9294         return "sal{l}\t{%2, %k0|%k0, %2}";
9295     }
9296 }
9297   [(set (attr "type")
9298      (cond [(eq_attr "alternative" "1")
9299               (const_string "lea")
9300             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9301                      (const_int 0))
9302                  (match_operand 2 "const1_operand" ""))
9303               (const_string "alu")
9304            ]
9305            (const_string "ishift")))
9306    (set (attr "length_immediate")
9307      (if_then_else
9308        (ior (eq_attr "type" "alu")
9309             (and (eq_attr "type" "ishift")
9310                  (and (match_operand 2 "const1_operand" "")
9311                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9312                           (const_int 0)))))
9313        (const_string "0")
9314        (const_string "*")))
9315    (set_attr "mode" "SI")])
9316
9317 (define_insn "*ashlhi3_1"
9318   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9319         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
9320                    (match_operand:QI 2 "nonmemory_operand" "cI")))
9321    (clobber (reg:CC FLAGS_REG))]
9322   "TARGET_PARTIAL_REG_STALL
9323    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9324 {
9325   switch (get_attr_type (insn))
9326     {
9327     case TYPE_ALU:
9328       gcc_assert (operands[2] == const1_rtx);
9329       return "add{w}\t%0, %0";
9330
9331     default:
9332       if (operands[2] == const1_rtx
9333           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9334         return "sal{w}\t%0";
9335       else
9336         return "sal{w}\t{%2, %0|%0, %2}";
9337     }
9338 }
9339   [(set (attr "type")
9340      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9341                           (const_int 0))
9342                       (match_operand 0 "register_operand" ""))
9343                  (match_operand 2 "const1_operand" ""))
9344               (const_string "alu")
9345            ]
9346            (const_string "ishift")))
9347    (set (attr "length_immediate")
9348      (if_then_else
9349        (ior (eq_attr "type" "alu")
9350             (and (eq_attr "type" "ishift")
9351                  (and (match_operand 2 "const1_operand" "")
9352                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9353                           (const_int 0)))))
9354        (const_string "0")
9355        (const_string "*")))
9356    (set_attr "mode" "HI")])
9357
9358 (define_insn "*ashlhi3_1_lea"
9359   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
9360         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9361                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9362    (clobber (reg:CC FLAGS_REG))]
9363   "!TARGET_PARTIAL_REG_STALL
9364    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9365 {
9366   switch (get_attr_type (insn))
9367     {
9368     case TYPE_LEA:
9369       return "#";
9370
9371     case TYPE_ALU:
9372       gcc_assert (operands[2] == const1_rtx);
9373       return "add{w}\t%0, %0";
9374
9375     default:
9376       if (operands[2] == const1_rtx
9377           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9378         return "sal{w}\t%0";
9379       else
9380         return "sal{w}\t{%2, %0|%0, %2}";
9381     }
9382 }
9383   [(set (attr "type")
9384      (cond [(eq_attr "alternative" "1")
9385               (const_string "lea")
9386             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9387                           (const_int 0))
9388                       (match_operand 0 "register_operand" ""))
9389                  (match_operand 2 "const1_operand" ""))
9390               (const_string "alu")
9391            ]
9392            (const_string "ishift")))
9393    (set (attr "length_immediate")
9394      (if_then_else
9395        (ior (eq_attr "type" "alu")
9396             (and (eq_attr "type" "ishift")
9397                  (and (match_operand 2 "const1_operand" "")
9398                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9399                           (const_int 0)))))
9400        (const_string "0")
9401        (const_string "*")))
9402    (set_attr "mode" "HI,SI")])
9403
9404 (define_insn "*ashlqi3_1"
9405   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9406         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
9407                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
9408    (clobber (reg:CC FLAGS_REG))]
9409   "TARGET_PARTIAL_REG_STALL
9410    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9411 {
9412   switch (get_attr_type (insn))
9413     {
9414     case TYPE_ALU:
9415       gcc_assert (operands[2] == const1_rtx);
9416       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9417         return "add{l}\t%k0, %k0";
9418       else
9419         return "add{b}\t%0, %0";
9420
9421     default:
9422       if (operands[2] == const1_rtx
9423           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9424         {
9425           if (get_attr_mode (insn) == MODE_SI)
9426             return "sal{l}\t%k0";
9427           else
9428             return "sal{b}\t%0";
9429         }
9430       else
9431         {
9432           if (get_attr_mode (insn) == MODE_SI)
9433             return "sal{l}\t{%2, %k0|%k0, %2}";
9434           else
9435             return "sal{b}\t{%2, %0|%0, %2}";
9436         }
9437     }
9438 }
9439   [(set (attr "type")
9440      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9441                           (const_int 0))
9442                       (match_operand 0 "register_operand" ""))
9443                  (match_operand 2 "const1_operand" ""))
9444               (const_string "alu")
9445            ]
9446            (const_string "ishift")))
9447    (set (attr "length_immediate")
9448      (if_then_else
9449        (ior (eq_attr "type" "alu")
9450             (and (eq_attr "type" "ishift")
9451                  (and (match_operand 2 "const1_operand" "")
9452                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9453                           (const_int 0)))))
9454        (const_string "0")
9455        (const_string "*")))
9456    (set_attr "mode" "QI,SI")])
9457
9458 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9459 (define_insn "*ashlqi3_1_lea"
9460   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
9461         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9462                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9463    (clobber (reg:CC FLAGS_REG))]
9464   "!TARGET_PARTIAL_REG_STALL
9465    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9466 {
9467   switch (get_attr_type (insn))
9468     {
9469     case TYPE_LEA:
9470       return "#";
9471
9472     case TYPE_ALU:
9473       gcc_assert (operands[2] == const1_rtx);
9474       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9475         return "add{l}\t%k0, %k0";
9476       else
9477         return "add{b}\t%0, %0";
9478
9479     default:
9480       if (operands[2] == const1_rtx
9481           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9482         {
9483           if (get_attr_mode (insn) == MODE_SI)
9484             return "sal{l}\t%k0";
9485           else
9486             return "sal{b}\t%0";
9487         }
9488       else
9489         {
9490           if (get_attr_mode (insn) == MODE_SI)
9491             return "sal{l}\t{%2, %k0|%k0, %2}";
9492           else
9493             return "sal{b}\t{%2, %0|%0, %2}";
9494         }
9495     }
9496 }
9497   [(set (attr "type")
9498      (cond [(eq_attr "alternative" "2")
9499               (const_string "lea")
9500             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9501                           (const_int 0))
9502                       (match_operand 0 "register_operand" ""))
9503                  (match_operand 2 "const1_operand" ""))
9504               (const_string "alu")
9505            ]
9506            (const_string "ishift")))
9507    (set (attr "length_immediate")
9508      (if_then_else
9509        (ior (eq_attr "type" "alu")
9510             (and (eq_attr "type" "ishift")
9511                  (and (match_operand 2 "const1_operand" "")
9512                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9513                           (const_int 0)))))
9514        (const_string "0")
9515        (const_string "*")))
9516    (set_attr "mode" "QI,SI,SI")])
9517
9518 (define_insn "*ashlqi3_1_slp"
9519   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9520         (ashift:QI (match_dup 0)
9521                    (match_operand:QI 1 "nonmemory_operand" "cI")))
9522    (clobber (reg:CC FLAGS_REG))]
9523   "(optimize_function_for_size_p (cfun)
9524     || !TARGET_PARTIAL_FLAG_REG_STALL
9525     || (operands[1] == const1_rtx
9526         && (TARGET_SHIFT1
9527             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9528 {
9529   switch (get_attr_type (insn))
9530     {
9531     case TYPE_ALU:
9532       gcc_assert (operands[1] == const1_rtx);
9533       return "add{b}\t%0, %0";
9534
9535     default:
9536       if (operands[1] == const1_rtx
9537           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9538         return "sal{b}\t%0";
9539       else
9540         return "sal{b}\t{%1, %0|%0, %1}";
9541     }
9542 }
9543   [(set (attr "type")
9544      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9545                           (const_int 0))
9546                       (match_operand 0 "register_operand" ""))
9547                  (match_operand 1 "const1_operand" ""))
9548               (const_string "alu")
9549            ]
9550            (const_string "ishift1")))
9551    (set (attr "length_immediate")
9552      (if_then_else
9553        (ior (eq_attr "type" "alu")
9554             (and (eq_attr "type" "ishift1")
9555                  (and (match_operand 1 "const1_operand" "")
9556                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9557                           (const_int 0)))))
9558        (const_string "0")
9559        (const_string "*")))
9560    (set_attr "mode" "QI")])
9561
9562 ;; Convert lea to the lea pattern to avoid flags dependency.
9563 (define_split
9564   [(set (match_operand 0 "register_operand" "")
9565         (ashift (match_operand 1 "index_register_operand" "")
9566                 (match_operand:QI 2 "const_int_operand" "")))
9567    (clobber (reg:CC FLAGS_REG))]
9568   "reload_completed
9569    && true_regnum (operands[0]) != true_regnum (operands[1])"
9570   [(const_int 0)]
9571 {
9572   rtx pat;
9573   enum machine_mode mode = GET_MODE (operands[0]);
9574
9575   if (mode != Pmode)
9576     operands[1] = gen_lowpart (Pmode, operands[1]);
9577   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
9578
9579   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
9580
9581   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9582     operands[0] = gen_lowpart (SImode, operands[0]);
9583
9584   if (TARGET_64BIT && mode != Pmode)
9585     pat = gen_rtx_SUBREG (SImode, pat, 0);
9586
9587   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9588   DONE;
9589 })
9590
9591 ;; Convert lea to the lea pattern to avoid flags dependency.
9592 (define_split
9593   [(set (match_operand:DI 0 "register_operand" "")
9594         (zero_extend:DI
9595           (ashift:SI (match_operand:SI 1 "index_register_operand" "")
9596                      (match_operand:QI 2 "const_int_operand" ""))))
9597    (clobber (reg:CC FLAGS_REG))]
9598   "TARGET_64BIT && reload_completed
9599    && true_regnum (operands[0]) != true_regnum (operands[1])"
9600   [(set (match_dup 0)
9601         (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9602 {
9603   operands[1] = gen_lowpart (DImode, operands[1]);
9604   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9605 })
9606
9607 ;; This pattern can't accept a variable shift count, since shifts by
9608 ;; zero don't affect the flags.  We assume that shifts by constant
9609 ;; zero are optimized away.
9610 (define_insn "*ashl<mode>3_cmp"
9611   [(set (reg FLAGS_REG)
9612         (compare
9613           (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9614                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9615           (const_int 0)))
9616    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9617         (ashift:SWI (match_dup 1) (match_dup 2)))]
9618   "(optimize_function_for_size_p (cfun)
9619     || !TARGET_PARTIAL_FLAG_REG_STALL
9620     || (operands[2] == const1_rtx
9621         && (TARGET_SHIFT1
9622             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9623    && ix86_match_ccmode (insn, CCGOCmode)
9624    && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9625 {
9626   switch (get_attr_type (insn))
9627     {
9628     case TYPE_ALU:
9629       gcc_assert (operands[2] == const1_rtx);
9630       return "add{<imodesuffix>}\t%0, %0";
9631
9632     default:
9633       if (operands[2] == const1_rtx
9634           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9635         return "sal{<imodesuffix>}\t%0";
9636       else
9637         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9638     }
9639 }
9640   [(set (attr "type")
9641      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9642                           (const_int 0))
9643                       (match_operand 0 "register_operand" ""))
9644                  (match_operand 2 "const1_operand" ""))
9645               (const_string "alu")
9646            ]
9647            (const_string "ishift")))
9648    (set (attr "length_immediate")
9649      (if_then_else
9650        (ior (eq_attr "type" "alu")
9651             (and (eq_attr "type" "ishift")
9652                  (and (match_operand 2 "const1_operand" "")
9653                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9654                           (const_int 0)))))
9655        (const_string "0")
9656        (const_string "*")))
9657    (set_attr "mode" "<MODE>")])
9658
9659 (define_insn "*ashlsi3_cmp_zext"
9660   [(set (reg FLAGS_REG)
9661         (compare
9662           (ashift:SI (match_operand:SI 1 "register_operand" "0")
9663                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
9664           (const_int 0)))
9665    (set (match_operand:DI 0 "register_operand" "=r")
9666         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9667   "TARGET_64BIT
9668    && (optimize_function_for_size_p (cfun)
9669        || !TARGET_PARTIAL_FLAG_REG_STALL
9670        || (operands[2] == const1_rtx
9671            && (TARGET_SHIFT1
9672                || TARGET_DOUBLE_WITH_ADD)))
9673    && ix86_match_ccmode (insn, CCGOCmode)
9674    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9675 {
9676   switch (get_attr_type (insn))
9677     {
9678     case TYPE_ALU:
9679       gcc_assert (operands[2] == const1_rtx);
9680       return "add{l}\t%k0, %k0";
9681
9682     default:
9683       if (operands[2] == const1_rtx
9684           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9685         return "sal{l}\t%k0";
9686       else
9687         return "sal{l}\t{%2, %k0|%k0, %2}";
9688     }
9689 }
9690   [(set (attr "type")
9691      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9692                      (const_int 0))
9693                  (match_operand 2 "const1_operand" ""))
9694               (const_string "alu")
9695            ]
9696            (const_string "ishift")))
9697    (set (attr "length_immediate")
9698      (if_then_else
9699        (ior (eq_attr "type" "alu")
9700             (and (eq_attr "type" "ishift")
9701                  (and (match_operand 2 "const1_operand" "")
9702                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9703                           (const_int 0)))))
9704        (const_string "0")
9705        (const_string "*")))
9706    (set_attr "mode" "SI")])
9707
9708 (define_insn "*ashl<mode>3_cconly"
9709   [(set (reg FLAGS_REG)
9710         (compare
9711           (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9712                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9713           (const_int 0)))
9714    (clobber (match_scratch:SWI 0 "=<r>"))]
9715   "(optimize_function_for_size_p (cfun)
9716     || !TARGET_PARTIAL_FLAG_REG_STALL
9717     || (operands[2] == const1_rtx
9718         && (TARGET_SHIFT1
9719             || TARGET_DOUBLE_WITH_ADD)))
9720    && ix86_match_ccmode (insn, CCGOCmode)
9721    && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9722 {
9723   switch (get_attr_type (insn))
9724     {
9725     case TYPE_ALU:
9726       gcc_assert (operands[2] == const1_rtx);
9727       return "add{<imodesuffix>}\t%0, %0";
9728
9729     default:
9730       if (operands[2] == const1_rtx
9731           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9732         return "sal{<imodesuffix>}\t%0";
9733       else
9734         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9735     }
9736 }
9737   [(set (attr "type")
9738      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9739                           (const_int 0))
9740                       (match_operand 0 "register_operand" ""))
9741                  (match_operand 2 "const1_operand" ""))
9742               (const_string "alu")
9743            ]
9744            (const_string "ishift")))
9745    (set (attr "length_immediate")
9746      (if_then_else
9747        (ior (eq_attr "type" "alu")
9748             (and (eq_attr "type" "ishift")
9749                  (and (match_operand 2 "const1_operand" "")
9750                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9751                           (const_int 0)))))
9752        (const_string "0")
9753        (const_string "*")))
9754    (set_attr "mode" "<MODE>")])
9755
9756 ;; See comment above `ashl<mode>3' about how this works.
9757
9758 (define_expand "<shiftrt_insn><mode>3"
9759   [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9760         (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
9761                            (match_operand:QI 2 "nonmemory_operand" "")))]
9762   ""
9763   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9764
9765 ;; Avoid useless masking of count operand.
9766 (define_insn_and_split "*<shiftrt_insn><mode>3_mask"
9767   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9768         (any_shiftrt:SWI48
9769           (match_operand:SWI48 1 "nonimmediate_operand" "0")
9770           (subreg:QI
9771             (and:SI
9772               (match_operand:SI 2 "nonimmediate_operand" "c")
9773               (match_operand:SI 3 "const_int_operand" "n")) 0)))
9774    (clobber (reg:CC FLAGS_REG))]
9775   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9776    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9777       == GET_MODE_BITSIZE (<MODE>mode)-1"
9778   "#"
9779   "&& 1"
9780   [(parallel [(set (match_dup 0)
9781                    (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))
9782               (clobber (reg:CC FLAGS_REG))])]
9783 {
9784   if (can_create_pseudo_p ())
9785     operands [2] = force_reg (SImode, operands[2]);
9786
9787   operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9788 }
9789   [(set_attr "type" "ishift")
9790    (set_attr "mode" "<MODE>")])
9791
9792 (define_insn_and_split "*<shiftrt_insn><mode>3_doubleword"
9793   [(set (match_operand:DWI 0 "register_operand" "=r")
9794         (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9795                          (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9796    (clobber (reg:CC FLAGS_REG))]
9797   ""
9798   "#"
9799   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9800   [(const_int 0)]
9801   "ix86_split_<shiftrt_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9802   [(set_attr "type" "multi")])
9803
9804 ;; By default we don't ask for a scratch register, because when DWImode
9805 ;; values are manipulated, registers are already at a premium.  But if
9806 ;; we have one handy, we won't turn it away.
9807
9808 (define_peephole2
9809   [(match_scratch:DWIH 3 "r")
9810    (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9811                    (any_shiftrt:<DWI>
9812                      (match_operand:<DWI> 1 "register_operand" "")
9813                      (match_operand:QI 2 "nonmemory_operand" "")))
9814               (clobber (reg:CC FLAGS_REG))])
9815    (match_dup 3)]
9816   "TARGET_CMOVE"
9817   [(const_int 0)]
9818   "ix86_split_<shiftrt_insn> (operands, operands[3], <DWI>mode); DONE;")
9819
9820 (define_insn "x86_64_shrd"
9821   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9822         (ior:DI (ashiftrt:DI (match_dup 0)
9823                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
9824                 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9825                   (minus:QI (const_int 64) (match_dup 2)))))
9826    (clobber (reg:CC FLAGS_REG))]
9827   "TARGET_64BIT"
9828   "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9829   [(set_attr "type" "ishift")
9830    (set_attr "prefix_0f" "1")
9831    (set_attr "mode" "DI")
9832    (set_attr "athlon_decode" "vector")
9833    (set_attr "amdfam10_decode" "vector")
9834    (set_attr "bdver1_decode" "vector")])
9835
9836 (define_insn "x86_shrd"
9837   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9838         (ior:SI (ashiftrt:SI (match_dup 0)
9839                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
9840                 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9841                   (minus:QI (const_int 32) (match_dup 2)))))
9842    (clobber (reg:CC FLAGS_REG))]
9843   ""
9844   "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9845   [(set_attr "type" "ishift")
9846    (set_attr "prefix_0f" "1")
9847    (set_attr "mode" "SI")
9848    (set_attr "pent_pair" "np")
9849    (set_attr "athlon_decode" "vector")
9850    (set_attr "amdfam10_decode" "vector")
9851    (set_attr "bdver1_decode" "vector")])
9852
9853 (define_insn "ashrdi3_cvt"
9854   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9855         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9856                      (match_operand:QI 2 "const_int_operand" "")))
9857    (clobber (reg:CC FLAGS_REG))]
9858   "TARGET_64BIT && INTVAL (operands[2]) == 63
9859    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9860    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9861   "@
9862    {cqto|cqo}
9863    sar{q}\t{%2, %0|%0, %2}"
9864   [(set_attr "type" "imovx,ishift")
9865    (set_attr "prefix_0f" "0,*")
9866    (set_attr "length_immediate" "0,*")
9867    (set_attr "modrm" "0,1")
9868    (set_attr "mode" "DI")])
9869
9870 (define_insn "ashrsi3_cvt"
9871   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9872         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9873                      (match_operand:QI 2 "const_int_operand" "")))
9874    (clobber (reg:CC FLAGS_REG))]
9875   "INTVAL (operands[2]) == 31
9876    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9877    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9878   "@
9879    {cltd|cdq}
9880    sar{l}\t{%2, %0|%0, %2}"
9881   [(set_attr "type" "imovx,ishift")
9882    (set_attr "prefix_0f" "0,*")
9883    (set_attr "length_immediate" "0,*")
9884    (set_attr "modrm" "0,1")
9885    (set_attr "mode" "SI")])
9886
9887 (define_insn "*ashrsi3_cvt_zext"
9888   [(set (match_operand:DI 0 "register_operand" "=*d,r")
9889         (zero_extend:DI
9890           (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9891                        (match_operand:QI 2 "const_int_operand" ""))))
9892    (clobber (reg:CC FLAGS_REG))]
9893   "TARGET_64BIT && INTVAL (operands[2]) == 31
9894    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9895    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9896   "@
9897    {cltd|cdq}
9898    sar{l}\t{%2, %k0|%k0, %2}"
9899   [(set_attr "type" "imovx,ishift")
9900    (set_attr "prefix_0f" "0,*")
9901    (set_attr "length_immediate" "0,*")
9902    (set_attr "modrm" "0,1")
9903    (set_attr "mode" "SI")])
9904
9905 (define_expand "x86_shift<mode>_adj_3"
9906   [(use (match_operand:SWI48 0 "register_operand" ""))
9907    (use (match_operand:SWI48 1 "register_operand" ""))
9908    (use (match_operand:QI 2 "register_operand" ""))]
9909   ""
9910 {
9911   rtx label = gen_label_rtx ();
9912   rtx tmp;
9913
9914   emit_insn (gen_testqi_ccz_1 (operands[2],
9915                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9916
9917   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9918   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9919   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9920                               gen_rtx_LABEL_REF (VOIDmode, label),
9921                               pc_rtx);
9922   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9923   JUMP_LABEL (tmp) = label;
9924
9925   emit_move_insn (operands[0], operands[1]);
9926   emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9927                                   GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9928   emit_label (label);
9929   LABEL_NUSES (label) = 1;
9930
9931   DONE;
9932 })
9933
9934 (define_insn "*<shiftrt_insn><mode>3_1"
9935   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9936         (any_shiftrt:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9937                          (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9938    (clobber (reg:CC FLAGS_REG))]
9939   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9940 {
9941   if (operands[2] == const1_rtx
9942       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9943     return "<shiftrt>{<imodesuffix>}\t%0";
9944   else
9945     return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9946 }
9947   [(set_attr "type" "ishift")
9948    (set (attr "length_immediate")
9949      (if_then_else
9950        (and (match_operand 2 "const1_operand" "")
9951             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9952                 (const_int 0)))
9953        (const_string "0")
9954        (const_string "*")))
9955    (set_attr "mode" "<MODE>")])
9956
9957 (define_insn "*<shiftrt_insn>si3_1_zext"
9958   [(set (match_operand:DI 0 "register_operand" "=r")
9959         (zero_extend:DI
9960           (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9961                           (match_operand:QI 2 "nonmemory_operand" "cI"))))
9962    (clobber (reg:CC FLAGS_REG))]
9963   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9964 {
9965   if (operands[2] == const1_rtx
9966       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9967     return "<shiftrt>{l}\t%k0";
9968   else
9969     return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
9970 }
9971   [(set_attr "type" "ishift")
9972    (set (attr "length_immediate")
9973      (if_then_else
9974        (and (match_operand 2 "const1_operand" "")
9975             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9976                 (const_int 0)))
9977        (const_string "0")
9978        (const_string "*")))
9979    (set_attr "mode" "SI")])
9980
9981 (define_insn "*<shiftrt_insn>qi3_1_slp"
9982   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9983         (any_shiftrt:QI (match_dup 0)
9984                         (match_operand:QI 1 "nonmemory_operand" "cI")))
9985    (clobber (reg:CC FLAGS_REG))]
9986   "(optimize_function_for_size_p (cfun)
9987     || !TARGET_PARTIAL_REG_STALL
9988     || (operands[1] == const1_rtx
9989         && TARGET_SHIFT1))"
9990 {
9991   if (operands[1] == const1_rtx
9992       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9993     return "<shiftrt>{b}\t%0";
9994   else
9995     return "<shiftrt>{b}\t{%1, %0|%0, %1}";
9996 }
9997   [(set_attr "type" "ishift1")
9998    (set (attr "length_immediate")
9999      (if_then_else
10000        (and (match_operand 1 "const1_operand" "")
10001             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10002                 (const_int 0)))
10003        (const_string "0")
10004        (const_string "*")))
10005    (set_attr "mode" "QI")])
10006
10007 ;; This pattern can't accept a variable shift count, since shifts by
10008 ;; zero don't affect the flags.  We assume that shifts by constant
10009 ;; zero are optimized away.
10010 (define_insn "*<shiftrt_insn><mode>3_cmp"
10011   [(set (reg FLAGS_REG)
10012         (compare
10013           (any_shiftrt:SWI
10014             (match_operand:SWI 1 "nonimmediate_operand" "0")
10015             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10016           (const_int 0)))
10017    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10018         (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
10019   "(optimize_function_for_size_p (cfun)
10020     || !TARGET_PARTIAL_FLAG_REG_STALL
10021     || (operands[2] == const1_rtx
10022         && TARGET_SHIFT1))
10023    && ix86_match_ccmode (insn, CCGOCmode)
10024    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10025 {
10026   if (operands[2] == const1_rtx
10027       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10028     return "<shiftrt>{<imodesuffix>}\t%0";
10029   else
10030     return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
10031 }
10032   [(set_attr "type" "ishift")
10033    (set (attr "length_immediate")
10034      (if_then_else
10035        (and (match_operand 2 "const1_operand" "")
10036             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10037                 (const_int 0)))
10038        (const_string "0")
10039        (const_string "*")))
10040    (set_attr "mode" "<MODE>")])
10041
10042 (define_insn "*<shiftrt_insn>si3_cmp_zext"
10043   [(set (reg FLAGS_REG)
10044         (compare
10045           (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10046                           (match_operand:QI 2 "const_1_to_31_operand" "I"))
10047           (const_int 0)))
10048    (set (match_operand:DI 0 "register_operand" "=r")
10049         (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10050   "TARGET_64BIT
10051    && (optimize_function_for_size_p (cfun)
10052        || !TARGET_PARTIAL_FLAG_REG_STALL
10053        || (operands[2] == const1_rtx
10054            && TARGET_SHIFT1))
10055    && ix86_match_ccmode (insn, CCGOCmode)
10056    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10057 {
10058   if (operands[2] == const1_rtx
10059       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10060     return "<shiftrt>{l}\t%k0";
10061   else
10062     return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
10063 }
10064   [(set_attr "type" "ishift")
10065    (set (attr "length_immediate")
10066      (if_then_else
10067        (and (match_operand 2 "const1_operand" "")
10068             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10069                 (const_int 0)))
10070        (const_string "0")
10071        (const_string "*")))
10072    (set_attr "mode" "SI")])
10073
10074 (define_insn "*<shiftrt_insn><mode>3_cconly"
10075   [(set (reg FLAGS_REG)
10076         (compare
10077           (any_shiftrt:SWI
10078             (match_operand:SWI 1 "nonimmediate_operand" "0")
10079             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10080           (const_int 0)))
10081    (clobber (match_scratch:SWI 0 "=<r>"))]
10082   "(optimize_function_for_size_p (cfun)
10083     || !TARGET_PARTIAL_FLAG_REG_STALL
10084     || (operands[2] == const1_rtx
10085         && TARGET_SHIFT1))
10086    && ix86_match_ccmode (insn, CCGOCmode)
10087    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10088 {
10089   if (operands[2] == const1_rtx
10090       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10091     return "<shiftrt>{<imodesuffix>}\t%0";
10092   else
10093     return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
10094 }
10095   [(set_attr "type" "ishift")
10096    (set (attr "length_immediate")
10097      (if_then_else
10098        (and (match_operand 2 "const1_operand" "")
10099             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10100                 (const_int 0)))
10101        (const_string "0")
10102        (const_string "*")))
10103    (set_attr "mode" "<MODE>")])
10104 \f
10105 ;; Rotate instructions
10106
10107 (define_expand "<rotate_insn>ti3"
10108   [(set (match_operand:TI 0 "register_operand" "")
10109         (any_rotate:TI (match_operand:TI 1 "register_operand" "")
10110                        (match_operand:QI 2 "nonmemory_operand" "")))]
10111   "TARGET_64BIT"
10112 {
10113   if (const_1_to_63_operand (operands[2], VOIDmode))
10114     emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10115                 (operands[0], operands[1], operands[2]));
10116   else
10117     FAIL;
10118
10119   DONE;
10120 })
10121
10122 (define_expand "<rotate_insn>di3"
10123   [(set (match_operand:DI 0 "shiftdi_operand" "")
10124         (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
10125                        (match_operand:QI 2 "nonmemory_operand" "")))]
10126  ""
10127 {
10128   if (TARGET_64BIT)
10129     ix86_expand_binary_operator (<CODE>, DImode, operands);
10130   else if (const_1_to_31_operand (operands[2], VOIDmode))
10131     emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10132                 (operands[0], operands[1], operands[2]));
10133   else
10134     FAIL;
10135
10136   DONE;
10137 })
10138
10139 (define_expand "<rotate_insn><mode>3"
10140   [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
10141         (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
10142                             (match_operand:QI 2 "nonmemory_operand" "")))]
10143   ""
10144   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10145
10146 ;; Avoid useless masking of count operand.
10147 (define_insn_and_split "*<rotate_insn><mode>3_mask"
10148   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10149         (any_rotate:SWI48
10150           (match_operand:SWI48 1 "nonimmediate_operand" "0")
10151           (subreg:QI
10152             (and:SI
10153               (match_operand:SI 2 "nonimmediate_operand" "c")
10154               (match_operand:SI 3 "const_int_operand" "n")) 0)))
10155    (clobber (reg:CC FLAGS_REG))]
10156   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10157    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10158       == GET_MODE_BITSIZE (<MODE>mode)-1"
10159   "#"
10160   "&& 1"
10161   [(parallel [(set (match_dup 0)
10162                    (any_rotate:SWI48 (match_dup 1) (match_dup 2)))
10163               (clobber (reg:CC FLAGS_REG))])]
10164 {
10165   if (can_create_pseudo_p ())
10166     operands [2] = force_reg (SImode, operands[2]);
10167
10168   operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
10169 }
10170   [(set_attr "type" "rotate")
10171    (set_attr "mode" "<MODE>")])
10172
10173 ;; Implement rotation using two double-precision
10174 ;; shift instructions and a scratch register.
10175
10176 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10177  [(set (match_operand:<DWI> 0 "register_operand" "=r")
10178        (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10179                      (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10180   (clobber (reg:CC FLAGS_REG))
10181   (clobber (match_scratch:DWIH 3 "=&r"))]
10182  ""
10183  "#"
10184  "reload_completed"
10185  [(set (match_dup 3) (match_dup 4))
10186   (parallel
10187    [(set (match_dup 4)
10188          (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10189                    (lshiftrt:DWIH (match_dup 5)
10190                                   (minus:QI (match_dup 6) (match_dup 2)))))
10191     (clobber (reg:CC FLAGS_REG))])
10192   (parallel
10193    [(set (match_dup 5)
10194          (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10195                    (lshiftrt:DWIH (match_dup 3)
10196                                   (minus:QI (match_dup 6) (match_dup 2)))))
10197     (clobber (reg:CC FLAGS_REG))])]
10198 {
10199   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10200
10201   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10202 })
10203
10204 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10205  [(set (match_operand:<DWI> 0 "register_operand" "=r")
10206        (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10207                        (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10208   (clobber (reg:CC FLAGS_REG))
10209   (clobber (match_scratch:DWIH 3 "=&r"))]
10210  ""
10211  "#"
10212  "reload_completed"
10213  [(set (match_dup 3) (match_dup 4))
10214   (parallel
10215    [(set (match_dup 4)
10216          (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10217                    (ashift:DWIH (match_dup 5)
10218                                 (minus:QI (match_dup 6) (match_dup 2)))))
10219     (clobber (reg:CC FLAGS_REG))])
10220   (parallel
10221    [(set (match_dup 5)
10222          (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10223                    (ashift:DWIH (match_dup 3)
10224                                 (minus:QI (match_dup 6) (match_dup 2)))))
10225     (clobber (reg:CC FLAGS_REG))])]
10226 {
10227   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10228
10229   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10230 })
10231
10232 (define_insn "*<rotate_insn><mode>3_1"
10233   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10234         (any_rotate:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10235                         (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10236    (clobber (reg:CC FLAGS_REG))]
10237   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10238 {
10239   if (operands[2] == const1_rtx
10240       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10241     return "<rotate>{<imodesuffix>}\t%0";
10242   else
10243     return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10244 }
10245   [(set_attr "type" "rotate")
10246    (set (attr "length_immediate")
10247      (if_then_else
10248        (and (match_operand 2 "const1_operand" "")
10249             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10250                 (const_int 0)))
10251        (const_string "0")
10252        (const_string "*")))
10253    (set_attr "mode" "<MODE>")])
10254
10255 (define_insn "*<rotate_insn>si3_1_zext"
10256   [(set (match_operand:DI 0 "register_operand" "=r")
10257         (zero_extend:DI
10258           (any_rotate:SI (match_operand:SI 1 "register_operand" "0")
10259                          (match_operand:QI 2 "nonmemory_operand" "cI"))))
10260    (clobber (reg:CC FLAGS_REG))]
10261   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10262 {
10263     if (operands[2] == const1_rtx
10264         && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10265     return "<rotate>{l}\t%k0";
10266   else
10267     return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10268 }
10269   [(set_attr "type" "rotate")
10270    (set (attr "length_immediate")
10271      (if_then_else
10272        (and (match_operand 2 "const1_operand" "")
10273             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10274                 (const_int 0)))
10275        (const_string "0")
10276        (const_string "*")))
10277    (set_attr "mode" "SI")])
10278
10279 (define_insn "*<rotate_insn>qi3_1_slp"
10280   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10281         (any_rotate:QI (match_dup 0)
10282                        (match_operand:QI 1 "nonmemory_operand" "cI")))
10283    (clobber (reg:CC FLAGS_REG))]
10284   "(optimize_function_for_size_p (cfun)
10285     || !TARGET_PARTIAL_REG_STALL
10286     || (operands[1] == const1_rtx
10287         && TARGET_SHIFT1))"
10288 {
10289   if (operands[1] == const1_rtx
10290       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10291     return "<rotate>{b}\t%0";
10292   else
10293     return "<rotate>{b}\t{%1, %0|%0, %1}";
10294 }
10295   [(set_attr "type" "rotate1")
10296    (set (attr "length_immediate")
10297      (if_then_else
10298        (and (match_operand 1 "const1_operand" "")
10299             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10300                 (const_int 0)))
10301        (const_string "0")
10302        (const_string "*")))
10303    (set_attr "mode" "QI")])
10304
10305 (define_split
10306  [(set (match_operand:HI 0 "register_operand" "")
10307        (any_rotate:HI (match_dup 0) (const_int 8)))
10308   (clobber (reg:CC FLAGS_REG))]
10309  "reload_completed
10310   && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10311  [(parallel [(set (strict_low_part (match_dup 0))
10312                   (bswap:HI (match_dup 0)))
10313              (clobber (reg:CC FLAGS_REG))])])
10314 \f
10315 ;; Bit set / bit test instructions
10316
10317 (define_expand "extv"
10318   [(set (match_operand:SI 0 "register_operand" "")
10319         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10320                          (match_operand:SI 2 "const8_operand" "")
10321                          (match_operand:SI 3 "const8_operand" "")))]
10322   ""
10323 {
10324   /* Handle extractions from %ah et al.  */
10325   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10326     FAIL;
10327
10328   /* From mips.md: extract_bit_field doesn't verify that our source
10329      matches the predicate, so check it again here.  */
10330   if (! ext_register_operand (operands[1], VOIDmode))
10331     FAIL;
10332 })
10333
10334 (define_expand "extzv"
10335   [(set (match_operand:SI 0 "register_operand" "")
10336         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10337                          (match_operand:SI 2 "const8_operand" "")
10338                          (match_operand:SI 3 "const8_operand" "")))]
10339   ""
10340 {
10341   /* Handle extractions from %ah et al.  */
10342   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10343     FAIL;
10344
10345   /* From mips.md: extract_bit_field doesn't verify that our source
10346      matches the predicate, so check it again here.  */
10347   if (! ext_register_operand (operands[1], VOIDmode))
10348     FAIL;
10349 })
10350
10351 (define_expand "insv"
10352   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
10353                       (match_operand 1 "const8_operand" "")
10354                       (match_operand 2 "const8_operand" ""))
10355         (match_operand 3 "register_operand" ""))]
10356   ""
10357 {
10358   rtx (*gen_mov_insv_1) (rtx, rtx);
10359
10360   /* Handle insertions to %ah et al.  */
10361   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10362     FAIL;
10363
10364   /* From mips.md: insert_bit_field doesn't verify that our source
10365      matches the predicate, so check it again here.  */
10366   if (! ext_register_operand (operands[0], VOIDmode))
10367     FAIL;
10368
10369   gen_mov_insv_1 = (TARGET_64BIT
10370                     ? gen_movdi_insv_1 : gen_movsi_insv_1);
10371
10372   emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10373   DONE;
10374 })
10375
10376 ;; %%% bts, btr, btc, bt.
10377 ;; In general these instructions are *slow* when applied to memory,
10378 ;; since they enforce atomic operation.  When applied to registers,
10379 ;; it depends on the cpu implementation.  They're never faster than
10380 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10381 ;; no point.  But in 64-bit, we can't hold the relevant immediates
10382 ;; within the instruction itself, so operating on bits in the high
10383 ;; 32-bits of a register becomes easier.
10384 ;;
10385 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
10386 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10387 ;; negdf respectively, so they can never be disabled entirely.
10388
10389 (define_insn "*btsq"
10390   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10391                          (const_int 1)
10392                          (match_operand:DI 1 "const_0_to_63_operand" ""))
10393         (const_int 1))
10394    (clobber (reg:CC FLAGS_REG))]
10395   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10396   "bts{q}\t{%1, %0|%0, %1}"
10397   [(set_attr "type" "alu1")
10398    (set_attr "prefix_0f" "1")
10399    (set_attr "mode" "DI")])
10400
10401 (define_insn "*btrq"
10402   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10403                          (const_int 1)
10404                          (match_operand:DI 1 "const_0_to_63_operand" ""))
10405         (const_int 0))
10406    (clobber (reg:CC FLAGS_REG))]
10407   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10408   "btr{q}\t{%1, %0|%0, %1}"
10409   [(set_attr "type" "alu1")
10410    (set_attr "prefix_0f" "1")
10411    (set_attr "mode" "DI")])
10412
10413 (define_insn "*btcq"
10414   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10415                          (const_int 1)
10416                          (match_operand:DI 1 "const_0_to_63_operand" ""))
10417         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10418    (clobber (reg:CC FLAGS_REG))]
10419   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10420   "btc{q}\t{%1, %0|%0, %1}"
10421   [(set_attr "type" "alu1")
10422    (set_attr "prefix_0f" "1")
10423    (set_attr "mode" "DI")])
10424
10425 ;; Allow Nocona to avoid these instructions if a register is available.
10426
10427 (define_peephole2
10428   [(match_scratch:DI 2 "r")
10429    (parallel [(set (zero_extract:DI
10430                      (match_operand:DI 0 "register_operand" "")
10431                      (const_int 1)
10432                      (match_operand:DI 1 "const_0_to_63_operand" ""))
10433                    (const_int 1))
10434               (clobber (reg:CC FLAGS_REG))])]
10435   "TARGET_64BIT && !TARGET_USE_BT"
10436   [(const_int 0)]
10437 {
10438   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10439   rtx op1;
10440
10441   if (HOST_BITS_PER_WIDE_INT >= 64)
10442     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10443   else if (i < HOST_BITS_PER_WIDE_INT)
10444     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10445   else
10446     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10447
10448   op1 = immed_double_const (lo, hi, DImode);
10449   if (i >= 31)
10450     {
10451       emit_move_insn (operands[2], op1);
10452       op1 = operands[2];
10453     }
10454
10455   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10456   DONE;
10457 })
10458
10459 (define_peephole2
10460   [(match_scratch:DI 2 "r")
10461    (parallel [(set (zero_extract:DI
10462                      (match_operand:DI 0 "register_operand" "")
10463                      (const_int 1)
10464                      (match_operand:DI 1 "const_0_to_63_operand" ""))
10465                    (const_int 0))
10466               (clobber (reg:CC FLAGS_REG))])]
10467   "TARGET_64BIT && !TARGET_USE_BT"
10468   [(const_int 0)]
10469 {
10470   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10471   rtx op1;
10472
10473   if (HOST_BITS_PER_WIDE_INT >= 64)
10474     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10475   else if (i < HOST_BITS_PER_WIDE_INT)
10476     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10477   else
10478     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10479
10480   op1 = immed_double_const (~lo, ~hi, DImode);
10481   if (i >= 32)
10482     {
10483       emit_move_insn (operands[2], op1);
10484       op1 = operands[2];
10485     }
10486
10487   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10488   DONE;
10489 })
10490
10491 (define_peephole2
10492   [(match_scratch:DI 2 "r")
10493    (parallel [(set (zero_extract:DI
10494                      (match_operand:DI 0 "register_operand" "")
10495                      (const_int 1)
10496                      (match_operand:DI 1 "const_0_to_63_operand" ""))
10497               (not:DI (zero_extract:DI
10498                         (match_dup 0) (const_int 1) (match_dup 1))))
10499               (clobber (reg:CC FLAGS_REG))])]
10500   "TARGET_64BIT && !TARGET_USE_BT"
10501   [(const_int 0)]
10502 {
10503   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10504   rtx op1;
10505
10506   if (HOST_BITS_PER_WIDE_INT >= 64)
10507     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10508   else if (i < HOST_BITS_PER_WIDE_INT)
10509     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10510   else
10511     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10512
10513   op1 = immed_double_const (lo, hi, DImode);
10514   if (i >= 31)
10515     {
10516       emit_move_insn (operands[2], op1);
10517       op1 = operands[2];
10518     }
10519
10520   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10521   DONE;
10522 })
10523
10524 (define_insn "*bt<mode>"
10525   [(set (reg:CCC FLAGS_REG)
10526         (compare:CCC
10527           (zero_extract:SWI48
10528             (match_operand:SWI48 0 "register_operand" "r")
10529             (const_int 1)
10530             (match_operand:SWI48 1 "nonmemory_operand" "rN"))
10531           (const_int 0)))]
10532   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10533   "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10534   [(set_attr "type" "alu1")
10535    (set_attr "prefix_0f" "1")
10536    (set_attr "mode" "<MODE>")])
10537 \f
10538 ;; Store-flag instructions.
10539
10540 ;; For all sCOND expanders, also expand the compare or test insn that
10541 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
10542
10543 (define_insn_and_split "*setcc_di_1"
10544   [(set (match_operand:DI 0 "register_operand" "=q")
10545         (match_operator:DI 1 "ix86_comparison_operator"
10546           [(reg FLAGS_REG) (const_int 0)]))]
10547   "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10548   "#"
10549   "&& reload_completed"
10550   [(set (match_dup 2) (match_dup 1))
10551    (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10552 {
10553   PUT_MODE (operands[1], QImode);
10554   operands[2] = gen_lowpart (QImode, operands[0]);
10555 })
10556
10557 (define_insn_and_split "*setcc_si_1_and"
10558   [(set (match_operand:SI 0 "register_operand" "=q")
10559         (match_operator:SI 1 "ix86_comparison_operator"
10560           [(reg FLAGS_REG) (const_int 0)]))
10561    (clobber (reg:CC FLAGS_REG))]
10562   "!TARGET_PARTIAL_REG_STALL
10563    && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10564   "#"
10565   "&& reload_completed"
10566   [(set (match_dup 2) (match_dup 1))
10567    (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10568               (clobber (reg:CC FLAGS_REG))])]
10569 {
10570   PUT_MODE (operands[1], QImode);
10571   operands[2] = gen_lowpart (QImode, operands[0]);
10572 })
10573
10574 (define_insn_and_split "*setcc_si_1_movzbl"
10575   [(set (match_operand:SI 0 "register_operand" "=q")
10576         (match_operator:SI 1 "ix86_comparison_operator"
10577           [(reg FLAGS_REG) (const_int 0)]))]
10578   "!TARGET_PARTIAL_REG_STALL
10579    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10580   "#"
10581   "&& reload_completed"
10582   [(set (match_dup 2) (match_dup 1))
10583    (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10584 {
10585   PUT_MODE (operands[1], QImode);
10586   operands[2] = gen_lowpart (QImode, operands[0]);
10587 })
10588
10589 (define_insn "*setcc_qi"
10590   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10591         (match_operator:QI 1 "ix86_comparison_operator"
10592           [(reg FLAGS_REG) (const_int 0)]))]
10593   ""
10594   "set%C1\t%0"
10595   [(set_attr "type" "setcc")
10596    (set_attr "mode" "QI")])
10597
10598 (define_insn "*setcc_qi_slp"
10599   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10600         (match_operator:QI 1 "ix86_comparison_operator"
10601           [(reg FLAGS_REG) (const_int 0)]))]
10602   ""
10603   "set%C1\t%0"
10604   [(set_attr "type" "setcc")
10605    (set_attr "mode" "QI")])
10606
10607 ;; In general it is not safe to assume too much about CCmode registers,
10608 ;; so simplify-rtx stops when it sees a second one.  Under certain
10609 ;; conditions this is safe on x86, so help combine not create
10610 ;;
10611 ;;      seta    %al
10612 ;;      testb   %al, %al
10613 ;;      sete    %al
10614
10615 (define_split
10616   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10617         (ne:QI (match_operator 1 "ix86_comparison_operator"
10618                  [(reg FLAGS_REG) (const_int 0)])
10619             (const_int 0)))]
10620   ""
10621   [(set (match_dup 0) (match_dup 1))]
10622   "PUT_MODE (operands[1], QImode);")
10623
10624 (define_split
10625   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10626         (ne:QI (match_operator 1 "ix86_comparison_operator"
10627                  [(reg FLAGS_REG) (const_int 0)])
10628             (const_int 0)))]
10629   ""
10630   [(set (match_dup 0) (match_dup 1))]
10631   "PUT_MODE (operands[1], QImode);")
10632
10633 (define_split
10634   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10635         (eq:QI (match_operator 1 "ix86_comparison_operator"
10636                  [(reg FLAGS_REG) (const_int 0)])
10637             (const_int 0)))]
10638   ""
10639   [(set (match_dup 0) (match_dup 1))]
10640 {
10641   rtx new_op1 = copy_rtx (operands[1]);
10642   operands[1] = new_op1;
10643   PUT_MODE (new_op1, QImode);
10644   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10645                                              GET_MODE (XEXP (new_op1, 0))));
10646
10647   /* Make sure that (a) the CCmode we have for the flags is strong
10648      enough for the reversed compare or (b) we have a valid FP compare.  */
10649   if (! ix86_comparison_operator (new_op1, VOIDmode))
10650     FAIL;
10651 })
10652
10653 (define_split
10654   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10655         (eq:QI (match_operator 1 "ix86_comparison_operator"
10656                  [(reg FLAGS_REG) (const_int 0)])
10657             (const_int 0)))]
10658   ""
10659   [(set (match_dup 0) (match_dup 1))]
10660 {
10661   rtx new_op1 = copy_rtx (operands[1]);
10662   operands[1] = new_op1;
10663   PUT_MODE (new_op1, QImode);
10664   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10665                                              GET_MODE (XEXP (new_op1, 0))));
10666
10667   /* Make sure that (a) the CCmode we have for the flags is strong
10668      enough for the reversed compare or (b) we have a valid FP compare.  */
10669   if (! ix86_comparison_operator (new_op1, VOIDmode))
10670     FAIL;
10671 })
10672
10673 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10674 ;; subsequent logical operations are used to imitate conditional moves.
10675 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10676 ;; it directly.
10677
10678 (define_insn "*avx_setcc<mode>"
10679   [(set (match_operand:MODEF 0 "register_operand" "=x")
10680         (match_operator:MODEF 1 "avx_comparison_float_operator"
10681           [(match_operand:MODEF 2 "register_operand" "x")
10682            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
10683   "TARGET_AVX"
10684   "vcmp%D1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
10685   [(set_attr "type" "ssecmp")
10686    (set_attr "prefix" "vex")
10687    (set_attr "length_immediate" "1")
10688    (set_attr "mode" "<MODE>")])
10689
10690 (define_insn "*sse_setcc<mode>"
10691   [(set (match_operand:MODEF 0 "register_operand" "=x")
10692         (match_operator:MODEF 1 "sse_comparison_operator"
10693           [(match_operand:MODEF 2 "register_operand" "0")
10694            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
10695   "SSE_FLOAT_MODE_P (<MODE>mode)"
10696   "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
10697   [(set_attr "type" "ssecmp")
10698    (set_attr "length_immediate" "1")
10699    (set_attr "mode" "<MODE>")])
10700 \f
10701 ;; Basic conditional jump instructions.
10702 ;; We ignore the overflow flag for signed branch instructions.
10703
10704 (define_insn "*jcc_1"
10705   [(set (pc)
10706         (if_then_else (match_operator 1 "ix86_comparison_operator"
10707                                       [(reg FLAGS_REG) (const_int 0)])
10708                       (label_ref (match_operand 0 "" ""))
10709                       (pc)))]
10710   ""
10711   "%+j%C1\t%l0"
10712   [(set_attr "type" "ibr")
10713    (set_attr "modrm" "0")
10714    (set (attr "length")
10715            (if_then_else (and (ge (minus (match_dup 0) (pc))
10716                                   (const_int -126))
10717                               (lt (minus (match_dup 0) (pc))
10718                                   (const_int 128)))
10719              (const_int 2)
10720              (const_int 6)))])
10721
10722 (define_insn "*jcc_2"
10723   [(set (pc)
10724         (if_then_else (match_operator 1 "ix86_comparison_operator"
10725                                       [(reg FLAGS_REG) (const_int 0)])
10726                       (pc)
10727                       (label_ref (match_operand 0 "" ""))))]
10728   ""
10729   "%+j%c1\t%l0"
10730   [(set_attr "type" "ibr")
10731    (set_attr "modrm" "0")
10732    (set (attr "length")
10733            (if_then_else (and (ge (minus (match_dup 0) (pc))
10734                                   (const_int -126))
10735                               (lt (minus (match_dup 0) (pc))
10736                                   (const_int 128)))
10737              (const_int 2)
10738              (const_int 6)))])
10739
10740 ;; In general it is not safe to assume too much about CCmode registers,
10741 ;; so simplify-rtx stops when it sees a second one.  Under certain
10742 ;; conditions this is safe on x86, so help combine not create
10743 ;;
10744 ;;      seta    %al
10745 ;;      testb   %al, %al
10746 ;;      je      Lfoo
10747
10748 (define_split
10749   [(set (pc)
10750         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10751                                       [(reg FLAGS_REG) (const_int 0)])
10752                           (const_int 0))
10753                       (label_ref (match_operand 1 "" ""))
10754                       (pc)))]
10755   ""
10756   [(set (pc)
10757         (if_then_else (match_dup 0)
10758                       (label_ref (match_dup 1))
10759                       (pc)))]
10760   "PUT_MODE (operands[0], VOIDmode);")
10761
10762 (define_split
10763   [(set (pc)
10764         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10765                                       [(reg FLAGS_REG) (const_int 0)])
10766                           (const_int 0))
10767                       (label_ref (match_operand 1 "" ""))
10768                       (pc)))]
10769   ""
10770   [(set (pc)
10771         (if_then_else (match_dup 0)
10772                       (label_ref (match_dup 1))
10773                       (pc)))]
10774 {
10775   rtx new_op0 = copy_rtx (operands[0]);
10776   operands[0] = new_op0;
10777   PUT_MODE (new_op0, VOIDmode);
10778   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10779                                              GET_MODE (XEXP (new_op0, 0))));
10780
10781   /* Make sure that (a) the CCmode we have for the flags is strong
10782      enough for the reversed compare or (b) we have a valid FP compare.  */
10783   if (! ix86_comparison_operator (new_op0, VOIDmode))
10784     FAIL;
10785 })
10786
10787 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10788 ;; pass generates from shift insn with QImode operand.  Actually, the mode
10789 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10790 ;; appropriate modulo of the bit offset value.
10791
10792 (define_insn_and_split "*jcc_bt<mode>"
10793   [(set (pc)
10794         (if_then_else (match_operator 0 "bt_comparison_operator"
10795                         [(zero_extract:SWI48
10796                            (match_operand:SWI48 1 "register_operand" "r")
10797                            (const_int 1)
10798                            (zero_extend:SI
10799                              (match_operand:QI 2 "register_operand" "r")))
10800                          (const_int 0)])
10801                       (label_ref (match_operand 3 "" ""))
10802                       (pc)))
10803    (clobber (reg:CC FLAGS_REG))]
10804   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10805   "#"
10806   "&& 1"
10807   [(set (reg:CCC FLAGS_REG)
10808         (compare:CCC
10809           (zero_extract:SWI48
10810             (match_dup 1)
10811             (const_int 1)
10812             (match_dup 2))
10813           (const_int 0)))
10814    (set (pc)
10815         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10816                       (label_ref (match_dup 3))
10817                       (pc)))]
10818 {
10819   operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10820
10821   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10822 })
10823
10824 ;; Avoid useless masking of bit offset operand.  "and" in SImode is correct
10825 ;; also for DImode, this is what combine produces.
10826 (define_insn_and_split "*jcc_bt<mode>_mask"
10827   [(set (pc)
10828         (if_then_else (match_operator 0 "bt_comparison_operator"
10829                         [(zero_extract:SWI48
10830                            (match_operand:SWI48 1 "register_operand" "r")
10831                            (const_int 1)
10832                            (and:SI
10833                              (match_operand:SI 2 "register_operand" "r")
10834                              (match_operand:SI 3 "const_int_operand" "n")))])
10835                       (label_ref (match_operand 4 "" ""))
10836                       (pc)))
10837    (clobber (reg:CC FLAGS_REG))]
10838   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10839    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10840       == GET_MODE_BITSIZE (<MODE>mode)-1"
10841   "#"
10842   "&& 1"
10843   [(set (reg:CCC FLAGS_REG)
10844         (compare:CCC
10845           (zero_extract:SWI48
10846             (match_dup 1)
10847             (const_int 1)
10848             (match_dup 2))
10849           (const_int 0)))
10850    (set (pc)
10851         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10852                       (label_ref (match_dup 4))
10853                       (pc)))]
10854 {
10855   operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10856
10857   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10858 })
10859
10860 (define_insn_and_split "*jcc_btsi_1"
10861   [(set (pc)
10862         (if_then_else (match_operator 0 "bt_comparison_operator"
10863                         [(and:SI
10864                            (lshiftrt:SI
10865                              (match_operand:SI 1 "register_operand" "r")
10866                              (match_operand:QI 2 "register_operand" "r"))
10867                            (const_int 1))
10868                          (const_int 0)])
10869                       (label_ref (match_operand 3 "" ""))
10870                       (pc)))
10871    (clobber (reg:CC FLAGS_REG))]
10872   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10873   "#"
10874   "&& 1"
10875   [(set (reg:CCC FLAGS_REG)
10876         (compare:CCC
10877           (zero_extract:SI
10878             (match_dup 1)
10879             (const_int 1)
10880             (match_dup 2))
10881           (const_int 0)))
10882    (set (pc)
10883         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10884                       (label_ref (match_dup 3))
10885                       (pc)))]
10886 {
10887   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10888
10889   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10890 })
10891
10892 ;; avoid useless masking of bit offset operand
10893 (define_insn_and_split "*jcc_btsi_mask_1"
10894   [(set (pc)
10895         (if_then_else
10896           (match_operator 0 "bt_comparison_operator"
10897             [(and:SI
10898                (lshiftrt:SI
10899                  (match_operand:SI 1 "register_operand" "r")
10900                  (subreg:QI
10901                    (and:SI
10902                      (match_operand:SI 2 "register_operand" "r")
10903                      (match_operand:SI 3 "const_int_operand" "n")) 0))
10904                (const_int 1))
10905              (const_int 0)])
10906           (label_ref (match_operand 4 "" ""))
10907           (pc)))
10908    (clobber (reg:CC FLAGS_REG))]
10909   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10910    && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10911   "#"
10912   "&& 1"
10913   [(set (reg:CCC FLAGS_REG)
10914         (compare:CCC
10915           (zero_extract:SI
10916             (match_dup 1)
10917             (const_int 1)
10918             (match_dup 2))
10919           (const_int 0)))
10920    (set (pc)
10921         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10922                       (label_ref (match_dup 4))
10923                       (pc)))]
10924   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10925
10926 ;; Define combination compare-and-branch fp compare instructions to help
10927 ;; combine.
10928
10929 (define_insn "*fp_jcc_1_387"
10930   [(set (pc)
10931         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10932                         [(match_operand 1 "register_operand" "f")
10933                          (match_operand 2 "nonimmediate_operand" "fm")])
10934           (label_ref (match_operand 3 "" ""))
10935           (pc)))
10936    (clobber (reg:CCFP FPSR_REG))
10937    (clobber (reg:CCFP FLAGS_REG))
10938    (clobber (match_scratch:HI 4 "=a"))]
10939   "TARGET_80387
10940    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10941    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10942    && SELECT_CC_MODE (GET_CODE (operands[0]),
10943                       operands[1], operands[2]) == CCFPmode
10944    && !TARGET_CMOVE"
10945   "#")
10946
10947 (define_insn "*fp_jcc_1r_387"
10948   [(set (pc)
10949         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10950                         [(match_operand 1 "register_operand" "f")
10951                          (match_operand 2 "nonimmediate_operand" "fm")])
10952           (pc)
10953           (label_ref (match_operand 3 "" ""))))
10954    (clobber (reg:CCFP FPSR_REG))
10955    (clobber (reg:CCFP FLAGS_REG))
10956    (clobber (match_scratch:HI 4 "=a"))]
10957   "TARGET_80387
10958    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10959    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10960    && SELECT_CC_MODE (GET_CODE (operands[0]),
10961                       operands[1], operands[2]) == CCFPmode
10962    && !TARGET_CMOVE"
10963   "#")
10964
10965 (define_insn "*fp_jcc_2_387"
10966   [(set (pc)
10967         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10968                         [(match_operand 1 "register_operand" "f")
10969                          (match_operand 2 "register_operand" "f")])
10970           (label_ref (match_operand 3 "" ""))
10971           (pc)))
10972    (clobber (reg:CCFP FPSR_REG))
10973    (clobber (reg:CCFP FLAGS_REG))
10974    (clobber (match_scratch:HI 4 "=a"))]
10975   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10976    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10977    && !TARGET_CMOVE"
10978   "#")
10979
10980 (define_insn "*fp_jcc_2r_387"
10981   [(set (pc)
10982         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10983                         [(match_operand 1 "register_operand" "f")
10984                          (match_operand 2 "register_operand" "f")])
10985           (pc)
10986           (label_ref (match_operand 3 "" ""))))
10987    (clobber (reg:CCFP FPSR_REG))
10988    (clobber (reg:CCFP FLAGS_REG))
10989    (clobber (match_scratch:HI 4 "=a"))]
10990   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10991    && GET_MODE (operands[1]) == GET_MODE (operands[2])
10992    && !TARGET_CMOVE"
10993   "#")
10994
10995 (define_insn "*fp_jcc_3_387"
10996   [(set (pc)
10997         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10998                         [(match_operand 1 "register_operand" "f")
10999                          (match_operand 2 "const0_operand" "")])
11000           (label_ref (match_operand 3 "" ""))
11001           (pc)))
11002    (clobber (reg:CCFP FPSR_REG))
11003    (clobber (reg:CCFP FLAGS_REG))
11004    (clobber (match_scratch:HI 4 "=a"))]
11005   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11006    && GET_MODE (operands[1]) == GET_MODE (operands[2])
11007    && SELECT_CC_MODE (GET_CODE (operands[0]),
11008                       operands[1], operands[2]) == CCFPmode
11009    && !TARGET_CMOVE"
11010   "#")
11011
11012 (define_split
11013   [(set (pc)
11014         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11015                         [(match_operand 1 "register_operand" "")
11016                          (match_operand 2 "nonimmediate_operand" "")])
11017           (match_operand 3 "" "")
11018           (match_operand 4 "" "")))
11019    (clobber (reg:CCFP FPSR_REG))
11020    (clobber (reg:CCFP FLAGS_REG))]
11021   "reload_completed"
11022   [(const_int 0)]
11023 {
11024   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11025                         operands[3], operands[4], NULL_RTX, NULL_RTX);
11026   DONE;
11027 })
11028
11029 (define_split
11030   [(set (pc)
11031         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11032                         [(match_operand 1 "register_operand" "")
11033                          (match_operand 2 "general_operand" "")])
11034           (match_operand 3 "" "")
11035           (match_operand 4 "" "")))
11036    (clobber (reg:CCFP FPSR_REG))
11037    (clobber (reg:CCFP FLAGS_REG))
11038    (clobber (match_scratch:HI 5 "=a"))]
11039   "reload_completed"
11040   [(const_int 0)]
11041 {
11042   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11043                         operands[3], operands[4], operands[5], NULL_RTX);
11044   DONE;
11045 })
11046
11047 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
11048 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11049 ;; with a precedence over other operators and is always put in the first
11050 ;; place. Swap condition and operands to match ficom instruction.
11051
11052 (define_insn "*fp_jcc_4_<mode>_387"
11053   [(set (pc)
11054         (if_then_else
11055           (match_operator 0 "ix86_swapped_fp_comparison_operator"
11056             [(match_operator 1 "float_operator"
11057               [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
11058              (match_operand 3 "register_operand" "f,f")])
11059           (label_ref (match_operand 4 "" ""))
11060           (pc)))
11061    (clobber (reg:CCFP FPSR_REG))
11062    (clobber (reg:CCFP FLAGS_REG))
11063    (clobber (match_scratch:HI 5 "=a,a"))]
11064   "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
11065    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
11066    && GET_MODE (operands[1]) == GET_MODE (operands[3])
11067    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
11068    && !TARGET_CMOVE"
11069   "#")
11070
11071 (define_split
11072   [(set (pc)
11073         (if_then_else
11074           (match_operator 0 "ix86_swapped_fp_comparison_operator"
11075             [(match_operator 1 "float_operator"
11076               [(match_operand:X87MODEI12 2 "memory_operand" "")])
11077              (match_operand 3 "register_operand" "")])
11078           (match_operand 4 "" "")
11079           (match_operand 5 "" "")))
11080    (clobber (reg:CCFP FPSR_REG))
11081    (clobber (reg:CCFP FLAGS_REG))
11082    (clobber (match_scratch:HI 6 "=a"))]
11083   "reload_completed"
11084   [(const_int 0)]
11085 {
11086   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
11087
11088   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11089                         operands[3], operands[7],
11090                         operands[4], operands[5], operands[6], NULL_RTX);
11091   DONE;
11092 })
11093
11094 ;; %%% Kill this when reload knows how to do it.
11095 (define_split
11096   [(set (pc)
11097         (if_then_else
11098           (match_operator 0 "ix86_swapped_fp_comparison_operator"
11099             [(match_operator 1 "float_operator"
11100               [(match_operand:X87MODEI12 2 "register_operand" "")])
11101              (match_operand 3 "register_operand" "")])
11102           (match_operand 4 "" "")
11103           (match_operand 5 "" "")))
11104    (clobber (reg:CCFP FPSR_REG))
11105    (clobber (reg:CCFP FLAGS_REG))
11106    (clobber (match_scratch:HI 6 "=a"))]
11107   "reload_completed"
11108   [(const_int 0)]
11109 {
11110   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11111   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
11112
11113   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11114                         operands[3], operands[7],
11115                         operands[4], operands[5], operands[6], operands[2]);
11116   DONE;
11117 })
11118 \f
11119 ;; Unconditional and other jump instructions
11120
11121 (define_insn "jump"
11122   [(set (pc)
11123         (label_ref (match_operand 0 "" "")))]
11124   ""
11125   "jmp\t%l0"
11126   [(set_attr "type" "ibr")
11127    (set (attr "length")
11128            (if_then_else (and (ge (minus (match_dup 0) (pc))
11129                                   (const_int -126))
11130                               (lt (minus (match_dup 0) (pc))
11131                                   (const_int 128)))
11132              (const_int 2)
11133              (const_int 5)))
11134    (set_attr "modrm" "0")])
11135
11136 (define_expand "indirect_jump"
11137   [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
11138   ""
11139   "")
11140
11141 (define_insn "*indirect_jump"
11142   [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
11143   ""
11144   "jmp\t%A0"
11145   [(set_attr "type" "ibr")
11146    (set_attr "length_immediate" "0")])
11147
11148 (define_expand "tablejump"
11149   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
11150               (use (label_ref (match_operand 1 "" "")))])]
11151   ""
11152 {
11153   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11154      relative.  Convert the relative address to an absolute address.  */
11155   if (flag_pic)
11156     {
11157       rtx op0, op1;
11158       enum rtx_code code;
11159
11160       /* We can't use @GOTOFF for text labels on VxWorks;
11161          see gotoff_operand.  */
11162       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11163         {
11164           code = PLUS;
11165           op0 = operands[0];
11166           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11167         }
11168       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11169         {
11170           code = PLUS;
11171           op0 = operands[0];
11172           op1 = pic_offset_table_rtx;
11173         }
11174       else
11175         {
11176           code = MINUS;
11177           op0 = pic_offset_table_rtx;
11178           op1 = operands[0];
11179         }
11180
11181       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11182                                          OPTAB_DIRECT);
11183     }
11184 })
11185
11186 (define_insn "*tablejump_1"
11187   [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
11188    (use (label_ref (match_operand 1 "" "")))]
11189   ""
11190   "jmp\t%A0"
11191   [(set_attr "type" "ibr")
11192    (set_attr "length_immediate" "0")])
11193 \f
11194 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11195
11196 (define_peephole2
11197   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11198    (set (match_operand:QI 1 "register_operand" "")
11199         (match_operator:QI 2 "ix86_comparison_operator"
11200           [(reg FLAGS_REG) (const_int 0)]))
11201    (set (match_operand 3 "q_regs_operand" "")
11202         (zero_extend (match_dup 1)))]
11203   "(peep2_reg_dead_p (3, operands[1])
11204     || operands_match_p (operands[1], operands[3]))
11205    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11206   [(set (match_dup 4) (match_dup 0))
11207    (set (strict_low_part (match_dup 5))
11208         (match_dup 2))]
11209 {
11210   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11211   operands[5] = gen_lowpart (QImode, operands[3]);
11212   ix86_expand_clear (operands[3]);
11213 })
11214
11215 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
11216
11217 (define_peephole2
11218   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11219    (set (match_operand:QI 1 "register_operand" "")
11220         (match_operator:QI 2 "ix86_comparison_operator"
11221           [(reg FLAGS_REG) (const_int 0)]))
11222    (parallel [(set (match_operand 3 "q_regs_operand" "")
11223                    (zero_extend (match_dup 1)))
11224               (clobber (reg:CC FLAGS_REG))])]
11225   "(peep2_reg_dead_p (3, operands[1])
11226     || operands_match_p (operands[1], operands[3]))
11227    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11228   [(set (match_dup 4) (match_dup 0))
11229    (set (strict_low_part (match_dup 5))
11230         (match_dup 2))]
11231 {
11232   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11233   operands[5] = gen_lowpart (QImode, operands[3]);
11234   ix86_expand_clear (operands[3]);
11235 })
11236 \f
11237 ;; Call instructions.
11238
11239 ;; The predicates normally associated with named expanders are not properly
11240 ;; checked for calls.  This is a bug in the generic code, but it isn't that
11241 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
11242
11243 ;; P6 processors will jump to the address after the decrement when %esp
11244 ;; is used as a call operand, so they will execute return address as a code.
11245 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11246  
11247 ;; Call subroutine returning no value.
11248
11249 (define_expand "call_pop"
11250   [(parallel [(call (match_operand:QI 0 "" "")
11251                     (match_operand:SI 1 "" ""))
11252               (set (reg:SI SP_REG)
11253                    (plus:SI (reg:SI SP_REG)
11254                             (match_operand:SI 3 "" "")))])]
11255   "!TARGET_64BIT"
11256 {
11257   ix86_expand_call (NULL, operands[0], operands[1],
11258                     operands[2], operands[3], 0);
11259   DONE;
11260 })
11261
11262 (define_insn "*call_pop_0"
11263   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
11264          (match_operand:SI 1 "" ""))
11265    (set (reg:SI SP_REG)
11266         (plus:SI (reg:SI SP_REG)
11267                  (match_operand:SI 2 "immediate_operand" "")))]
11268   "!TARGET_64BIT"
11269 {
11270   if (SIBLING_CALL_P (insn))
11271     return "jmp\t%P0";
11272   else
11273     return "call\t%P0";
11274 }
11275   [(set_attr "type" "call")])
11276
11277 (define_insn "*call_pop_1"
11278   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11279          (match_operand:SI 1 "" ""))
11280    (set (reg:SI SP_REG)
11281         (plus:SI (reg:SI SP_REG)
11282                  (match_operand:SI 2 "immediate_operand" "i")))]
11283   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11284 {
11285   if (constant_call_address_operand (operands[0], Pmode))
11286     return "call\t%P0";
11287   return "call\t%A0";
11288 }
11289   [(set_attr "type" "call")])
11290
11291 (define_insn "*sibcall_pop_1"
11292   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11293          (match_operand:SI 1 "" ""))
11294    (set (reg:SI SP_REG)
11295         (plus:SI (reg:SI SP_REG)
11296                  (match_operand:SI 2 "immediate_operand" "i,i")))]
11297   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11298   "@
11299    jmp\t%P0
11300    jmp\t%A0"
11301   [(set_attr "type" "call")])
11302
11303 (define_expand "call"
11304   [(call (match_operand:QI 0 "" "")
11305          (match_operand 1 "" ""))
11306    (use (match_operand 2 "" ""))]
11307   ""
11308 {
11309   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
11310   DONE;
11311 })
11312
11313 (define_expand "sibcall"
11314   [(call (match_operand:QI 0 "" "")
11315          (match_operand 1 "" ""))
11316    (use (match_operand 2 "" ""))]
11317   ""
11318 {
11319   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
11320   DONE;
11321 })
11322
11323 (define_insn "*call_0"
11324   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
11325          (match_operand 1 "" ""))]
11326   ""
11327 {
11328   if (SIBLING_CALL_P (insn))
11329     return "jmp\t%P0";
11330   else
11331     return "call\t%P0";
11332 }
11333   [(set_attr "type" "call")])
11334
11335 (define_insn "*call_1"
11336   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11337          (match_operand 1 "" ""))]
11338   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11339 {
11340   if (constant_call_address_operand (operands[0], Pmode))
11341     return "call\t%P0";
11342   return "call\t%A0";
11343 }
11344   [(set_attr "type" "call")])
11345
11346 (define_insn "*sibcall_1"
11347   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11348          (match_operand 1 "" ""))]
11349   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11350   "@
11351    jmp\t%P0
11352    jmp\t%A0"
11353   [(set_attr "type" "call")])
11354
11355 (define_insn "*call_1_rex64"
11356   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11357          (match_operand 1 "" ""))]
11358   "TARGET_64BIT && !SIBLING_CALL_P (insn)
11359    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
11360 {
11361   if (constant_call_address_operand (operands[0], Pmode))
11362     return "call\t%P0";
11363   return "call\t%A0";
11364 }
11365   [(set_attr "type" "call")])
11366
11367 (define_insn "*call_1_rex64_ms_sysv"
11368   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11369          (match_operand 1 "" ""))
11370    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11371    (clobber (reg:TI XMM6_REG))
11372    (clobber (reg:TI XMM7_REG))
11373    (clobber (reg:TI XMM8_REG))
11374    (clobber (reg:TI XMM9_REG))
11375    (clobber (reg:TI XMM10_REG))
11376    (clobber (reg:TI XMM11_REG))
11377    (clobber (reg:TI XMM12_REG))
11378    (clobber (reg:TI XMM13_REG))
11379    (clobber (reg:TI XMM14_REG))
11380    (clobber (reg:TI XMM15_REG))
11381    (clobber (reg:DI SI_REG))
11382    (clobber (reg:DI DI_REG))]
11383   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11384 {
11385   if (constant_call_address_operand (operands[0], Pmode))
11386     return "call\t%P0";
11387   return "call\t%A0";
11388 }
11389   [(set_attr "type" "call")])
11390
11391 (define_insn "*call_1_rex64_large"
11392   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
11393          (match_operand 1 "" ""))]
11394   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11395   "call\t%A0"
11396   [(set_attr "type" "call")])
11397
11398 (define_insn "*sibcall_1_rex64"
11399   [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
11400          (match_operand 1 "" ""))]
11401   "TARGET_64BIT && SIBLING_CALL_P (insn)"
11402   "@
11403    jmp\t%P0
11404    jmp\t%A0"
11405   [(set_attr "type" "call")])
11406
11407 ;; Call subroutine, returning value in operand 0
11408 (define_expand "call_value_pop"
11409   [(parallel [(set (match_operand 0 "" "")
11410                    (call (match_operand:QI 1 "" "")
11411                          (match_operand:SI 2 "" "")))
11412               (set (reg:SI SP_REG)
11413                    (plus:SI (reg:SI SP_REG)
11414                             (match_operand:SI 4 "" "")))])]
11415   "!TARGET_64BIT"
11416 {
11417   ix86_expand_call (operands[0], operands[1], operands[2],
11418                     operands[3], operands[4], 0);
11419   DONE;
11420 })
11421
11422 (define_expand "call_value"
11423   [(set (match_operand 0 "" "")
11424         (call (match_operand:QI 1 "" "")
11425               (match_operand:SI 2 "" "")))
11426    (use (match_operand:SI 3 "" ""))]
11427   ;; Operand 3 is not used on the i386.
11428   ""
11429 {
11430   ix86_expand_call (operands[0], operands[1], operands[2],
11431                     operands[3], NULL, 0);
11432   DONE;
11433 })
11434
11435 (define_expand "sibcall_value"
11436   [(set (match_operand 0 "" "")
11437         (call (match_operand:QI 1 "" "")
11438               (match_operand:SI 2 "" "")))
11439    (use (match_operand:SI 3 "" ""))]
11440   ;; Operand 3 is not used on the i386.
11441   ""
11442 {
11443   ix86_expand_call (operands[0], operands[1], operands[2],
11444                     operands[3], NULL, 1);
11445   DONE;
11446 })
11447
11448 ;; Call subroutine returning any type.
11449
11450 (define_expand "untyped_call"
11451   [(parallel [(call (match_operand 0 "" "")
11452                     (const_int 0))
11453               (match_operand 1 "" "")
11454               (match_operand 2 "" "")])]
11455   ""
11456 {
11457   int i;
11458
11459   /* In order to give reg-stack an easier job in validating two
11460      coprocessor registers as containing a possible return value,
11461      simply pretend the untyped call returns a complex long double
11462      value. 
11463
11464      We can't use SSE_REGPARM_MAX here since callee is unprototyped
11465      and should have the default ABI.  */
11466
11467   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11468                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11469                     operands[0], const0_rtx,
11470                     GEN_INT ((TARGET_64BIT
11471                               ? (ix86_abi == SYSV_ABI
11472                                  ? X86_64_SSE_REGPARM_MAX
11473                                  : X86_64_MS_SSE_REGPARM_MAX)
11474                               : X86_32_SSE_REGPARM_MAX)
11475                              - 1),
11476                     NULL, 0);
11477
11478   for (i = 0; i < XVECLEN (operands[2], 0); i++)
11479     {
11480       rtx set = XVECEXP (operands[2], 0, i);
11481       emit_move_insn (SET_DEST (set), SET_SRC (set));
11482     }
11483
11484   /* The optimizer does not know that the call sets the function value
11485      registers we stored in the result block.  We avoid problems by
11486      claiming that all hard registers are used and clobbered at this
11487      point.  */
11488   emit_insn (gen_blockage ());
11489
11490   DONE;
11491 })
11492 \f
11493 ;; Prologue and epilogue instructions
11494
11495 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11496 ;; all of memory.  This blocks insns from being moved across this point.
11497
11498 (define_insn "blockage"
11499   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11500   ""
11501   ""
11502   [(set_attr "length" "0")])
11503
11504 ;; Do not schedule instructions accessing memory across this point.
11505
11506 (define_expand "memory_blockage"
11507   [(set (match_dup 0)
11508         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11509   ""
11510 {
11511   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11512   MEM_VOLATILE_P (operands[0]) = 1;
11513 })
11514
11515 (define_insn "*memory_blockage"
11516   [(set (match_operand:BLK 0 "" "")
11517         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11518   ""
11519   ""
11520   [(set_attr "length" "0")])
11521
11522 ;; As USE insns aren't meaningful after reload, this is used instead
11523 ;; to prevent deleting instructions setting registers for PIC code
11524 (define_insn "prologue_use"
11525   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11526   ""
11527   ""
11528   [(set_attr "length" "0")])
11529
11530 ;; Insn emitted into the body of a function to return from a function.
11531 ;; This is only done if the function's epilogue is known to be simple.
11532 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11533
11534 (define_expand "return"
11535   [(return)]
11536   "ix86_can_use_return_insn_p ()"
11537 {
11538   if (crtl->args.pops_args)
11539     {
11540       rtx popc = GEN_INT (crtl->args.pops_args);
11541       emit_jump_insn (gen_return_pop_internal (popc));
11542       DONE;
11543     }
11544 })
11545
11546 (define_insn "return_internal"
11547   [(return)]
11548   "reload_completed"
11549   "ret"
11550   [(set_attr "length" "1")
11551    (set_attr "atom_unit" "jeu")
11552    (set_attr "length_immediate" "0")
11553    (set_attr "modrm" "0")])
11554
11555 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11556 ;; instruction Athlon and K8 have.
11557
11558 (define_insn "return_internal_long"
11559   [(return)
11560    (unspec [(const_int 0)] UNSPEC_REP)]
11561   "reload_completed"
11562   "rep\;ret"
11563   [(set_attr "length" "2")
11564    (set_attr "atom_unit" "jeu")
11565    (set_attr "length_immediate" "0")
11566    (set_attr "prefix_rep" "1")
11567    (set_attr "modrm" "0")])
11568
11569 (define_insn "return_pop_internal"
11570   [(return)
11571    (use (match_operand:SI 0 "const_int_operand" ""))]
11572   "reload_completed"
11573   "ret\t%0"
11574   [(set_attr "length" "3")
11575    (set_attr "atom_unit" "jeu")
11576    (set_attr "length_immediate" "2")
11577    (set_attr "modrm" "0")])
11578
11579 (define_insn "return_indirect_internal"
11580   [(return)
11581    (use (match_operand:SI 0 "register_operand" "r"))]
11582   "reload_completed"
11583   "jmp\t%A0"
11584   [(set_attr "type" "ibr")
11585    (set_attr "length_immediate" "0")])
11586
11587 (define_insn "nop"
11588   [(const_int 0)]
11589   ""
11590   "nop"
11591   [(set_attr "length" "1")
11592    (set_attr "length_immediate" "0")
11593    (set_attr "modrm" "0")])
11594
11595 ;; Generate nops.  Operand 0 is the number of nops, up to 8.
11596 (define_insn "nops"
11597   [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
11598                     UNSPECV_NOPS)]
11599   "reload_completed"
11600 {
11601   int num = INTVAL (operands[0]);
11602
11603   gcc_assert (num >= 1 && num <= 8);
11604
11605   while (num--)
11606     fputs ("\tnop\n", asm_out_file);
11607
11608   return "";
11609 }
11610   [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11611    (set_attr "length_immediate" "0")
11612    (set_attr "modrm" "0")])
11613
11614 ;; Pad to 16-byte boundary, max skip in op0.  Used to avoid
11615 ;; branch prediction penalty for the third jump in a 16-byte
11616 ;; block on K8.
11617
11618 (define_insn "pad"
11619   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
11620   ""
11621 {
11622 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11623   ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11624 #else
11625   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11626      The align insn is used to avoid 3 jump instructions in the row to improve
11627      branch prediction and the benefits hardly outweigh the cost of extra 8
11628      nops on the average inserted by full alignment pseudo operation.  */
11629 #endif
11630   return "";
11631 }
11632   [(set_attr "length" "16")])
11633
11634 (define_expand "prologue"
11635   [(const_int 0)]
11636   ""
11637   "ix86_expand_prologue (); DONE;")
11638
11639 (define_insn "set_got"
11640   [(set (match_operand:SI 0 "register_operand" "=r")
11641         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11642    (clobber (reg:CC FLAGS_REG))]
11643   "!TARGET_64BIT"
11644   "* return output_set_got (operands[0], NULL_RTX);"
11645   [(set_attr "type" "multi")
11646    (set_attr "length" "12")])
11647
11648 (define_insn "set_got_labelled"
11649   [(set (match_operand:SI 0 "register_operand" "=r")
11650         (unspec:SI [(label_ref (match_operand 1 "" ""))]
11651          UNSPEC_SET_GOT))
11652    (clobber (reg:CC FLAGS_REG))]
11653   "!TARGET_64BIT"
11654   "* return output_set_got (operands[0], operands[1]);"
11655   [(set_attr "type" "multi")
11656    (set_attr "length" "12")])
11657
11658 (define_insn "set_got_rex64"
11659   [(set (match_operand:DI 0 "register_operand" "=r")
11660         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11661   "TARGET_64BIT"
11662   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11663   [(set_attr "type" "lea")
11664    (set_attr "length_address" "4")
11665    (set_attr "mode" "DI")])
11666
11667 (define_insn "set_rip_rex64"
11668   [(set (match_operand:DI 0 "register_operand" "=r")
11669         (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
11670   "TARGET_64BIT"
11671   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11672   [(set_attr "type" "lea")
11673    (set_attr "length_address" "4")
11674    (set_attr "mode" "DI")])
11675
11676 (define_insn "set_got_offset_rex64"
11677   [(set (match_operand:DI 0 "register_operand" "=r")
11678         (unspec:DI
11679           [(label_ref (match_operand 1 "" ""))]
11680           UNSPEC_SET_GOT_OFFSET))]
11681   "TARGET_64BIT"
11682   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11683   [(set_attr "type" "imov")
11684    (set_attr "length_immediate" "0")
11685    (set_attr "length_address" "8")
11686    (set_attr "mode" "DI")])
11687
11688 (define_expand "epilogue"
11689   [(const_int 0)]
11690   ""
11691   "ix86_expand_epilogue (1); DONE;")
11692
11693 (define_expand "sibcall_epilogue"
11694   [(const_int 0)]
11695   ""
11696   "ix86_expand_epilogue (0); DONE;")
11697
11698 (define_expand "eh_return"
11699   [(use (match_operand 0 "register_operand" ""))]
11700   ""
11701 {
11702   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11703
11704   /* Tricky bit: we write the address of the handler to which we will
11705      be returning into someone else's stack frame, one word below the
11706      stack address we wish to restore.  */
11707   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11708   tmp = plus_constant (tmp, -UNITS_PER_WORD);
11709   tmp = gen_rtx_MEM (Pmode, tmp);
11710   emit_move_insn (tmp, ra);
11711
11712   emit_jump_insn (gen_eh_return_internal ());
11713   emit_barrier ();
11714   DONE;
11715 })
11716
11717 (define_insn_and_split "eh_return_internal"
11718   [(eh_return)]
11719   ""
11720   "#"
11721   "epilogue_completed"
11722   [(const_int 0)]
11723   "ix86_expand_epilogue (2); DONE;")
11724
11725 (define_insn "leave"
11726   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11727    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11728    (clobber (mem:BLK (scratch)))]
11729   "!TARGET_64BIT"
11730   "leave"
11731   [(set_attr "type" "leave")])
11732
11733 (define_insn "leave_rex64"
11734   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11735    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11736    (clobber (mem:BLK (scratch)))]
11737   "TARGET_64BIT"
11738   "leave"
11739   [(set_attr "type" "leave")])
11740 \f
11741 ;; Handle -fsplit-stack.
11742
11743 (define_expand "split_stack_prologue"
11744   [(const_int 0)]
11745   ""
11746 {
11747   ix86_expand_split_stack_prologue ();
11748   DONE;
11749 })
11750
11751 ;; In order to support the call/return predictor, we use a return
11752 ;; instruction which the middle-end doesn't see.
11753 (define_insn "split_stack_return"
11754   [(unspec [(match_operand:SI 0 "const_int_operand" "")]
11755             UNSPEC_STACK_CHECK)]
11756   ""
11757 {
11758   if (operands[0] == const0_rtx)
11759     return "ret";
11760   else
11761     return "ret\t%0";
11762 }
11763   [(set_attr "atom_unit" "jeu")
11764    (set_attr "modrm" "0")
11765    (set (attr "length")
11766         (if_then_else (match_operand:SI 0 "const0_operand" "")
11767                       (const_int 1)
11768                       (const_int 3)))
11769    (set (attr "length_immediate")
11770         (if_then_else (match_operand:SI 0 "const0_operand" "")
11771                       (const_int 0)
11772                       (const_int 2)))])
11773
11774 ;; If there are operand 0 bytes available on the stack, jump to
11775 ;; operand 1.
11776
11777 (define_expand "split_stack_space_check"
11778   [(set (pc) (if_then_else
11779               (ltu (minus (reg SP_REG)
11780                           (match_operand 0 "register_operand" ""))
11781                    (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11782               (label_ref (match_operand 1 "" ""))
11783               (pc)))]
11784   ""
11785 {
11786   rtx reg, size, limit;
11787
11788   reg = gen_reg_rtx (Pmode);
11789   size = force_reg (Pmode, operands[0]);
11790   emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
11791   limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
11792                           UNSPEC_STACK_CHECK);
11793   limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
11794   ix86_expand_branch (GEU, reg, limit, operands[1]);
11795
11796   DONE;
11797 })
11798 \f
11799 ;; Bit manipulation instructions.
11800
11801 (define_expand "ffs<mode>2"
11802   [(set (match_dup 2) (const_int -1))
11803    (parallel [(set (reg:CCZ FLAGS_REG)
11804                    (compare:CCZ
11805                      (match_operand:SWI48 1 "nonimmediate_operand" "")
11806                      (const_int 0)))
11807               (set (match_operand:SWI48 0 "register_operand" "")
11808                    (ctz:SWI48 (match_dup 1)))])
11809    (set (match_dup 0) (if_then_else:SWI48
11810                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
11811                         (match_dup 2)
11812                         (match_dup 0)))
11813    (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11814               (clobber (reg:CC FLAGS_REG))])]
11815   ""
11816 {
11817   if (<MODE>mode == SImode && !TARGET_CMOVE)
11818     {
11819       emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
11820       DONE;
11821     }
11822   operands[2] = gen_reg_rtx (<MODE>mode);
11823 })
11824
11825 (define_insn_and_split "ffssi2_no_cmove"
11826   [(set (match_operand:SI 0 "register_operand" "=r")
11827         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
11828    (clobber (match_scratch:SI 2 "=&q"))
11829    (clobber (reg:CC FLAGS_REG))]
11830   "!TARGET_CMOVE"
11831   "#"
11832   "&& reload_completed"
11833   [(parallel [(set (reg:CCZ FLAGS_REG)
11834                    (compare:CCZ (match_dup 1) (const_int 0)))
11835               (set (match_dup 0) (ctz:SI (match_dup 1)))])
11836    (set (strict_low_part (match_dup 3))
11837         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
11838    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
11839               (clobber (reg:CC FLAGS_REG))])
11840    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
11841               (clobber (reg:CC FLAGS_REG))])
11842    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
11843               (clobber (reg:CC FLAGS_REG))])]
11844 {
11845   operands[3] = gen_lowpart (QImode, operands[2]);
11846   ix86_expand_clear (operands[2]);
11847 })
11848
11849 (define_insn "*ffs<mode>_1"
11850   [(set (reg:CCZ FLAGS_REG)
11851         (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11852                      (const_int 0)))
11853    (set (match_operand:SWI48 0 "register_operand" "=r")
11854         (ctz:SWI48 (match_dup 1)))]
11855   ""
11856   "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
11857   [(set_attr "type" "alu1")
11858    (set_attr "prefix_0f" "1")
11859    (set_attr "mode" "<MODE>")])
11860
11861 (define_insn "ctz<mode>2"
11862   [(set (match_operand:SWI48 0 "register_operand" "=r")
11863         (ctz:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
11864    (clobber (reg:CC FLAGS_REG))]
11865   ""
11866   "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
11867   [(set_attr "type" "alu1")
11868    (set_attr "prefix_0f" "1")
11869    (set_attr "mode" "<MODE>")])
11870
11871 (define_expand "clz<mode>2"
11872   [(parallel
11873      [(set (match_operand:SWI248 0 "register_operand" "")
11874            (minus:SWI248
11875              (match_dup 2)
11876              (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
11877       (clobber (reg:CC FLAGS_REG))])
11878    (parallel
11879      [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
11880       (clobber (reg:CC FLAGS_REG))])]
11881   ""
11882 {
11883   if (TARGET_ABM)
11884     {
11885       emit_insn (gen_clz<mode>2_abm (operands[0], operands[1]));
11886       DONE;
11887     }
11888   operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
11889 })
11890
11891 (define_insn "clz<mode>2_abm"
11892   [(set (match_operand:SWI248 0 "register_operand" "=r")
11893         (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11894    (clobber (reg:CC FLAGS_REG))]
11895   "TARGET_ABM"
11896   "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
11897   [(set_attr "prefix_rep" "1")
11898    (set_attr "type" "bitmanip")
11899    (set_attr "mode" "<MODE>")])
11900
11901 (define_insn "bsr_rex64"
11902   [(set (match_operand:DI 0 "register_operand" "=r")
11903         (minus:DI (const_int 63)
11904                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
11905    (clobber (reg:CC FLAGS_REG))]
11906   "TARGET_64BIT"
11907   "bsr{q}\t{%1, %0|%0, %1}"
11908   [(set_attr "type" "alu1")
11909    (set_attr "prefix_0f" "1")
11910    (set_attr "mode" "DI")])
11911
11912 (define_insn "bsr"
11913   [(set (match_operand:SI 0 "register_operand" "=r")
11914         (minus:SI (const_int 31)
11915                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
11916    (clobber (reg:CC FLAGS_REG))]
11917   ""
11918   "bsr{l}\t{%1, %0|%0, %1}"
11919   [(set_attr "type" "alu1")
11920    (set_attr "prefix_0f" "1")
11921    (set_attr "mode" "SI")])
11922
11923 (define_insn "*bsrhi"
11924   [(set (match_operand:HI 0 "register_operand" "=r")
11925         (minus:HI (const_int 15)
11926                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
11927    (clobber (reg:CC FLAGS_REG))]
11928   ""
11929   "bsr{w}\t{%1, %0|%0, %1}"
11930   [(set_attr "type" "alu1")
11931    (set_attr "prefix_0f" "1")
11932    (set_attr "mode" "HI")])
11933
11934 (define_insn "popcount<mode>2"
11935   [(set (match_operand:SWI248 0 "register_operand" "=r")
11936         (popcount:SWI248
11937           (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11938    (clobber (reg:CC FLAGS_REG))]
11939   "TARGET_POPCNT"
11940 {
11941 #if TARGET_MACHO
11942   return "popcnt\t{%1, %0|%0, %1}";
11943 #else
11944   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
11945 #endif
11946 }
11947   [(set_attr "prefix_rep" "1")
11948    (set_attr "type" "bitmanip")
11949    (set_attr "mode" "<MODE>")])
11950
11951 (define_insn "*popcount<mode>2_cmp"
11952   [(set (reg FLAGS_REG)
11953         (compare
11954           (popcount:SWI248
11955             (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
11956           (const_int 0)))
11957    (set (match_operand:SWI248 0 "register_operand" "=r")
11958         (popcount:SWI248 (match_dup 1)))]
11959   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
11960 {
11961 #if TARGET_MACHO
11962   return "popcnt\t{%1, %0|%0, %1}";
11963 #else
11964   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
11965 #endif
11966 }
11967   [(set_attr "prefix_rep" "1")
11968    (set_attr "type" "bitmanip")
11969    (set_attr "mode" "<MODE>")])
11970
11971 (define_insn "*popcountsi2_cmp_zext"
11972   [(set (reg FLAGS_REG)
11973         (compare
11974           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
11975           (const_int 0)))
11976    (set (match_operand:DI 0 "register_operand" "=r")
11977         (zero_extend:DI(popcount:SI (match_dup 1))))]
11978   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
11979 {
11980 #if TARGET_MACHO
11981   return "popcnt\t{%1, %0|%0, %1}";
11982 #else
11983   return "popcnt{l}\t{%1, %0|%0, %1}";
11984 #endif
11985 }
11986   [(set_attr "prefix_rep" "1")
11987    (set_attr "type" "bitmanip")
11988    (set_attr "mode" "SI")])
11989
11990 (define_expand "bswap<mode>2"
11991   [(set (match_operand:SWI48 0 "register_operand" "")
11992         (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
11993   ""
11994 {
11995   if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
11996     {
11997       rtx x = operands[0];
11998
11999       emit_move_insn (x, operands[1]);
12000       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12001       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12002       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12003       DONE;
12004     }
12005 })
12006
12007 (define_insn "*bswap<mode>2_movbe"
12008   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12009         (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12010   "TARGET_MOVBE
12011    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12012   "@
12013     bswap\t%0
12014     movbe\t{%1, %0|%0, %1}
12015     movbe\t{%1, %0|%0, %1}"
12016   [(set_attr "type" "bitmanip,imov,imov")
12017    (set_attr "modrm" "0,1,1")
12018    (set_attr "prefix_0f" "*,1,1")
12019    (set_attr "prefix_extra" "*,1,1")
12020    (set_attr "mode" "<MODE>")])
12021
12022 (define_insn "*bswap<mode>2_1"
12023   [(set (match_operand:SWI48 0 "register_operand" "=r")
12024         (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12025   "TARGET_BSWAP"
12026   "bswap\t%0"
12027   [(set_attr "type" "bitmanip")
12028    (set_attr "modrm" "0")
12029    (set_attr "mode" "<MODE>")])
12030
12031 (define_insn "*bswaphi_lowpart_1"
12032   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12033         (bswap:HI (match_dup 0)))
12034    (clobber (reg:CC FLAGS_REG))]
12035   "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12036   "@
12037     xchg{b}\t{%h0, %b0|%b0, %h0}
12038     rol{w}\t{$8, %0|%0, 8}"
12039   [(set_attr "length" "2,4")
12040    (set_attr "mode" "QI,HI")])
12041
12042 (define_insn "bswaphi_lowpart"
12043   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12044         (bswap:HI (match_dup 0)))
12045    (clobber (reg:CC FLAGS_REG))]
12046   ""
12047   "rol{w}\t{$8, %0|%0, 8}"
12048   [(set_attr "length" "4")
12049    (set_attr "mode" "HI")])
12050
12051 (define_expand "paritydi2"
12052   [(set (match_operand:DI 0 "register_operand" "")
12053         (parity:DI (match_operand:DI 1 "register_operand" "")))]
12054   "! TARGET_POPCNT"
12055 {
12056   rtx scratch = gen_reg_rtx (QImode);
12057   rtx cond;
12058
12059   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12060                                 NULL_RTX, operands[1]));
12061
12062   cond = gen_rtx_fmt_ee (ORDERED, QImode,
12063                          gen_rtx_REG (CCmode, FLAGS_REG),
12064                          const0_rtx);
12065   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12066
12067   if (TARGET_64BIT)
12068     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12069   else
12070     {
12071       rtx tmp = gen_reg_rtx (SImode);
12072
12073       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12074       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12075     }
12076   DONE;
12077 })
12078
12079 (define_expand "paritysi2"
12080   [(set (match_operand:SI 0 "register_operand" "")
12081         (parity:SI (match_operand:SI 1 "register_operand" "")))]
12082   "! TARGET_POPCNT"
12083 {
12084   rtx scratch = gen_reg_rtx (QImode);
12085   rtx cond;
12086
12087   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12088
12089   cond = gen_rtx_fmt_ee (ORDERED, QImode,
12090                          gen_rtx_REG (CCmode, FLAGS_REG),
12091                          const0_rtx);
12092   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12093
12094   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12095   DONE;
12096 })
12097
12098 (define_insn_and_split "paritydi2_cmp"
12099   [(set (reg:CC FLAGS_REG)
12100         (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12101                    UNSPEC_PARITY))
12102    (clobber (match_scratch:DI 0 "=r"))
12103    (clobber (match_scratch:SI 1 "=&r"))
12104    (clobber (match_scratch:HI 2 "=Q"))]
12105   "! TARGET_POPCNT"
12106   "#"
12107   "&& reload_completed"
12108   [(parallel
12109      [(set (match_dup 1)
12110            (xor:SI (match_dup 1) (match_dup 4)))
12111       (clobber (reg:CC FLAGS_REG))])
12112    (parallel
12113      [(set (reg:CC FLAGS_REG)
12114            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12115       (clobber (match_dup 1))
12116       (clobber (match_dup 2))])]
12117 {
12118   operands[4] = gen_lowpart (SImode, operands[3]);
12119
12120   if (TARGET_64BIT)
12121     {
12122       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12123       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12124     }
12125   else
12126     operands[1] = gen_highpart (SImode, operands[3]);
12127 })
12128
12129 (define_insn_and_split "paritysi2_cmp"
12130   [(set (reg:CC FLAGS_REG)
12131         (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12132                    UNSPEC_PARITY))
12133    (clobber (match_scratch:SI 0 "=r"))
12134    (clobber (match_scratch:HI 1 "=&Q"))]
12135   "! TARGET_POPCNT"
12136   "#"
12137   "&& reload_completed"
12138   [(parallel
12139      [(set (match_dup 1)
12140            (xor:HI (match_dup 1) (match_dup 3)))
12141       (clobber (reg:CC FLAGS_REG))])
12142    (parallel
12143      [(set (reg:CC FLAGS_REG)
12144            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12145       (clobber (match_dup 1))])]
12146 {
12147   operands[3] = gen_lowpart (HImode, operands[2]);
12148
12149   emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12150   emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12151 })
12152
12153 (define_insn "*parityhi2_cmp"
12154   [(set (reg:CC FLAGS_REG)
12155         (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12156                    UNSPEC_PARITY))
12157    (clobber (match_scratch:HI 0 "=Q"))]
12158   "! TARGET_POPCNT"
12159   "xor{b}\t{%h0, %b0|%b0, %h0}"
12160   [(set_attr "length" "2")
12161    (set_attr "mode" "HI")])
12162 \f
12163 ;; Thread-local storage patterns for ELF.
12164 ;;
12165 ;; Note that these code sequences must appear exactly as shown
12166 ;; in order to allow linker relaxation.
12167
12168 (define_insn "*tls_global_dynamic_32_gnu"
12169   [(set (match_operand:SI 0 "register_operand" "=a")
12170         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12171                     (match_operand:SI 2 "tls_symbolic_operand" "")
12172                     (match_operand:SI 3 "call_insn_operand" "")]
12173                     UNSPEC_TLS_GD))
12174    (clobber (match_scratch:SI 4 "=d"))
12175    (clobber (match_scratch:SI 5 "=c"))
12176    (clobber (reg:CC FLAGS_REG))]
12177   "!TARGET_64BIT && TARGET_GNU_TLS"
12178   "lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}\;call\t%P3"
12179   [(set_attr "type" "multi")
12180    (set_attr "length" "12")])
12181
12182 (define_expand "tls_global_dynamic_32"
12183   [(parallel [(set (match_operand:SI 0 "register_operand" "")
12184                    (unspec:SI
12185                     [(match_dup 2)
12186                      (match_operand:SI 1 "tls_symbolic_operand" "")
12187                      (match_dup 3)]
12188                     UNSPEC_TLS_GD))
12189               (clobber (match_scratch:SI 4 ""))
12190               (clobber (match_scratch:SI 5 ""))
12191               (clobber (reg:CC FLAGS_REG))])]
12192   ""
12193 {
12194   if (flag_pic)
12195     operands[2] = pic_offset_table_rtx;
12196   else
12197     {
12198       operands[2] = gen_reg_rtx (Pmode);
12199       emit_insn (gen_set_got (operands[2]));
12200     }
12201   if (TARGET_GNU2_TLS)
12202     {
12203        emit_insn (gen_tls_dynamic_gnu2_32
12204                   (operands[0], operands[1], operands[2]));
12205        DONE;
12206     }
12207   operands[3] = ix86_tls_get_addr ();
12208 })
12209
12210 (define_insn "*tls_global_dynamic_64"
12211   [(set (match_operand:DI 0 "register_operand" "=a")
12212         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
12213                  (match_operand:DI 3 "" "")))
12214    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12215               UNSPEC_TLS_GD)]
12216   "TARGET_64BIT"
12217   { 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"; }
12218   [(set_attr "type" "multi")
12219    (set_attr "length" "16")])
12220
12221 (define_expand "tls_global_dynamic_64"
12222   [(parallel [(set (match_operand:DI 0 "register_operand" "")
12223                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
12224               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12225                          UNSPEC_TLS_GD)])]
12226   ""
12227 {
12228   if (TARGET_GNU2_TLS)
12229     {
12230        emit_insn (gen_tls_dynamic_gnu2_64
12231                   (operands[0], operands[1]));
12232        DONE;
12233     }
12234   operands[2] = ix86_tls_get_addr ();
12235 })
12236
12237 (define_insn "*tls_local_dynamic_base_32_gnu"
12238   [(set (match_operand:SI 0 "register_operand" "=a")
12239         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12240                     (match_operand:SI 2 "call_insn_operand" "")]
12241                    UNSPEC_TLS_LD_BASE))
12242    (clobber (match_scratch:SI 3 "=d"))
12243    (clobber (match_scratch:SI 4 "=c"))
12244    (clobber (reg:CC FLAGS_REG))]
12245   "!TARGET_64BIT && TARGET_GNU_TLS"
12246   "lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}\;call\t%P2"
12247   [(set_attr "type" "multi")
12248    (set_attr "length" "11")])
12249
12250 (define_expand "tls_local_dynamic_base_32"
12251   [(parallel [(set (match_operand:SI 0 "register_operand" "")
12252                    (unspec:SI [(match_dup 1) (match_dup 2)]
12253                               UNSPEC_TLS_LD_BASE))
12254               (clobber (match_scratch:SI 3 ""))
12255               (clobber (match_scratch:SI 4 ""))
12256               (clobber (reg:CC FLAGS_REG))])]
12257   ""
12258 {
12259   if (flag_pic)
12260     operands[1] = pic_offset_table_rtx;
12261   else
12262     {
12263       operands[1] = gen_reg_rtx (Pmode);
12264       emit_insn (gen_set_got (operands[1]));
12265     }
12266   if (TARGET_GNU2_TLS)
12267     {
12268        emit_insn (gen_tls_dynamic_gnu2_32
12269                   (operands[0], ix86_tls_module_base (), operands[1]));
12270        DONE;
12271     }
12272   operands[2] = ix86_tls_get_addr ();
12273 })
12274
12275 (define_insn "*tls_local_dynamic_base_64"
12276   [(set (match_operand:DI 0 "register_operand" "=a")
12277         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
12278                  (match_operand:DI 2 "" "")))
12279    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12280   "TARGET_64BIT"
12281   "lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}\;call\t%P1"
12282   [(set_attr "type" "multi")
12283    (set_attr "length" "12")])
12284
12285 (define_expand "tls_local_dynamic_base_64"
12286   [(parallel [(set (match_operand:DI 0 "register_operand" "")
12287                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
12288               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
12289   ""
12290 {
12291   if (TARGET_GNU2_TLS)
12292     {
12293        emit_insn (gen_tls_dynamic_gnu2_64
12294                   (operands[0], ix86_tls_module_base ()));
12295        DONE;
12296     }
12297   operands[1] = ix86_tls_get_addr ();
12298 })
12299
12300 ;; Local dynamic of a single variable is a lose.  Show combine how
12301 ;; to convert that back to global dynamic.
12302
12303 (define_insn_and_split "*tls_local_dynamic_32_once"
12304   [(set (match_operand:SI 0 "register_operand" "=a")
12305         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12306                              (match_operand:SI 2 "call_insn_operand" "")]
12307                             UNSPEC_TLS_LD_BASE)
12308                  (const:SI (unspec:SI
12309                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
12310                             UNSPEC_DTPOFF))))
12311    (clobber (match_scratch:SI 4 "=d"))
12312    (clobber (match_scratch:SI 5 "=c"))
12313    (clobber (reg:CC FLAGS_REG))]
12314   ""
12315   "#"
12316   ""
12317   [(parallel [(set (match_dup 0)
12318                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12319                               UNSPEC_TLS_GD))
12320               (clobber (match_dup 4))
12321               (clobber (match_dup 5))
12322               (clobber (reg:CC FLAGS_REG))])])
12323
12324 ;; Segment register for the thread base ptr load
12325 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12326
12327 ;; Load and add the thread base pointer from %gs:0.
12328 (define_insn "*load_tp_<mode>"
12329   [(set (match_operand:P 0 "register_operand" "=r")
12330         (unspec:P [(const_int 0)] UNSPEC_TP))]
12331   ""
12332   "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12333   [(set_attr "type" "imov")
12334    (set_attr "modrm" "0")
12335    (set_attr "length" "7")
12336    (set_attr "memory" "load")
12337    (set_attr "imm_disp" "false")])
12338
12339 (define_insn "*add_tp_<mode>"
12340   [(set (match_operand:P 0 "register_operand" "=r")
12341         (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12342                 (match_operand:P 1 "register_operand" "0")))
12343    (clobber (reg:CC FLAGS_REG))]
12344   ""
12345   "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12346   [(set_attr "type" "alu")
12347    (set_attr "modrm" "0")
12348    (set_attr "length" "7")
12349    (set_attr "memory" "load")
12350    (set_attr "imm_disp" "false")])
12351
12352 ;; GNU2 TLS patterns can be split.
12353
12354 (define_expand "tls_dynamic_gnu2_32"
12355   [(set (match_dup 3)
12356         (plus:SI (match_operand:SI 2 "register_operand" "")
12357                  (const:SI
12358                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12359                              UNSPEC_TLSDESC))))
12360    (parallel
12361     [(set (match_operand:SI 0 "register_operand" "")
12362           (unspec:SI [(match_dup 1) (match_dup 3)
12363                       (match_dup 2) (reg:SI SP_REG)]
12364                       UNSPEC_TLSDESC))
12365      (clobber (reg:CC FLAGS_REG))])]
12366   "!TARGET_64BIT && TARGET_GNU2_TLS"
12367 {
12368   operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12369   ix86_tls_descriptor_calls_expanded_in_cfun = true;
12370 })
12371
12372 (define_insn "*tls_dynamic_lea_32"
12373   [(set (match_operand:SI 0 "register_operand" "=r")
12374         (plus:SI (match_operand:SI 1 "register_operand" "b")
12375                  (const:SI
12376                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12377                               UNSPEC_TLSDESC))))]
12378   "!TARGET_64BIT && TARGET_GNU2_TLS"
12379   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
12380   [(set_attr "type" "lea")
12381    (set_attr "mode" "SI")
12382    (set_attr "length" "6")
12383    (set_attr "length_address" "4")])
12384
12385 (define_insn "*tls_dynamic_call_32"
12386   [(set (match_operand:SI 0 "register_operand" "=a")
12387         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12388                     (match_operand:SI 2 "register_operand" "0")
12389                     ;; we have to make sure %ebx still points to the GOT
12390                     (match_operand:SI 3 "register_operand" "b")
12391                     (reg:SI SP_REG)]
12392                    UNSPEC_TLSDESC))
12393    (clobber (reg:CC FLAGS_REG))]
12394   "!TARGET_64BIT && TARGET_GNU2_TLS"
12395   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12396   [(set_attr "type" "call")
12397    (set_attr "length" "2")
12398    (set_attr "length_address" "0")])
12399
12400 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12401   [(set (match_operand:SI 0 "register_operand" "=&a")
12402         (plus:SI
12403          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12404                      (match_operand:SI 4 "" "")
12405                      (match_operand:SI 2 "register_operand" "b")
12406                      (reg:SI SP_REG)]
12407                     UNSPEC_TLSDESC)
12408          (const:SI (unspec:SI
12409                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
12410                     UNSPEC_DTPOFF))))
12411    (clobber (reg:CC FLAGS_REG))]
12412   "!TARGET_64BIT && TARGET_GNU2_TLS"
12413   "#"
12414   ""
12415   [(set (match_dup 0) (match_dup 5))]
12416 {
12417   operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12418   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12419 })
12420
12421 (define_expand "tls_dynamic_gnu2_64"
12422   [(set (match_dup 2)
12423         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12424                    UNSPEC_TLSDESC))
12425    (parallel
12426     [(set (match_operand:DI 0 "register_operand" "")
12427           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12428                      UNSPEC_TLSDESC))
12429      (clobber (reg:CC FLAGS_REG))])]
12430   "TARGET_64BIT && TARGET_GNU2_TLS"
12431 {
12432   operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12433   ix86_tls_descriptor_calls_expanded_in_cfun = true;
12434 })
12435
12436 (define_insn "*tls_dynamic_lea_64"
12437   [(set (match_operand:DI 0 "register_operand" "=r")
12438         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12439                    UNSPEC_TLSDESC))]
12440   "TARGET_64BIT && TARGET_GNU2_TLS"
12441   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
12442   [(set_attr "type" "lea")
12443    (set_attr "mode" "DI")
12444    (set_attr "length" "7")
12445    (set_attr "length_address" "4")])
12446
12447 (define_insn "*tls_dynamic_call_64"
12448   [(set (match_operand:DI 0 "register_operand" "=a")
12449         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
12450                     (match_operand:DI 2 "register_operand" "0")
12451                     (reg:DI SP_REG)]
12452                    UNSPEC_TLSDESC))
12453    (clobber (reg:CC FLAGS_REG))]
12454   "TARGET_64BIT && TARGET_GNU2_TLS"
12455   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12456   [(set_attr "type" "call")
12457    (set_attr "length" "2")
12458    (set_attr "length_address" "0")])
12459
12460 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12461   [(set (match_operand:DI 0 "register_operand" "=&a")
12462         (plus:DI
12463          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12464                      (match_operand:DI 3 "" "")
12465                      (reg:DI SP_REG)]
12466                     UNSPEC_TLSDESC)
12467          (const:DI (unspec:DI
12468                     [(match_operand:DI 1 "tls_symbolic_operand" "")]
12469                     UNSPEC_DTPOFF))))
12470    (clobber (reg:CC FLAGS_REG))]
12471   "TARGET_64BIT && TARGET_GNU2_TLS"
12472   "#"
12473   ""
12474   [(set (match_dup 0) (match_dup 4))]
12475 {
12476   operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12477   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12478 })
12479 \f
12480 ;; These patterns match the binary 387 instructions for addM3, subM3,
12481 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
12482 ;; SFmode.  The first is the normal insn, the second the same insn but
12483 ;; with one operand a conversion, and the third the same insn but with
12484 ;; the other operand a conversion.  The conversion may be SFmode or
12485 ;; SImode if the target mode DFmode, but only SImode if the target mode
12486 ;; is SFmode.
12487
12488 ;; Gcc is slightly more smart about handling normal two address instructions
12489 ;; so use special patterns for add and mull.
12490
12491 (define_insn "*fop_<mode>_comm_mixed_avx"
12492   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
12493         (match_operator:MODEF 3 "binary_fp_operator"
12494           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
12495            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
12496   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12497    && COMMUTATIVE_ARITH_P (operands[3])
12498    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12499   "* return output_387_binary_op (insn, operands);"
12500   [(set (attr "type")
12501         (if_then_else (eq_attr "alternative" "1")
12502            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12503               (const_string "ssemul")
12504               (const_string "sseadd"))
12505            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12506               (const_string "fmul")
12507               (const_string "fop"))))
12508    (set_attr "prefix" "orig,maybe_vex")
12509    (set_attr "mode" "<MODE>")])
12510
12511 (define_insn "*fop_<mode>_comm_mixed"
12512   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
12513         (match_operator:MODEF 3 "binary_fp_operator"
12514           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
12515            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
12516   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12517    && COMMUTATIVE_ARITH_P (operands[3])
12518    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12519   "* return output_387_binary_op (insn, operands);"
12520   [(set (attr "type")
12521         (if_then_else (eq_attr "alternative" "1")
12522            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12523               (const_string "ssemul")
12524               (const_string "sseadd"))
12525            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12526               (const_string "fmul")
12527               (const_string "fop"))))
12528    (set_attr "mode" "<MODE>")])
12529
12530 (define_insn "*fop_<mode>_comm_avx"
12531   [(set (match_operand:MODEF 0 "register_operand" "=x")
12532         (match_operator:MODEF 3 "binary_fp_operator"
12533           [(match_operand:MODEF 1 "nonimmediate_operand" "%x")
12534            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12535   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12536    && COMMUTATIVE_ARITH_P (operands[3])
12537    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12538   "* return output_387_binary_op (insn, operands);"
12539   [(set (attr "type")
12540         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12541            (const_string "ssemul")
12542            (const_string "sseadd")))
12543    (set_attr "prefix" "vex")
12544    (set_attr "mode" "<MODE>")])
12545
12546 (define_insn "*fop_<mode>_comm_sse"
12547   [(set (match_operand:MODEF 0 "register_operand" "=x")
12548         (match_operator:MODEF 3 "binary_fp_operator"
12549           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12550            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12551   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12552    && COMMUTATIVE_ARITH_P (operands[3])
12553    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12554   "* return output_387_binary_op (insn, operands);"
12555   [(set (attr "type")
12556         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12557            (const_string "ssemul")
12558            (const_string "sseadd")))
12559    (set_attr "mode" "<MODE>")])
12560
12561 (define_insn "*fop_<mode>_comm_i387"
12562   [(set (match_operand:MODEF 0 "register_operand" "=f")
12563         (match_operator:MODEF 3 "binary_fp_operator"
12564           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12565            (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
12566   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12567    && COMMUTATIVE_ARITH_P (operands[3])
12568    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12569   "* return output_387_binary_op (insn, operands);"
12570   [(set (attr "type")
12571         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12572            (const_string "fmul")
12573            (const_string "fop")))
12574    (set_attr "mode" "<MODE>")])
12575
12576 (define_insn "*fop_<mode>_1_mixed_avx"
12577   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
12578         (match_operator:MODEF 3 "binary_fp_operator"
12579           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,x")
12580            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
12581   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12582    && !COMMUTATIVE_ARITH_P (operands[3])
12583    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12584   "* return output_387_binary_op (insn, operands);"
12585   [(set (attr "type")
12586         (cond [(and (eq_attr "alternative" "2")
12587                     (match_operand:MODEF 3 "mult_operator" ""))
12588                  (const_string "ssemul")
12589                (and (eq_attr "alternative" "2")
12590                     (match_operand:MODEF 3 "div_operator" ""))
12591                  (const_string "ssediv")
12592                (eq_attr "alternative" "2")
12593                  (const_string "sseadd")
12594                (match_operand:MODEF 3 "mult_operator" "")
12595                  (const_string "fmul")
12596                (match_operand:MODEF 3 "div_operator" "")
12597                  (const_string "fdiv")
12598               ]
12599               (const_string "fop")))
12600    (set_attr "prefix" "orig,orig,maybe_vex")
12601    (set_attr "mode" "<MODE>")])
12602
12603 (define_insn "*fop_<mode>_1_mixed"
12604   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
12605         (match_operator:MODEF 3 "binary_fp_operator"
12606           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
12607            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
12608   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12609    && !COMMUTATIVE_ARITH_P (operands[3])
12610    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12611   "* return output_387_binary_op (insn, operands);"
12612   [(set (attr "type")
12613         (cond [(and (eq_attr "alternative" "2")
12614                     (match_operand:MODEF 3 "mult_operator" ""))
12615                  (const_string "ssemul")
12616                (and (eq_attr "alternative" "2")
12617                     (match_operand:MODEF 3 "div_operator" ""))
12618                  (const_string "ssediv")
12619                (eq_attr "alternative" "2")
12620                  (const_string "sseadd")
12621                (match_operand:MODEF 3 "mult_operator" "")
12622                  (const_string "fmul")
12623                (match_operand:MODEF 3 "div_operator" "")
12624                  (const_string "fdiv")
12625               ]
12626               (const_string "fop")))
12627    (set_attr "mode" "<MODE>")])
12628
12629 (define_insn "*rcpsf2_sse"
12630   [(set (match_operand:SF 0 "register_operand" "=x")
12631         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
12632                    UNSPEC_RCP))]
12633   "TARGET_SSE_MATH"
12634   "%vrcpss\t{%1, %d0|%d0, %1}"
12635   [(set_attr "type" "sse")
12636    (set_attr "atom_sse_attr" "rcp")
12637    (set_attr "prefix" "maybe_vex")
12638    (set_attr "mode" "SF")])
12639
12640 (define_insn "*fop_<mode>_1_avx"
12641   [(set (match_operand:MODEF 0 "register_operand" "=x")
12642         (match_operator:MODEF 3 "binary_fp_operator"
12643           [(match_operand:MODEF 1 "register_operand" "x")
12644            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12645   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12646    && !COMMUTATIVE_ARITH_P (operands[3])"
12647   "* return output_387_binary_op (insn, operands);"
12648   [(set (attr "type")
12649         (cond [(match_operand:MODEF 3 "mult_operator" "")
12650                  (const_string "ssemul")
12651                (match_operand:MODEF 3 "div_operator" "")
12652                  (const_string "ssediv")
12653               ]
12654               (const_string "sseadd")))
12655    (set_attr "prefix" "vex")
12656    (set_attr "mode" "<MODE>")])
12657
12658 (define_insn "*fop_<mode>_1_sse"
12659   [(set (match_operand:MODEF 0 "register_operand" "=x")
12660         (match_operator:MODEF 3 "binary_fp_operator"
12661           [(match_operand:MODEF 1 "register_operand" "0")
12662            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12663   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12664    && !COMMUTATIVE_ARITH_P (operands[3])"
12665   "* return output_387_binary_op (insn, operands);"
12666   [(set (attr "type")
12667         (cond [(match_operand:MODEF 3 "mult_operator" "")
12668                  (const_string "ssemul")
12669                (match_operand:MODEF 3 "div_operator" "")
12670                  (const_string "ssediv")
12671               ]
12672               (const_string "sseadd")))
12673    (set_attr "mode" "<MODE>")])
12674
12675 ;; This pattern is not fully shadowed by the pattern above.
12676 (define_insn "*fop_<mode>_1_i387"
12677   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12678         (match_operator:MODEF 3 "binary_fp_operator"
12679           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
12680            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
12681   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12682    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
12683    && !COMMUTATIVE_ARITH_P (operands[3])
12684    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12685   "* return output_387_binary_op (insn, operands);"
12686   [(set (attr "type")
12687         (cond [(match_operand:MODEF 3 "mult_operator" "")
12688                  (const_string "fmul")
12689                (match_operand:MODEF 3 "div_operator" "")
12690                  (const_string "fdiv")
12691               ]
12692               (const_string "fop")))
12693    (set_attr "mode" "<MODE>")])
12694
12695 ;; ??? Add SSE splitters for these!
12696 (define_insn "*fop_<MODEF:mode>_2_i387"
12697   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12698         (match_operator:MODEF 3 "binary_fp_operator"
12699           [(float:MODEF
12700              (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
12701            (match_operand:MODEF 2 "register_operand" "0,0")]))]
12702   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
12703    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12704    && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12705   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12706   [(set (attr "type")
12707         (cond [(match_operand:MODEF 3 "mult_operator" "")
12708                  (const_string "fmul")
12709                (match_operand:MODEF 3 "div_operator" "")
12710                  (const_string "fdiv")
12711               ]
12712               (const_string "fop")))
12713    (set_attr "fp_int_src" "true")
12714    (set_attr "mode" "<X87MODEI12:MODE>")])
12715
12716 (define_insn "*fop_<MODEF:mode>_3_i387"
12717   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12718         (match_operator:MODEF 3 "binary_fp_operator"
12719           [(match_operand:MODEF 1 "register_operand" "0,0")
12720            (float:MODEF
12721              (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
12722   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
12723    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12724    && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12725   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12726   [(set (attr "type")
12727         (cond [(match_operand:MODEF 3 "mult_operator" "")
12728                  (const_string "fmul")
12729                (match_operand:MODEF 3 "div_operator" "")
12730                  (const_string "fdiv")
12731               ]
12732               (const_string "fop")))
12733    (set_attr "fp_int_src" "true")
12734    (set_attr "mode" "<MODE>")])
12735
12736 (define_insn "*fop_df_4_i387"
12737   [(set (match_operand:DF 0 "register_operand" "=f,f")
12738         (match_operator:DF 3 "binary_fp_operator"
12739            [(float_extend:DF
12740              (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
12741             (match_operand:DF 2 "register_operand" "0,f")]))]
12742   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12743    && !(TARGET_SSE2 && TARGET_SSE_MATH)
12744    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12745   "* return output_387_binary_op (insn, operands);"
12746   [(set (attr "type")
12747         (cond [(match_operand:DF 3 "mult_operator" "")
12748                  (const_string "fmul")
12749                (match_operand:DF 3 "div_operator" "")
12750                  (const_string "fdiv")
12751               ]
12752               (const_string "fop")))
12753    (set_attr "mode" "SF")])
12754
12755 (define_insn "*fop_df_5_i387"
12756   [(set (match_operand:DF 0 "register_operand" "=f,f")
12757         (match_operator:DF 3 "binary_fp_operator"
12758           [(match_operand:DF 1 "register_operand" "0,f")
12759            (float_extend:DF
12760             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12761   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12762    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12763   "* return output_387_binary_op (insn, operands);"
12764   [(set (attr "type")
12765         (cond [(match_operand:DF 3 "mult_operator" "")
12766                  (const_string "fmul")
12767                (match_operand:DF 3 "div_operator" "")
12768                  (const_string "fdiv")
12769               ]
12770               (const_string "fop")))
12771    (set_attr "mode" "SF")])
12772
12773 (define_insn "*fop_df_6_i387"
12774   [(set (match_operand:DF 0 "register_operand" "=f,f")
12775         (match_operator:DF 3 "binary_fp_operator"
12776           [(float_extend:DF
12777             (match_operand:SF 1 "register_operand" "0,f"))
12778            (float_extend:DF
12779             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12780   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12781    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12782   "* return output_387_binary_op (insn, operands);"
12783   [(set (attr "type")
12784         (cond [(match_operand:DF 3 "mult_operator" "")
12785                  (const_string "fmul")
12786                (match_operand:DF 3 "div_operator" "")
12787                  (const_string "fdiv")
12788               ]
12789               (const_string "fop")))
12790    (set_attr "mode" "SF")])
12791
12792 (define_insn "*fop_xf_comm_i387"
12793   [(set (match_operand:XF 0 "register_operand" "=f")
12794         (match_operator:XF 3 "binary_fp_operator"
12795                         [(match_operand:XF 1 "register_operand" "%0")
12796                          (match_operand:XF 2 "register_operand" "f")]))]
12797   "TARGET_80387
12798    && COMMUTATIVE_ARITH_P (operands[3])"
12799   "* return output_387_binary_op (insn, operands);"
12800   [(set (attr "type")
12801         (if_then_else (match_operand:XF 3 "mult_operator" "")
12802            (const_string "fmul")
12803            (const_string "fop")))
12804    (set_attr "mode" "XF")])
12805
12806 (define_insn "*fop_xf_1_i387"
12807   [(set (match_operand:XF 0 "register_operand" "=f,f")
12808         (match_operator:XF 3 "binary_fp_operator"
12809                         [(match_operand:XF 1 "register_operand" "0,f")
12810                          (match_operand:XF 2 "register_operand" "f,0")]))]
12811   "TARGET_80387
12812    && !COMMUTATIVE_ARITH_P (operands[3])"
12813   "* return output_387_binary_op (insn, operands);"
12814   [(set (attr "type")
12815         (cond [(match_operand:XF 3 "mult_operator" "")
12816                  (const_string "fmul")
12817                (match_operand:XF 3 "div_operator" "")
12818                  (const_string "fdiv")
12819               ]
12820               (const_string "fop")))
12821    (set_attr "mode" "XF")])
12822
12823 (define_insn "*fop_xf_2_i387"
12824   [(set (match_operand:XF 0 "register_operand" "=f,f")
12825         (match_operator:XF 3 "binary_fp_operator"
12826           [(float:XF
12827              (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
12828            (match_operand:XF 2 "register_operand" "0,0")]))]
12829   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12830   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12831   [(set (attr "type")
12832         (cond [(match_operand:XF 3 "mult_operator" "")
12833                  (const_string "fmul")
12834                (match_operand:XF 3 "div_operator" "")
12835                  (const_string "fdiv")
12836               ]
12837               (const_string "fop")))
12838    (set_attr "fp_int_src" "true")
12839    (set_attr "mode" "<MODE>")])
12840
12841 (define_insn "*fop_xf_3_i387"
12842   [(set (match_operand:XF 0 "register_operand" "=f,f")
12843         (match_operator:XF 3 "binary_fp_operator"
12844           [(match_operand:XF 1 "register_operand" "0,0")
12845            (float:XF
12846              (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
12847   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12848   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12849   [(set (attr "type")
12850         (cond [(match_operand:XF 3 "mult_operator" "")
12851                  (const_string "fmul")
12852                (match_operand:XF 3 "div_operator" "")
12853                  (const_string "fdiv")
12854               ]
12855               (const_string "fop")))
12856    (set_attr "fp_int_src" "true")
12857    (set_attr "mode" "<MODE>")])
12858
12859 (define_insn "*fop_xf_4_i387"
12860   [(set (match_operand:XF 0 "register_operand" "=f,f")
12861         (match_operator:XF 3 "binary_fp_operator"
12862            [(float_extend:XF
12863               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
12864             (match_operand:XF 2 "register_operand" "0,f")]))]
12865   "TARGET_80387"
12866   "* return output_387_binary_op (insn, operands);"
12867   [(set (attr "type")
12868         (cond [(match_operand:XF 3 "mult_operator" "")
12869                  (const_string "fmul")
12870                (match_operand:XF 3 "div_operator" "")
12871                  (const_string "fdiv")
12872               ]
12873               (const_string "fop")))
12874    (set_attr "mode" "<MODE>")])
12875
12876 (define_insn "*fop_xf_5_i387"
12877   [(set (match_operand:XF 0 "register_operand" "=f,f")
12878         (match_operator:XF 3 "binary_fp_operator"
12879           [(match_operand:XF 1 "register_operand" "0,f")
12880            (float_extend:XF
12881              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
12882   "TARGET_80387"
12883   "* return output_387_binary_op (insn, operands);"
12884   [(set (attr "type")
12885         (cond [(match_operand:XF 3 "mult_operator" "")
12886                  (const_string "fmul")
12887                (match_operand:XF 3 "div_operator" "")
12888                  (const_string "fdiv")
12889               ]
12890               (const_string "fop")))
12891    (set_attr "mode" "<MODE>")])
12892
12893 (define_insn "*fop_xf_6_i387"
12894   [(set (match_operand:XF 0 "register_operand" "=f,f")
12895         (match_operator:XF 3 "binary_fp_operator"
12896           [(float_extend:XF
12897              (match_operand:MODEF 1 "register_operand" "0,f"))
12898            (float_extend:XF
12899              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
12900   "TARGET_80387"
12901   "* return output_387_binary_op (insn, operands);"
12902   [(set (attr "type")
12903         (cond [(match_operand:XF 3 "mult_operator" "")
12904                  (const_string "fmul")
12905                (match_operand:XF 3 "div_operator" "")
12906                  (const_string "fdiv")
12907               ]
12908               (const_string "fop")))
12909    (set_attr "mode" "<MODE>")])
12910
12911 (define_split
12912   [(set (match_operand 0 "register_operand" "")
12913         (match_operator 3 "binary_fp_operator"
12914            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
12915             (match_operand 2 "register_operand" "")]))]
12916   "reload_completed
12917    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
12918    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
12919   [(const_int 0)]
12920 {
12921   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
12922   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
12923   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
12924                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
12925                                           GET_MODE (operands[3]),
12926                                           operands[4],
12927                                           operands[2])));
12928   ix86_free_from_memory (GET_MODE (operands[1]));
12929   DONE;
12930 })
12931
12932 (define_split
12933   [(set (match_operand 0 "register_operand" "")
12934         (match_operator 3 "binary_fp_operator"
12935            [(match_operand 1 "register_operand" "")
12936             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
12937   "reload_completed
12938    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
12939    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
12940   [(const_int 0)]
12941 {
12942   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
12943   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
12944   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
12945                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
12946                                           GET_MODE (operands[3]),
12947                                           operands[1],
12948                                           operands[4])));
12949   ix86_free_from_memory (GET_MODE (operands[2]));
12950   DONE;
12951 })
12952 \f
12953 ;; FPU special functions.
12954
12955 ;; This pattern implements a no-op XFmode truncation for
12956 ;; all fancy i386 XFmode math functions.
12957
12958 (define_insn "truncxf<mode>2_i387_noop_unspec"
12959   [(set (match_operand:MODEF 0 "register_operand" "=f")
12960         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
12961         UNSPEC_TRUNC_NOOP))]
12962   "TARGET_USE_FANCY_MATH_387"
12963   "* return output_387_reg_move (insn, operands);"
12964   [(set_attr "type" "fmov")
12965    (set_attr "mode" "<MODE>")])
12966
12967 (define_insn "sqrtxf2"
12968   [(set (match_operand:XF 0 "register_operand" "=f")
12969         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
12970   "TARGET_USE_FANCY_MATH_387"
12971   "fsqrt"
12972   [(set_attr "type" "fpspc")
12973    (set_attr "mode" "XF")
12974    (set_attr "athlon_decode" "direct")
12975    (set_attr "amdfam10_decode" "direct")
12976    (set_attr "bdver1_decode" "direct")])
12977
12978 (define_insn "sqrt_extend<mode>xf2_i387"
12979   [(set (match_operand:XF 0 "register_operand" "=f")
12980         (sqrt:XF
12981           (float_extend:XF
12982             (match_operand:MODEF 1 "register_operand" "0"))))]
12983   "TARGET_USE_FANCY_MATH_387"
12984   "fsqrt"
12985   [(set_attr "type" "fpspc")
12986    (set_attr "mode" "XF")
12987    (set_attr "athlon_decode" "direct")
12988    (set_attr "amdfam10_decode" "direct")
12989    (set_attr "bdver1_decode" "direct")])
12990
12991 (define_insn "*rsqrtsf2_sse"
12992   [(set (match_operand:SF 0 "register_operand" "=x")
12993         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
12994                    UNSPEC_RSQRT))]
12995   "TARGET_SSE_MATH"
12996   "%vrsqrtss\t{%1, %d0|%d0, %1}"
12997   [(set_attr "type" "sse")
12998    (set_attr "atom_sse_attr" "rcp")
12999    (set_attr "prefix" "maybe_vex")
13000    (set_attr "mode" "SF")])
13001
13002 (define_expand "rsqrtsf2"
13003   [(set (match_operand:SF 0 "register_operand" "")
13004         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
13005                    UNSPEC_RSQRT))]
13006   "TARGET_SSE_MATH"
13007 {
13008   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13009   DONE;
13010 })
13011
13012 (define_insn "*sqrt<mode>2_sse"
13013   [(set (match_operand:MODEF 0 "register_operand" "=x")
13014         (sqrt:MODEF
13015           (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13016   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13017   "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}"
13018   [(set_attr "type" "sse")
13019    (set_attr "atom_sse_attr" "sqrt")
13020    (set_attr "prefix" "maybe_vex")
13021    (set_attr "mode" "<MODE>")
13022    (set_attr "athlon_decode" "*")
13023    (set_attr "amdfam10_decode" "*")
13024    (set_attr "bdver1_decode" "*")])
13025
13026 (define_expand "sqrt<mode>2"
13027   [(set (match_operand:MODEF 0 "register_operand" "")
13028         (sqrt:MODEF
13029           (match_operand:MODEF 1 "nonimmediate_operand" "")))]
13030   "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13031    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13032 {
13033   if (<MODE>mode == SFmode
13034       && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
13035       && flag_finite_math_only && !flag_trapping_math
13036       && flag_unsafe_math_optimizations)
13037     {
13038       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13039       DONE;
13040     }
13041
13042   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13043     {
13044       rtx op0 = gen_reg_rtx (XFmode);
13045       rtx op1 = force_reg (<MODE>mode, operands[1]);
13046
13047       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13048       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13049       DONE;
13050    }
13051 })
13052
13053 (define_insn "fpremxf4_i387"
13054   [(set (match_operand:XF 0 "register_operand" "=f")
13055         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13056                     (match_operand:XF 3 "register_operand" "1")]
13057                    UNSPEC_FPREM_F))
13058    (set (match_operand:XF 1 "register_operand" "=u")
13059         (unspec:XF [(match_dup 2) (match_dup 3)]
13060                    UNSPEC_FPREM_U))
13061    (set (reg:CCFP FPSR_REG)
13062         (unspec:CCFP [(match_dup 2) (match_dup 3)]
13063                      UNSPEC_C2_FLAG))]
13064   "TARGET_USE_FANCY_MATH_387"
13065   "fprem"
13066   [(set_attr "type" "fpspc")
13067    (set_attr "mode" "XF")])
13068
13069 (define_expand "fmodxf3"
13070   [(use (match_operand:XF 0 "register_operand" ""))
13071    (use (match_operand:XF 1 "general_operand" ""))
13072    (use (match_operand:XF 2 "general_operand" ""))]
13073   "TARGET_USE_FANCY_MATH_387"
13074 {
13075   rtx label = gen_label_rtx ();
13076
13077   rtx op1 = gen_reg_rtx (XFmode);
13078   rtx op2 = gen_reg_rtx (XFmode);
13079
13080   emit_move_insn (op2, operands[2]);
13081   emit_move_insn (op1, operands[1]);
13082
13083   emit_label (label);
13084   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13085   ix86_emit_fp_unordered_jump (label);
13086   LABEL_NUSES (label) = 1;
13087
13088   emit_move_insn (operands[0], op1);
13089   DONE;
13090 })
13091
13092 (define_expand "fmod<mode>3"
13093   [(use (match_operand:MODEF 0 "register_operand" ""))
13094    (use (match_operand:MODEF 1 "general_operand" ""))
13095    (use (match_operand:MODEF 2 "general_operand" ""))]
13096   "TARGET_USE_FANCY_MATH_387"
13097 {
13098   rtx (*gen_truncxf) (rtx, rtx);
13099
13100   rtx label = gen_label_rtx ();
13101
13102   rtx op1 = gen_reg_rtx (XFmode);
13103   rtx op2 = gen_reg_rtx (XFmode);
13104
13105   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13106   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13107
13108   emit_label (label);
13109   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13110   ix86_emit_fp_unordered_jump (label);
13111   LABEL_NUSES (label) = 1;
13112
13113   /* Truncate the result properly for strict SSE math.  */
13114   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13115       && !TARGET_MIX_SSE_I387)
13116     gen_truncxf = gen_truncxf<mode>2;
13117   else
13118     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13119
13120   emit_insn (gen_truncxf (operands[0], op1));
13121   DONE;
13122 })
13123
13124 (define_insn "fprem1xf4_i387"
13125   [(set (match_operand:XF 0 "register_operand" "=f")
13126         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13127                     (match_operand:XF 3 "register_operand" "1")]
13128                    UNSPEC_FPREM1_F))
13129    (set (match_operand:XF 1 "register_operand" "=u")
13130         (unspec:XF [(match_dup 2) (match_dup 3)]
13131                    UNSPEC_FPREM1_U))
13132    (set (reg:CCFP FPSR_REG)
13133         (unspec:CCFP [(match_dup 2) (match_dup 3)]
13134                      UNSPEC_C2_FLAG))]
13135   "TARGET_USE_FANCY_MATH_387"
13136   "fprem1"
13137   [(set_attr "type" "fpspc")
13138    (set_attr "mode" "XF")])
13139
13140 (define_expand "remainderxf3"
13141   [(use (match_operand:XF 0 "register_operand" ""))
13142    (use (match_operand:XF 1 "general_operand" ""))
13143    (use (match_operand:XF 2 "general_operand" ""))]
13144   "TARGET_USE_FANCY_MATH_387"
13145 {
13146   rtx label = gen_label_rtx ();
13147
13148   rtx op1 = gen_reg_rtx (XFmode);
13149   rtx op2 = gen_reg_rtx (XFmode);
13150
13151   emit_move_insn (op2, operands[2]);
13152   emit_move_insn (op1, operands[1]);
13153
13154   emit_label (label);
13155   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13156   ix86_emit_fp_unordered_jump (label);
13157   LABEL_NUSES (label) = 1;
13158
13159   emit_move_insn (operands[0], op1);
13160   DONE;
13161 })
13162
13163 (define_expand "remainder<mode>3"
13164   [(use (match_operand:MODEF 0 "register_operand" ""))
13165    (use (match_operand:MODEF 1 "general_operand" ""))
13166    (use (match_operand:MODEF 2 "general_operand" ""))]
13167   "TARGET_USE_FANCY_MATH_387"
13168 {
13169   rtx (*gen_truncxf) (rtx, rtx);
13170
13171   rtx label = gen_label_rtx ();
13172
13173   rtx op1 = gen_reg_rtx (XFmode);
13174   rtx op2 = gen_reg_rtx (XFmode);
13175
13176   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13177   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13178
13179   emit_label (label);
13180
13181   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13182   ix86_emit_fp_unordered_jump (label);
13183   LABEL_NUSES (label) = 1;
13184
13185   /* Truncate the result properly for strict SSE math.  */
13186   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13187       && !TARGET_MIX_SSE_I387)
13188     gen_truncxf = gen_truncxf<mode>2;
13189   else
13190     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13191
13192   emit_insn (gen_truncxf (operands[0], op1));
13193   DONE;
13194 })
13195
13196 (define_insn "*sinxf2_i387"
13197   [(set (match_operand:XF 0 "register_operand" "=f")
13198         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13199   "TARGET_USE_FANCY_MATH_387
13200    && flag_unsafe_math_optimizations"
13201   "fsin"
13202   [(set_attr "type" "fpspc")
13203    (set_attr "mode" "XF")])
13204
13205 (define_insn "*sin_extend<mode>xf2_i387"
13206   [(set (match_operand:XF 0 "register_operand" "=f")
13207         (unspec:XF [(float_extend:XF
13208                       (match_operand:MODEF 1 "register_operand" "0"))]
13209                    UNSPEC_SIN))]
13210   "TARGET_USE_FANCY_MATH_387
13211    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13212        || TARGET_MIX_SSE_I387)
13213    && flag_unsafe_math_optimizations"
13214   "fsin"
13215   [(set_attr "type" "fpspc")
13216    (set_attr "mode" "XF")])
13217
13218 (define_insn "*cosxf2_i387"
13219   [(set (match_operand:XF 0 "register_operand" "=f")
13220         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13221   "TARGET_USE_FANCY_MATH_387
13222    && flag_unsafe_math_optimizations"
13223   "fcos"
13224   [(set_attr "type" "fpspc")
13225    (set_attr "mode" "XF")])
13226
13227 (define_insn "*cos_extend<mode>xf2_i387"
13228   [(set (match_operand:XF 0 "register_operand" "=f")
13229         (unspec:XF [(float_extend:XF
13230                       (match_operand:MODEF 1 "register_operand" "0"))]
13231                    UNSPEC_COS))]
13232   "TARGET_USE_FANCY_MATH_387
13233    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13234        || TARGET_MIX_SSE_I387)
13235    && flag_unsafe_math_optimizations"
13236   "fcos"
13237   [(set_attr "type" "fpspc")
13238    (set_attr "mode" "XF")])
13239
13240 ;; When sincos pattern is defined, sin and cos builtin functions will be
13241 ;; expanded to sincos pattern with one of its outputs left unused.
13242 ;; CSE pass will figure out if two sincos patterns can be combined,
13243 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13244 ;; depending on the unused output.
13245
13246 (define_insn "sincosxf3"
13247   [(set (match_operand:XF 0 "register_operand" "=f")
13248         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13249                    UNSPEC_SINCOS_COS))
13250    (set (match_operand:XF 1 "register_operand" "=u")
13251         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13252   "TARGET_USE_FANCY_MATH_387
13253    && flag_unsafe_math_optimizations"
13254   "fsincos"
13255   [(set_attr "type" "fpspc")
13256    (set_attr "mode" "XF")])
13257
13258 (define_split
13259   [(set (match_operand:XF 0 "register_operand" "")
13260         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13261                    UNSPEC_SINCOS_COS))
13262    (set (match_operand:XF 1 "register_operand" "")
13263         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13264   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13265    && !(reload_completed || reload_in_progress)"
13266   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13267
13268 (define_split
13269   [(set (match_operand:XF 0 "register_operand" "")
13270         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13271                    UNSPEC_SINCOS_COS))
13272    (set (match_operand:XF 1 "register_operand" "")
13273         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13274   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13275    && !(reload_completed || reload_in_progress)"
13276   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13277
13278 (define_insn "sincos_extend<mode>xf3_i387"
13279   [(set (match_operand:XF 0 "register_operand" "=f")
13280         (unspec:XF [(float_extend:XF
13281                       (match_operand:MODEF 2 "register_operand" "0"))]
13282                    UNSPEC_SINCOS_COS))
13283    (set (match_operand:XF 1 "register_operand" "=u")
13284         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13285   "TARGET_USE_FANCY_MATH_387
13286    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13287        || TARGET_MIX_SSE_I387)
13288    && flag_unsafe_math_optimizations"
13289   "fsincos"
13290   [(set_attr "type" "fpspc")
13291    (set_attr "mode" "XF")])
13292
13293 (define_split
13294   [(set (match_operand:XF 0 "register_operand" "")
13295         (unspec:XF [(float_extend:XF
13296                       (match_operand:MODEF 2 "register_operand" ""))]
13297                    UNSPEC_SINCOS_COS))
13298    (set (match_operand:XF 1 "register_operand" "")
13299         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13300   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13301    && !(reload_completed || reload_in_progress)"
13302   [(set (match_dup 1)
13303         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13304
13305 (define_split
13306   [(set (match_operand:XF 0 "register_operand" "")
13307         (unspec:XF [(float_extend:XF
13308                       (match_operand:MODEF 2 "register_operand" ""))]
13309                    UNSPEC_SINCOS_COS))
13310    (set (match_operand:XF 1 "register_operand" "")
13311         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13312   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13313    && !(reload_completed || reload_in_progress)"
13314   [(set (match_dup 0)
13315         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13316
13317 (define_expand "sincos<mode>3"
13318   [(use (match_operand:MODEF 0 "register_operand" ""))
13319    (use (match_operand:MODEF 1 "register_operand" ""))
13320    (use (match_operand:MODEF 2 "register_operand" ""))]
13321   "TARGET_USE_FANCY_MATH_387
13322    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13323        || TARGET_MIX_SSE_I387)
13324    && flag_unsafe_math_optimizations"
13325 {
13326   rtx op0 = gen_reg_rtx (XFmode);
13327   rtx op1 = gen_reg_rtx (XFmode);
13328
13329   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13330   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13331   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13332   DONE;
13333 })
13334
13335 (define_insn "fptanxf4_i387"
13336   [(set (match_operand:XF 0 "register_operand" "=f")
13337         (match_operand:XF 3 "const_double_operand" "F"))
13338    (set (match_operand:XF 1 "register_operand" "=u")
13339         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13340                    UNSPEC_TAN))]
13341   "TARGET_USE_FANCY_MATH_387
13342    && flag_unsafe_math_optimizations
13343    && standard_80387_constant_p (operands[3]) == 2"
13344   "fptan"
13345   [(set_attr "type" "fpspc")
13346    (set_attr "mode" "XF")])
13347
13348 (define_insn "fptan_extend<mode>xf4_i387"
13349   [(set (match_operand:MODEF 0 "register_operand" "=f")
13350         (match_operand:MODEF 3 "const_double_operand" "F"))
13351    (set (match_operand:XF 1 "register_operand" "=u")
13352         (unspec:XF [(float_extend:XF
13353                       (match_operand:MODEF 2 "register_operand" "0"))]
13354                    UNSPEC_TAN))]
13355   "TARGET_USE_FANCY_MATH_387
13356    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13357        || TARGET_MIX_SSE_I387)
13358    && flag_unsafe_math_optimizations
13359    && standard_80387_constant_p (operands[3]) == 2"
13360   "fptan"
13361   [(set_attr "type" "fpspc")
13362    (set_attr "mode" "XF")])
13363
13364 (define_expand "tanxf2"
13365   [(use (match_operand:XF 0 "register_operand" ""))
13366    (use (match_operand:XF 1 "register_operand" ""))]
13367   "TARGET_USE_FANCY_MATH_387
13368    && flag_unsafe_math_optimizations"
13369 {
13370   rtx one = gen_reg_rtx (XFmode);
13371   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13372
13373   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13374   DONE;
13375 })
13376
13377 (define_expand "tan<mode>2"
13378   [(use (match_operand:MODEF 0 "register_operand" ""))
13379    (use (match_operand:MODEF 1 "register_operand" ""))]
13380   "TARGET_USE_FANCY_MATH_387
13381    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13382        || TARGET_MIX_SSE_I387)
13383    && flag_unsafe_math_optimizations"
13384 {
13385   rtx op0 = gen_reg_rtx (XFmode);
13386
13387   rtx one = gen_reg_rtx (<MODE>mode);
13388   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13389
13390   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13391                                              operands[1], op2));
13392   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13393   DONE;
13394 })
13395
13396 (define_insn "*fpatanxf3_i387"
13397   [(set (match_operand:XF 0 "register_operand" "=f")
13398         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13399                     (match_operand:XF 2 "register_operand" "u")]
13400                    UNSPEC_FPATAN))
13401    (clobber (match_scratch:XF 3 "=2"))]
13402   "TARGET_USE_FANCY_MATH_387
13403    && flag_unsafe_math_optimizations"
13404   "fpatan"
13405   [(set_attr "type" "fpspc")
13406    (set_attr "mode" "XF")])
13407
13408 (define_insn "fpatan_extend<mode>xf3_i387"
13409   [(set (match_operand:XF 0 "register_operand" "=f")
13410         (unspec:XF [(float_extend:XF
13411                       (match_operand:MODEF 1 "register_operand" "0"))
13412                     (float_extend:XF
13413                       (match_operand:MODEF 2 "register_operand" "u"))]
13414                    UNSPEC_FPATAN))
13415    (clobber (match_scratch:XF 3 "=2"))]
13416   "TARGET_USE_FANCY_MATH_387
13417    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13418        || TARGET_MIX_SSE_I387)
13419    && flag_unsafe_math_optimizations"
13420   "fpatan"
13421   [(set_attr "type" "fpspc")
13422    (set_attr "mode" "XF")])
13423
13424 (define_expand "atan2xf3"
13425   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13426                    (unspec:XF [(match_operand:XF 2 "register_operand" "")
13427                                (match_operand:XF 1 "register_operand" "")]
13428                               UNSPEC_FPATAN))
13429               (clobber (match_scratch:XF 3 ""))])]
13430   "TARGET_USE_FANCY_MATH_387
13431    && flag_unsafe_math_optimizations")
13432
13433 (define_expand "atan2<mode>3"
13434   [(use (match_operand:MODEF 0 "register_operand" ""))
13435    (use (match_operand:MODEF 1 "register_operand" ""))
13436    (use (match_operand:MODEF 2 "register_operand" ""))]
13437   "TARGET_USE_FANCY_MATH_387
13438    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13439        || TARGET_MIX_SSE_I387)
13440    && flag_unsafe_math_optimizations"
13441 {
13442   rtx op0 = gen_reg_rtx (XFmode);
13443
13444   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13445   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13446   DONE;
13447 })
13448
13449 (define_expand "atanxf2"
13450   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13451                    (unspec:XF [(match_dup 2)
13452                                (match_operand:XF 1 "register_operand" "")]
13453                               UNSPEC_FPATAN))
13454               (clobber (match_scratch:XF 3 ""))])]
13455   "TARGET_USE_FANCY_MATH_387
13456    && flag_unsafe_math_optimizations"
13457 {
13458   operands[2] = gen_reg_rtx (XFmode);
13459   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
13460 })
13461
13462 (define_expand "atan<mode>2"
13463   [(use (match_operand:MODEF 0 "register_operand" ""))
13464    (use (match_operand:MODEF 1 "register_operand" ""))]
13465   "TARGET_USE_FANCY_MATH_387
13466    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13467        || TARGET_MIX_SSE_I387)
13468    && flag_unsafe_math_optimizations"
13469 {
13470   rtx op0 = gen_reg_rtx (XFmode);
13471
13472   rtx op2 = gen_reg_rtx (<MODE>mode);
13473   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
13474
13475   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13476   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13477   DONE;
13478 })
13479
13480 (define_expand "asinxf2"
13481   [(set (match_dup 2)
13482         (mult:XF (match_operand:XF 1 "register_operand" "")
13483                  (match_dup 1)))
13484    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13485    (set (match_dup 5) (sqrt:XF (match_dup 4)))
13486    (parallel [(set (match_operand:XF 0 "register_operand" "")
13487                    (unspec:XF [(match_dup 5) (match_dup 1)]
13488                               UNSPEC_FPATAN))
13489               (clobber (match_scratch:XF 6 ""))])]
13490   "TARGET_USE_FANCY_MATH_387
13491    && flag_unsafe_math_optimizations"
13492 {
13493   int i;
13494
13495   if (optimize_insn_for_size_p ())
13496     FAIL;
13497
13498   for (i = 2; i < 6; i++)
13499     operands[i] = gen_reg_rtx (XFmode);
13500
13501   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
13502 })
13503
13504 (define_expand "asin<mode>2"
13505   [(use (match_operand:MODEF 0 "register_operand" ""))
13506    (use (match_operand:MODEF 1 "general_operand" ""))]
13507  "TARGET_USE_FANCY_MATH_387
13508    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13509        || TARGET_MIX_SSE_I387)
13510    && flag_unsafe_math_optimizations"
13511 {
13512   rtx op0 = gen_reg_rtx (XFmode);
13513   rtx op1 = gen_reg_rtx (XFmode);
13514
13515   if (optimize_insn_for_size_p ())
13516     FAIL;
13517
13518   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13519   emit_insn (gen_asinxf2 (op0, op1));
13520   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13521   DONE;
13522 })
13523
13524 (define_expand "acosxf2"
13525   [(set (match_dup 2)
13526         (mult:XF (match_operand:XF 1 "register_operand" "")
13527                  (match_dup 1)))
13528    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13529    (set (match_dup 5) (sqrt:XF (match_dup 4)))
13530    (parallel [(set (match_operand:XF 0 "register_operand" "")
13531                    (unspec:XF [(match_dup 1) (match_dup 5)]
13532                               UNSPEC_FPATAN))
13533               (clobber (match_scratch:XF 6 ""))])]
13534   "TARGET_USE_FANCY_MATH_387
13535    && flag_unsafe_math_optimizations"
13536 {
13537   int i;
13538
13539   if (optimize_insn_for_size_p ())
13540     FAIL;
13541
13542   for (i = 2; i < 6; i++)
13543     operands[i] = gen_reg_rtx (XFmode);
13544
13545   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
13546 })
13547
13548 (define_expand "acos<mode>2"
13549   [(use (match_operand:MODEF 0 "register_operand" ""))
13550    (use (match_operand:MODEF 1 "general_operand" ""))]
13551  "TARGET_USE_FANCY_MATH_387
13552    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13553        || TARGET_MIX_SSE_I387)
13554    && flag_unsafe_math_optimizations"
13555 {
13556   rtx op0 = gen_reg_rtx (XFmode);
13557   rtx op1 = gen_reg_rtx (XFmode);
13558
13559   if (optimize_insn_for_size_p ())
13560     FAIL;
13561
13562   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13563   emit_insn (gen_acosxf2 (op0, op1));
13564   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13565   DONE;
13566 })
13567
13568 (define_insn "fyl2xxf3_i387"
13569   [(set (match_operand:XF 0 "register_operand" "=f")
13570         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13571                     (match_operand:XF 2 "register_operand" "u")]
13572                    UNSPEC_FYL2X))
13573    (clobber (match_scratch:XF 3 "=2"))]
13574   "TARGET_USE_FANCY_MATH_387
13575    && flag_unsafe_math_optimizations"
13576   "fyl2x"
13577   [(set_attr "type" "fpspc")
13578    (set_attr "mode" "XF")])
13579
13580 (define_insn "fyl2x_extend<mode>xf3_i387"
13581   [(set (match_operand:XF 0 "register_operand" "=f")
13582         (unspec:XF [(float_extend:XF
13583                       (match_operand:MODEF 1 "register_operand" "0"))
13584                     (match_operand:XF 2 "register_operand" "u")]
13585                    UNSPEC_FYL2X))
13586    (clobber (match_scratch:XF 3 "=2"))]
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   "fyl2x"
13592   [(set_attr "type" "fpspc")
13593    (set_attr "mode" "XF")])
13594
13595 (define_expand "logxf2"
13596   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13597                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
13598                                (match_dup 2)] UNSPEC_FYL2X))
13599               (clobber (match_scratch:XF 3 ""))])]
13600   "TARGET_USE_FANCY_MATH_387
13601    && flag_unsafe_math_optimizations"
13602 {
13603   operands[2] = gen_reg_rtx (XFmode);
13604   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
13605 })
13606
13607 (define_expand "log<mode>2"
13608   [(use (match_operand:MODEF 0 "register_operand" ""))
13609    (use (match_operand:MODEF 1 "register_operand" ""))]
13610   "TARGET_USE_FANCY_MATH_387
13611    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13612        || TARGET_MIX_SSE_I387)
13613    && flag_unsafe_math_optimizations"
13614 {
13615   rtx op0 = gen_reg_rtx (XFmode);
13616
13617   rtx op2 = gen_reg_rtx (XFmode);
13618   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
13619
13620   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13621   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13622   DONE;
13623 })
13624
13625 (define_expand "log10xf2"
13626   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13627                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
13628                                (match_dup 2)] UNSPEC_FYL2X))
13629               (clobber (match_scratch:XF 3 ""))])]
13630   "TARGET_USE_FANCY_MATH_387
13631    && flag_unsafe_math_optimizations"
13632 {
13633   operands[2] = gen_reg_rtx (XFmode);
13634   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
13635 })
13636
13637 (define_expand "log10<mode>2"
13638   [(use (match_operand:MODEF 0 "register_operand" ""))
13639    (use (match_operand:MODEF 1 "register_operand" ""))]
13640   "TARGET_USE_FANCY_MATH_387
13641    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13642        || TARGET_MIX_SSE_I387)
13643    && flag_unsafe_math_optimizations"
13644 {
13645   rtx op0 = gen_reg_rtx (XFmode);
13646
13647   rtx op2 = gen_reg_rtx (XFmode);
13648   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
13649
13650   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13651   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13652   DONE;
13653 })
13654
13655 (define_expand "log2xf2"
13656   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13657                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
13658                                (match_dup 2)] UNSPEC_FYL2X))
13659               (clobber (match_scratch:XF 3 ""))])]
13660   "TARGET_USE_FANCY_MATH_387
13661    && flag_unsafe_math_optimizations"
13662 {
13663   operands[2] = gen_reg_rtx (XFmode);
13664   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13665 })
13666
13667 (define_expand "log2<mode>2"
13668   [(use (match_operand:MODEF 0 "register_operand" ""))
13669    (use (match_operand:MODEF 1 "register_operand" ""))]
13670   "TARGET_USE_FANCY_MATH_387
13671    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13672        || TARGET_MIX_SSE_I387)
13673    && flag_unsafe_math_optimizations"
13674 {
13675   rtx op0 = gen_reg_rtx (XFmode);
13676
13677   rtx op2 = gen_reg_rtx (XFmode);
13678   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
13679
13680   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13681   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13682   DONE;
13683 })
13684
13685 (define_insn "fyl2xp1xf3_i387"
13686   [(set (match_operand:XF 0 "register_operand" "=f")
13687         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13688                     (match_operand:XF 2 "register_operand" "u")]
13689                    UNSPEC_FYL2XP1))
13690    (clobber (match_scratch:XF 3 "=2"))]
13691   "TARGET_USE_FANCY_MATH_387
13692    && flag_unsafe_math_optimizations"
13693   "fyl2xp1"
13694   [(set_attr "type" "fpspc")
13695    (set_attr "mode" "XF")])
13696
13697 (define_insn "fyl2xp1_extend<mode>xf3_i387"
13698   [(set (match_operand:XF 0 "register_operand" "=f")
13699         (unspec:XF [(float_extend:XF
13700                       (match_operand:MODEF 1 "register_operand" "0"))
13701                     (match_operand:XF 2 "register_operand" "u")]
13702                    UNSPEC_FYL2XP1))
13703    (clobber (match_scratch:XF 3 "=2"))]
13704   "TARGET_USE_FANCY_MATH_387
13705    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13706        || TARGET_MIX_SSE_I387)
13707    && flag_unsafe_math_optimizations"
13708   "fyl2xp1"
13709   [(set_attr "type" "fpspc")
13710    (set_attr "mode" "XF")])
13711
13712 (define_expand "log1pxf2"
13713   [(use (match_operand:XF 0 "register_operand" ""))
13714    (use (match_operand:XF 1 "register_operand" ""))]
13715   "TARGET_USE_FANCY_MATH_387
13716    && flag_unsafe_math_optimizations"
13717 {
13718   if (optimize_insn_for_size_p ())
13719     FAIL;
13720
13721   ix86_emit_i387_log1p (operands[0], operands[1]);
13722   DONE;
13723 })
13724
13725 (define_expand "log1p<mode>2"
13726   [(use (match_operand:MODEF 0 "register_operand" ""))
13727    (use (match_operand:MODEF 1 "register_operand" ""))]
13728   "TARGET_USE_FANCY_MATH_387
13729    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13730        || TARGET_MIX_SSE_I387)
13731    && flag_unsafe_math_optimizations"
13732 {
13733   rtx op0;
13734
13735   if (optimize_insn_for_size_p ())
13736     FAIL;
13737
13738   op0 = gen_reg_rtx (XFmode);
13739
13740   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
13741
13742   ix86_emit_i387_log1p (op0, operands[1]);
13743   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13744   DONE;
13745 })
13746
13747 (define_insn "fxtractxf3_i387"
13748   [(set (match_operand:XF 0 "register_operand" "=f")
13749         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13750                    UNSPEC_XTRACT_FRACT))
13751    (set (match_operand:XF 1 "register_operand" "=u")
13752         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
13753   "TARGET_USE_FANCY_MATH_387
13754    && flag_unsafe_math_optimizations"
13755   "fxtract"
13756   [(set_attr "type" "fpspc")
13757    (set_attr "mode" "XF")])
13758
13759 (define_insn "fxtract_extend<mode>xf3_i387"
13760   [(set (match_operand:XF 0 "register_operand" "=f")
13761         (unspec:XF [(float_extend:XF
13762                       (match_operand:MODEF 2 "register_operand" "0"))]
13763                    UNSPEC_XTRACT_FRACT))
13764    (set (match_operand:XF 1 "register_operand" "=u")
13765         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
13766   "TARGET_USE_FANCY_MATH_387
13767    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13768        || TARGET_MIX_SSE_I387)
13769    && flag_unsafe_math_optimizations"
13770   "fxtract"
13771   [(set_attr "type" "fpspc")
13772    (set_attr "mode" "XF")])
13773
13774 (define_expand "logbxf2"
13775   [(parallel [(set (match_dup 2)
13776                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
13777                               UNSPEC_XTRACT_FRACT))
13778               (set (match_operand:XF 0 "register_operand" "")
13779                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
13780   "TARGET_USE_FANCY_MATH_387
13781    && flag_unsafe_math_optimizations"
13782   "operands[2] = gen_reg_rtx (XFmode);")
13783
13784 (define_expand "logb<mode>2"
13785   [(use (match_operand:MODEF 0 "register_operand" ""))
13786    (use (match_operand:MODEF 1 "register_operand" ""))]
13787   "TARGET_USE_FANCY_MATH_387
13788    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13789        || TARGET_MIX_SSE_I387)
13790    && flag_unsafe_math_optimizations"
13791 {
13792   rtx op0 = gen_reg_rtx (XFmode);
13793   rtx op1 = gen_reg_rtx (XFmode);
13794
13795   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13796   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
13797   DONE;
13798 })
13799
13800 (define_expand "ilogbxf2"
13801   [(use (match_operand:SI 0 "register_operand" ""))
13802    (use (match_operand:XF 1 "register_operand" ""))]
13803   "TARGET_USE_FANCY_MATH_387
13804    && flag_unsafe_math_optimizations"
13805 {
13806   rtx op0, op1;
13807
13808   if (optimize_insn_for_size_p ())
13809     FAIL;
13810
13811   op0 = gen_reg_rtx (XFmode);
13812   op1 = gen_reg_rtx (XFmode);
13813
13814   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
13815   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13816   DONE;
13817 })
13818
13819 (define_expand "ilogb<mode>2"
13820   [(use (match_operand:SI 0 "register_operand" ""))
13821    (use (match_operand:MODEF 1 "register_operand" ""))]
13822   "TARGET_USE_FANCY_MATH_387
13823    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13824        || TARGET_MIX_SSE_I387)
13825    && flag_unsafe_math_optimizations"
13826 {
13827   rtx op0, op1;
13828
13829   if (optimize_insn_for_size_p ())
13830     FAIL;
13831
13832   op0 = gen_reg_rtx (XFmode);
13833   op1 = gen_reg_rtx (XFmode);
13834
13835   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13836   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13837   DONE;
13838 })
13839
13840 (define_insn "*f2xm1xf2_i387"
13841   [(set (match_operand:XF 0 "register_operand" "=f")
13842         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13843                    UNSPEC_F2XM1))]
13844   "TARGET_USE_FANCY_MATH_387
13845    && flag_unsafe_math_optimizations"
13846   "f2xm1"
13847   [(set_attr "type" "fpspc")
13848    (set_attr "mode" "XF")])
13849
13850 (define_insn "*fscalexf4_i387"
13851   [(set (match_operand:XF 0 "register_operand" "=f")
13852         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13853                     (match_operand:XF 3 "register_operand" "1")]
13854                    UNSPEC_FSCALE_FRACT))
13855    (set (match_operand:XF 1 "register_operand" "=u")
13856         (unspec:XF [(match_dup 2) (match_dup 3)]
13857                    UNSPEC_FSCALE_EXP))]
13858   "TARGET_USE_FANCY_MATH_387
13859    && flag_unsafe_math_optimizations"
13860   "fscale"
13861   [(set_attr "type" "fpspc")
13862    (set_attr "mode" "XF")])
13863
13864 (define_expand "expNcorexf3"
13865   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
13866                                (match_operand:XF 2 "register_operand" "")))
13867    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
13868    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
13869    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
13870    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
13871    (parallel [(set (match_operand:XF 0 "register_operand" "")
13872                    (unspec:XF [(match_dup 8) (match_dup 4)]
13873                               UNSPEC_FSCALE_FRACT))
13874               (set (match_dup 9)
13875                    (unspec:XF [(match_dup 8) (match_dup 4)]
13876                               UNSPEC_FSCALE_EXP))])]
13877   "TARGET_USE_FANCY_MATH_387
13878    && flag_unsafe_math_optimizations"
13879 {
13880   int i;
13881
13882   if (optimize_insn_for_size_p ())
13883     FAIL;
13884
13885   for (i = 3; i < 10; i++)
13886     operands[i] = gen_reg_rtx (XFmode);
13887
13888   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
13889 })
13890
13891 (define_expand "expxf2"
13892   [(use (match_operand:XF 0 "register_operand" ""))
13893    (use (match_operand:XF 1 "register_operand" ""))]
13894   "TARGET_USE_FANCY_MATH_387
13895    && flag_unsafe_math_optimizations"
13896 {
13897   rtx op2;
13898
13899   if (optimize_insn_for_size_p ())
13900     FAIL;
13901
13902   op2 = gen_reg_rtx (XFmode);
13903   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
13904
13905   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
13906   DONE;
13907 })
13908
13909 (define_expand "exp<mode>2"
13910   [(use (match_operand:MODEF 0 "register_operand" ""))
13911    (use (match_operand:MODEF 1 "general_operand" ""))]
13912  "TARGET_USE_FANCY_MATH_387
13913    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13914        || TARGET_MIX_SSE_I387)
13915    && flag_unsafe_math_optimizations"
13916 {
13917   rtx op0, op1;
13918
13919   if (optimize_insn_for_size_p ())
13920     FAIL;
13921
13922   op0 = gen_reg_rtx (XFmode);
13923   op1 = gen_reg_rtx (XFmode);
13924
13925   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13926   emit_insn (gen_expxf2 (op0, op1));
13927   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13928   DONE;
13929 })
13930
13931 (define_expand "exp10xf2"
13932   [(use (match_operand:XF 0 "register_operand" ""))
13933    (use (match_operand:XF 1 "register_operand" ""))]
13934   "TARGET_USE_FANCY_MATH_387
13935    && flag_unsafe_math_optimizations"
13936 {
13937   rtx op2;
13938
13939   if (optimize_insn_for_size_p ())
13940     FAIL;
13941
13942   op2 = gen_reg_rtx (XFmode);
13943   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
13944
13945   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
13946   DONE;
13947 })
13948
13949 (define_expand "exp10<mode>2"
13950   [(use (match_operand:MODEF 0 "register_operand" ""))
13951    (use (match_operand:MODEF 1 "general_operand" ""))]
13952  "TARGET_USE_FANCY_MATH_387
13953    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13954        || TARGET_MIX_SSE_I387)
13955    && flag_unsafe_math_optimizations"
13956 {
13957   rtx op0, op1;
13958
13959   if (optimize_insn_for_size_p ())
13960     FAIL;
13961
13962   op0 = gen_reg_rtx (XFmode);
13963   op1 = gen_reg_rtx (XFmode);
13964
13965   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13966   emit_insn (gen_exp10xf2 (op0, op1));
13967   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13968   DONE;
13969 })
13970
13971 (define_expand "exp2xf2"
13972   [(use (match_operand:XF 0 "register_operand" ""))
13973    (use (match_operand:XF 1 "register_operand" ""))]
13974   "TARGET_USE_FANCY_MATH_387
13975    && flag_unsafe_math_optimizations"
13976 {
13977   rtx op2;
13978
13979   if (optimize_insn_for_size_p ())
13980     FAIL;
13981
13982   op2 = gen_reg_rtx (XFmode);
13983   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
13984
13985   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
13986   DONE;
13987 })
13988
13989 (define_expand "exp2<mode>2"
13990   [(use (match_operand:MODEF 0 "register_operand" ""))
13991    (use (match_operand:MODEF 1 "general_operand" ""))]
13992  "TARGET_USE_FANCY_MATH_387
13993    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13994        || TARGET_MIX_SSE_I387)
13995    && flag_unsafe_math_optimizations"
13996 {
13997   rtx op0, op1;
13998
13999   if (optimize_insn_for_size_p ())
14000     FAIL;
14001
14002   op0 = gen_reg_rtx (XFmode);
14003   op1 = gen_reg_rtx (XFmode);
14004
14005   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14006   emit_insn (gen_exp2xf2 (op0, op1));
14007   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14008   DONE;
14009 })
14010
14011 (define_expand "expm1xf2"
14012   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14013                                (match_dup 2)))
14014    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14015    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14016    (set (match_dup 9) (float_extend:XF (match_dup 13)))
14017    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14018    (parallel [(set (match_dup 7)
14019                    (unspec:XF [(match_dup 6) (match_dup 4)]
14020                               UNSPEC_FSCALE_FRACT))
14021               (set (match_dup 8)
14022                    (unspec:XF [(match_dup 6) (match_dup 4)]
14023                               UNSPEC_FSCALE_EXP))])
14024    (parallel [(set (match_dup 10)
14025                    (unspec:XF [(match_dup 9) (match_dup 8)]
14026                               UNSPEC_FSCALE_FRACT))
14027               (set (match_dup 11)
14028                    (unspec:XF [(match_dup 9) (match_dup 8)]
14029                               UNSPEC_FSCALE_EXP))])
14030    (set (match_dup 12) (minus:XF (match_dup 10)
14031                                  (float_extend:XF (match_dup 13))))
14032    (set (match_operand:XF 0 "register_operand" "")
14033         (plus:XF (match_dup 12) (match_dup 7)))]
14034   "TARGET_USE_FANCY_MATH_387
14035    && flag_unsafe_math_optimizations"
14036 {
14037   int i;
14038
14039   if (optimize_insn_for_size_p ())
14040     FAIL;
14041
14042   for (i = 2; i < 13; i++)
14043     operands[i] = gen_reg_rtx (XFmode);
14044
14045   operands[13]
14046     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14047
14048   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14049 })
14050
14051 (define_expand "expm1<mode>2"
14052   [(use (match_operand:MODEF 0 "register_operand" ""))
14053    (use (match_operand:MODEF 1 "general_operand" ""))]
14054  "TARGET_USE_FANCY_MATH_387
14055    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14056        || TARGET_MIX_SSE_I387)
14057    && flag_unsafe_math_optimizations"
14058 {
14059   rtx op0, op1;
14060
14061   if (optimize_insn_for_size_p ())
14062     FAIL;
14063
14064   op0 = gen_reg_rtx (XFmode);
14065   op1 = gen_reg_rtx (XFmode);
14066
14067   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14068   emit_insn (gen_expm1xf2 (op0, op1));
14069   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14070   DONE;
14071 })
14072
14073 (define_expand "ldexpxf3"
14074   [(set (match_dup 3)
14075         (float:XF (match_operand:SI 2 "register_operand" "")))
14076    (parallel [(set (match_operand:XF 0 " register_operand" "")
14077                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
14078                                (match_dup 3)]
14079                               UNSPEC_FSCALE_FRACT))
14080               (set (match_dup 4)
14081                    (unspec:XF [(match_dup 1) (match_dup 3)]
14082                               UNSPEC_FSCALE_EXP))])]
14083   "TARGET_USE_FANCY_MATH_387
14084    && flag_unsafe_math_optimizations"
14085 {
14086   if (optimize_insn_for_size_p ())
14087     FAIL;
14088
14089   operands[3] = gen_reg_rtx (XFmode);
14090   operands[4] = gen_reg_rtx (XFmode);
14091 })
14092
14093 (define_expand "ldexp<mode>3"
14094   [(use (match_operand:MODEF 0 "register_operand" ""))
14095    (use (match_operand:MODEF 1 "general_operand" ""))
14096    (use (match_operand:SI 2 "register_operand" ""))]
14097  "TARGET_USE_FANCY_MATH_387
14098    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14099        || TARGET_MIX_SSE_I387)
14100    && flag_unsafe_math_optimizations"
14101 {
14102   rtx op0, op1;
14103
14104   if (optimize_insn_for_size_p ())
14105     FAIL;
14106
14107   op0 = gen_reg_rtx (XFmode);
14108   op1 = gen_reg_rtx (XFmode);
14109
14110   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14111   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14112   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14113   DONE;
14114 })
14115
14116 (define_expand "scalbxf3"
14117   [(parallel [(set (match_operand:XF 0 " register_operand" "")
14118                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
14119                                (match_operand:XF 2 "register_operand" "")]
14120                               UNSPEC_FSCALE_FRACT))
14121               (set (match_dup 3)
14122                    (unspec:XF [(match_dup 1) (match_dup 2)]
14123                               UNSPEC_FSCALE_EXP))])]
14124   "TARGET_USE_FANCY_MATH_387
14125    && flag_unsafe_math_optimizations"
14126 {
14127   if (optimize_insn_for_size_p ())
14128     FAIL;
14129
14130   operands[3] = gen_reg_rtx (XFmode);
14131 })
14132
14133 (define_expand "scalb<mode>3"
14134   [(use (match_operand:MODEF 0 "register_operand" ""))
14135    (use (match_operand:MODEF 1 "general_operand" ""))
14136    (use (match_operand:MODEF 2 "general_operand" ""))]
14137  "TARGET_USE_FANCY_MATH_387
14138    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14139        || TARGET_MIX_SSE_I387)
14140    && flag_unsafe_math_optimizations"
14141 {
14142   rtx op0, op1, op2;
14143
14144   if (optimize_insn_for_size_p ())
14145     FAIL;
14146
14147   op0 = gen_reg_rtx (XFmode);
14148   op1 = gen_reg_rtx (XFmode);
14149   op2 = gen_reg_rtx (XFmode);
14150
14151   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14152   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14153   emit_insn (gen_scalbxf3 (op0, op1, op2));
14154   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14155   DONE;
14156 })
14157
14158 (define_expand "significandxf2"
14159   [(parallel [(set (match_operand:XF 0 "register_operand" "")
14160                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14161                               UNSPEC_XTRACT_FRACT))
14162               (set (match_dup 2)
14163                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14164   "TARGET_USE_FANCY_MATH_387
14165    && flag_unsafe_math_optimizations"
14166   "operands[2] = gen_reg_rtx (XFmode);")
14167
14168 (define_expand "significand<mode>2"
14169   [(use (match_operand:MODEF 0 "register_operand" ""))
14170    (use (match_operand:MODEF 1 "register_operand" ""))]
14171   "TARGET_USE_FANCY_MATH_387
14172    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14173        || TARGET_MIX_SSE_I387)
14174    && flag_unsafe_math_optimizations"
14175 {
14176   rtx op0 = gen_reg_rtx (XFmode);
14177   rtx op1 = gen_reg_rtx (XFmode);
14178
14179   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14180   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14181   DONE;
14182 })
14183 \f
14184
14185 (define_insn "sse4_1_round<mode>2"
14186   [(set (match_operand:MODEF 0 "register_operand" "=x")
14187         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14188                        (match_operand:SI 2 "const_0_to_15_operand" "n")]
14189                       UNSPEC_ROUND))]
14190   "TARGET_ROUND"
14191   "%vrounds<ssemodefsuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14192   [(set_attr "type" "ssecvt")
14193    (set_attr "prefix_extra" "1")
14194    (set_attr "prefix" "maybe_vex")
14195    (set_attr "mode" "<MODE>")])
14196
14197 (define_insn "rintxf2"
14198   [(set (match_operand:XF 0 "register_operand" "=f")
14199         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14200                    UNSPEC_FRNDINT))]
14201   "TARGET_USE_FANCY_MATH_387
14202    && flag_unsafe_math_optimizations"
14203   "frndint"
14204   [(set_attr "type" "fpspc")
14205    (set_attr "mode" "XF")])
14206
14207 (define_expand "rint<mode>2"
14208   [(use (match_operand:MODEF 0 "register_operand" ""))
14209    (use (match_operand:MODEF 1 "register_operand" ""))]
14210   "(TARGET_USE_FANCY_MATH_387
14211     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14212         || TARGET_MIX_SSE_I387)
14213     && flag_unsafe_math_optimizations)
14214    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14215        && !flag_trapping_math)"
14216 {
14217   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14218       && !flag_trapping_math)
14219     {
14220       if (!TARGET_ROUND && optimize_insn_for_size_p ())
14221         FAIL;
14222       if (TARGET_ROUND)
14223         emit_insn (gen_sse4_1_round<mode>2
14224                    (operands[0], operands[1], GEN_INT (0x04)));
14225       else
14226         ix86_expand_rint (operand0, operand1);
14227     }
14228   else
14229     {
14230       rtx op0 = gen_reg_rtx (XFmode);
14231       rtx op1 = gen_reg_rtx (XFmode);
14232
14233       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14234       emit_insn (gen_rintxf2 (op0, op1));
14235
14236       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14237     }
14238   DONE;
14239 })
14240
14241 (define_expand "round<mode>2"
14242   [(match_operand:MODEF 0 "register_operand" "")
14243    (match_operand:MODEF 1 "nonimmediate_operand" "")]
14244   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14245    && !flag_trapping_math && !flag_rounding_math"
14246 {
14247   if (optimize_insn_for_size_p ())
14248     FAIL;
14249   if (TARGET_64BIT || (<MODE>mode != DFmode))
14250     ix86_expand_round (operand0, operand1);
14251   else
14252     ix86_expand_rounddf_32 (operand0, operand1);
14253   DONE;
14254 })
14255
14256 (define_insn_and_split "*fistdi2_1"
14257   [(set (match_operand:DI 0 "nonimmediate_operand" "")
14258         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14259                    UNSPEC_FIST))]
14260   "TARGET_USE_FANCY_MATH_387
14261    && can_create_pseudo_p ()"
14262   "#"
14263   "&& 1"
14264   [(const_int 0)]
14265 {
14266   if (memory_operand (operands[0], VOIDmode))
14267     emit_insn (gen_fistdi2 (operands[0], operands[1]));
14268   else
14269     {
14270       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14271       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14272                                          operands[2]));
14273     }
14274   DONE;
14275 }
14276   [(set_attr "type" "fpspc")
14277    (set_attr "mode" "DI")])
14278
14279 (define_insn "fistdi2"
14280   [(set (match_operand:DI 0 "memory_operand" "=m")
14281         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14282                    UNSPEC_FIST))
14283    (clobber (match_scratch:XF 2 "=&1f"))]
14284   "TARGET_USE_FANCY_MATH_387"
14285   "* return output_fix_trunc (insn, operands, 0);"
14286   [(set_attr "type" "fpspc")
14287    (set_attr "mode" "DI")])
14288
14289 (define_insn "fistdi2_with_temp"
14290   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14291         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14292                    UNSPEC_FIST))
14293    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14294    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14295   "TARGET_USE_FANCY_MATH_387"
14296   "#"
14297   [(set_attr "type" "fpspc")
14298    (set_attr "mode" "DI")])
14299
14300 (define_split
14301   [(set (match_operand:DI 0 "register_operand" "")
14302         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14303                    UNSPEC_FIST))
14304    (clobber (match_operand:DI 2 "memory_operand" ""))
14305    (clobber (match_scratch 3 ""))]
14306   "reload_completed"
14307   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14308               (clobber (match_dup 3))])
14309    (set (match_dup 0) (match_dup 2))])
14310
14311 (define_split
14312   [(set (match_operand:DI 0 "memory_operand" "")
14313         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14314                    UNSPEC_FIST))
14315    (clobber (match_operand:DI 2 "memory_operand" ""))
14316    (clobber (match_scratch 3 ""))]
14317   "reload_completed"
14318   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14319               (clobber (match_dup 3))])])
14320
14321 (define_insn_and_split "*fist<mode>2_1"
14322   [(set (match_operand:X87MODEI12 0 "register_operand" "")
14323         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14324                            UNSPEC_FIST))]
14325   "TARGET_USE_FANCY_MATH_387
14326    && can_create_pseudo_p ()"
14327   "#"
14328   "&& 1"
14329   [(const_int 0)]
14330 {
14331   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14332   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14333                                         operands[2]));
14334   DONE;
14335 }
14336   [(set_attr "type" "fpspc")
14337    (set_attr "mode" "<MODE>")])
14338
14339 (define_insn "fist<mode>2"
14340   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14341         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14342                            UNSPEC_FIST))]
14343   "TARGET_USE_FANCY_MATH_387"
14344   "* return output_fix_trunc (insn, operands, 0);"
14345   [(set_attr "type" "fpspc")
14346    (set_attr "mode" "<MODE>")])
14347
14348 (define_insn "fist<mode>2_with_temp"
14349   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
14350         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14351                            UNSPEC_FIST))
14352    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
14353   "TARGET_USE_FANCY_MATH_387"
14354   "#"
14355   [(set_attr "type" "fpspc")
14356    (set_attr "mode" "<MODE>")])
14357
14358 (define_split
14359   [(set (match_operand:X87MODEI12 0 "register_operand" "")
14360         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14361                            UNSPEC_FIST))
14362    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14363   "reload_completed"
14364   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
14365    (set (match_dup 0) (match_dup 2))])
14366
14367 (define_split
14368   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14369         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14370                            UNSPEC_FIST))
14371    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14372   "reload_completed"
14373   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))])
14374
14375 (define_expand "lrintxf<mode>2"
14376   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14377      (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14378                       UNSPEC_FIST))]
14379   "TARGET_USE_FANCY_MATH_387")
14380
14381 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
14382   [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14383      (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
14384                         UNSPEC_FIX_NOTRUNC))]
14385   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14386    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)")
14387
14388 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
14389   [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14390    (match_operand:MODEF 1 "register_operand" "")]
14391   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14392    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
14393    && !flag_trapping_math && !flag_rounding_math"
14394 {
14395   if (optimize_insn_for_size_p ())
14396     FAIL;
14397   ix86_expand_lround (operand0, operand1);
14398   DONE;
14399 })
14400
14401 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14402 (define_insn_and_split "frndintxf2_floor"
14403   [(set (match_operand:XF 0 "register_operand" "")
14404         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14405          UNSPEC_FRNDINT_FLOOR))
14406    (clobber (reg:CC FLAGS_REG))]
14407   "TARGET_USE_FANCY_MATH_387
14408    && flag_unsafe_math_optimizations
14409    && can_create_pseudo_p ()"
14410   "#"
14411   "&& 1"
14412   [(const_int 0)]
14413 {
14414   ix86_optimize_mode_switching[I387_FLOOR] = 1;
14415
14416   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14417   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14418
14419   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14420                                         operands[2], operands[3]));
14421   DONE;
14422 }
14423   [(set_attr "type" "frndint")
14424    (set_attr "i387_cw" "floor")
14425    (set_attr "mode" "XF")])
14426
14427 (define_insn "frndintxf2_floor_i387"
14428   [(set (match_operand:XF 0 "register_operand" "=f")
14429         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14430          UNSPEC_FRNDINT_FLOOR))
14431    (use (match_operand:HI 2 "memory_operand" "m"))
14432    (use (match_operand:HI 3 "memory_operand" "m"))]
14433   "TARGET_USE_FANCY_MATH_387
14434    && flag_unsafe_math_optimizations"
14435   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14436   [(set_attr "type" "frndint")
14437    (set_attr "i387_cw" "floor")
14438    (set_attr "mode" "XF")])
14439
14440 (define_expand "floorxf2"
14441   [(use (match_operand:XF 0 "register_operand" ""))
14442    (use (match_operand:XF 1 "register_operand" ""))]
14443   "TARGET_USE_FANCY_MATH_387
14444    && flag_unsafe_math_optimizations"
14445 {
14446   if (optimize_insn_for_size_p ())
14447     FAIL;
14448   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14449   DONE;
14450 })
14451
14452 (define_expand "floor<mode>2"
14453   [(use (match_operand:MODEF 0 "register_operand" ""))
14454    (use (match_operand:MODEF 1 "register_operand" ""))]
14455   "(TARGET_USE_FANCY_MATH_387
14456     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14457         || TARGET_MIX_SSE_I387)
14458     && flag_unsafe_math_optimizations)
14459    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14460        && !flag_trapping_math)"
14461 {
14462   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14463       && !flag_trapping_math
14464       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14465     {
14466       if (!TARGET_ROUND && optimize_insn_for_size_p ())
14467         FAIL;
14468       if (TARGET_ROUND)
14469         emit_insn (gen_sse4_1_round<mode>2
14470                    (operands[0], operands[1], GEN_INT (0x01)));
14471       else if (TARGET_64BIT || (<MODE>mode != DFmode))
14472         ix86_expand_floorceil (operand0, operand1, true);
14473       else
14474         ix86_expand_floorceildf_32 (operand0, operand1, true);
14475     }
14476   else
14477     {
14478       rtx op0, op1;
14479
14480       if (optimize_insn_for_size_p ())
14481         FAIL;
14482
14483       op0 = gen_reg_rtx (XFmode);
14484       op1 = gen_reg_rtx (XFmode);
14485       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14486       emit_insn (gen_frndintxf2_floor (op0, op1));
14487
14488       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14489     }
14490   DONE;
14491 })
14492
14493 (define_insn_and_split "*fist<mode>2_floor_1"
14494   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14495         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14496          UNSPEC_FIST_FLOOR))
14497    (clobber (reg:CC FLAGS_REG))]
14498   "TARGET_USE_FANCY_MATH_387
14499    && flag_unsafe_math_optimizations
14500    && can_create_pseudo_p ()"
14501   "#"
14502   "&& 1"
14503   [(const_int 0)]
14504 {
14505   ix86_optimize_mode_switching[I387_FLOOR] = 1;
14506
14507   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14508   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14509   if (memory_operand (operands[0], VOIDmode))
14510     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14511                                       operands[2], operands[3]));
14512   else
14513     {
14514       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14515       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14516                                                   operands[2], operands[3],
14517                                                   operands[4]));
14518     }
14519   DONE;
14520 }
14521   [(set_attr "type" "fistp")
14522    (set_attr "i387_cw" "floor")
14523    (set_attr "mode" "<MODE>")])
14524
14525 (define_insn "fistdi2_floor"
14526   [(set (match_operand:DI 0 "memory_operand" "=m")
14527         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14528          UNSPEC_FIST_FLOOR))
14529    (use (match_operand:HI 2 "memory_operand" "m"))
14530    (use (match_operand:HI 3 "memory_operand" "m"))
14531    (clobber (match_scratch:XF 4 "=&1f"))]
14532   "TARGET_USE_FANCY_MATH_387
14533    && flag_unsafe_math_optimizations"
14534   "* return output_fix_trunc (insn, operands, 0);"
14535   [(set_attr "type" "fistp")
14536    (set_attr "i387_cw" "floor")
14537    (set_attr "mode" "DI")])
14538
14539 (define_insn "fistdi2_floor_with_temp"
14540   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14541         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14542          UNSPEC_FIST_FLOOR))
14543    (use (match_operand:HI 2 "memory_operand" "m,m"))
14544    (use (match_operand:HI 3 "memory_operand" "m,m"))
14545    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14546    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14547   "TARGET_USE_FANCY_MATH_387
14548    && flag_unsafe_math_optimizations"
14549   "#"
14550   [(set_attr "type" "fistp")
14551    (set_attr "i387_cw" "floor")
14552    (set_attr "mode" "DI")])
14553
14554 (define_split
14555   [(set (match_operand:DI 0 "register_operand" "")
14556         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14557          UNSPEC_FIST_FLOOR))
14558    (use (match_operand:HI 2 "memory_operand" ""))
14559    (use (match_operand:HI 3 "memory_operand" ""))
14560    (clobber (match_operand:DI 4 "memory_operand" ""))
14561    (clobber (match_scratch 5 ""))]
14562   "reload_completed"
14563   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14564               (use (match_dup 2))
14565               (use (match_dup 3))
14566               (clobber (match_dup 5))])
14567    (set (match_dup 0) (match_dup 4))])
14568
14569 (define_split
14570   [(set (match_operand:DI 0 "memory_operand" "")
14571         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14572          UNSPEC_FIST_FLOOR))
14573    (use (match_operand:HI 2 "memory_operand" ""))
14574    (use (match_operand:HI 3 "memory_operand" ""))
14575    (clobber (match_operand:DI 4 "memory_operand" ""))
14576    (clobber (match_scratch 5 ""))]
14577   "reload_completed"
14578   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14579               (use (match_dup 2))
14580               (use (match_dup 3))
14581               (clobber (match_dup 5))])])
14582
14583 (define_insn "fist<mode>2_floor"
14584   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14585         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14586          UNSPEC_FIST_FLOOR))
14587    (use (match_operand:HI 2 "memory_operand" "m"))
14588    (use (match_operand:HI 3 "memory_operand" "m"))]
14589   "TARGET_USE_FANCY_MATH_387
14590    && flag_unsafe_math_optimizations"
14591   "* return output_fix_trunc (insn, operands, 0);"
14592   [(set_attr "type" "fistp")
14593    (set_attr "i387_cw" "floor")
14594    (set_attr "mode" "<MODE>")])
14595
14596 (define_insn "fist<mode>2_floor_with_temp"
14597   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
14598         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
14599          UNSPEC_FIST_FLOOR))
14600    (use (match_operand:HI 2 "memory_operand" "m,m"))
14601    (use (match_operand:HI 3 "memory_operand" "m,m"))
14602    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
14603   "TARGET_USE_FANCY_MATH_387
14604    && flag_unsafe_math_optimizations"
14605   "#"
14606   [(set_attr "type" "fistp")
14607    (set_attr "i387_cw" "floor")
14608    (set_attr "mode" "<MODE>")])
14609
14610 (define_split
14611   [(set (match_operand:X87MODEI12 0 "register_operand" "")
14612         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14613          UNSPEC_FIST_FLOOR))
14614    (use (match_operand:HI 2 "memory_operand" ""))
14615    (use (match_operand:HI 3 "memory_operand" ""))
14616    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14617   "reload_completed"
14618   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
14619                                   UNSPEC_FIST_FLOOR))
14620               (use (match_dup 2))
14621               (use (match_dup 3))])
14622    (set (match_dup 0) (match_dup 4))])
14623
14624 (define_split
14625   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14626         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14627          UNSPEC_FIST_FLOOR))
14628    (use (match_operand:HI 2 "memory_operand" ""))
14629    (use (match_operand:HI 3 "memory_operand" ""))
14630    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14631   "reload_completed"
14632   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
14633                                   UNSPEC_FIST_FLOOR))
14634               (use (match_dup 2))
14635               (use (match_dup 3))])])
14636
14637 (define_expand "lfloorxf<mode>2"
14638   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14639                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14640                     UNSPEC_FIST_FLOOR))
14641               (clobber (reg:CC FLAGS_REG))])]
14642   "TARGET_USE_FANCY_MATH_387
14643    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14644    && flag_unsafe_math_optimizations")
14645
14646 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
14647   [(match_operand:SWI48 0 "nonimmediate_operand" "")
14648    (match_operand:MODEF 1 "register_operand" "")]
14649   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14650    && !flag_trapping_math"
14651 {
14652   if (TARGET_64BIT && optimize_insn_for_size_p ())
14653     FAIL;
14654   ix86_expand_lfloorceil (operand0, operand1, true);
14655   DONE;
14656 })
14657
14658 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14659 (define_insn_and_split "frndintxf2_ceil"
14660   [(set (match_operand:XF 0 "register_operand" "")
14661         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14662          UNSPEC_FRNDINT_CEIL))
14663    (clobber (reg:CC FLAGS_REG))]
14664   "TARGET_USE_FANCY_MATH_387
14665    && flag_unsafe_math_optimizations
14666    && can_create_pseudo_p ()"
14667   "#"
14668   "&& 1"
14669   [(const_int 0)]
14670 {
14671   ix86_optimize_mode_switching[I387_CEIL] = 1;
14672
14673   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14674   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14675
14676   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
14677                                        operands[2], operands[3]));
14678   DONE;
14679 }
14680   [(set_attr "type" "frndint")
14681    (set_attr "i387_cw" "ceil")
14682    (set_attr "mode" "XF")])
14683
14684 (define_insn "frndintxf2_ceil_i387"
14685   [(set (match_operand:XF 0 "register_operand" "=f")
14686         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14687          UNSPEC_FRNDINT_CEIL))
14688    (use (match_operand:HI 2 "memory_operand" "m"))
14689    (use (match_operand:HI 3 "memory_operand" "m"))]
14690   "TARGET_USE_FANCY_MATH_387
14691    && flag_unsafe_math_optimizations"
14692   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14693   [(set_attr "type" "frndint")
14694    (set_attr "i387_cw" "ceil")
14695    (set_attr "mode" "XF")])
14696
14697 (define_expand "ceilxf2"
14698   [(use (match_operand:XF 0 "register_operand" ""))
14699    (use (match_operand:XF 1 "register_operand" ""))]
14700   "TARGET_USE_FANCY_MATH_387
14701    && flag_unsafe_math_optimizations"
14702 {
14703   if (optimize_insn_for_size_p ())
14704     FAIL;
14705   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
14706   DONE;
14707 })
14708
14709 (define_expand "ceil<mode>2"
14710   [(use (match_operand:MODEF 0 "register_operand" ""))
14711    (use (match_operand:MODEF 1 "register_operand" ""))]
14712   "(TARGET_USE_FANCY_MATH_387
14713     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14714         || TARGET_MIX_SSE_I387)
14715     && flag_unsafe_math_optimizations)
14716    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14717        && !flag_trapping_math)"
14718 {
14719   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14720       && !flag_trapping_math
14721       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14722     {
14723       if (TARGET_ROUND)
14724         emit_insn (gen_sse4_1_round<mode>2
14725                    (operands[0], operands[1], GEN_INT (0x02)));
14726       else if (optimize_insn_for_size_p ())
14727         FAIL;
14728       else if (TARGET_64BIT || (<MODE>mode != DFmode))
14729         ix86_expand_floorceil (operand0, operand1, false);
14730       else
14731         ix86_expand_floorceildf_32 (operand0, operand1, false);
14732     }
14733   else
14734     {
14735       rtx op0, op1;
14736
14737       if (optimize_insn_for_size_p ())
14738         FAIL;
14739
14740       op0 = gen_reg_rtx (XFmode);
14741       op1 = gen_reg_rtx (XFmode);
14742       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14743       emit_insn (gen_frndintxf2_ceil (op0, op1));
14744
14745       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14746     }
14747   DONE;
14748 })
14749
14750 (define_insn_and_split "*fist<mode>2_ceil_1"
14751   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14752         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14753          UNSPEC_FIST_CEIL))
14754    (clobber (reg:CC FLAGS_REG))]
14755   "TARGET_USE_FANCY_MATH_387
14756    && flag_unsafe_math_optimizations
14757    && can_create_pseudo_p ()"
14758   "#"
14759   "&& 1"
14760   [(const_int 0)]
14761 {
14762   ix86_optimize_mode_switching[I387_CEIL] = 1;
14763
14764   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14765   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14766   if (memory_operand (operands[0], VOIDmode))
14767     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
14768                                      operands[2], operands[3]));
14769   else
14770     {
14771       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14772       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
14773                                                  operands[2], operands[3],
14774                                                  operands[4]));
14775     }
14776   DONE;
14777 }
14778   [(set_attr "type" "fistp")
14779    (set_attr "i387_cw" "ceil")
14780    (set_attr "mode" "<MODE>")])
14781
14782 (define_insn "fistdi2_ceil"
14783   [(set (match_operand:DI 0 "memory_operand" "=m")
14784         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14785          UNSPEC_FIST_CEIL))
14786    (use (match_operand:HI 2 "memory_operand" "m"))
14787    (use (match_operand:HI 3 "memory_operand" "m"))
14788    (clobber (match_scratch:XF 4 "=&1f"))]
14789   "TARGET_USE_FANCY_MATH_387
14790    && flag_unsafe_math_optimizations"
14791   "* return output_fix_trunc (insn, operands, 0);"
14792   [(set_attr "type" "fistp")
14793    (set_attr "i387_cw" "ceil")
14794    (set_attr "mode" "DI")])
14795
14796 (define_insn "fistdi2_ceil_with_temp"
14797   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14798         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14799          UNSPEC_FIST_CEIL))
14800    (use (match_operand:HI 2 "memory_operand" "m,m"))
14801    (use (match_operand:HI 3 "memory_operand" "m,m"))
14802    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14803    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14804   "TARGET_USE_FANCY_MATH_387
14805    && flag_unsafe_math_optimizations"
14806   "#"
14807   [(set_attr "type" "fistp")
14808    (set_attr "i387_cw" "ceil")
14809    (set_attr "mode" "DI")])
14810
14811 (define_split
14812   [(set (match_operand:DI 0 "register_operand" "")
14813         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14814          UNSPEC_FIST_CEIL))
14815    (use (match_operand:HI 2 "memory_operand" ""))
14816    (use (match_operand:HI 3 "memory_operand" ""))
14817    (clobber (match_operand:DI 4 "memory_operand" ""))
14818    (clobber (match_scratch 5 ""))]
14819   "reload_completed"
14820   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
14821               (use (match_dup 2))
14822               (use (match_dup 3))
14823               (clobber (match_dup 5))])
14824    (set (match_dup 0) (match_dup 4))])
14825
14826 (define_split
14827   [(set (match_operand:DI 0 "memory_operand" "")
14828         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14829          UNSPEC_FIST_CEIL))
14830    (use (match_operand:HI 2 "memory_operand" ""))
14831    (use (match_operand:HI 3 "memory_operand" ""))
14832    (clobber (match_operand:DI 4 "memory_operand" ""))
14833    (clobber (match_scratch 5 ""))]
14834   "reload_completed"
14835   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
14836               (use (match_dup 2))
14837               (use (match_dup 3))
14838               (clobber (match_dup 5))])])
14839
14840 (define_insn "fist<mode>2_ceil"
14841   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14842         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14843          UNSPEC_FIST_CEIL))
14844    (use (match_operand:HI 2 "memory_operand" "m"))
14845    (use (match_operand:HI 3 "memory_operand" "m"))]
14846   "TARGET_USE_FANCY_MATH_387
14847    && flag_unsafe_math_optimizations"
14848   "* return output_fix_trunc (insn, operands, 0);"
14849   [(set_attr "type" "fistp")
14850    (set_attr "i387_cw" "ceil")
14851    (set_attr "mode" "<MODE>")])
14852
14853 (define_insn "fist<mode>2_ceil_with_temp"
14854   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
14855         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
14856          UNSPEC_FIST_CEIL))
14857    (use (match_operand:HI 2 "memory_operand" "m,m"))
14858    (use (match_operand:HI 3 "memory_operand" "m,m"))
14859    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
14860   "TARGET_USE_FANCY_MATH_387
14861    && flag_unsafe_math_optimizations"
14862   "#"
14863   [(set_attr "type" "fistp")
14864    (set_attr "i387_cw" "ceil")
14865    (set_attr "mode" "<MODE>")])
14866
14867 (define_split
14868   [(set (match_operand:X87MODEI12 0 "register_operand" "")
14869         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14870          UNSPEC_FIST_CEIL))
14871    (use (match_operand:HI 2 "memory_operand" ""))
14872    (use (match_operand:HI 3 "memory_operand" ""))
14873    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14874   "reload_completed"
14875   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
14876                                   UNSPEC_FIST_CEIL))
14877               (use (match_dup 2))
14878               (use (match_dup 3))])
14879    (set (match_dup 0) (match_dup 4))])
14880
14881 (define_split
14882   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14883         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14884          UNSPEC_FIST_CEIL))
14885    (use (match_operand:HI 2 "memory_operand" ""))
14886    (use (match_operand:HI 3 "memory_operand" ""))
14887    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14888   "reload_completed"
14889   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
14890                                   UNSPEC_FIST_CEIL))
14891               (use (match_dup 2))
14892               (use (match_dup 3))])])
14893
14894 (define_expand "lceilxf<mode>2"
14895   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14896                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14897                     UNSPEC_FIST_CEIL))
14898               (clobber (reg:CC FLAGS_REG))])]
14899   "TARGET_USE_FANCY_MATH_387
14900    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14901    && flag_unsafe_math_optimizations")
14902
14903 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
14904   [(match_operand:SWI48 0 "nonimmediate_operand" "")
14905    (match_operand:MODEF 1 "register_operand" "")]
14906   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14907    && !flag_trapping_math"
14908 {
14909   ix86_expand_lfloorceil (operand0, operand1, false);
14910   DONE;
14911 })
14912
14913 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14914 (define_insn_and_split "frndintxf2_trunc"
14915   [(set (match_operand:XF 0 "register_operand" "")
14916         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14917          UNSPEC_FRNDINT_TRUNC))
14918    (clobber (reg:CC FLAGS_REG))]
14919   "TARGET_USE_FANCY_MATH_387
14920    && flag_unsafe_math_optimizations
14921    && can_create_pseudo_p ()"
14922   "#"
14923   "&& 1"
14924   [(const_int 0)]
14925 {
14926   ix86_optimize_mode_switching[I387_TRUNC] = 1;
14927
14928   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14929   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
14930
14931   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
14932                                         operands[2], operands[3]));
14933   DONE;
14934 }
14935   [(set_attr "type" "frndint")
14936    (set_attr "i387_cw" "trunc")
14937    (set_attr "mode" "XF")])
14938
14939 (define_insn "frndintxf2_trunc_i387"
14940   [(set (match_operand:XF 0 "register_operand" "=f")
14941         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14942          UNSPEC_FRNDINT_TRUNC))
14943    (use (match_operand:HI 2 "memory_operand" "m"))
14944    (use (match_operand:HI 3 "memory_operand" "m"))]
14945   "TARGET_USE_FANCY_MATH_387
14946    && flag_unsafe_math_optimizations"
14947   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14948   [(set_attr "type" "frndint")
14949    (set_attr "i387_cw" "trunc")
14950    (set_attr "mode" "XF")])
14951
14952 (define_expand "btruncxf2"
14953   [(use (match_operand:XF 0 "register_operand" ""))
14954    (use (match_operand:XF 1 "register_operand" ""))]
14955   "TARGET_USE_FANCY_MATH_387
14956    && flag_unsafe_math_optimizations"
14957 {
14958   if (optimize_insn_for_size_p ())
14959     FAIL;
14960   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
14961   DONE;
14962 })
14963
14964 (define_expand "btrunc<mode>2"
14965   [(use (match_operand:MODEF 0 "register_operand" ""))
14966    (use (match_operand:MODEF 1 "register_operand" ""))]
14967   "(TARGET_USE_FANCY_MATH_387
14968     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14969         || TARGET_MIX_SSE_I387)
14970     && flag_unsafe_math_optimizations)
14971    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14972        && !flag_trapping_math)"
14973 {
14974   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14975       && !flag_trapping_math
14976       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14977     {
14978       if (TARGET_ROUND)
14979         emit_insn (gen_sse4_1_round<mode>2
14980                    (operands[0], operands[1], GEN_INT (0x03)));
14981       else if (optimize_insn_for_size_p ())
14982         FAIL;
14983       else if (TARGET_64BIT || (<MODE>mode != DFmode))
14984         ix86_expand_trunc (operand0, operand1);
14985       else
14986         ix86_expand_truncdf_32 (operand0, operand1);
14987     }
14988   else
14989     {
14990       rtx op0, op1;
14991
14992       if (optimize_insn_for_size_p ())
14993         FAIL;
14994
14995       op0 = gen_reg_rtx (XFmode);
14996       op1 = gen_reg_rtx (XFmode);
14997       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14998       emit_insn (gen_frndintxf2_trunc (op0, op1));
14999
15000       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15001     }
15002   DONE;
15003 })
15004
15005 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15006 (define_insn_and_split "frndintxf2_mask_pm"
15007   [(set (match_operand:XF 0 "register_operand" "")
15008         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15009          UNSPEC_FRNDINT_MASK_PM))
15010    (clobber (reg:CC FLAGS_REG))]
15011   "TARGET_USE_FANCY_MATH_387
15012    && flag_unsafe_math_optimizations
15013    && can_create_pseudo_p ()"
15014   "#"
15015   "&& 1"
15016   [(const_int 0)]
15017 {
15018   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15019
15020   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15021   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15022
15023   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15024                                           operands[2], operands[3]));
15025   DONE;
15026 }
15027   [(set_attr "type" "frndint")
15028    (set_attr "i387_cw" "mask_pm")
15029    (set_attr "mode" "XF")])
15030
15031 (define_insn "frndintxf2_mask_pm_i387"
15032   [(set (match_operand:XF 0 "register_operand" "=f")
15033         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15034          UNSPEC_FRNDINT_MASK_PM))
15035    (use (match_operand:HI 2 "memory_operand" "m"))
15036    (use (match_operand:HI 3 "memory_operand" "m"))]
15037   "TARGET_USE_FANCY_MATH_387
15038    && flag_unsafe_math_optimizations"
15039   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15040   [(set_attr "type" "frndint")
15041    (set_attr "i387_cw" "mask_pm")
15042    (set_attr "mode" "XF")])
15043
15044 (define_expand "nearbyintxf2"
15045   [(use (match_operand:XF 0 "register_operand" ""))
15046    (use (match_operand:XF 1 "register_operand" ""))]
15047   "TARGET_USE_FANCY_MATH_387
15048    && flag_unsafe_math_optimizations"
15049 {
15050   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15051   DONE;
15052 })
15053
15054 (define_expand "nearbyint<mode>2"
15055   [(use (match_operand:MODEF 0 "register_operand" ""))
15056    (use (match_operand:MODEF 1 "register_operand" ""))]
15057   "TARGET_USE_FANCY_MATH_387
15058    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15059        || TARGET_MIX_SSE_I387)
15060    && flag_unsafe_math_optimizations"
15061 {
15062   rtx op0 = gen_reg_rtx (XFmode);
15063   rtx op1 = gen_reg_rtx (XFmode);
15064
15065   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15066   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15067
15068   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15069   DONE;
15070 })
15071
15072 (define_insn "fxam<mode>2_i387"
15073   [(set (match_operand:HI 0 "register_operand" "=a")
15074         (unspec:HI
15075           [(match_operand:X87MODEF 1 "register_operand" "f")]
15076           UNSPEC_FXAM))]
15077   "TARGET_USE_FANCY_MATH_387"
15078   "fxam\n\tfnstsw\t%0"
15079   [(set_attr "type" "multi")
15080    (set_attr "length" "4")
15081    (set_attr "unit" "i387")
15082    (set_attr "mode" "<MODE>")])
15083
15084 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15085   [(set (match_operand:HI 0 "register_operand" "")
15086         (unspec:HI
15087           [(match_operand:MODEF 1 "memory_operand" "")]
15088           UNSPEC_FXAM_MEM))]
15089   "TARGET_USE_FANCY_MATH_387
15090    && can_create_pseudo_p ()"
15091   "#"
15092   "&& 1"
15093   [(set (match_dup 2)(match_dup 1))
15094    (set (match_dup 0)
15095         (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15096 {
15097   operands[2] = gen_reg_rtx (<MODE>mode);
15098
15099   MEM_VOLATILE_P (operands[1]) = 1;
15100 }
15101   [(set_attr "type" "multi")
15102    (set_attr "unit" "i387")
15103    (set_attr "mode" "<MODE>")])
15104
15105 (define_expand "isinfxf2"
15106   [(use (match_operand:SI 0 "register_operand" ""))
15107    (use (match_operand:XF 1 "register_operand" ""))]
15108   "TARGET_USE_FANCY_MATH_387
15109    && TARGET_C99_FUNCTIONS"
15110 {
15111   rtx mask = GEN_INT (0x45);
15112   rtx val = GEN_INT (0x05);
15113
15114   rtx cond;
15115
15116   rtx scratch = gen_reg_rtx (HImode);
15117   rtx res = gen_reg_rtx (QImode);
15118
15119   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15120
15121   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15122   emit_insn (gen_cmpqi_ext_3 (scratch, val));
15123   cond = gen_rtx_fmt_ee (EQ, QImode,
15124                          gen_rtx_REG (CCmode, FLAGS_REG),
15125                          const0_rtx);
15126   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15127   emit_insn (gen_zero_extendqisi2 (operands[0], res));
15128   DONE;
15129 })
15130
15131 (define_expand "isinf<mode>2"
15132   [(use (match_operand:SI 0 "register_operand" ""))
15133    (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15134   "TARGET_USE_FANCY_MATH_387
15135    && TARGET_C99_FUNCTIONS
15136    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15137 {
15138   rtx mask = GEN_INT (0x45);
15139   rtx val = GEN_INT (0x05);
15140
15141   rtx cond;
15142
15143   rtx scratch = gen_reg_rtx (HImode);
15144   rtx res = gen_reg_rtx (QImode);
15145
15146   /* Remove excess precision by forcing value through memory. */
15147   if (memory_operand (operands[1], VOIDmode))
15148     emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15149   else
15150     {
15151       enum ix86_stack_slot slot = (virtuals_instantiated
15152                                    ? SLOT_TEMP
15153                                    : SLOT_VIRTUAL);
15154       rtx temp = assign_386_stack_local (<MODE>mode, slot);
15155
15156       emit_move_insn (temp, operands[1]);
15157       emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15158     }
15159
15160   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15161   emit_insn (gen_cmpqi_ext_3 (scratch, val));
15162   cond = gen_rtx_fmt_ee (EQ, QImode,
15163                          gen_rtx_REG (CCmode, FLAGS_REG),
15164                          const0_rtx);
15165   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15166   emit_insn (gen_zero_extendqisi2 (operands[0], res));
15167   DONE;
15168 })
15169
15170 (define_expand "signbitxf2"
15171   [(use (match_operand:SI 0 "register_operand" ""))
15172    (use (match_operand:XF 1 "register_operand" ""))]
15173   "TARGET_USE_FANCY_MATH_387"
15174 {
15175   rtx scratch = gen_reg_rtx (HImode);
15176
15177   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15178   emit_insn (gen_andsi3 (operands[0],
15179              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15180   DONE;
15181 })
15182
15183 (define_insn "movmsk_df"
15184   [(set (match_operand:SI 0 "register_operand" "=r")
15185         (unspec:SI
15186           [(match_operand:DF 1 "register_operand" "x")]
15187           UNSPEC_MOVMSK))]
15188   "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15189   "%vmovmskpd\t{%1, %0|%0, %1}"
15190   [(set_attr "type" "ssemov")
15191    (set_attr "prefix" "maybe_vex")
15192    (set_attr "mode" "DF")])
15193
15194 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15195 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15196 (define_expand "signbitdf2"
15197   [(use (match_operand:SI 0 "register_operand" ""))
15198    (use (match_operand:DF 1 "register_operand" ""))]
15199   "TARGET_USE_FANCY_MATH_387
15200    || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15201 {
15202   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15203     {
15204       emit_insn (gen_movmsk_df (operands[0], operands[1]));
15205       emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15206     }
15207   else
15208     {
15209       rtx scratch = gen_reg_rtx (HImode);
15210
15211       emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15212       emit_insn (gen_andsi3 (operands[0],
15213                  gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15214     }
15215   DONE;
15216 })
15217
15218 (define_expand "signbitsf2"
15219   [(use (match_operand:SI 0 "register_operand" ""))
15220    (use (match_operand:SF 1 "register_operand" ""))]
15221   "TARGET_USE_FANCY_MATH_387
15222    && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15223 {
15224   rtx scratch = gen_reg_rtx (HImode);
15225
15226   emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15227   emit_insn (gen_andsi3 (operands[0],
15228              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15229   DONE;
15230 })
15231 \f
15232 ;; Block operation instructions
15233
15234 (define_insn "cld"
15235   [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15236   ""
15237   "cld"
15238   [(set_attr "length" "1")
15239    (set_attr "length_immediate" "0")
15240    (set_attr "modrm" "0")])
15241
15242 (define_expand "movmem<mode>"
15243   [(use (match_operand:BLK 0 "memory_operand" ""))
15244    (use (match_operand:BLK 1 "memory_operand" ""))
15245    (use (match_operand:SWI48 2 "nonmemory_operand" ""))
15246    (use (match_operand:SWI48 3 "const_int_operand" ""))
15247    (use (match_operand:SI 4 "const_int_operand" ""))
15248    (use (match_operand:SI 5 "const_int_operand" ""))]
15249   ""
15250 {
15251  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15252                          operands[4], operands[5]))
15253    DONE;
15254  else
15255    FAIL;
15256 })
15257
15258 ;; Most CPUs don't like single string operations
15259 ;; Handle this case here to simplify previous expander.
15260
15261 (define_expand "strmov"
15262   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15263    (set (match_operand 1 "memory_operand" "") (match_dup 4))
15264    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15265               (clobber (reg:CC FLAGS_REG))])
15266    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15267               (clobber (reg:CC FLAGS_REG))])]
15268   ""
15269 {
15270   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15271
15272   /* If .md ever supports :P for Pmode, these can be directly
15273      in the pattern above.  */
15274   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15275   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15276
15277   /* Can't use this if the user has appropriated esi or edi.  */
15278   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15279       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15280     {
15281       emit_insn (gen_strmov_singleop (operands[0], operands[1],
15282                                       operands[2], operands[3],
15283                                       operands[5], operands[6]));
15284       DONE;
15285     }
15286
15287   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15288 })
15289
15290 (define_expand "strmov_singleop"
15291   [(parallel [(set (match_operand 1 "memory_operand" "")
15292                    (match_operand 3 "memory_operand" ""))
15293               (set (match_operand 0 "register_operand" "")
15294                    (match_operand 4 "" ""))
15295               (set (match_operand 2 "register_operand" "")
15296                    (match_operand 5 "" ""))])]
15297   ""
15298   "ix86_current_function_needs_cld = 1;")
15299
15300 (define_insn "*strmovdi_rex_1"
15301   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15302         (mem:DI (match_operand:DI 3 "register_operand" "1")))
15303    (set (match_operand:DI 0 "register_operand" "=D")
15304         (plus:DI (match_dup 2)
15305                  (const_int 8)))
15306    (set (match_operand:DI 1 "register_operand" "=S")
15307         (plus:DI (match_dup 3)
15308                  (const_int 8)))]
15309   "TARGET_64BIT"
15310   "movsq"
15311   [(set_attr "type" "str")
15312    (set_attr "memory" "both")
15313    (set_attr "mode" "DI")])
15314
15315 (define_insn "*strmovsi_1"
15316   [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15317         (mem:SI (match_operand:P 3 "register_operand" "1")))
15318    (set (match_operand:P 0 "register_operand" "=D")
15319         (plus:P (match_dup 2)
15320                 (const_int 4)))
15321    (set (match_operand:P 1 "register_operand" "=S")
15322         (plus:P (match_dup 3)
15323                 (const_int 4)))]
15324   ""
15325   "movs{l|d}"
15326   [(set_attr "type" "str")
15327    (set_attr "memory" "both")
15328    (set_attr "mode" "SI")])
15329
15330 (define_insn "*strmovhi_1"
15331   [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15332         (mem:HI (match_operand:P 3 "register_operand" "1")))
15333    (set (match_operand:P 0 "register_operand" "=D")
15334         (plus:P (match_dup 2)
15335                 (const_int 2)))
15336    (set (match_operand:P 1 "register_operand" "=S")
15337         (plus:P (match_dup 3)
15338                 (const_int 2)))]
15339   ""
15340   "movsw"
15341   [(set_attr "type" "str")
15342    (set_attr "memory" "both")
15343    (set_attr "mode" "HI")])
15344
15345 (define_insn "*strmovqi_1"
15346   [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15347         (mem:QI (match_operand:P 3 "register_operand" "1")))
15348    (set (match_operand:P 0 "register_operand" "=D")
15349         (plus:P (match_dup 2)
15350                 (const_int 1)))
15351    (set (match_operand:P 1 "register_operand" "=S")
15352         (plus:P (match_dup 3)
15353                 (const_int 1)))]
15354   ""
15355   "movsb"
15356   [(set_attr "type" "str")
15357    (set_attr "memory" "both")
15358    (set (attr "prefix_rex")
15359         (if_then_else
15360           (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15361           (const_string "0")
15362           (const_string "*")))
15363    (set_attr "mode" "QI")])
15364
15365 (define_expand "rep_mov"
15366   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15367               (set (match_operand 0 "register_operand" "")
15368                    (match_operand 5 "" ""))
15369               (set (match_operand 2 "register_operand" "")
15370                    (match_operand 6 "" ""))
15371               (set (match_operand 1 "memory_operand" "")
15372                    (match_operand 3 "memory_operand" ""))
15373               (use (match_dup 4))])]
15374   ""
15375   "ix86_current_function_needs_cld = 1;")
15376
15377 (define_insn "*rep_movdi_rex64"
15378   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15379    (set (match_operand:DI 0 "register_operand" "=D")
15380         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15381                             (const_int 3))
15382                  (match_operand:DI 3 "register_operand" "0")))
15383    (set (match_operand:DI 1 "register_operand" "=S")
15384         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15385                  (match_operand:DI 4 "register_operand" "1")))
15386    (set (mem:BLK (match_dup 3))
15387         (mem:BLK (match_dup 4)))
15388    (use (match_dup 5))]
15389   "TARGET_64BIT"
15390   "rep{%;} movsq"
15391   [(set_attr "type" "str")
15392    (set_attr "prefix_rep" "1")
15393    (set_attr "memory" "both")
15394    (set_attr "mode" "DI")])
15395
15396 (define_insn "*rep_movsi"
15397   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15398    (set (match_operand:P 0 "register_operand" "=D")
15399         (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15400                           (const_int 2))
15401                  (match_operand:P 3 "register_operand" "0")))
15402    (set (match_operand:P 1 "register_operand" "=S")
15403         (plus:P (ashift:P (match_dup 5) (const_int 2))
15404                 (match_operand:P 4 "register_operand" "1")))
15405    (set (mem:BLK (match_dup 3))
15406         (mem:BLK (match_dup 4)))
15407    (use (match_dup 5))]
15408   ""
15409   "rep{%;} movs{l|d}"
15410   [(set_attr "type" "str")
15411    (set_attr "prefix_rep" "1")
15412    (set_attr "memory" "both")
15413    (set_attr "mode" "SI")])
15414
15415 (define_insn "*rep_movqi"
15416   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15417    (set (match_operand:P 0 "register_operand" "=D")
15418         (plus:P (match_operand:P 3 "register_operand" "0")
15419                 (match_operand:P 5 "register_operand" "2")))
15420    (set (match_operand:P 1 "register_operand" "=S")
15421         (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15422    (set (mem:BLK (match_dup 3))
15423         (mem:BLK (match_dup 4)))
15424    (use (match_dup 5))]
15425   ""
15426   "rep{%;} movsb"
15427   [(set_attr "type" "str")
15428    (set_attr "prefix_rep" "1")
15429    (set_attr "memory" "both")
15430    (set_attr "mode" "QI")])
15431
15432 (define_expand "setmem<mode>"
15433    [(use (match_operand:BLK 0 "memory_operand" ""))
15434     (use (match_operand:SWI48 1 "nonmemory_operand" ""))
15435     (use (match_operand 2 "const_int_operand" ""))
15436     (use (match_operand 3 "const_int_operand" ""))
15437     (use (match_operand:SI 4 "const_int_operand" ""))
15438     (use (match_operand:SI 5 "const_int_operand" ""))]
15439   ""
15440 {
15441  if (ix86_expand_setmem (operands[0], operands[1],
15442                          operands[2], operands[3],
15443                          operands[4], operands[5]))
15444    DONE;
15445  else
15446    FAIL;
15447 })
15448
15449 ;; Most CPUs don't like single string operations
15450 ;; Handle this case here to simplify previous expander.
15451
15452 (define_expand "strset"
15453   [(set (match_operand 1 "memory_operand" "")
15454         (match_operand 2 "register_operand" ""))
15455    (parallel [(set (match_operand 0 "register_operand" "")
15456                    (match_dup 3))
15457               (clobber (reg:CC FLAGS_REG))])]
15458   ""
15459 {
15460   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15461     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15462
15463   /* If .md ever supports :P for Pmode, this can be directly
15464      in the pattern above.  */
15465   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15466                               GEN_INT (GET_MODE_SIZE (GET_MODE
15467                                                       (operands[2]))));
15468   if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15469     {
15470       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15471                                       operands[3]));
15472       DONE;
15473     }
15474 })
15475
15476 (define_expand "strset_singleop"
15477   [(parallel [(set (match_operand 1 "memory_operand" "")
15478                    (match_operand 2 "register_operand" ""))
15479               (set (match_operand 0 "register_operand" "")
15480                    (match_operand 3 "" ""))])]
15481   ""
15482   "ix86_current_function_needs_cld = 1;")
15483
15484 (define_insn "*strsetdi_rex_1"
15485   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
15486         (match_operand:DI 2 "register_operand" "a"))
15487    (set (match_operand:DI 0 "register_operand" "=D")
15488         (plus:DI (match_dup 1)
15489                  (const_int 8)))]
15490   "TARGET_64BIT"
15491   "stosq"
15492   [(set_attr "type" "str")
15493    (set_attr "memory" "store")
15494    (set_attr "mode" "DI")])
15495
15496 (define_insn "*strsetsi_1"
15497   [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15498         (match_operand:SI 2 "register_operand" "a"))
15499    (set (match_operand:P 0 "register_operand" "=D")
15500         (plus:P (match_dup 1)
15501                 (const_int 4)))]
15502   ""
15503   "stos{l|d}"
15504   [(set_attr "type" "str")
15505    (set_attr "memory" "store")
15506    (set_attr "mode" "SI")])
15507
15508 (define_insn "*strsethi_1"
15509   [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15510         (match_operand:HI 2 "register_operand" "a"))
15511    (set (match_operand:P 0 "register_operand" "=D")
15512         (plus:P (match_dup 1)
15513                 (const_int 2)))]
15514   ""
15515   "stosw"
15516   [(set_attr "type" "str")
15517    (set_attr "memory" "store")
15518    (set_attr "mode" "HI")])
15519
15520 (define_insn "*strsetqi_1"
15521   [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15522         (match_operand:QI 2 "register_operand" "a"))
15523    (set (match_operand:P 0 "register_operand" "=D")
15524         (plus:P (match_dup 1)
15525                 (const_int 1)))]
15526   ""
15527   "stosb"
15528   [(set_attr "type" "str")
15529    (set_attr "memory" "store")
15530    (set (attr "prefix_rex")
15531         (if_then_else
15532           (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15533           (const_string "0")
15534           (const_string "*")))
15535    (set_attr "mode" "QI")])
15536
15537 (define_expand "rep_stos"
15538   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15539               (set (match_operand 0 "register_operand" "")
15540                    (match_operand 4 "" ""))
15541               (set (match_operand 2 "memory_operand" "") (const_int 0))
15542               (use (match_operand 3 "register_operand" ""))
15543               (use (match_dup 1))])]
15544   ""
15545   "ix86_current_function_needs_cld = 1;")
15546
15547 (define_insn "*rep_stosdi_rex64"
15548   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15549    (set (match_operand:DI 0 "register_operand" "=D")
15550         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15551                             (const_int 3))
15552                  (match_operand:DI 3 "register_operand" "0")))
15553    (set (mem:BLK (match_dup 3))
15554         (const_int 0))
15555    (use (match_operand:DI 2 "register_operand" "a"))
15556    (use (match_dup 4))]
15557   "TARGET_64BIT"
15558   "rep{%;} stosq"
15559   [(set_attr "type" "str")
15560    (set_attr "prefix_rep" "1")
15561    (set_attr "memory" "store")
15562    (set_attr "mode" "DI")])
15563
15564 (define_insn "*rep_stossi"
15565   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15566    (set (match_operand:P 0 "register_operand" "=D")
15567         (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15568                           (const_int 2))
15569                  (match_operand:P 3 "register_operand" "0")))
15570    (set (mem:BLK (match_dup 3))
15571         (const_int 0))
15572    (use (match_operand:SI 2 "register_operand" "a"))
15573    (use (match_dup 4))]
15574   ""
15575   "rep{%;} stos{l|d}"
15576   [(set_attr "type" "str")
15577    (set_attr "prefix_rep" "1")
15578    (set_attr "memory" "store")
15579    (set_attr "mode" "SI")])
15580
15581 (define_insn "*rep_stosqi"
15582   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15583    (set (match_operand:P 0 "register_operand" "=D")
15584         (plus:P (match_operand:P 3 "register_operand" "0")
15585                 (match_operand:P 4 "register_operand" "1")))
15586    (set (mem:BLK (match_dup 3))
15587         (const_int 0))
15588    (use (match_operand:QI 2 "register_operand" "a"))
15589    (use (match_dup 4))]
15590   ""
15591   "rep{%;} stosb"
15592   [(set_attr "type" "str")
15593    (set_attr "prefix_rep" "1")
15594    (set_attr "memory" "store")
15595    (set (attr "prefix_rex")
15596         (if_then_else
15597           (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15598           (const_string "0")
15599           (const_string "*")))
15600    (set_attr "mode" "QI")])
15601
15602 (define_expand "cmpstrnsi"
15603   [(set (match_operand:SI 0 "register_operand" "")
15604         (compare:SI (match_operand:BLK 1 "general_operand" "")
15605                     (match_operand:BLK 2 "general_operand" "")))
15606    (use (match_operand 3 "general_operand" ""))
15607    (use (match_operand 4 "immediate_operand" ""))]
15608   ""
15609 {
15610   rtx addr1, addr2, out, outlow, count, countreg, align;
15611
15612   if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
15613     FAIL;
15614
15615   /* Can't use this if the user has appropriated esi or edi.  */
15616   if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
15617     FAIL;
15618
15619   out = operands[0];
15620   if (!REG_P (out))
15621     out = gen_reg_rtx (SImode);
15622
15623   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
15624   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
15625   if (addr1 != XEXP (operands[1], 0))
15626     operands[1] = replace_equiv_address_nv (operands[1], addr1);
15627   if (addr2 != XEXP (operands[2], 0))
15628     operands[2] = replace_equiv_address_nv (operands[2], addr2);
15629
15630   count = operands[3];
15631   countreg = ix86_zero_extend_to_Pmode (count);
15632
15633   /* %%% Iff we are testing strict equality, we can use known alignment
15634      to good advantage.  This may be possible with combine, particularly
15635      once cc0 is dead.  */
15636   align = operands[4];
15637
15638   if (CONST_INT_P (count))
15639     {
15640       if (INTVAL (count) == 0)
15641         {
15642           emit_move_insn (operands[0], const0_rtx);
15643           DONE;
15644         }
15645       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
15646                                      operands[1], operands[2]));
15647     }
15648   else
15649     {
15650       rtx (*gen_cmp) (rtx, rtx);
15651
15652       gen_cmp = (TARGET_64BIT
15653                  ? gen_cmpdi_1 : gen_cmpsi_1);
15654
15655       emit_insn (gen_cmp (countreg, countreg));
15656       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
15657                                   operands[1], operands[2]));
15658     }
15659
15660   outlow = gen_lowpart (QImode, out);
15661   emit_insn (gen_cmpintqi (outlow));
15662   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
15663
15664   if (operands[0] != out)
15665     emit_move_insn (operands[0], out);
15666
15667   DONE;
15668 })
15669
15670 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
15671
15672 (define_expand "cmpintqi"
15673   [(set (match_dup 1)
15674         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15675    (set (match_dup 2)
15676         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15677    (parallel [(set (match_operand:QI 0 "register_operand" "")
15678                    (minus:QI (match_dup 1)
15679                              (match_dup 2)))
15680               (clobber (reg:CC FLAGS_REG))])]
15681   ""
15682 {
15683   operands[1] = gen_reg_rtx (QImode);
15684   operands[2] = gen_reg_rtx (QImode);
15685 })
15686
15687 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
15688 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
15689
15690 (define_expand "cmpstrnqi_nz_1"
15691   [(parallel [(set (reg:CC FLAGS_REG)
15692                    (compare:CC (match_operand 4 "memory_operand" "")
15693                                (match_operand 5 "memory_operand" "")))
15694               (use (match_operand 2 "register_operand" ""))
15695               (use (match_operand:SI 3 "immediate_operand" ""))
15696               (clobber (match_operand 0 "register_operand" ""))
15697               (clobber (match_operand 1 "register_operand" ""))
15698               (clobber (match_dup 2))])]
15699   ""
15700   "ix86_current_function_needs_cld = 1;")
15701
15702 (define_insn "*cmpstrnqi_nz_1"
15703   [(set (reg:CC FLAGS_REG)
15704         (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
15705                     (mem:BLK (match_operand:P 5 "register_operand" "1"))))
15706    (use (match_operand:P 6 "register_operand" "2"))
15707    (use (match_operand:SI 3 "immediate_operand" "i"))
15708    (clobber (match_operand:P 0 "register_operand" "=S"))
15709    (clobber (match_operand:P 1 "register_operand" "=D"))
15710    (clobber (match_operand:P 2 "register_operand" "=c"))]
15711   ""
15712   "repz{%;} cmpsb"
15713   [(set_attr "type" "str")
15714    (set_attr "mode" "QI")
15715    (set (attr "prefix_rex")
15716         (if_then_else
15717           (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15718           (const_string "0")
15719           (const_string "*")))
15720    (set_attr "prefix_rep" "1")])
15721
15722 ;; The same, but the count is not known to not be zero.
15723
15724 (define_expand "cmpstrnqi_1"
15725   [(parallel [(set (reg:CC FLAGS_REG)
15726                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
15727                                      (const_int 0))
15728                   (compare:CC (match_operand 4 "memory_operand" "")
15729                               (match_operand 5 "memory_operand" ""))
15730                   (const_int 0)))
15731               (use (match_operand:SI 3 "immediate_operand" ""))
15732               (use (reg:CC FLAGS_REG))
15733               (clobber (match_operand 0 "register_operand" ""))
15734               (clobber (match_operand 1 "register_operand" ""))
15735               (clobber (match_dup 2))])]
15736   ""
15737   "ix86_current_function_needs_cld = 1;")
15738
15739 (define_insn "*cmpstrnqi_1"
15740   [(set (reg:CC FLAGS_REG)
15741         (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
15742                              (const_int 0))
15743           (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
15744                       (mem:BLK (match_operand:P 5 "register_operand" "1")))
15745           (const_int 0)))
15746    (use (match_operand:SI 3 "immediate_operand" "i"))
15747    (use (reg:CC FLAGS_REG))
15748    (clobber (match_operand:P 0 "register_operand" "=S"))
15749    (clobber (match_operand:P 1 "register_operand" "=D"))
15750    (clobber (match_operand:P 2 "register_operand" "=c"))]
15751   ""
15752   "repz{%;} cmpsb"
15753   [(set_attr "type" "str")
15754    (set_attr "mode" "QI")
15755    (set (attr "prefix_rex")
15756         (if_then_else
15757           (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15758           (const_string "0")
15759           (const_string "*")))
15760    (set_attr "prefix_rep" "1")])
15761
15762 (define_expand "strlen<mode>"
15763   [(set (match_operand:SWI48x 0 "register_operand" "")
15764         (unspec:SWI48x [(match_operand:BLK 1 "general_operand" "")
15765                         (match_operand:QI 2 "immediate_operand" "")
15766                         (match_operand 3 "immediate_operand" "")]
15767                        UNSPEC_SCAS))]
15768   ""
15769 {
15770  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
15771    DONE;
15772  else
15773    FAIL;
15774 })
15775
15776 (define_expand "strlenqi_1"
15777   [(parallel [(set (match_operand 0 "register_operand" "")
15778                    (match_operand 2 "" ""))
15779               (clobber (match_operand 1 "register_operand" ""))
15780               (clobber (reg:CC FLAGS_REG))])]
15781   ""
15782   "ix86_current_function_needs_cld = 1;")
15783
15784 (define_insn "*strlenqi_1"
15785   [(set (match_operand:P 0 "register_operand" "=&c")
15786         (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
15787                    (match_operand:QI 2 "register_operand" "a")
15788                    (match_operand:P 3 "immediate_operand" "i")
15789                    (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
15790    (clobber (match_operand:P 1 "register_operand" "=D"))
15791    (clobber (reg:CC FLAGS_REG))]
15792   ""
15793   "repnz{%;} scasb"
15794   [(set_attr "type" "str")
15795    (set_attr "mode" "QI")
15796    (set (attr "prefix_rex")
15797         (if_then_else
15798           (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15799           (const_string "0")
15800           (const_string "*")))
15801    (set_attr "prefix_rep" "1")])
15802
15803 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
15804 ;; handled in combine, but it is not currently up to the task.
15805 ;; When used for their truth value, the cmpstrn* expanders generate
15806 ;; code like this:
15807 ;;
15808 ;;   repz cmpsb
15809 ;;   seta       %al
15810 ;;   setb       %dl
15811 ;;   cmpb       %al, %dl
15812 ;;   jcc        label
15813 ;;
15814 ;; The intermediate three instructions are unnecessary.
15815
15816 ;; This one handles cmpstrn*_nz_1...
15817 (define_peephole2
15818   [(parallel[
15819      (set (reg:CC FLAGS_REG)
15820           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15821                       (mem:BLK (match_operand 5 "register_operand" ""))))
15822      (use (match_operand 6 "register_operand" ""))
15823      (use (match_operand:SI 3 "immediate_operand" ""))
15824      (clobber (match_operand 0 "register_operand" ""))
15825      (clobber (match_operand 1 "register_operand" ""))
15826      (clobber (match_operand 2 "register_operand" ""))])
15827    (set (match_operand:QI 7 "register_operand" "")
15828         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15829    (set (match_operand:QI 8 "register_operand" "")
15830         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15831    (set (reg FLAGS_REG)
15832         (compare (match_dup 7) (match_dup 8)))
15833   ]
15834   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15835   [(parallel[
15836      (set (reg:CC FLAGS_REG)
15837           (compare:CC (mem:BLK (match_dup 4))
15838                       (mem:BLK (match_dup 5))))
15839      (use (match_dup 6))
15840      (use (match_dup 3))
15841      (clobber (match_dup 0))
15842      (clobber (match_dup 1))
15843      (clobber (match_dup 2))])])
15844
15845 ;; ...and this one handles cmpstrn*_1.
15846 (define_peephole2
15847   [(parallel[
15848      (set (reg:CC FLAGS_REG)
15849           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
15850                                (const_int 0))
15851             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15852                         (mem:BLK (match_operand 5 "register_operand" "")))
15853             (const_int 0)))
15854      (use (match_operand:SI 3 "immediate_operand" ""))
15855      (use (reg:CC FLAGS_REG))
15856      (clobber (match_operand 0 "register_operand" ""))
15857      (clobber (match_operand 1 "register_operand" ""))
15858      (clobber (match_operand 2 "register_operand" ""))])
15859    (set (match_operand:QI 7 "register_operand" "")
15860         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15861    (set (match_operand:QI 8 "register_operand" "")
15862         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15863    (set (reg FLAGS_REG)
15864         (compare (match_dup 7) (match_dup 8)))
15865   ]
15866   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15867   [(parallel[
15868      (set (reg:CC FLAGS_REG)
15869           (if_then_else:CC (ne (match_dup 6)
15870                                (const_int 0))
15871             (compare:CC (mem:BLK (match_dup 4))
15872                         (mem:BLK (match_dup 5)))
15873             (const_int 0)))
15874      (use (match_dup 3))
15875      (use (reg:CC FLAGS_REG))
15876      (clobber (match_dup 0))
15877      (clobber (match_dup 1))
15878      (clobber (match_dup 2))])])
15879 \f
15880 ;; Conditional move instructions.
15881
15882 (define_expand "mov<mode>cc"
15883   [(set (match_operand:SWIM 0 "register_operand" "")
15884         (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator" "")
15885                            (match_operand:SWIM 2 "general_operand" "")
15886                            (match_operand:SWIM 3 "general_operand" "")))]
15887   ""
15888   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
15889
15890 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
15891 ;; the register first winds up with `sbbl $0,reg', which is also weird.
15892 ;; So just document what we're doing explicitly.
15893
15894 (define_expand "x86_mov<mode>cc_0_m1"
15895   [(parallel
15896     [(set (match_operand:SWI48 0 "register_operand" "")
15897           (if_then_else:SWI48
15898             (match_operator:SWI48 2 "ix86_carry_flag_operator"
15899              [(match_operand 1 "flags_reg_operand" "")
15900               (const_int 0)])
15901             (const_int -1)
15902             (const_int 0)))
15903      (clobber (reg:CC FLAGS_REG))])])
15904
15905 (define_insn "*x86_mov<mode>cc_0_m1"
15906   [(set (match_operand:SWI48 0 "register_operand" "=r")
15907         (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
15908                              [(reg FLAGS_REG) (const_int 0)])
15909           (const_int -1)
15910           (const_int 0)))
15911    (clobber (reg:CC FLAGS_REG))]
15912   ""
15913   "sbb{<imodesuffix>}\t%0, %0"
15914   ; Since we don't have the proper number of operands for an alu insn,
15915   ; fill in all the blanks.
15916   [(set_attr "type" "alu")
15917    (set_attr "use_carry" "1")
15918    (set_attr "pent_pair" "pu")
15919    (set_attr "memory" "none")
15920    (set_attr "imm_disp" "false")
15921    (set_attr "mode" "<MODE>")
15922    (set_attr "length_immediate" "0")])
15923
15924 (define_insn "*x86_mov<mode>cc_0_m1_se"
15925   [(set (match_operand:SWI48 0 "register_operand" "=r")
15926         (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
15927                              [(reg FLAGS_REG) (const_int 0)])
15928                             (const_int 1)
15929                             (const_int 0)))
15930    (clobber (reg:CC FLAGS_REG))]
15931   ""
15932   "sbb{<imodesuffix>}\t%0, %0"
15933   [(set_attr "type" "alu")
15934    (set_attr "use_carry" "1")
15935    (set_attr "pent_pair" "pu")
15936    (set_attr "memory" "none")
15937    (set_attr "imm_disp" "false")
15938    (set_attr "mode" "<MODE>")
15939    (set_attr "length_immediate" "0")])
15940
15941 (define_insn "*x86_mov<mode>cc_0_m1_neg"
15942   [(set (match_operand:SWI48 0 "register_operand" "=r")
15943         (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
15944                     [(reg FLAGS_REG) (const_int 0)])))]
15945   ""
15946   "sbb{<imodesuffix>}\t%0, %0"
15947   [(set_attr "type" "alu")
15948    (set_attr "use_carry" "1")
15949    (set_attr "pent_pair" "pu")
15950    (set_attr "memory" "none")
15951    (set_attr "imm_disp" "false")
15952    (set_attr "mode" "<MODE>")
15953    (set_attr "length_immediate" "0")])
15954
15955 (define_insn "*mov<mode>cc_noc"
15956   [(set (match_operand:SWI248 0 "register_operand" "=r,r")
15957         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
15958                                [(reg FLAGS_REG) (const_int 0)])
15959           (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
15960           (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
15961   "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
15962   "@
15963    cmov%O2%C1\t{%2, %0|%0, %2}
15964    cmov%O2%c1\t{%3, %0|%0, %3}"
15965   [(set_attr "type" "icmov")
15966    (set_attr "mode" "<MODE>")])
15967
15968 (define_insn_and_split "*movqicc_noc"
15969   [(set (match_operand:QI 0 "register_operand" "=r,r")
15970         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
15971                            [(match_operand 4 "flags_reg_operand" "")
15972                             (const_int 0)])
15973                       (match_operand:QI 2 "register_operand" "r,0")
15974                       (match_operand:QI 3 "register_operand" "0,r")))]
15975   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
15976   "#"
15977   "&& reload_completed"
15978   [(set (match_dup 0)
15979         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
15980                       (match_dup 2)
15981                       (match_dup 3)))]
15982   "operands[0] = gen_lowpart (SImode, operands[0]);
15983    operands[2] = gen_lowpart (SImode, operands[2]);
15984    operands[3] = gen_lowpart (SImode, operands[3]);"
15985   [(set_attr "type" "icmov")
15986    (set_attr "mode" "SI")])
15987
15988 (define_expand "mov<mode>cc"
15989   [(set (match_operand:X87MODEF 0 "register_operand" "")
15990         (if_then_else:X87MODEF
15991           (match_operand 1 "ix86_fp_comparison_operator" "")
15992           (match_operand:X87MODEF 2 "register_operand" "")
15993           (match_operand:X87MODEF 3 "register_operand" "")))]
15994   "(TARGET_80387 && TARGET_CMOVE)
15995    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15996   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
15997
15998 (define_insn "*movxfcc_1"
15999   [(set (match_operand:XF 0 "register_operand" "=f,f")
16000         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16001                                 [(reg FLAGS_REG) (const_int 0)])
16002                       (match_operand:XF 2 "register_operand" "f,0")
16003                       (match_operand:XF 3 "register_operand" "0,f")))]
16004   "TARGET_80387 && TARGET_CMOVE"
16005   "@
16006    fcmov%F1\t{%2, %0|%0, %2}
16007    fcmov%f1\t{%3, %0|%0, %3}"
16008   [(set_attr "type" "fcmov")
16009    (set_attr "mode" "XF")])
16010
16011 (define_insn "*movdfcc_1_rex64"
16012   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16013         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16014                                 [(reg FLAGS_REG) (const_int 0)])
16015                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16016                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16017   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16018    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16019   "@
16020    fcmov%F1\t{%2, %0|%0, %2}
16021    fcmov%f1\t{%3, %0|%0, %3}
16022    cmov%O2%C1\t{%2, %0|%0, %2}
16023    cmov%O2%c1\t{%3, %0|%0, %3}"
16024   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16025    (set_attr "mode" "DF,DF,DI,DI")])
16026
16027 (define_insn "*movdfcc_1"
16028   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16029         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16030                                 [(reg FLAGS_REG) (const_int 0)])
16031                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16032                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16033   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16034    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16035   "@
16036    fcmov%F1\t{%2, %0|%0, %2}
16037    fcmov%f1\t{%3, %0|%0, %3}
16038    #
16039    #"
16040   [(set_attr "type" "fcmov,fcmov,multi,multi")
16041    (set_attr "mode" "DF,DF,DI,DI")])
16042
16043 (define_split
16044   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16045         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16046                                 [(match_operand 4 "flags_reg_operand" "")
16047                                  (const_int 0)])
16048                       (match_operand:DF 2 "nonimmediate_operand" "")
16049                       (match_operand:DF 3 "nonimmediate_operand" "")))]
16050   "!TARGET_64BIT && reload_completed"
16051   [(set (match_dup 2)
16052         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16053                       (match_dup 5)
16054                       (match_dup 6)))
16055    (set (match_dup 3)
16056         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16057                       (match_dup 7)
16058                       (match_dup 8)))]
16059 {
16060   split_double_mode (DImode, &operands[2], 2, &operands[5], &operands[7]);
16061   split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16062 })
16063
16064 (define_insn "*movsfcc_1_387"
16065   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16066         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16067                                 [(reg FLAGS_REG) (const_int 0)])
16068                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16069                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16070   "TARGET_80387 && TARGET_CMOVE
16071    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16072   "@
16073    fcmov%F1\t{%2, %0|%0, %2}
16074    fcmov%f1\t{%3, %0|%0, %3}
16075    cmov%O2%C1\t{%2, %0|%0, %2}
16076    cmov%O2%c1\t{%3, %0|%0, %3}"
16077   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16078    (set_attr "mode" "SF,SF,SI,SI")])
16079
16080 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16081 ;; the scalar versions to have only XMM registers as operands.
16082
16083 ;; XOP conditional move
16084 (define_insn "*xop_pcmov_<mode>"
16085   [(set (match_operand:MODEF 0 "register_operand" "=x")
16086         (if_then_else:MODEF
16087           (match_operand:MODEF 1 "register_operand" "x")
16088           (match_operand:MODEF 2 "register_operand" "x")
16089           (match_operand:MODEF 3 "register_operand" "x")))]
16090   "TARGET_XOP"
16091   "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16092   [(set_attr "type" "sse4arg")])
16093
16094 ;; These versions of the min/max patterns are intentionally ignorant of
16095 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16096 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16097 ;; are undefined in this condition, we're certain this is correct.
16098
16099 (define_insn "*avx_<code><mode>3"
16100   [(set (match_operand:MODEF 0 "register_operand" "=x")
16101         (smaxmin:MODEF
16102           (match_operand:MODEF 1 "nonimmediate_operand" "%x")
16103           (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
16104   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16105   "v<maxmin_float>s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16106   [(set_attr "type" "sseadd")
16107    (set_attr "prefix" "vex")
16108    (set_attr "mode" "<MODE>")])
16109
16110 (define_insn "<code><mode>3"
16111   [(set (match_operand:MODEF 0 "register_operand" "=x")
16112         (smaxmin:MODEF
16113           (match_operand:MODEF 1 "nonimmediate_operand" "%0")
16114           (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
16115   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16116   "<maxmin_float>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
16117   [(set_attr "type" "sseadd")
16118    (set_attr "mode" "<MODE>")])
16119
16120 ;; These versions of the min/max patterns implement exactly the operations
16121 ;;   min = (op1 < op2 ? op1 : op2)
16122 ;;   max = (!(op1 < op2) ? op1 : op2)
16123 ;; Their operands are not commutative, and thus they may be used in the
16124 ;; presence of -0.0 and NaN.
16125
16126 (define_insn "*avx_ieee_smin<mode>3"
16127   [(set (match_operand:MODEF 0 "register_operand" "=x")
16128         (unspec:MODEF
16129           [(match_operand:MODEF 1 "register_operand" "x")
16130            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16131          UNSPEC_IEEE_MIN))]
16132   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16133   "vmins<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16134   [(set_attr "type" "sseadd")
16135    (set_attr "prefix" "vex")
16136    (set_attr "mode" "<MODE>")])
16137
16138 (define_insn "*ieee_smin<mode>3"
16139   [(set (match_operand:MODEF 0 "register_operand" "=x")
16140         (unspec:MODEF
16141           [(match_operand:MODEF 1 "register_operand" "0")
16142            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16143          UNSPEC_IEEE_MIN))]
16144   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16145   "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
16146   [(set_attr "type" "sseadd")
16147    (set_attr "mode" "<MODE>")])
16148
16149 (define_insn "*avx_ieee_smax<mode>3"
16150   [(set (match_operand:MODEF 0 "register_operand" "=x")
16151         (unspec:MODEF
16152           [(match_operand:MODEF 1 "register_operand" "0")
16153            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16154          UNSPEC_IEEE_MAX))]
16155   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16156   "vmaxs<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16157   [(set_attr "type" "sseadd")
16158    (set_attr "prefix" "vex")
16159    (set_attr "mode" "<MODE>")])
16160
16161 (define_insn "*ieee_smax<mode>3"
16162   [(set (match_operand:MODEF 0 "register_operand" "=x")
16163         (unspec:MODEF
16164           [(match_operand:MODEF 1 "register_operand" "0")
16165            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16166          UNSPEC_IEEE_MAX))]
16167   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16168   "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
16169   [(set_attr "type" "sseadd")
16170    (set_attr "mode" "<MODE>")])
16171
16172 ;; Make two stack loads independent:
16173 ;;   fld aa              fld aa
16174 ;;   fld %st(0)     ->   fld bb
16175 ;;   fmul bb             fmul %st(1), %st
16176 ;;
16177 ;; Actually we only match the last two instructions for simplicity.
16178 (define_peephole2
16179   [(set (match_operand 0 "fp_register_operand" "")
16180         (match_operand 1 "fp_register_operand" ""))
16181    (set (match_dup 0)
16182         (match_operator 2 "binary_fp_operator"
16183            [(match_dup 0)
16184             (match_operand 3 "memory_operand" "")]))]
16185   "REGNO (operands[0]) != REGNO (operands[1])"
16186   [(set (match_dup 0) (match_dup 3))
16187    (set (match_dup 0) (match_dup 4))]
16188
16189   ;; The % modifier is not operational anymore in peephole2's, so we have to
16190   ;; swap the operands manually in the case of addition and multiplication.
16191   "if (COMMUTATIVE_ARITH_P (operands[2]))
16192      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16193                                    GET_MODE (operands[2]),
16194                                    operands[0], operands[1]);
16195    else
16196      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16197                                    GET_MODE (operands[2]),
16198                                    operands[1], operands[0]);")
16199
16200 ;; Conditional addition patterns
16201 (define_expand "add<mode>cc"
16202   [(match_operand:SWI 0 "register_operand" "")
16203    (match_operand 1 "ordered_comparison_operator" "")
16204    (match_operand:SWI 2 "register_operand" "")
16205    (match_operand:SWI 3 "const_int_operand" "")]
16206   ""
16207   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16208 \f
16209 ;; Misc patterns (?)
16210
16211 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16212 ;; Otherwise there will be nothing to keep
16213 ;;
16214 ;; [(set (reg ebp) (reg esp))]
16215 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16216 ;;  (clobber (eflags)]
16217 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16218 ;;
16219 ;; in proper program order.
16220
16221 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16222   [(set (match_operand:P 0 "register_operand" "=r,r")
16223         (plus:P (match_operand:P 1 "register_operand" "0,r")
16224                 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16225    (clobber (reg:CC FLAGS_REG))
16226    (clobber (mem:BLK (scratch)))]
16227   ""
16228 {
16229   switch (get_attr_type (insn))
16230     {
16231     case TYPE_IMOV:
16232       return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16233
16234     case TYPE_ALU:
16235       gcc_assert (rtx_equal_p (operands[0], operands[1]));
16236       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16237         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16238
16239       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16240
16241     default:
16242       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16243       return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
16244     }
16245 }
16246   [(set (attr "type")
16247         (cond [(and (eq_attr "alternative" "0")
16248                     (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
16249                  (const_string "alu")
16250                (match_operand:<MODE> 2 "const0_operand" "")
16251                  (const_string "imov")
16252               ]
16253               (const_string "lea")))
16254    (set (attr "length_immediate")
16255         (cond [(eq_attr "type" "imov")
16256                  (const_string "0")
16257                (and (eq_attr "type" "alu")
16258                     (match_operand 2 "const128_operand" ""))
16259                  (const_string "1")
16260               ]
16261               (const_string "*")))
16262    (set_attr "mode" "<MODE>")])
16263
16264 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16265   [(set (match_operand:P 0 "register_operand" "=r")
16266         (minus:P (match_operand:P 1 "register_operand" "0")
16267                  (match_operand:P 2 "register_operand" "r")))
16268    (clobber (reg:CC FLAGS_REG))
16269    (clobber (mem:BLK (scratch)))]
16270   ""
16271   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16272   [(set_attr "type" "alu")
16273    (set_attr "mode" "<MODE>")])
16274
16275 (define_insn "allocate_stack_worker_probe_<mode>"
16276   [(set (match_operand:P 0 "register_operand" "=a")
16277         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16278                             UNSPECV_STACK_PROBE))
16279    (clobber (reg:CC FLAGS_REG))]
16280   "ix86_target_stack_probe ()"
16281   "call\t___chkstk_ms"
16282   [(set_attr "type" "multi")
16283    (set_attr "length" "5")])
16284
16285 (define_expand "allocate_stack"
16286   [(match_operand 0 "register_operand" "")
16287    (match_operand 1 "general_operand" "")]
16288   "ix86_target_stack_probe ()"
16289 {
16290   rtx x;
16291
16292 #ifndef CHECK_STACK_LIMIT
16293 #define CHECK_STACK_LIMIT 0
16294 #endif
16295
16296   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16297       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16298     {
16299       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16300                                stack_pointer_rtx, 0, OPTAB_DIRECT);
16301       if (x != stack_pointer_rtx)
16302         emit_move_insn (stack_pointer_rtx, x);
16303     }
16304   else
16305     {
16306       x = copy_to_mode_reg (Pmode, operands[1]);
16307       if (TARGET_64BIT)
16308         emit_insn (gen_allocate_stack_worker_probe_di (x, x));
16309       else
16310         emit_insn (gen_allocate_stack_worker_probe_si (x, x));
16311       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16312                                stack_pointer_rtx, 0, OPTAB_DIRECT);
16313       if (x != stack_pointer_rtx)
16314         emit_move_insn (stack_pointer_rtx, x);
16315     }
16316
16317   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16318   DONE;
16319 })
16320
16321 ;; Use IOR for stack probes, this is shorter.
16322 (define_expand "probe_stack"
16323   [(match_operand 0 "memory_operand" "")]
16324   ""
16325 {
16326   rtx (*gen_ior3) (rtx, rtx, rtx);
16327
16328   gen_ior3 = (GET_MODE (operands[0]) == DImode
16329               ? gen_iordi3 : gen_iorsi3);
16330
16331   emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16332   DONE;
16333 })
16334
16335 (define_insn "adjust_stack_and_probe<mode>"
16336   [(set (match_operand:P 0 "register_operand" "=r")
16337         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16338                             UNSPECV_PROBE_STACK_RANGE))
16339    (set (reg:P SP_REG)
16340         (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16341    (clobber (reg:CC FLAGS_REG))
16342    (clobber (mem:BLK (scratch)))]
16343   ""
16344   "* return output_adjust_stack_and_probe (operands[0]);"
16345   [(set_attr "type" "multi")])
16346
16347 (define_insn "probe_stack_range<mode>"
16348   [(set (match_operand:P 0 "register_operand" "=r")
16349         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16350                             (match_operand:P 2 "const_int_operand" "n")]
16351                             UNSPECV_PROBE_STACK_RANGE))
16352    (clobber (reg:CC FLAGS_REG))]
16353   ""
16354   "* return output_probe_stack_range (operands[0], operands[2]);"
16355   [(set_attr "type" "multi")])
16356
16357 (define_expand "builtin_setjmp_receiver"
16358   [(label_ref (match_operand 0 "" ""))]
16359   "!TARGET_64BIT && flag_pic"
16360 {
16361 #if TARGET_MACHO
16362   if (TARGET_MACHO)
16363     {
16364       rtx xops[3];
16365       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16366       rtx label_rtx = gen_label_rtx ();
16367       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16368       xops[0] = xops[1] = picreg;
16369       xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16370       ix86_expand_binary_operator (MINUS, SImode, xops);
16371     }
16372   else
16373 #endif
16374     emit_insn (gen_set_got (pic_offset_table_rtx));
16375   DONE;
16376 })
16377 \f
16378 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16379
16380 (define_split
16381   [(set (match_operand 0 "register_operand" "")
16382         (match_operator 3 "promotable_binary_operator"
16383            [(match_operand 1 "register_operand" "")
16384             (match_operand 2 "aligned_operand" "")]))
16385    (clobber (reg:CC FLAGS_REG))]
16386   "! TARGET_PARTIAL_REG_STALL && reload_completed
16387    && ((GET_MODE (operands[0]) == HImode
16388         && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16389             /* ??? next two lines just !satisfies_constraint_K (...) */
16390             || !CONST_INT_P (operands[2])
16391             || satisfies_constraint_K (operands[2])))
16392        || (GET_MODE (operands[0]) == QImode
16393            && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16394   [(parallel [(set (match_dup 0)
16395                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16396               (clobber (reg:CC FLAGS_REG))])]
16397   "operands[0] = gen_lowpart (SImode, operands[0]);
16398    operands[1] = gen_lowpart (SImode, operands[1]);
16399    if (GET_CODE (operands[3]) != ASHIFT)
16400      operands[2] = gen_lowpart (SImode, operands[2]);
16401    PUT_MODE (operands[3], SImode);")
16402
16403 ; Promote the QImode tests, as i386 has encoding of the AND
16404 ; instruction with 32-bit sign-extended immediate and thus the
16405 ; instruction size is unchanged, except in the %eax case for
16406 ; which it is increased by one byte, hence the ! optimize_size.
16407 (define_split
16408   [(set (match_operand 0 "flags_reg_operand" "")
16409         (match_operator 2 "compare_operator"
16410           [(and (match_operand 3 "aligned_operand" "")
16411                 (match_operand 4 "const_int_operand" ""))
16412            (const_int 0)]))
16413    (set (match_operand 1 "register_operand" "")
16414         (and (match_dup 3) (match_dup 4)))]
16415   "! TARGET_PARTIAL_REG_STALL && reload_completed
16416    && optimize_insn_for_speed_p ()
16417    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16418        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16419    /* Ensure that the operand will remain sign-extended immediate.  */
16420    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16421   [(parallel [(set (match_dup 0)
16422                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16423                                     (const_int 0)]))
16424               (set (match_dup 1)
16425                    (and:SI (match_dup 3) (match_dup 4)))])]
16426 {
16427   operands[4]
16428     = gen_int_mode (INTVAL (operands[4])
16429                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16430   operands[1] = gen_lowpart (SImode, operands[1]);
16431   operands[3] = gen_lowpart (SImode, operands[3]);
16432 })
16433
16434 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16435 ; the TEST instruction with 32-bit sign-extended immediate and thus
16436 ; the instruction size would at least double, which is not what we
16437 ; want even with ! optimize_size.
16438 (define_split
16439   [(set (match_operand 0 "flags_reg_operand" "")
16440         (match_operator 1 "compare_operator"
16441           [(and (match_operand:HI 2 "aligned_operand" "")
16442                 (match_operand:HI 3 "const_int_operand" ""))
16443            (const_int 0)]))]
16444   "! TARGET_PARTIAL_REG_STALL && reload_completed
16445    && ! TARGET_FAST_PREFIX
16446    && optimize_insn_for_speed_p ()
16447    /* Ensure that the operand will remain sign-extended immediate.  */
16448    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16449   [(set (match_dup 0)
16450         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16451                          (const_int 0)]))]
16452 {
16453   operands[3]
16454     = gen_int_mode (INTVAL (operands[3])
16455                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16456   operands[2] = gen_lowpart (SImode, operands[2]);
16457 })
16458
16459 (define_split
16460   [(set (match_operand 0 "register_operand" "")
16461         (neg (match_operand 1 "register_operand" "")))
16462    (clobber (reg:CC FLAGS_REG))]
16463   "! TARGET_PARTIAL_REG_STALL && reload_completed
16464    && (GET_MODE (operands[0]) == HImode
16465        || (GET_MODE (operands[0]) == QImode
16466            && (TARGET_PROMOTE_QImode
16467                || optimize_insn_for_size_p ())))"
16468   [(parallel [(set (match_dup 0)
16469                    (neg:SI (match_dup 1)))
16470               (clobber (reg:CC FLAGS_REG))])]
16471   "operands[0] = gen_lowpart (SImode, operands[0]);
16472    operands[1] = gen_lowpart (SImode, operands[1]);")
16473
16474 (define_split
16475   [(set (match_operand 0 "register_operand" "")
16476         (not (match_operand 1 "register_operand" "")))]
16477   "! TARGET_PARTIAL_REG_STALL && reload_completed
16478    && (GET_MODE (operands[0]) == HImode
16479        || (GET_MODE (operands[0]) == QImode
16480            && (TARGET_PROMOTE_QImode
16481                || optimize_insn_for_size_p ())))"
16482   [(set (match_dup 0)
16483         (not:SI (match_dup 1)))]
16484   "operands[0] = gen_lowpart (SImode, operands[0]);
16485    operands[1] = gen_lowpart (SImode, operands[1]);")
16486
16487 (define_split
16488   [(set (match_operand 0 "register_operand" "")
16489         (if_then_else (match_operator 1 "ordered_comparison_operator"
16490                                 [(reg FLAGS_REG) (const_int 0)])
16491                       (match_operand 2 "register_operand" "")
16492                       (match_operand 3 "register_operand" "")))]
16493   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
16494    && (GET_MODE (operands[0]) == HImode
16495        || (GET_MODE (operands[0]) == QImode
16496            && (TARGET_PROMOTE_QImode
16497                || optimize_insn_for_size_p ())))"
16498   [(set (match_dup 0)
16499         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16500   "operands[0] = gen_lowpart (SImode, operands[0]);
16501    operands[2] = gen_lowpart (SImode, operands[2]);
16502    operands[3] = gen_lowpart (SImode, operands[3]);")
16503 \f
16504 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
16505 ;; transform a complex memory operation into two memory to register operations.
16506
16507 ;; Don't push memory operands
16508 (define_peephole2
16509   [(set (match_operand:SWI 0 "push_operand" "")
16510         (match_operand:SWI 1 "memory_operand" ""))
16511    (match_scratch:SWI 2 "<r>")]
16512   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16513    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16514   [(set (match_dup 2) (match_dup 1))
16515    (set (match_dup 0) (match_dup 2))])
16516
16517 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16518 ;; SImode pushes.
16519 (define_peephole2
16520   [(set (match_operand:SF 0 "push_operand" "")
16521         (match_operand:SF 1 "memory_operand" ""))
16522    (match_scratch:SF 2 "r")]
16523   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16524    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16525   [(set (match_dup 2) (match_dup 1))
16526    (set (match_dup 0) (match_dup 2))])
16527
16528 ;; Don't move an immediate directly to memory when the instruction
16529 ;; gets too big.
16530 (define_peephole2
16531   [(match_scratch:SWI124 1 "<r>")
16532    (set (match_operand:SWI124 0 "memory_operand" "")
16533         (const_int 0))]
16534   "optimize_insn_for_speed_p ()
16535    && !TARGET_USE_MOV0
16536    && TARGET_SPLIT_LONG_MOVES
16537    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16538    && peep2_regno_dead_p (0, FLAGS_REG)"
16539   [(parallel [(set (match_dup 2) (const_int 0))
16540               (clobber (reg:CC FLAGS_REG))])
16541    (set (match_dup 0) (match_dup 1))]
16542   "operands[2] = gen_lowpart (SImode, operands[1]);")
16543
16544 (define_peephole2
16545   [(match_scratch:SWI124 2 "<r>")
16546    (set (match_operand:SWI124 0 "memory_operand" "")
16547         (match_operand:SWI124 1 "immediate_operand" ""))]
16548   "optimize_insn_for_speed_p ()
16549    && TARGET_SPLIT_LONG_MOVES
16550    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16551   [(set (match_dup 2) (match_dup 1))
16552    (set (match_dup 0) (match_dup 2))])
16553
16554 ;; Don't compare memory with zero, load and use a test instead.
16555 (define_peephole2
16556   [(set (match_operand 0 "flags_reg_operand" "")
16557         (match_operator 1 "compare_operator"
16558           [(match_operand:SI 2 "memory_operand" "")
16559            (const_int 0)]))
16560    (match_scratch:SI 3 "r")]
16561   "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16562   [(set (match_dup 3) (match_dup 2))
16563    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16564
16565 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16566 ;; Don't split NOTs with a displacement operand, because resulting XOR
16567 ;; will not be pairable anyway.
16568 ;;
16569 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16570 ;; represented using a modRM byte.  The XOR replacement is long decoded,
16571 ;; so this split helps here as well.
16572 ;;
16573 ;; Note: Can't do this as a regular split because we can't get proper
16574 ;; lifetime information then.
16575
16576 (define_peephole2
16577   [(set (match_operand:SWI124 0 "nonimmediate_operand" "")
16578         (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand" "")))]
16579   "optimize_insn_for_speed_p ()
16580    && ((TARGET_NOT_UNPAIRABLE
16581         && (!MEM_P (operands[0])
16582             || !memory_displacement_operand (operands[0], <MODE>mode)))
16583        || (TARGET_NOT_VECTORMODE
16584            && long_memory_operand (operands[0], <MODE>mode)))
16585    && peep2_regno_dead_p (0, FLAGS_REG)"
16586   [(parallel [(set (match_dup 0)
16587                    (xor:SWI124 (match_dup 1) (const_int -1)))
16588               (clobber (reg:CC FLAGS_REG))])])
16589
16590 ;; Non pairable "test imm, reg" instructions can be translated to
16591 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
16592 ;; byte opcode instead of two, have a short form for byte operands),
16593 ;; so do it for other CPUs as well.  Given that the value was dead,
16594 ;; this should not create any new dependencies.  Pass on the sub-word
16595 ;; versions if we're concerned about partial register stalls.
16596
16597 (define_peephole2
16598   [(set (match_operand 0 "flags_reg_operand" "")
16599         (match_operator 1 "compare_operator"
16600           [(and:SI (match_operand:SI 2 "register_operand" "")
16601                    (match_operand:SI 3 "immediate_operand" ""))
16602            (const_int 0)]))]
16603   "ix86_match_ccmode (insn, CCNOmode)
16604    && (true_regnum (operands[2]) != AX_REG
16605        || satisfies_constraint_K (operands[3]))
16606    && peep2_reg_dead_p (1, operands[2])"
16607   [(parallel
16608      [(set (match_dup 0)
16609            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16610                             (const_int 0)]))
16611       (set (match_dup 2)
16612            (and:SI (match_dup 2) (match_dup 3)))])])
16613
16614 ;; We don't need to handle HImode case, because it will be promoted to SImode
16615 ;; on ! TARGET_PARTIAL_REG_STALL
16616
16617 (define_peephole2
16618   [(set (match_operand 0 "flags_reg_operand" "")
16619         (match_operator 1 "compare_operator"
16620           [(and:QI (match_operand:QI 2 "register_operand" "")
16621                    (match_operand:QI 3 "immediate_operand" ""))
16622            (const_int 0)]))]
16623   "! TARGET_PARTIAL_REG_STALL
16624    && ix86_match_ccmode (insn, CCNOmode)
16625    && true_regnum (operands[2]) != AX_REG
16626    && peep2_reg_dead_p (1, operands[2])"
16627   [(parallel
16628      [(set (match_dup 0)
16629            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
16630                             (const_int 0)]))
16631       (set (match_dup 2)
16632            (and:QI (match_dup 2) (match_dup 3)))])])
16633
16634 (define_peephole2
16635   [(set (match_operand 0 "flags_reg_operand" "")
16636         (match_operator 1 "compare_operator"
16637           [(and:SI
16638              (zero_extract:SI
16639                (match_operand 2 "ext_register_operand" "")
16640                (const_int 8)
16641                (const_int 8))
16642              (match_operand 3 "const_int_operand" ""))
16643            (const_int 0)]))]
16644   "! TARGET_PARTIAL_REG_STALL
16645    && ix86_match_ccmode (insn, CCNOmode)
16646    && true_regnum (operands[2]) != AX_REG
16647    && peep2_reg_dead_p (1, operands[2])"
16648   [(parallel [(set (match_dup 0)
16649                    (match_op_dup 1
16650                      [(and:SI
16651                         (zero_extract:SI
16652                           (match_dup 2)
16653                           (const_int 8)
16654                           (const_int 8))
16655                         (match_dup 3))
16656                       (const_int 0)]))
16657               (set (zero_extract:SI (match_dup 2)
16658                                     (const_int 8)
16659                                     (const_int 8))
16660                    (and:SI
16661                      (zero_extract:SI
16662                        (match_dup 2)
16663                        (const_int 8)
16664                        (const_int 8))
16665                      (match_dup 3)))])])
16666
16667 ;; Don't do logical operations with memory inputs.
16668 (define_peephole2
16669   [(match_scratch:SI 2 "r")
16670    (parallel [(set (match_operand:SI 0 "register_operand" "")
16671                    (match_operator:SI 3 "arith_or_logical_operator"
16672                      [(match_dup 0)
16673                       (match_operand:SI 1 "memory_operand" "")]))
16674               (clobber (reg:CC FLAGS_REG))])]
16675   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
16676   [(set (match_dup 2) (match_dup 1))
16677    (parallel [(set (match_dup 0)
16678                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
16679               (clobber (reg:CC FLAGS_REG))])])
16680
16681 (define_peephole2
16682   [(match_scratch:SI 2 "r")
16683    (parallel [(set (match_operand:SI 0 "register_operand" "")
16684                    (match_operator:SI 3 "arith_or_logical_operator"
16685                      [(match_operand:SI 1 "memory_operand" "")
16686                       (match_dup 0)]))
16687               (clobber (reg:CC FLAGS_REG))])]
16688   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
16689   [(set (match_dup 2) (match_dup 1))
16690    (parallel [(set (match_dup 0)
16691                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
16692               (clobber (reg:CC FLAGS_REG))])])
16693
16694 ;; Prefer Load+RegOp to Mov+MemOp.  Watch out for cases when the memory address
16695 ;; refers to the destination of the load!
16696
16697 (define_peephole2
16698   [(set (match_operand:SI 0 "register_operand" "")
16699         (match_operand:SI 1 "register_operand" ""))
16700    (parallel [(set (match_dup 0)
16701                    (match_operator:SI 3 "commutative_operator"
16702                      [(match_dup 0)
16703                       (match_operand:SI 2 "memory_operand" "")]))
16704               (clobber (reg:CC FLAGS_REG))])]
16705   "REGNO (operands[0]) != REGNO (operands[1])
16706    && GENERAL_REGNO_P (REGNO (operands[0]))
16707    && GENERAL_REGNO_P (REGNO (operands[1]))"
16708   [(set (match_dup 0) (match_dup 4))
16709    (parallel [(set (match_dup 0)
16710                    (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
16711               (clobber (reg:CC FLAGS_REG))])]
16712   "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
16713
16714 (define_peephole2
16715   [(set (match_operand 0 "register_operand" "")
16716         (match_operand 1 "register_operand" ""))
16717    (set (match_dup 0)
16718                    (match_operator 3 "commutative_operator"
16719                      [(match_dup 0)
16720                       (match_operand 2 "memory_operand" "")]))]
16721   "REGNO (operands[0]) != REGNO (operands[1])
16722    && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1])) 
16723        || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
16724   [(set (match_dup 0) (match_dup 2))
16725    (set (match_dup 0)
16726         (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
16727
16728 ; Don't do logical operations with memory outputs
16729 ;
16730 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
16731 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
16732 ; the same decoder scheduling characteristics as the original.
16733
16734 (define_peephole2
16735   [(match_scratch:SI 2 "r")
16736    (parallel [(set (match_operand:SI 0 "memory_operand" "")
16737                    (match_operator:SI 3 "arith_or_logical_operator"
16738                      [(match_dup 0)
16739                       (match_operand:SI 1 "nonmemory_operand" "")]))
16740               (clobber (reg:CC FLAGS_REG))])]
16741   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
16742    /* Do not split stack checking probes.  */
16743    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
16744   [(set (match_dup 2) (match_dup 0))
16745    (parallel [(set (match_dup 2)
16746                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
16747               (clobber (reg:CC FLAGS_REG))])
16748    (set (match_dup 0) (match_dup 2))])
16749
16750 (define_peephole2
16751   [(match_scratch:SI 2 "r")
16752    (parallel [(set (match_operand:SI 0 "memory_operand" "")
16753                    (match_operator:SI 3 "arith_or_logical_operator"
16754                      [(match_operand:SI 1 "nonmemory_operand" "")
16755                       (match_dup 0)]))
16756               (clobber (reg:CC FLAGS_REG))])]
16757   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
16758    /* Do not split stack checking probes.  */
16759    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
16760   [(set (match_dup 2) (match_dup 0))
16761    (parallel [(set (match_dup 2)
16762                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16763               (clobber (reg:CC FLAGS_REG))])
16764    (set (match_dup 0) (match_dup 2))])
16765
16766 ;; Attempt to always use XOR for zeroing registers.
16767 (define_peephole2
16768   [(set (match_operand 0 "register_operand" "")
16769         (match_operand 1 "const0_operand" ""))]
16770   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
16771    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
16772    && GENERAL_REG_P (operands[0])
16773    && peep2_regno_dead_p (0, FLAGS_REG)"
16774   [(parallel [(set (match_dup 0) (const_int 0))
16775               (clobber (reg:CC FLAGS_REG))])]
16776   "operands[0] = gen_lowpart (word_mode, operands[0]);")
16777
16778 (define_peephole2
16779   [(set (strict_low_part (match_operand 0 "register_operand" ""))
16780         (const_int 0))]
16781   "(GET_MODE (operands[0]) == QImode
16782     || GET_MODE (operands[0]) == HImode)
16783    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
16784    && peep2_regno_dead_p (0, FLAGS_REG)"
16785   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
16786               (clobber (reg:CC FLAGS_REG))])])
16787
16788 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
16789 (define_peephole2
16790   [(set (match_operand:SWI248 0 "register_operand" "")
16791         (const_int -1))]
16792   "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
16793    && peep2_regno_dead_p (0, FLAGS_REG)"
16794   [(parallel [(set (match_dup 0) (const_int -1))
16795               (clobber (reg:CC FLAGS_REG))])]
16796 {
16797   if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
16798     operands[0] = gen_lowpart (SImode, operands[0]);
16799 })
16800
16801 ;; Attempt to convert simple lea to add/shift.
16802 ;; These can be created by move expanders.
16803
16804 (define_peephole2
16805   [(set (match_operand:SWI48 0 "register_operand" "")
16806         (plus:SWI48 (match_dup 0)
16807                     (match_operand:SWI48 1 "<nonmemory_operand>" "")))]
16808   "peep2_regno_dead_p (0, FLAGS_REG)"
16809   [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
16810               (clobber (reg:CC FLAGS_REG))])])
16811
16812 (define_peephole2
16813   [(set (match_operand:SI 0 "register_operand" "")
16814         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
16815                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
16816   "TARGET_64BIT
16817    && peep2_regno_dead_p (0, FLAGS_REG)
16818    && REGNO (operands[0]) == REGNO (operands[1])"
16819   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
16820               (clobber (reg:CC FLAGS_REG))])]
16821   "operands[2] = gen_lowpart (SImode, operands[2]);")
16822
16823 (define_peephole2
16824   [(set (match_operand:SWI48 0 "register_operand" "")
16825         (mult:SWI48 (match_dup 0)
16826                     (match_operand:SWI48 1 "const_int_operand" "")))]
16827   "exact_log2 (INTVAL (operands[1])) >= 0
16828    && peep2_regno_dead_p (0, FLAGS_REG)"
16829   [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
16830               (clobber (reg:CC FLAGS_REG))])]
16831   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
16832
16833 (define_peephole2
16834   [(set (match_operand:SI 0 "register_operand" "")
16835         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
16836                    (match_operand:DI 2 "const_int_operand" "")) 0))]
16837   "TARGET_64BIT
16838    && exact_log2 (INTVAL (operands[2])) >= 0
16839    && REGNO (operands[0]) == REGNO (operands[1])
16840    && peep2_regno_dead_p (0, FLAGS_REG)"
16841   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
16842               (clobber (reg:CC FLAGS_REG))])]
16843   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
16844
16845 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
16846 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
16847 ;; On many CPUs it is also faster, since special hardware to avoid esp
16848 ;; dependencies is present.
16849
16850 ;; While some of these conversions may be done using splitters, we use
16851 ;; peepholes in order to allow combine_stack_adjustments pass to see
16852 ;; nonobfuscated RTL.
16853
16854 ;; Convert prologue esp subtractions to push.
16855 ;; We need register to push.  In order to keep verify_flow_info happy we have
16856 ;; two choices
16857 ;; - use scratch and clobber it in order to avoid dependencies
16858 ;; - use already live register
16859 ;; We can't use the second way right now, since there is no reliable way how to
16860 ;; verify that given register is live.  First choice will also most likely in
16861 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
16862 ;; call clobbered registers are dead.  We may want to use base pointer as an
16863 ;; alternative when no register is available later.
16864
16865 (define_peephole2
16866   [(match_scratch:P 1 "r")
16867    (parallel [(set (reg:P SP_REG)
16868                    (plus:P (reg:P SP_REG)
16869                            (match_operand:P 0 "const_int_operand" "")))
16870               (clobber (reg:CC FLAGS_REG))
16871               (clobber (mem:BLK (scratch)))])]
16872   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
16873    && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
16874   [(clobber (match_dup 1))
16875    (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16876               (clobber (mem:BLK (scratch)))])])
16877
16878 (define_peephole2
16879   [(match_scratch:P 1 "r")
16880    (parallel [(set (reg:P SP_REG)
16881                    (plus:P (reg:P SP_REG)
16882                            (match_operand:P 0 "const_int_operand" "")))
16883               (clobber (reg:CC FLAGS_REG))
16884               (clobber (mem:BLK (scratch)))])]
16885   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
16886    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
16887   [(clobber (match_dup 1))
16888    (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16889    (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16890               (clobber (mem:BLK (scratch)))])])
16891
16892 ;; Convert esp subtractions to push.
16893 (define_peephole2
16894   [(match_scratch:P 1 "r")
16895    (parallel [(set (reg:P SP_REG)
16896                    (plus:P (reg:P SP_REG)
16897                            (match_operand:P 0 "const_int_operand" "")))
16898               (clobber (reg:CC FLAGS_REG))])]
16899   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
16900    && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
16901   [(clobber (match_dup 1))
16902    (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
16903
16904 (define_peephole2
16905   [(match_scratch:P 1 "r")
16906    (parallel [(set (reg:P SP_REG)
16907                    (plus:P (reg:P SP_REG)
16908                            (match_operand:P 0 "const_int_operand" "")))
16909               (clobber (reg:CC FLAGS_REG))])]
16910   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
16911    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
16912   [(clobber (match_dup 1))
16913    (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16914    (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
16915
16916 ;; Convert epilogue deallocator to pop.
16917 (define_peephole2
16918   [(match_scratch:P 1 "r")
16919    (parallel [(set (reg:P SP_REG)
16920                    (plus:P (reg:P SP_REG)
16921                            (match_operand:P 0 "const_int_operand" "")))
16922               (clobber (reg:CC FLAGS_REG))
16923               (clobber (mem:BLK (scratch)))])]
16924   "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
16925    && INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
16926   [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
16927               (clobber (mem:BLK (scratch)))])])
16928
16929 ;; Two pops case is tricky, since pop causes dependency
16930 ;; on destination register.  We use two registers if available.
16931 (define_peephole2
16932   [(match_scratch:P 1 "r")
16933    (match_scratch:P 2 "r")
16934    (parallel [(set (reg:P SP_REG)
16935                    (plus:P (reg:P SP_REG)
16936                            (match_operand:P 0 "const_int_operand" "")))
16937               (clobber (reg:CC FLAGS_REG))
16938               (clobber (mem:BLK (scratch)))])]
16939   "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
16940    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
16941   [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
16942               (clobber (mem:BLK (scratch)))])
16943    (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
16944
16945 (define_peephole2
16946   [(match_scratch:P 1 "r")
16947    (parallel [(set (reg:P SP_REG)
16948                    (plus:P (reg:P SP_REG)
16949                            (match_operand:P 0 "const_int_operand" "")))
16950               (clobber (reg:CC FLAGS_REG))
16951               (clobber (mem:BLK (scratch)))])]
16952   "optimize_insn_for_size_p ()
16953    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
16954   [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
16955               (clobber (mem:BLK (scratch)))])
16956    (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
16957
16958 ;; Convert esp additions to pop.
16959 (define_peephole2
16960   [(match_scratch:P 1 "r")
16961    (parallel [(set (reg:P SP_REG)
16962                    (plus:P (reg:P SP_REG)
16963                            (match_operand:P 0 "const_int_operand" "")))
16964               (clobber (reg:CC FLAGS_REG))])]
16965   "INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
16966   [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
16967
16968 ;; Two pops case is tricky, since pop causes dependency
16969 ;; on destination register.  We use two registers if available.
16970 (define_peephole2
16971   [(match_scratch:P 1 "r")
16972    (match_scratch:P 2 "r")
16973    (parallel [(set (reg:P SP_REG)
16974                    (plus:P (reg:P SP_REG)
16975                            (match_operand:P 0 "const_int_operand" "")))
16976               (clobber (reg:CC FLAGS_REG))])]
16977   "INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
16978   [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
16979    (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
16980
16981 (define_peephole2
16982   [(match_scratch:P 1 "r")
16983    (parallel [(set (reg:P SP_REG)
16984                    (plus:P (reg:P SP_REG)
16985                            (match_operand:P 0 "const_int_operand" "")))
16986               (clobber (reg:CC FLAGS_REG))])]
16987   "optimize_insn_for_size_p ()
16988    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
16989   [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
16990    (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
16991 \f
16992 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
16993 ;; required and register dies.  Similarly for 128 to -128.
16994 (define_peephole2
16995   [(set (match_operand 0 "flags_reg_operand" "")
16996         (match_operator 1 "compare_operator"
16997           [(match_operand 2 "register_operand" "")
16998            (match_operand 3 "const_int_operand" "")]))]
16999   "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17000      && incdec_operand (operands[3], GET_MODE (operands[3])))
17001     || (!TARGET_FUSE_CMP_AND_BRANCH
17002         && INTVAL (operands[3]) == 128))
17003    && ix86_match_ccmode (insn, CCGCmode)
17004    && peep2_reg_dead_p (1, operands[2])"
17005   [(parallel [(set (match_dup 0)
17006                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17007               (clobber (match_dup 2))])])
17008 \f
17009 ;; Convert imul by three, five and nine into lea
17010 (define_peephole2
17011   [(parallel
17012     [(set (match_operand:SWI48 0 "register_operand" "")
17013           (mult:SWI48 (match_operand:SWI48 1 "register_operand" "")
17014                       (match_operand:SWI48 2 "const_int_operand" "")))
17015      (clobber (reg:CC FLAGS_REG))])]
17016   "INTVAL (operands[2]) == 3
17017    || INTVAL (operands[2]) == 5
17018    || INTVAL (operands[2]) == 9"
17019   [(set (match_dup 0)
17020         (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17021                     (match_dup 1)))]
17022   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17023
17024 (define_peephole2
17025   [(parallel
17026     [(set (match_operand:SWI48 0 "register_operand" "")
17027           (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
17028                       (match_operand:SWI48 2 "const_int_operand" "")))
17029      (clobber (reg:CC FLAGS_REG))])]
17030   "optimize_insn_for_speed_p ()
17031    && (INTVAL (operands[2]) == 3
17032        || INTVAL (operands[2]) == 5
17033        || INTVAL (operands[2]) == 9)"
17034   [(set (match_dup 0) (match_dup 1))
17035    (set (match_dup 0)
17036         (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17037                     (match_dup 0)))]
17038   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17039
17040 ;; imul $32bit_imm, mem, reg is vector decoded, while
17041 ;; imul $32bit_imm, reg, reg is direct decoded.
17042 (define_peephole2
17043   [(match_scratch:SWI48 3 "r")
17044    (parallel [(set (match_operand:SWI48 0 "register_operand" "")
17045                    (mult:SWI48 (match_operand:SWI48 1 "memory_operand" "")
17046                                (match_operand:SWI48 2 "immediate_operand" "")))
17047               (clobber (reg:CC FLAGS_REG))])]
17048   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17049    && !satisfies_constraint_K (operands[2])"
17050   [(set (match_dup 3) (match_dup 1))
17051    (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17052               (clobber (reg:CC FLAGS_REG))])])
17053
17054 (define_peephole2
17055   [(match_scratch:SI 3 "r")
17056    (parallel [(set (match_operand:DI 0 "register_operand" "")
17057                    (zero_extend:DI
17058                      (mult:SI (match_operand:SI 1 "memory_operand" "")
17059                               (match_operand:SI 2 "immediate_operand" ""))))
17060               (clobber (reg:CC FLAGS_REG))])]
17061   "TARGET_64BIT
17062    && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17063    && !satisfies_constraint_K (operands[2])"
17064   [(set (match_dup 3) (match_dup 1))
17065    (parallel [(set (match_dup 0)
17066                    (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17067               (clobber (reg:CC FLAGS_REG))])])
17068
17069 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17070 ;; Convert it into imul reg, reg
17071 ;; It would be better to force assembler to encode instruction using long
17072 ;; immediate, but there is apparently no way to do so.
17073 (define_peephole2
17074   [(parallel [(set (match_operand:SWI248 0 "register_operand" "")
17075                    (mult:SWI248
17076                     (match_operand:SWI248 1 "nonimmediate_operand" "")
17077                     (match_operand:SWI248 2 "const_int_operand" "")))
17078               (clobber (reg:CC FLAGS_REG))])
17079    (match_scratch:SWI248 3 "r")]
17080   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17081    && satisfies_constraint_K (operands[2])"
17082   [(set (match_dup 3) (match_dup 2))
17083    (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17084               (clobber (reg:CC FLAGS_REG))])]
17085 {
17086   if (!rtx_equal_p (operands[0], operands[1]))
17087     emit_move_insn (operands[0], operands[1]);
17088 })
17089
17090 ;; After splitting up read-modify operations, array accesses with memory
17091 ;; operands might end up in form:
17092 ;;  sall    $2, %eax
17093 ;;  movl    4(%esp), %edx
17094 ;;  addl    %edx, %eax
17095 ;; instead of pre-splitting:
17096 ;;  sall    $2, %eax
17097 ;;  addl    4(%esp), %eax
17098 ;; Turn it into:
17099 ;;  movl    4(%esp), %edx
17100 ;;  leal    (%edx,%eax,4), %eax
17101
17102 (define_peephole2
17103   [(match_scratch:P 5 "r")
17104    (parallel [(set (match_operand 0 "register_operand" "")
17105                    (ashift (match_operand 1 "register_operand" "")
17106                            (match_operand 2 "const_int_operand" "")))
17107                (clobber (reg:CC FLAGS_REG))])
17108    (parallel [(set (match_operand 3 "register_operand" "")
17109                    (plus (match_dup 0)
17110                          (match_operand 4 "x86_64_general_operand" "")))
17111                    (clobber (reg:CC FLAGS_REG))])]
17112   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
17113    /* Validate MODE for lea.  */
17114    && ((!TARGET_PARTIAL_REG_STALL
17115         && (GET_MODE (operands[0]) == QImode
17116             || GET_MODE (operands[0]) == HImode))
17117        || GET_MODE (operands[0]) == SImode
17118        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17119    && (rtx_equal_p (operands[0], operands[3])
17120        || peep2_reg_dead_p (2, operands[0]))
17121    /* We reorder load and the shift.  */
17122    && !reg_overlap_mentioned_p (operands[0], operands[4])"
17123   [(set (match_dup 5) (match_dup 4))
17124    (set (match_dup 0) (match_dup 1))]
17125 {
17126   enum machine_mode mode = GET_MODE (operands[1]) == DImode ? DImode : SImode;
17127   int scale = 1 << INTVAL (operands[2]);
17128   rtx index = gen_lowpart (Pmode, operands[1]);
17129   rtx base = gen_lowpart (Pmode, operands[5]);
17130   rtx dest = gen_lowpart (mode, operands[3]);
17131
17132   operands[1] = gen_rtx_PLUS (Pmode, base,
17133                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
17134   operands[5] = base;
17135   if (mode != Pmode)
17136     {
17137       operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17138       operands[5] = gen_rtx_SUBREG (mode, operands[5], 0);
17139     }
17140   operands[0] = dest;
17141 })
17142 \f
17143 ;; Call-value patterns last so that the wildcard operand does not
17144 ;; disrupt insn-recog's switch tables.
17145
17146 (define_insn "*call_value_pop_0"
17147   [(set (match_operand 0 "" "")
17148         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17149               (match_operand:SI 2 "" "")))
17150    (set (reg:SI SP_REG)
17151         (plus:SI (reg:SI SP_REG)
17152                  (match_operand:SI 3 "immediate_operand" "")))]
17153   "!TARGET_64BIT"
17154 {
17155   if (SIBLING_CALL_P (insn))
17156     return "jmp\t%P1";
17157   else
17158     return "call\t%P1";
17159 }
17160   [(set_attr "type" "callv")])
17161
17162 (define_insn "*call_value_pop_1"
17163   [(set (match_operand 0 "" "")
17164         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17165               (match_operand:SI 2 "" "")))
17166    (set (reg:SI SP_REG)
17167         (plus:SI (reg:SI SP_REG)
17168                  (match_operand:SI 3 "immediate_operand" "i")))]
17169   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17170 {
17171   if (constant_call_address_operand (operands[1], Pmode))
17172     return "call\t%P1";
17173   return "call\t%A1";
17174 }
17175   [(set_attr "type" "callv")])
17176
17177 (define_insn "*sibcall_value_pop_1"
17178   [(set (match_operand 0 "" "")
17179         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17180               (match_operand:SI 2 "" "")))
17181    (set (reg:SI SP_REG)
17182         (plus:SI (reg:SI SP_REG)
17183                  (match_operand:SI 3 "immediate_operand" "i,i")))]
17184   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17185   "@
17186    jmp\t%P1
17187    jmp\t%A1"
17188   [(set_attr "type" "callv")])
17189
17190 (define_insn "*call_value_0"
17191   [(set (match_operand 0 "" "")
17192         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17193               (match_operand:SI 2 "" "")))]
17194   "!TARGET_64BIT"
17195 {
17196   if (SIBLING_CALL_P (insn))
17197     return "jmp\t%P1";
17198   else
17199     return "call\t%P1";
17200 }
17201   [(set_attr "type" "callv")])
17202
17203 (define_insn "*call_value_0_rex64"
17204   [(set (match_operand 0 "" "")
17205         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17206               (match_operand:DI 2 "const_int_operand" "")))]
17207   "TARGET_64BIT"
17208 {
17209   if (SIBLING_CALL_P (insn))
17210     return "jmp\t%P1";
17211   else
17212     return "call\t%P1";
17213 }
17214   [(set_attr "type" "callv")])
17215
17216 (define_insn "*call_value_0_rex64_ms_sysv"
17217   [(set (match_operand 0 "" "")
17218         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17219               (match_operand:DI 2 "const_int_operand" "")))
17220    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17221    (clobber (reg:TI XMM6_REG))
17222    (clobber (reg:TI XMM7_REG))
17223    (clobber (reg:TI XMM8_REG))
17224    (clobber (reg:TI XMM9_REG))
17225    (clobber (reg:TI XMM10_REG))
17226    (clobber (reg:TI XMM11_REG))
17227    (clobber (reg:TI XMM12_REG))
17228    (clobber (reg:TI XMM13_REG))
17229    (clobber (reg:TI XMM14_REG))
17230    (clobber (reg:TI XMM15_REG))
17231    (clobber (reg:DI SI_REG))
17232    (clobber (reg:DI DI_REG))]
17233   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17234 {
17235   if (SIBLING_CALL_P (insn))
17236     return "jmp\t%P1";
17237   else
17238     return "call\t%P1";
17239 }
17240   [(set_attr "type" "callv")])
17241
17242 (define_insn "*call_value_1"
17243   [(set (match_operand 0 "" "")
17244         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17245               (match_operand:SI 2 "" "")))]
17246   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17247 {
17248   if (constant_call_address_operand (operands[1], Pmode))
17249     return "call\t%P1";
17250   return "call\t%A1";
17251 }
17252   [(set_attr "type" "callv")])
17253
17254 (define_insn "*sibcall_value_1"
17255   [(set (match_operand 0 "" "")
17256         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17257               (match_operand:SI 2 "" "")))]
17258   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17259   "@
17260    jmp\t%P1
17261    jmp\t%A1"
17262   [(set_attr "type" "callv")])
17263
17264 (define_insn "*call_value_1_rex64"
17265   [(set (match_operand 0 "" "")
17266         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17267               (match_operand:DI 2 "" "")))]
17268   "TARGET_64BIT && !SIBLING_CALL_P (insn)
17269    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
17270 {
17271   if (constant_call_address_operand (operands[1], Pmode))
17272     return "call\t%P1";
17273   return "call\t%A1";
17274 }
17275   [(set_attr "type" "callv")])
17276
17277 (define_insn "*call_value_1_rex64_ms_sysv"
17278   [(set (match_operand 0 "" "")
17279         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17280               (match_operand:DI 2 "" "")))
17281    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17282    (clobber (reg:TI XMM6_REG))
17283    (clobber (reg:TI XMM7_REG))
17284    (clobber (reg:TI XMM8_REG))
17285    (clobber (reg:TI XMM9_REG))
17286    (clobber (reg:TI XMM10_REG))
17287    (clobber (reg:TI XMM11_REG))
17288    (clobber (reg:TI XMM12_REG))
17289    (clobber (reg:TI XMM13_REG))
17290    (clobber (reg:TI XMM14_REG))
17291    (clobber (reg:TI XMM15_REG))
17292    (clobber (reg:DI SI_REG))
17293    (clobber (reg:DI DI_REG))]
17294   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17295 {
17296   if (constant_call_address_operand (operands[1], Pmode))
17297     return "call\t%P1";
17298   return "call\t%A1";
17299 }
17300   [(set_attr "type" "callv")])
17301
17302 (define_insn "*call_value_1_rex64_large"
17303   [(set (match_operand 0 "" "")
17304         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
17305               (match_operand:DI 2 "" "")))]
17306   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17307   "call\t%A1"
17308   [(set_attr "type" "callv")])
17309
17310 (define_insn "*sibcall_value_1_rex64"
17311   [(set (match_operand 0 "" "")
17312         (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
17313               (match_operand:DI 2 "" "")))]
17314   "TARGET_64BIT && SIBLING_CALL_P (insn)"
17315   "@
17316    jmp\t%P1
17317    jmp\t%A1"
17318   [(set_attr "type" "callv")])
17319 \f
17320 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17321 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17322 ;; caught for use by garbage collectors and the like.  Using an insn that
17323 ;; maps to SIGILL makes it more likely the program will rightfully die.
17324 ;; Keeping with tradition, "6" is in honor of #UD.
17325 (define_insn "trap"
17326   [(trap_if (const_int 1) (const_int 6))]
17327   ""
17328   { return ASM_SHORT "0x0b0f"; }
17329   [(set_attr "length" "2")])
17330
17331 (define_expand "prefetch"
17332   [(prefetch (match_operand 0 "address_operand" "")
17333              (match_operand:SI 1 "const_int_operand" "")
17334              (match_operand:SI 2 "const_int_operand" ""))]
17335   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17336 {
17337   int rw = INTVAL (operands[1]);
17338   int locality = INTVAL (operands[2]);
17339
17340   gcc_assert (rw == 0 || rw == 1);
17341   gcc_assert (locality >= 0 && locality <= 3);
17342   gcc_assert (GET_MODE (operands[0]) == Pmode
17343               || GET_MODE (operands[0]) == VOIDmode);
17344
17345   /* Use 3dNOW prefetch in case we are asking for write prefetch not
17346      supported by SSE counterpart or the SSE prefetch is not available
17347      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
17348      of locality.  */
17349   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17350     operands[2] = GEN_INT (3);
17351   else
17352     operands[1] = const0_rtx;
17353 })
17354
17355 (define_insn "*prefetch_sse_<mode>"
17356   [(prefetch (match_operand:P 0 "address_operand" "p")
17357              (const_int 0)
17358              (match_operand:SI 1 "const_int_operand" ""))]
17359   "TARGET_PREFETCH_SSE"
17360 {
17361   static const char * const patterns[4] = {
17362    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17363   };
17364
17365   int locality = INTVAL (operands[1]);
17366   gcc_assert (locality >= 0 && locality <= 3);
17367
17368   return patterns[locality];
17369 }
17370   [(set_attr "type" "sse")
17371    (set_attr "atom_sse_attr" "prefetch")
17372    (set (attr "length_address")
17373         (symbol_ref "memory_address_length (operands[0])"))
17374    (set_attr "memory" "none")])
17375
17376 (define_insn "*prefetch_3dnow_<mode>"
17377   [(prefetch (match_operand:P 0 "address_operand" "p")
17378              (match_operand:SI 1 "const_int_operand" "n")
17379              (const_int 3))]
17380   "TARGET_3DNOW"
17381 {
17382   if (INTVAL (operands[1]) == 0)
17383     return "prefetch\t%a0";
17384   else
17385     return "prefetchw\t%a0";
17386 }
17387   [(set_attr "type" "mmx")
17388    (set (attr "length_address")
17389         (symbol_ref "memory_address_length (operands[0])"))
17390    (set_attr "memory" "none")])
17391
17392 (define_expand "stack_protect_set"
17393   [(match_operand 0 "memory_operand" "")
17394    (match_operand 1 "memory_operand" "")]
17395   ""
17396 {
17397   rtx (*insn)(rtx, rtx);
17398
17399 #ifdef TARGET_THREAD_SSP_OFFSET
17400   operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17401   insn = (TARGET_64BIT
17402           ? gen_stack_tls_protect_set_di
17403           : gen_stack_tls_protect_set_si);
17404 #else
17405   insn = (TARGET_64BIT
17406           ? gen_stack_protect_set_di
17407           : gen_stack_protect_set_si);
17408 #endif
17409
17410   emit_insn (insn (operands[0], operands[1]));
17411   DONE;
17412 })
17413
17414 (define_insn "stack_protect_set_<mode>"
17415   [(set (match_operand:P 0 "memory_operand" "=m")
17416         (unspec:P [(match_operand:P 1 "memory_operand" "m")] UNSPEC_SP_SET))
17417    (set (match_scratch:P 2 "=&r") (const_int 0))
17418    (clobber (reg:CC FLAGS_REG))]
17419   ""
17420   "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17421   [(set_attr "type" "multi")])
17422
17423 (define_insn "stack_tls_protect_set_<mode>"
17424   [(set (match_operand:P 0 "memory_operand" "=m")
17425         (unspec:P [(match_operand:P 1 "const_int_operand" "i")]
17426                   UNSPEC_SP_TLS_SET))
17427    (set (match_scratch:P 2 "=&r") (const_int 0))
17428    (clobber (reg:CC FLAGS_REG))]
17429   ""
17430   "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17431   [(set_attr "type" "multi")])
17432
17433 (define_expand "stack_protect_test"
17434   [(match_operand 0 "memory_operand" "")
17435    (match_operand 1 "memory_operand" "")
17436    (match_operand 2 "" "")]
17437   ""
17438 {
17439   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17440
17441   rtx (*insn)(rtx, rtx, rtx);
17442
17443 #ifdef TARGET_THREAD_SSP_OFFSET
17444   operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17445   insn = (TARGET_64BIT
17446           ? gen_stack_tls_protect_test_di
17447           : gen_stack_tls_protect_test_si);
17448 #else
17449   insn = (TARGET_64BIT
17450           ? gen_stack_protect_test_di
17451           : gen_stack_protect_test_si);
17452 #endif
17453
17454   emit_insn (insn (flags, operands[0], operands[1]));
17455
17456   emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17457                                   flags, const0_rtx, operands[2]));
17458   DONE;
17459 })
17460
17461 (define_insn "stack_protect_test_<mode>"
17462   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17463         (unspec:CCZ [(match_operand:P 1 "memory_operand" "m")
17464                      (match_operand:P 2 "memory_operand" "m")]
17465                     UNSPEC_SP_TEST))
17466    (clobber (match_scratch:P 3 "=&r"))]
17467   ""
17468   "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17469   [(set_attr "type" "multi")])
17470
17471 (define_insn "stack_tls_protect_test_<mode>"
17472   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17473         (unspec:CCZ [(match_operand:P 1 "memory_operand" "m")
17474                      (match_operand:P 2 "const_int_operand" "i")]
17475                     UNSPEC_SP_TLS_TEST))
17476    (clobber (match_scratch:P 3 "=r"))]
17477   ""
17478   "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17479   [(set_attr "type" "multi")])
17480
17481 (define_insn "sse4_2_crc32<mode>"
17482   [(set (match_operand:SI 0 "register_operand" "=r")
17483         (unspec:SI
17484           [(match_operand:SI 1 "register_operand" "0")
17485            (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17486           UNSPEC_CRC32))]
17487   "TARGET_SSE4_2 || TARGET_CRC32"
17488   "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17489   [(set_attr "type" "sselog1")
17490    (set_attr "prefix_rep" "1")
17491    (set_attr "prefix_extra" "1")
17492    (set (attr "prefix_data16")
17493      (if_then_else (match_operand:HI 2 "" "")
17494        (const_string "1")
17495        (const_string "*")))
17496    (set (attr "prefix_rex")
17497      (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
17498        (const_string "1")
17499        (const_string "*")))
17500    (set_attr "mode" "SI")])
17501
17502 (define_insn "sse4_2_crc32di"
17503   [(set (match_operand:DI 0 "register_operand" "=r")
17504         (unspec:DI
17505           [(match_operand:DI 1 "register_operand" "0")
17506            (match_operand:DI 2 "nonimmediate_operand" "rm")]
17507           UNSPEC_CRC32))]
17508   "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17509   "crc32{q}\t{%2, %0|%0, %2}"
17510   [(set_attr "type" "sselog1")
17511    (set_attr "prefix_rep" "1")
17512    (set_attr "prefix_extra" "1")
17513    (set_attr "mode" "DI")])
17514
17515 (define_expand "rdpmc"
17516   [(match_operand:DI 0 "register_operand" "")
17517    (match_operand:SI 1 "register_operand" "")]
17518   ""
17519 {
17520   rtx reg = gen_reg_rtx (DImode);
17521   rtx si;
17522
17523   /* Force operand 1 into ECX.  */
17524   rtx ecx = gen_rtx_REG (SImode, CX_REG);
17525   emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
17526   si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
17527                                 UNSPECV_RDPMC);
17528
17529   if (TARGET_64BIT)
17530     {
17531       rtvec vec = rtvec_alloc (2);
17532       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17533       rtx upper = gen_reg_rtx (DImode);
17534       rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17535                                         gen_rtvec (1, const0_rtx),
17536                                         UNSPECV_RDPMC);
17537       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
17538       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17539       emit_insn (load);
17540       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17541                                    NULL, 1, OPTAB_DIRECT);
17542       reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17543                                  OPTAB_DIRECT);
17544     }
17545   else
17546     emit_insn (gen_rtx_SET (VOIDmode, reg, si));
17547   emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17548   DONE;
17549 })
17550
17551 (define_insn "*rdpmc"
17552   [(set (match_operand:DI 0 "register_operand" "=A")
17553         (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17554                             UNSPECV_RDPMC))]
17555   "!TARGET_64BIT"
17556   "rdpmc"
17557   [(set_attr "type" "other")
17558    (set_attr "length" "2")])
17559
17560 (define_insn "*rdpmc_rex64"
17561   [(set (match_operand:DI 0 "register_operand" "=a")
17562         (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17563                             UNSPECV_RDPMC))
17564   (set (match_operand:DI 1 "register_operand" "=d")
17565        (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
17566   "TARGET_64BIT"
17567   "rdpmc"
17568   [(set_attr "type" "other")
17569    (set_attr "length" "2")])
17570
17571 (define_expand "rdtsc"
17572   [(set (match_operand:DI 0 "register_operand" "")
17573         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17574   ""
17575 {
17576   if (TARGET_64BIT)
17577     {
17578       rtvec vec = rtvec_alloc (2);
17579       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17580       rtx upper = gen_reg_rtx (DImode);
17581       rtx lower = gen_reg_rtx (DImode);
17582       rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
17583                                          gen_rtvec (1, const0_rtx),
17584                                          UNSPECV_RDTSC);
17585       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
17586       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
17587       emit_insn (load);
17588       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17589                                    NULL, 1, OPTAB_DIRECT);
17590       lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
17591                                    OPTAB_DIRECT);
17592       emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
17593       DONE;
17594     }
17595 })
17596
17597 (define_insn "*rdtsc"
17598   [(set (match_operand:DI 0 "register_operand" "=A")
17599         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17600   "!TARGET_64BIT"
17601   "rdtsc"
17602   [(set_attr "type" "other")
17603    (set_attr "length" "2")])
17604
17605 (define_insn "*rdtsc_rex64"
17606   [(set (match_operand:DI 0 "register_operand" "=a")
17607         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17608    (set (match_operand:DI 1 "register_operand" "=d")
17609         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17610   "TARGET_64BIT"
17611   "rdtsc"
17612   [(set_attr "type" "other")
17613    (set_attr "length" "2")])
17614
17615 (define_expand "rdtscp"
17616   [(match_operand:DI 0 "register_operand" "")
17617    (match_operand:SI 1 "memory_operand" "")]
17618   ""
17619 {
17620   rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17621                                     gen_rtvec (1, const0_rtx),
17622                                     UNSPECV_RDTSCP);
17623   rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
17624                                     gen_rtvec (1, const0_rtx),
17625                                     UNSPECV_RDTSCP);
17626   rtx reg = gen_reg_rtx (DImode);
17627   rtx tmp = gen_reg_rtx (SImode);
17628
17629   if (TARGET_64BIT)
17630     {
17631       rtvec vec = rtvec_alloc (3);
17632       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17633       rtx upper = gen_reg_rtx (DImode);
17634       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17635       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17636       RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
17637       emit_insn (load);
17638       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17639                                    NULL, 1, OPTAB_DIRECT);
17640       reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17641                                  OPTAB_DIRECT);
17642     }
17643   else
17644     {
17645       rtvec vec = rtvec_alloc (2);
17646       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17647       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17648       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
17649       emit_insn (load);
17650     }
17651   emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17652   emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
17653   DONE;
17654 })
17655
17656 (define_insn "*rdtscp"
17657   [(set (match_operand:DI 0 "register_operand" "=A")
17658         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17659    (set (match_operand:SI 1 "register_operand" "=c")
17660         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17661   "!TARGET_64BIT"
17662   "rdtscp"
17663   [(set_attr "type" "other")
17664    (set_attr "length" "3")])
17665
17666 (define_insn "*rdtscp_rex64"
17667   [(set (match_operand:DI 0 "register_operand" "=a")
17668         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17669    (set (match_operand:DI 1 "register_operand" "=d")
17670         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17671    (set (match_operand:SI 2 "register_operand" "=c")
17672         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17673   "TARGET_64BIT"
17674   "rdtscp"
17675   [(set_attr "type" "other")
17676    (set_attr "length" "3")])
17677
17678 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17679 ;;
17680 ;; LWP instructions
17681 ;;
17682 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17683
17684 (define_expand "lwp_llwpcb"
17685   [(unspec_volatile [(match_operand 0 "register_operand" "r")]
17686                     UNSPECV_LLWP_INTRINSIC)]
17687   "TARGET_LWP")
17688
17689 (define_insn "*lwp_llwpcb<mode>1"
17690   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
17691                     UNSPECV_LLWP_INTRINSIC)]
17692   "TARGET_LWP"
17693   "llwpcb\t%0"
17694   [(set_attr "type" "lwp")
17695    (set_attr "mode" "<MODE>")
17696    (set_attr "length" "5")])
17697
17698 (define_expand "lwp_slwpcb"
17699   [(set (match_operand 0 "register_operand" "=r")
17700         (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
17701   "TARGET_LWP"
17702 {
17703   if (TARGET_64BIT)
17704     emit_insn (gen_lwp_slwpcbdi (operands[0]));
17705   else
17706     emit_insn (gen_lwp_slwpcbsi (operands[0]));
17707   DONE;
17708 })
17709
17710 (define_insn "lwp_slwpcb<mode>"
17711   [(set (match_operand:P 0 "register_operand" "=r")
17712         (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
17713   "TARGET_LWP"
17714   "slwpcb\t%0"
17715   [(set_attr "type" "lwp")
17716    (set_attr "mode" "<MODE>")
17717    (set_attr "length" "5")])
17718
17719 (define_expand "lwp_lwpval<mode>3"
17720   [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
17721                      (match_operand:SI 2 "nonimmediate_operand" "rm")
17722                      (match_operand:SI 3 "const_int_operand" "i")]
17723                     UNSPECV_LWPVAL_INTRINSIC)]
17724   "TARGET_LWP"
17725   "/* Avoid unused variable warning.  */
17726    (void) operand0;")
17727
17728 (define_insn "*lwp_lwpval<mode>3_1"
17729   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
17730                      (match_operand:SI 1 "nonimmediate_operand" "rm")
17731                      (match_operand:SI 2 "const_int_operand" "i")]
17732                     UNSPECV_LWPVAL_INTRINSIC)]
17733   "TARGET_LWP"
17734   "lwpval\t{%2, %1, %0|%0, %1, %2}"
17735   [(set_attr "type" "lwp")
17736    (set_attr "mode" "<MODE>")
17737    (set (attr "length")
17738         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
17739
17740 (define_expand "lwp_lwpins<mode>3"
17741   [(set (reg:CCC FLAGS_REG)
17742         (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
17743                               (match_operand:SI 2 "nonimmediate_operand" "rm")
17744                               (match_operand:SI 3 "const_int_operand" "i")]
17745                              UNSPECV_LWPINS_INTRINSIC))
17746    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
17747         (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
17748   "TARGET_LWP")
17749
17750 (define_insn "*lwp_lwpins<mode>3_1"
17751   [(set (reg:CCC FLAGS_REG)
17752         (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
17753                               (match_operand:SI 1 "nonimmediate_operand" "rm")
17754                               (match_operand:SI 2 "const_int_operand" "i")]
17755                              UNSPECV_LWPINS_INTRINSIC))]
17756   "TARGET_LWP"
17757   "lwpins\t{%2, %1, %0|%0, %1, %2}"
17758   [(set_attr "type" "lwp")
17759    (set_attr "mode" "<MODE>")
17760    (set (attr "length")
17761         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
17762
17763 (define_insn "rdfsbase<mode>"
17764   [(set (match_operand:SWI48 0 "register_operand" "=r")
17765         (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDFSBASE))]
17766   "TARGET_64BIT && TARGET_FSGSBASE"
17767   "rdfsbase %0"
17768   [(set_attr "type" "other")
17769    (set_attr "prefix_extra" "2")])
17770
17771 (define_insn "rdgsbase<mode>"
17772   [(set (match_operand:SWI48 0 "register_operand" "=r")
17773         (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDGSBASE))]
17774   "TARGET_64BIT && TARGET_FSGSBASE"
17775   "rdgsbase %0"
17776   [(set_attr "type" "other")
17777    (set_attr "prefix_extra" "2")])
17778
17779 (define_insn "wrfsbase<mode>"
17780   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
17781                     UNSPECV_WRFSBASE)]
17782   "TARGET_64BIT && TARGET_FSGSBASE"
17783   "wrfsbase %0"
17784   [(set_attr "type" "other")
17785    (set_attr "prefix_extra" "2")])
17786
17787 (define_insn "wrgsbase<mode>"
17788   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
17789                     UNSPECV_WRGSBASE)]
17790   "TARGET_64BIT && TARGET_FSGSBASE"
17791   "wrgsbase %0"
17792   [(set_attr "type" "other")
17793    (set_attr "prefix_extra" "2")])
17794
17795 (define_expand "rdrand<mode>"
17796   [(set (match_operand:SWI248 0 "register_operand" "=r")
17797         (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))]
17798   "TARGET_RDRND"
17799 {
17800   rtx retry_label, insn, ccc;
17801
17802   retry_label = gen_label_rtx ();
17803
17804   emit_label (retry_label);
17805
17806   /* Generate rdrand.  */
17807   emit_insn (gen_rdrand<mode>_1 (operands[0]));
17808
17809   /* Retry if the carry flag isn't valid.  */
17810   ccc = gen_rtx_REG (CCCmode, FLAGS_REG);
17811   ccc = gen_rtx_EQ (VOIDmode, ccc, const0_rtx);
17812   ccc = gen_rtx_IF_THEN_ELSE (VOIDmode, ccc, pc_rtx,
17813                               gen_rtx_LABEL_REF (VOIDmode, retry_label));
17814   insn = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, ccc));
17815   JUMP_LABEL (insn) = retry_label;
17816
17817   DONE;
17818 })
17819
17820 (define_insn "rdrand<mode>_1"
17821   [(set (match_operand:SWI248 0 "register_operand" "=r")
17822         (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))]
17823   "TARGET_RDRND"
17824   "rdrand %0"
17825   [(set_attr "type" "other")
17826    (set_attr "prefix_extra" "1")])
17827
17828 (include "mmx.md")
17829 (include "sse.md")
17830 (include "sync.md")