OSDN Git Service

c81b647b4244ed0cc19caba7adacd4176190eebd
[pf3gnuchains/gcc-fork.git] / gcc / config / i386 / i386.md
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
7 ;;
8 ;; This file is part of GCC.
9 ;;
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 3, or (at your option)
13 ;; any later version.
14 ;;
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 ;; GNU General Public License for more details.
19 ;;
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING3.  If not see
22 ;; <http://www.gnu.org/licenses/>.  */
23 ;;
24 ;; The original PO technology requires these to be ordered by speed,
25 ;; so that assigner will pick the fastest.
26 ;;
27 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
28 ;;
29 ;; The special asm out single letter directives following a '%' are:
30 ;; L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
31 ;; C -- print opcode suffix for set/cmov insn.
32 ;; c -- like C, but print reversed condition
33 ;; F,f -- likewise, but for floating-point.
34 ;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
35 ;;      otherwise nothing
36 ;; R -- print the prefix for register names.
37 ;; z -- print the opcode suffix for the size of the current operand.
38 ;; Z -- likewise, with special suffixes for x87 instructions.
39 ;; * -- print a star (in certain assembler syntax)
40 ;; A -- print an absolute memory reference.
41 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
42 ;; s -- print a shift double count, followed by the assemblers argument
43 ;;      delimiter.
44 ;; b -- print the QImode name of the register for the indicated operand.
45 ;;      %b0 would print %al if operands[0] is reg 0.
46 ;; w --  likewise, print the HImode name of the register.
47 ;; k --  likewise, print the SImode name of the register.
48 ;; q --  likewise, print the DImode name of the register.
49 ;; x --  likewise, print the V4SFmode name of the register.
50 ;; t --  likewise, print the V8SFmode name of the register.
51 ;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
52 ;; y -- print "st(0)" instead of "st" as a register.
53 ;; d -- print duplicated register operand for AVX instruction.
54 ;; D -- print condition for SSE cmp instruction.
55 ;; P -- if PIC, print an @PLT suffix.
56 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
57 ;; & -- print some in-use local-dynamic symbol name.
58 ;; H -- print a memory address offset by 8; used for sse high-parts
59 ;; Y -- print condition for XOP pcom* instruction.
60 ;; + -- print a branch hint as 'cs' or 'ds' prefix
61 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
62
63 ;; UNSPEC usage:
64
65 (define_c_enum "unspec" [
66   ;; Relocation specifiers
67   UNSPEC_GOT
68   UNSPEC_GOTOFF
69   UNSPEC_GOTPCREL
70   UNSPEC_GOTTPOFF
71   UNSPEC_TPOFF
72   UNSPEC_NTPOFF
73   UNSPEC_DTPOFF
74   UNSPEC_GOTNTPOFF
75   UNSPEC_INDNTPOFF
76   UNSPEC_PLTOFF
77   UNSPEC_MACHOPIC_OFFSET
78
79   ;; Prologue support
80   UNSPEC_STACK_ALLOC
81   UNSPEC_SET_GOT
82   UNSPEC_SSE_PROLOGUE_SAVE
83   UNSPEC_REG_SAVE
84   UNSPEC_DEF_CFA
85   UNSPEC_SET_RIP
86   UNSPEC_SET_GOT_OFFSET
87   UNSPEC_MEMORY_BLOCKAGE
88   UNSPEC_SSE_PROLOGUE_SAVE_LOW
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
108   ;; For SSE/MMX support:
109   UNSPEC_FIX_NOTRUNC
110   UNSPEC_MASKMOV
111   UNSPEC_MOVMSK
112   UNSPEC_MOVNT
113   UNSPEC_MOVU
114   UNSPEC_RCP
115   UNSPEC_RSQRT
116   UNSPEC_SFENCE
117   UNSPEC_PFRCP
118   UNSPEC_PFRCPIT1
119   UNSPEC_PFRCPIT2
120   UNSPEC_PFRSQRT
121   UNSPEC_PFRSQIT1
122   UNSPEC_MFENCE
123   UNSPEC_LFENCE
124   UNSPEC_PSADBW
125   UNSPEC_LDDQU
126   UNSPEC_MS_TO_SYSV_CALL
127
128   ;; Generic math support
129   UNSPEC_COPYSIGN
130   UNSPEC_IEEE_MIN       ; not commutative
131   UNSPEC_IEEE_MAX       ; not commutative
132
133   ;; x87 Floating point
134   UNSPEC_SIN
135   UNSPEC_COS
136   UNSPEC_FPATAN
137   UNSPEC_FYL2X
138   UNSPEC_FYL2XP1
139   UNSPEC_FRNDINT
140   UNSPEC_FIST
141   UNSPEC_F2XM1
142   UNSPEC_TAN
143   UNSPEC_FXAM
144
145   ;; x87 Rounding
146   UNSPEC_FRNDINT_FLOOR
147   UNSPEC_FRNDINT_CEIL
148   UNSPEC_FRNDINT_TRUNC
149   UNSPEC_FRNDINT_MASK_PM
150   UNSPEC_FIST_FLOOR
151   UNSPEC_FIST_CEIL
152
153   ;; x87 Double output FP
154   UNSPEC_SINCOS_COS
155   UNSPEC_SINCOS_SIN
156   UNSPEC_XTRACT_FRACT
157   UNSPEC_XTRACT_EXP
158   UNSPEC_FSCALE_FRACT
159   UNSPEC_FSCALE_EXP
160   UNSPEC_FPREM_F
161   UNSPEC_FPREM_U
162   UNSPEC_FPREM1_F
163   UNSPEC_FPREM1_U
164
165   UNSPEC_C2_FLAG
166   UNSPEC_FXAM_MEM
167
168   ;; SSP patterns
169   UNSPEC_SP_SET
170   UNSPEC_SP_TEST
171   UNSPEC_SP_TLS_SET
172   UNSPEC_SP_TLS_TEST
173
174   ;; SSSE3
175   UNSPEC_PSHUFB
176   UNSPEC_PSIGN
177   UNSPEC_PALIGNR
178
179   ;; For SSE4A support
180   UNSPEC_EXTRQI
181   UNSPEC_EXTRQ
182   UNSPEC_INSERTQI
183   UNSPEC_INSERTQ
184
185   ;; For SSE4.1 support
186   UNSPEC_BLENDV
187   UNSPEC_INSERTPS
188   UNSPEC_DP
189   UNSPEC_MOVNTDQA
190   UNSPEC_MPSADBW
191   UNSPEC_PHMINPOSUW
192   UNSPEC_PTEST
193   UNSPEC_ROUND
194
195   ;; For SSE4.2 support
196   UNSPEC_CRC32
197   UNSPEC_PCMPESTR
198   UNSPEC_PCMPISTR
199
200   ;; For FMA4 support
201   UNSPEC_FMA4_INTRINSIC
202   UNSPEC_FMA4_FMADDSUB
203   UNSPEC_FMA4_FMSUBADD
204   UNSPEC_XOP_UNSIGNED_CMP
205   UNSPEC_XOP_TRUEFALSE
206   UNSPEC_XOP_PERMUTE
207   UNSPEC_FRCZ
208
209   ;; For AES support
210   UNSPEC_AESENC
211   UNSPEC_AESENCLAST
212   UNSPEC_AESDEC
213   UNSPEC_AESDECLAST
214   UNSPEC_AESIMC
215   UNSPEC_AESKEYGENASSIST
216
217   ;; For PCLMUL support
218   UNSPEC_PCLMUL
219
220   ;; For AVX support
221   UNSPEC_PCMP
222   UNSPEC_VPERMIL
223   UNSPEC_VPERMIL2
224   UNSPEC_VPERMIL2F128
225   UNSPEC_MASKLOAD
226   UNSPEC_MASKSTORE
227   UNSPEC_CAST
228   UNSPEC_VTESTP
229 ])
230
231 (define_c_enum "unspecv" [
232   UNSPECV_BLOCKAGE
233   UNSPECV_STACK_PROBE
234   UNSPECV_EMMS
235   UNSPECV_LDMXCSR
236   UNSPECV_STMXCSR
237   UNSPECV_FEMMS
238   UNSPECV_CLFLUSH
239   UNSPECV_ALIGN
240   UNSPECV_MONITOR
241   UNSPECV_MWAIT
242   UNSPECV_CMPXCHG
243   UNSPECV_XCHG
244   UNSPECV_LOCK
245   UNSPECV_PROLOGUE_USE
246   UNSPECV_CLD
247   UNSPECV_VZEROALL
248   UNSPECV_VZEROUPPER
249   UNSPECV_RDTSC
250   UNSPECV_RDTSCP
251   UNSPECV_RDPMC
252   UNSPECV_VSWAPMOV
253   UNSPECV_LLWP_INTRINSIC
254   UNSPECV_SLWP_INTRINSIC
255   UNSPECV_LWPVAL_INTRINSIC
256   UNSPECV_LWPINS_INTRINSIC
257 ])
258
259 ;; Constants to represent pcomtrue/pcomfalse variants
260 (define_constants
261   [(PCOM_FALSE                  0)
262    (PCOM_TRUE                   1)
263    (COM_FALSE_S                 2)
264    (COM_FALSE_P                 3)
265    (COM_TRUE_S                  4)
266    (COM_TRUE_P                  5)
267   ])
268
269 ;; Constants used in the XOP pperm instruction
270 (define_constants
271   [(PPERM_SRC                   0x00)   /* copy source */
272    (PPERM_INVERT                0x20)   /* invert source */
273    (PPERM_REVERSE               0x40)   /* bit reverse source */
274    (PPERM_REV_INV               0x60)   /* bit reverse & invert src */
275    (PPERM_ZERO                  0x80)   /* all 0's */
276    (PPERM_ONES                  0xa0)   /* all 1's */
277    (PPERM_SIGN                  0xc0)   /* propagate sign bit */
278    (PPERM_INV_SIGN              0xe0)   /* invert & propagate sign */
279    (PPERM_SRC1                  0x00)   /* use first source byte */
280    (PPERM_SRC2                  0x10)   /* use second source byte */
281    ])
282
283 ;; Registers by name.
284 (define_constants
285   [(AX_REG                       0)
286    (DX_REG                       1)
287    (CX_REG                       2)
288    (BX_REG                       3)
289    (SI_REG                       4)
290    (DI_REG                       5)
291    (BP_REG                       6)
292    (SP_REG                       7)
293    (ST0_REG                      8)
294    (ST1_REG                      9)
295    (ST2_REG                     10)
296    (ST3_REG                     11)
297    (ST4_REG                     12)
298    (ST5_REG                     13)
299    (ST6_REG                     14)
300    (ST7_REG                     15)
301    (FLAGS_REG                   17)
302    (FPSR_REG                    18)
303    (FPCR_REG                    19)
304    (XMM0_REG                    21)
305    (XMM1_REG                    22)
306    (XMM2_REG                    23)
307    (XMM3_REG                    24)
308    (XMM4_REG                    25)
309    (XMM5_REG                    26)
310    (XMM6_REG                    27)
311    (XMM7_REG                    28)
312    (MM0_REG                     29)
313    (MM1_REG                     30)
314    (MM2_REG                     31)
315    (MM3_REG                     32)
316    (MM4_REG                     33)
317    (MM5_REG                     34)
318    (MM6_REG                     35)
319    (MM7_REG                     36)
320    (R8_REG                      37)
321    (R9_REG                      38)
322    (R10_REG                     39)
323    (R11_REG                     40)
324    (R12_REG                     41)
325    (R13_REG                     42)
326    (XMM8_REG                    45)
327    (XMM9_REG                    46)
328    (XMM10_REG                   47)
329    (XMM11_REG                   48)
330    (XMM12_REG                   49)
331    (XMM13_REG                   50)
332    (XMM14_REG                   51)
333    (XMM15_REG                   52)
334   ])
335
336 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
337 ;; from i386.c.
338
339 ;; In C guard expressions, put expressions which may be compile-time
340 ;; constants first.  This allows for better optimization.  For
341 ;; example, write "TARGET_64BIT && reload_completed", not
342 ;; "reload_completed && TARGET_64BIT".
343
344 \f
345 ;; Processor type.
346 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,atom,
347                     generic64,amdfam10,bdver1"
348   (const (symbol_ref "ix86_schedule")))
349
350 ;; A basic instruction type.  Refinements due to arguments to be
351 ;; provided in other attributes.
352 (define_attr "type"
353   "other,multi,
354    alu,alu1,negnot,imov,imovx,lea,
355    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
356    icmp,test,ibr,setcc,icmov,
357    push,pop,call,callv,leave,
358    str,bitmanip,
359    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
360    sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
361    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
362    ssemuladd,sse4arg,lwp,
363    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
364   (const_string "other"))
365
366 ;; Main data type used by the insn
367 (define_attr "mode"
368   "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
369   (const_string "unknown"))
370
371 ;; The CPU unit operations uses.
372 (define_attr "unit" "integer,i387,sse,mmx,unknown"
373   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
374            (const_string "i387")
375          (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
376                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
377                           ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
378            (const_string "sse")
379          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
380            (const_string "mmx")
381          (eq_attr "type" "other")
382            (const_string "unknown")]
383          (const_string "integer")))
384
385 ;; The (bounding maximum) length of an instruction immediate.
386 (define_attr "length_immediate" ""
387   (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
388                           bitmanip")
389            (const_int 0)
390          (eq_attr "unit" "i387,sse,mmx")
391            (const_int 0)
392          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
393                           imul,icmp,push,pop")
394            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
395          (eq_attr "type" "imov,test")
396            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
397          (eq_attr "type" "call")
398            (if_then_else (match_operand 0 "constant_call_address_operand" "")
399              (const_int 4)
400              (const_int 0))
401          (eq_attr "type" "callv")
402            (if_then_else (match_operand 1 "constant_call_address_operand" "")
403              (const_int 4)
404              (const_int 0))
405          ;; We don't know the size before shorten_branches.  Expect
406          ;; the instruction to fit for better scheduling.
407          (eq_attr "type" "ibr")
408            (const_int 1)
409          ]
410          (symbol_ref "/* Update immediate_length and other attributes! */
411                       gcc_unreachable (),1")))
412
413 ;; The (bounding maximum) length of an instruction address.
414 (define_attr "length_address" ""
415   (cond [(eq_attr "type" "str,other,multi,fxch")
416            (const_int 0)
417          (and (eq_attr "type" "call")
418               (match_operand 0 "constant_call_address_operand" ""))
419              (const_int 0)
420          (and (eq_attr "type" "callv")
421               (match_operand 1 "constant_call_address_operand" ""))
422              (const_int 0)
423          ]
424          (symbol_ref "ix86_attr_length_address_default (insn)")))
425
426 ;; Set when length prefix is used.
427 (define_attr "prefix_data16" ""
428   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
429            (const_int 0)
430          (eq_attr "mode" "HI")
431            (const_int 1)
432          (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
433            (const_int 1)
434         ]
435         (const_int 0)))
436
437 ;; Set when string REP prefix is used.
438 (define_attr "prefix_rep" ""
439   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
440            (const_int 0)
441          (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
442            (const_int 1)
443         ]
444         (const_int 0)))
445
446 ;; Set when 0f opcode prefix is used.
447 (define_attr "prefix_0f" ""
448   (if_then_else
449     (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
450          (eq_attr "unit" "sse,mmx"))
451     (const_int 1)
452     (const_int 0)))
453
454 ;; Set when REX opcode prefix is used.
455 (define_attr "prefix_rex" ""
456   (cond [(ne (symbol_ref "!TARGET_64BIT") (const_int 0))
457            (const_int 0)
458          (and (eq_attr "mode" "DI")
459               (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
460                    (eq_attr "unit" "!mmx")))
461            (const_int 1)
462          (and (eq_attr "mode" "QI")
463               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
464                   (const_int 0)))
465            (const_int 1)
466          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
467              (const_int 0))
468            (const_int 1)
469          (and (eq_attr "type" "imovx")
470               (match_operand:QI 1 "ext_QIreg_operand" ""))
471            (const_int 1)
472         ]
473         (const_int 0)))
474
475 ;; There are also additional prefixes in 3DNOW, SSSE3.
476 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
477 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
478 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
479 (define_attr "prefix_extra" ""
480   (cond [(eq_attr "type" "ssemuladd,sse4arg")
481            (const_int 2)
482          (eq_attr "type" "sseiadd1,ssecvt1")
483            (const_int 1)
484         ]
485         (const_int 0)))
486
487 ;; Prefix used: original, VEX or maybe VEX.
488 (define_attr "prefix" "orig,vex,maybe_vex"
489   (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
490     (const_string "vex")
491     (const_string "orig")))
492
493 ;; VEX W bit is used.
494 (define_attr "prefix_vex_w" "" (const_int 0))
495
496 ;; The length of VEX prefix
497 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
498 ;; 0f38/0f3a prefixes can't.  In i386.md 0f3[8a] is
499 ;; still prefix_0f 1, with prefix_extra 1.
500 (define_attr "length_vex" ""
501   (if_then_else (and (eq_attr "prefix_0f" "1")
502                      (eq_attr "prefix_extra" "0"))
503     (if_then_else (eq_attr "prefix_vex_w" "1")
504       (symbol_ref "ix86_attr_length_vex_default (insn, 1, 1)")
505       (symbol_ref "ix86_attr_length_vex_default (insn, 1, 0)"))
506     (if_then_else (eq_attr "prefix_vex_w" "1")
507       (symbol_ref "ix86_attr_length_vex_default (insn, 0, 1)")
508       (symbol_ref "ix86_attr_length_vex_default (insn, 0, 0)"))))
509
510 ;; Set when modrm byte is used.
511 (define_attr "modrm" ""
512   (cond [(eq_attr "type" "str,leave")
513            (const_int 0)
514          (eq_attr "unit" "i387")
515            (const_int 0)
516          (and (eq_attr "type" "incdec")
517               (and (eq (symbol_ref "TARGET_64BIT") (const_int 0))
518                    (ior (match_operand:SI 1 "register_operand" "")
519                         (match_operand:HI 1 "register_operand" ""))))
520            (const_int 0)
521          (and (eq_attr "type" "push")
522               (not (match_operand 1 "memory_operand" "")))
523            (const_int 0)
524          (and (eq_attr "type" "pop")
525               (not (match_operand 0 "memory_operand" "")))
526            (const_int 0)
527          (and (eq_attr "type" "imov")
528               (and (not (eq_attr "mode" "DI"))
529                    (ior (and (match_operand 0 "register_operand" "")
530                              (match_operand 1 "immediate_operand" ""))
531                         (ior (and (match_operand 0 "ax_reg_operand" "")
532                                   (match_operand 1 "memory_displacement_only_operand" ""))
533                              (and (match_operand 0 "memory_displacement_only_operand" "")
534                                   (match_operand 1 "ax_reg_operand" ""))))))
535            (const_int 0)
536          (and (eq_attr "type" "call")
537               (match_operand 0 "constant_call_address_operand" ""))
538              (const_int 0)
539          (and (eq_attr "type" "callv")
540               (match_operand 1 "constant_call_address_operand" ""))
541              (const_int 0)
542          (and (eq_attr "type" "alu,alu1,icmp,test")
543               (match_operand 0 "ax_reg_operand" ""))
544              (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
545          ]
546          (const_int 1)))
547
548 ;; The (bounding maximum) length of an instruction in bytes.
549 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
550 ;; Later we may want to split them and compute proper length as for
551 ;; other insns.
552 (define_attr "length" ""
553   (cond [(eq_attr "type" "other,multi,fistp,frndint")
554            (const_int 16)
555          (eq_attr "type" "fcmp")
556            (const_int 4)
557          (eq_attr "unit" "i387")
558            (plus (const_int 2)
559                  (plus (attr "prefix_data16")
560                        (attr "length_address")))
561          (ior (eq_attr "prefix" "vex")
562               (and (eq_attr "prefix" "maybe_vex")
563                     (ne (symbol_ref "TARGET_AVX") (const_int 0))))
564            (plus (attr "length_vex")
565                  (plus (attr "length_immediate")
566                        (plus (attr "modrm")
567                              (attr "length_address"))))]
568          (plus (plus (attr "modrm")
569                      (plus (attr "prefix_0f")
570                            (plus (attr "prefix_rex")
571                                  (plus (attr "prefix_extra")
572                                        (const_int 1)))))
573                (plus (attr "prefix_rep")
574                      (plus (attr "prefix_data16")
575                            (plus (attr "length_immediate")
576                                  (attr "length_address")))))))
577
578 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
579 ;; `store' if there is a simple memory reference therein, or `unknown'
580 ;; if the instruction is complex.
581
582 (define_attr "memory" "none,load,store,both,unknown"
583   (cond [(eq_attr "type" "other,multi,str,lwp")
584            (const_string "unknown")
585          (eq_attr "type" "lea,fcmov,fpspc")
586            (const_string "none")
587          (eq_attr "type" "fistp,leave")
588            (const_string "both")
589          (eq_attr "type" "frndint")
590            (const_string "load")
591          (eq_attr "type" "push")
592            (if_then_else (match_operand 1 "memory_operand" "")
593              (const_string "both")
594              (const_string "store"))
595          (eq_attr "type" "pop")
596            (if_then_else (match_operand 0 "memory_operand" "")
597              (const_string "both")
598              (const_string "load"))
599          (eq_attr "type" "setcc")
600            (if_then_else (match_operand 0 "memory_operand" "")
601              (const_string "store")
602              (const_string "none"))
603          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
604            (if_then_else (ior (match_operand 0 "memory_operand" "")
605                               (match_operand 1 "memory_operand" ""))
606              (const_string "load")
607              (const_string "none"))
608          (eq_attr "type" "ibr")
609            (if_then_else (match_operand 0 "memory_operand" "")
610              (const_string "load")
611              (const_string "none"))
612          (eq_attr "type" "call")
613            (if_then_else (match_operand 0 "constant_call_address_operand" "")
614              (const_string "none")
615              (const_string "load"))
616          (eq_attr "type" "callv")
617            (if_then_else (match_operand 1 "constant_call_address_operand" "")
618              (const_string "none")
619              (const_string "load"))
620          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
621               (match_operand 1 "memory_operand" ""))
622            (const_string "both")
623          (and (match_operand 0 "memory_operand" "")
624               (match_operand 1 "memory_operand" ""))
625            (const_string "both")
626          (match_operand 0 "memory_operand" "")
627            (const_string "store")
628          (match_operand 1 "memory_operand" "")
629            (const_string "load")
630          (and (eq_attr "type"
631                  "!alu1,negnot,ishift1,
632                    imov,imovx,icmp,test,bitmanip,
633                    fmov,fcmp,fsgn,
634                    sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
635                    sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
636               (match_operand 2 "memory_operand" ""))
637            (const_string "load")
638          (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
639               (match_operand 3 "memory_operand" ""))
640            (const_string "load")
641         ]
642         (const_string "none")))
643
644 ;; Indicates if an instruction has both an immediate and a displacement.
645
646 (define_attr "imm_disp" "false,true,unknown"
647   (cond [(eq_attr "type" "other,multi")
648            (const_string "unknown")
649          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
650               (and (match_operand 0 "memory_displacement_operand" "")
651                    (match_operand 1 "immediate_operand" "")))
652            (const_string "true")
653          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
654               (and (match_operand 0 "memory_displacement_operand" "")
655                    (match_operand 2 "immediate_operand" "")))
656            (const_string "true")
657         ]
658         (const_string "false")))
659
660 ;; Indicates if an FP operation has an integer source.
661
662 (define_attr "fp_int_src" "false,true"
663   (const_string "false"))
664
665 ;; Defines rounding mode of an FP operation.
666
667 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
668   (const_string "any"))
669
670 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
671 (define_attr "use_carry" "0,1" (const_string "0"))
672
673 ;; Define attribute to indicate unaligned ssemov insns
674 (define_attr "movu" "0,1" (const_string "0"))
675
676 ;; Describe a user's asm statement.
677 (define_asm_attributes
678   [(set_attr "length" "128")
679    (set_attr "type" "multi")])
680
681 ;; All integer comparison codes.
682 (define_code_iterator int_cond [ne eq ge gt le lt geu gtu leu ltu])
683
684 ;; All floating-point comparison codes.
685 (define_code_iterator fp_cond [unordered ordered
686                                uneq unge ungt unle unlt ltgt])
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 ;; Mapping of signed/unsigned max and min
715 (define_code_iterator maxmin [smax smin umax umin])
716
717 ;; Base name for integer and FP insn mnemonic
718 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
719                               (umax "maxu") (umin "minu")])
720 (define_code_attr maxmin_float [(smax "max") (smin "min")])
721
722 ;; Mapping of logic operators
723 (define_code_iterator any_logic [and ior xor])
724 (define_code_iterator any_or [ior xor])
725
726 ;; Base name for insn mnemonic.
727 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
728
729 ;; Mapping of shift-right operators
730 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
731
732 ;; Base name for define_insn
733 (define_code_attr shiftrt_insn [(lshiftrt "lshr") (ashiftrt "ashr")])
734
735 ;; Base name for insn mnemonic.
736 (define_code_attr shiftrt [(lshiftrt "shr") (ashiftrt "sar")])
737
738 ;; Mapping of rotate operators
739 (define_code_iterator any_rotate [rotate rotatert])
740
741 ;; Base name for define_insn
742 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
743
744 ;; Base name for insn mnemonic.
745 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
746
747 ;; Mapping of abs neg operators
748 (define_code_iterator absneg [abs neg])
749
750 ;; Base name for x87 insn mnemonic.
751 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
752
753 ;; Used in signed and unsigned widening multiplications.
754 (define_code_iterator any_extend [sign_extend zero_extend])
755
756 ;; Various insn prefixes for signed and unsigned operations.
757 (define_code_attr u [(sign_extend "") (zero_extend "u")
758                      (div "") (udiv "u")])
759 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
760
761 ;; Used in signed and unsigned divisions.
762 (define_code_iterator any_div [div udiv])
763
764 ;; Instruction prefix for signed and unsigned operations.
765 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")
766                              (div "i") (udiv "")])
767
768 ;; All single word integer modes.
769 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
770
771 ;; Single word integer modes without DImode.
772 (define_mode_iterator SWI124 [QI HI SI])
773
774 ;; Single word integer modes without QImode.
775 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
776
777 ;; Single word integer modes without QImode and HImode.
778 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
779
780 ;; All math-dependant single and double word integer modes.
781 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
782                              (HI "TARGET_HIMODE_MATH")
783                              SI DI (TI "TARGET_64BIT")])
784
785 ;; Math-dependant single word integer modes.
786 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
787                             (HI "TARGET_HIMODE_MATH")
788                             SI (DI "TARGET_64BIT")])
789
790 ;; Math-dependant single word integer modes without DImode.
791 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
792                                (HI "TARGET_HIMODE_MATH")
793                                SI])
794
795 ;; Math-dependant single word integer modes without QImode.
796 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
797                                SI (DI "TARGET_64BIT")])
798
799 ;; Double word integer modes.
800 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
801                            (TI "TARGET_64BIT")])
802
803 ;; Double word integer modes as mode attribute.
804 (define_mode_attr DWI [(SI "DI") (DI "TI")])
805 (define_mode_attr dwi [(SI "di") (DI "ti")])
806
807 ;; Half mode for double word integer modes.
808 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
809                             (DI "TARGET_64BIT")])
810
811 ;; Instruction suffix for integer modes.
812 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
813
814 ;; Register class for integer modes.
815 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
816
817 ;; Immediate operand constraint for integer modes.
818 (define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")])
819
820 ;; General operand constraint for word modes.
821 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "g") (DI "rme")])
822
823 ;; Immediate operand constraint for double integer modes.
824 (define_mode_attr di [(SI "iF") (DI "e")])
825
826 ;; Immediate operand constraint for shifts.
827 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
828
829 ;; General operand predicate for integer modes.
830 (define_mode_attr general_operand
831         [(QI "general_operand")
832          (HI "general_operand")
833          (SI "general_operand")
834          (DI "x86_64_general_operand")
835          (TI "x86_64_general_operand")])
836
837 ;; General sign/zero extend operand predicate for integer modes.
838 (define_mode_attr general_szext_operand
839         [(QI "general_operand")
840          (HI "general_operand")
841          (SI "general_operand")
842          (DI "x86_64_szext_general_operand")])
843
844 ;; Operand predicate for shifts.
845 (define_mode_attr shift_operand
846         [(QI "nonimmediate_operand")
847          (HI "nonimmediate_operand")
848          (SI "nonimmediate_operand")
849          (DI "shiftdi_operand")
850          (TI "register_operand")])
851
852 ;; Operand predicate for shift argument.
853 (define_mode_attr shift_immediate_operand
854         [(QI "const_1_to_31_operand")
855          (HI "const_1_to_31_operand")
856          (SI "const_1_to_31_operand")
857          (DI "const_1_to_63_operand")])
858
859 ;; Input operand predicate for arithmetic left shifts.
860 (define_mode_attr ashl_input_operand
861         [(QI "nonimmediate_operand")
862          (HI "nonimmediate_operand")
863          (SI "nonimmediate_operand")
864          (DI "ashldi_input_operand")
865          (TI "reg_or_pm1_operand")])
866
867 ;; SSE and x87 SFmode and DFmode floating point modes
868 (define_mode_iterator MODEF [SF DF])
869
870 ;; All x87 floating point modes
871 (define_mode_iterator X87MODEF [SF DF XF])
872
873 ;; All integer modes handled by x87 fisttp operator.
874 (define_mode_iterator X87MODEI [HI SI DI])
875
876 ;; All integer modes handled by integer x87 operators.
877 (define_mode_iterator X87MODEI12 [HI SI])
878
879 ;; All integer modes handled by SSE cvtts?2si* operators.
880 (define_mode_iterator SSEMODEI24 [SI DI])
881
882 ;; SSE asm suffix for floating point modes
883 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
884
885 ;; SSE vector mode corresponding to a scalar mode
886 (define_mode_attr ssevecmode
887   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
888
889 ;; Instruction suffix for REX 64bit operators.
890 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
891
892 ;; This mode iterator allows :P to be used for patterns that operate on
893 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
894 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
895 \f
896 ;; Scheduling descriptions
897
898 (include "pentium.md")
899 (include "ppro.md")
900 (include "k6.md")
901 (include "athlon.md")
902 (include "geode.md")
903 (include "atom.md")
904
905 \f
906 ;; Operand and operator predicates and constraints
907
908 (include "predicates.md")
909 (include "constraints.md")
910
911 \f
912 ;; Compare and branch/compare and store instructions.
913
914 (define_expand "cbranch<mode>4"
915   [(set (reg:CC FLAGS_REG)
916         (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
917                     (match_operand:SDWIM 2 "<general_operand>" "")))
918    (set (pc) (if_then_else
919                (match_operator 0 "comparison_operator"
920                 [(reg:CC FLAGS_REG) (const_int 0)])
921                (label_ref (match_operand 3 "" ""))
922                (pc)))]
923   ""
924 {
925   if (MEM_P (operands[1]) && MEM_P (operands[2]))
926     operands[1] = force_reg (<MODE>mode, operands[1]);
927   ix86_compare_op0 = operands[1];
928   ix86_compare_op1 = operands[2];
929   ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
930   DONE;
931 })
932
933 (define_expand "cstore<mode>4"
934   [(set (reg:CC FLAGS_REG)
935         (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
936                     (match_operand:SWIM 3 "<general_operand>" "")))
937    (set (match_operand:QI 0 "register_operand" "")
938         (match_operator 1 "comparison_operator"
939           [(reg:CC FLAGS_REG) (const_int 0)]))]
940   ""
941 {
942   if (MEM_P (operands[2]) && MEM_P (operands[3]))
943     operands[2] = force_reg (<MODE>mode, operands[2]);
944   ix86_compare_op0 = operands[2];
945   ix86_compare_op1 = operands[3];
946   ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
947   DONE;
948 })
949
950 (define_expand "cmp<mode>_1"
951   [(set (reg:CC FLAGS_REG)
952         (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
953                     (match_operand:SWI48 1 "<general_operand>" "")))]
954   ""
955   "")
956
957 (define_insn "*cmp<mode>_ccno_1"
958   [(set (reg FLAGS_REG)
959         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
960                  (match_operand:SWI 1 "const0_operand" "")))]
961   "ix86_match_ccmode (insn, CCNOmode)"
962   "@
963    test{<imodesuffix>}\t%0, %0
964    cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
965   [(set_attr "type" "test,icmp")
966    (set_attr "length_immediate" "0,1")
967    (set_attr "mode" "<MODE>")])
968
969 (define_insn "*cmp<mode>_1"
970   [(set (reg FLAGS_REG)
971         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
972                  (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
973   "ix86_match_ccmode (insn, CCmode)"
974   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
975   [(set_attr "type" "icmp")
976    (set_attr "mode" "<MODE>")])
977
978 (define_insn "*cmp<mode>_minus_1"
979   [(set (reg FLAGS_REG)
980         (compare
981           (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
982                      (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
983           (const_int 0)))]
984   "ix86_match_ccmode (insn, CCGOCmode)"
985   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
986   [(set_attr "type" "icmp")
987    (set_attr "mode" "<MODE>")])
988
989 (define_insn "*cmpqi_ext_1"
990   [(set (reg FLAGS_REG)
991         (compare
992           (match_operand:QI 0 "general_operand" "Qm")
993           (subreg:QI
994             (zero_extract:SI
995               (match_operand 1 "ext_register_operand" "Q")
996               (const_int 8)
997               (const_int 8)) 0)))]
998   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
999   "cmp{b}\t{%h1, %0|%0, %h1}"
1000   [(set_attr "type" "icmp")
1001    (set_attr "mode" "QI")])
1002
1003 (define_insn "*cmpqi_ext_1_rex64"
1004   [(set (reg FLAGS_REG)
1005         (compare
1006           (match_operand:QI 0 "register_operand" "Q")
1007           (subreg:QI
1008             (zero_extract:SI
1009               (match_operand 1 "ext_register_operand" "Q")
1010               (const_int 8)
1011               (const_int 8)) 0)))]
1012   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1013   "cmp{b}\t{%h1, %0|%0, %h1}"
1014   [(set_attr "type" "icmp")
1015    (set_attr "mode" "QI")])
1016
1017 (define_insn "*cmpqi_ext_2"
1018   [(set (reg FLAGS_REG)
1019         (compare
1020           (subreg:QI
1021             (zero_extract:SI
1022               (match_operand 0 "ext_register_operand" "Q")
1023               (const_int 8)
1024               (const_int 8)) 0)
1025           (match_operand:QI 1 "const0_operand" "")))]
1026   "ix86_match_ccmode (insn, CCNOmode)"
1027   "test{b}\t%h0, %h0"
1028   [(set_attr "type" "test")
1029    (set_attr "length_immediate" "0")
1030    (set_attr "mode" "QI")])
1031
1032 (define_expand "cmpqi_ext_3"
1033   [(set (reg:CC FLAGS_REG)
1034         (compare:CC
1035           (subreg:QI
1036             (zero_extract:SI
1037               (match_operand 0 "ext_register_operand" "")
1038               (const_int 8)
1039               (const_int 8)) 0)
1040           (match_operand:QI 1 "immediate_operand" "")))]
1041   ""
1042   "")
1043
1044 (define_insn "*cmpqi_ext_3_insn"
1045   [(set (reg FLAGS_REG)
1046         (compare
1047           (subreg:QI
1048             (zero_extract:SI
1049               (match_operand 0 "ext_register_operand" "Q")
1050               (const_int 8)
1051               (const_int 8)) 0)
1052           (match_operand:QI 1 "general_operand" "Qmn")))]
1053   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1054   "cmp{b}\t{%1, %h0|%h0, %1}"
1055   [(set_attr "type" "icmp")
1056    (set_attr "modrm" "1")
1057    (set_attr "mode" "QI")])
1058
1059 (define_insn "*cmpqi_ext_3_insn_rex64"
1060   [(set (reg FLAGS_REG)
1061         (compare
1062           (subreg:QI
1063             (zero_extract:SI
1064               (match_operand 0 "ext_register_operand" "Q")
1065               (const_int 8)
1066               (const_int 8)) 0)
1067           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1068   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1069   "cmp{b}\t{%1, %h0|%h0, %1}"
1070   [(set_attr "type" "icmp")
1071    (set_attr "modrm" "1")
1072    (set_attr "mode" "QI")])
1073
1074 (define_insn "*cmpqi_ext_4"
1075   [(set (reg FLAGS_REG)
1076         (compare
1077           (subreg:QI
1078             (zero_extract:SI
1079               (match_operand 0 "ext_register_operand" "Q")
1080               (const_int 8)
1081               (const_int 8)) 0)
1082           (subreg:QI
1083             (zero_extract:SI
1084               (match_operand 1 "ext_register_operand" "Q")
1085               (const_int 8)
1086               (const_int 8)) 0)))]
1087   "ix86_match_ccmode (insn, CCmode)"
1088   "cmp{b}\t{%h1, %h0|%h0, %h1}"
1089   [(set_attr "type" "icmp")
1090    (set_attr "mode" "QI")])
1091
1092 ;; These implement float point compares.
1093 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1094 ;; which would allow mix and match FP modes on the compares.  Which is what
1095 ;; the old patterns did, but with many more of them.
1096
1097 (define_expand "cbranchxf4"
1098   [(set (reg:CC FLAGS_REG)
1099         (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1100                     (match_operand:XF 2 "nonmemory_operand" "")))
1101    (set (pc) (if_then_else
1102               (match_operator 0 "ix86_fp_comparison_operator"
1103                [(reg:CC FLAGS_REG)
1104                 (const_int 0)])
1105               (label_ref (match_operand 3 "" ""))
1106               (pc)))]
1107   "TARGET_80387"
1108 {
1109   ix86_compare_op0 = operands[1];
1110   ix86_compare_op1 = operands[2];
1111   ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1112   DONE;
1113 })
1114
1115 (define_expand "cstorexf4"
1116   [(set (reg:CC FLAGS_REG)
1117         (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1118                     (match_operand:XF 3 "nonmemory_operand" "")))
1119    (set (match_operand:QI 0 "register_operand" "")
1120               (match_operator 1 "ix86_fp_comparison_operator"
1121                [(reg:CC FLAGS_REG)
1122                 (const_int 0)]))]
1123   "TARGET_80387"
1124 {
1125   ix86_compare_op0 = operands[2];
1126   ix86_compare_op1 = operands[3];
1127   ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1128   DONE;
1129 })
1130
1131 (define_expand "cbranch<mode>4"
1132   [(set (reg:CC FLAGS_REG)
1133         (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1134                     (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1135    (set (pc) (if_then_else
1136               (match_operator 0 "ix86_fp_comparison_operator"
1137                [(reg:CC FLAGS_REG)
1138                 (const_int 0)])
1139               (label_ref (match_operand 3 "" ""))
1140               (pc)))]
1141   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1142 {
1143   ix86_compare_op0 = operands[1];
1144   ix86_compare_op1 = operands[2];
1145   ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1146   DONE;
1147 })
1148
1149 (define_expand "cstore<mode>4"
1150   [(set (reg:CC FLAGS_REG)
1151         (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1152                     (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1153    (set (match_operand:QI 0 "register_operand" "")
1154               (match_operator 1 "ix86_fp_comparison_operator"
1155                [(reg:CC FLAGS_REG)
1156                 (const_int 0)]))]
1157   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1158 {
1159   ix86_compare_op0 = operands[2];
1160   ix86_compare_op1 = operands[3];
1161   ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1162   DONE;
1163 })
1164
1165 (define_expand "cbranchcc4"
1166   [(set (pc) (if_then_else
1167               (match_operator 0 "comparison_operator"
1168                [(match_operand 1 "flags_reg_operand" "")
1169                 (match_operand 2 "const0_operand" "")])
1170               (label_ref (match_operand 3 "" ""))
1171               (pc)))]
1172   ""
1173 {
1174   ix86_compare_op0 = operands[1];
1175   ix86_compare_op1 = operands[2];
1176   ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1177   DONE;
1178 })
1179
1180 (define_expand "cstorecc4"
1181   [(set (match_operand:QI 0 "register_operand" "")
1182               (match_operator 1 "comparison_operator"
1183                [(match_operand 2 "flags_reg_operand" "")
1184                 (match_operand 3 "const0_operand" "")]))]
1185   ""
1186 {
1187   ix86_compare_op0 = operands[2];
1188   ix86_compare_op1 = operands[3];
1189   ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1190   DONE;
1191 })
1192
1193
1194 ;; FP compares, step 1:
1195 ;; Set the FP condition codes.
1196 ;;
1197 ;; CCFPmode     compare with exceptions
1198 ;; CCFPUmode    compare with no exceptions
1199
1200 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1201 ;; used to manage the reg stack popping would not be preserved.
1202
1203 (define_insn "*cmpfp_0"
1204   [(set (match_operand:HI 0 "register_operand" "=a")
1205         (unspec:HI
1206           [(compare:CCFP
1207              (match_operand 1 "register_operand" "f")
1208              (match_operand 2 "const0_operand" ""))]
1209         UNSPEC_FNSTSW))]
1210   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1211    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1212   "* return output_fp_compare (insn, operands, 0, 0);"
1213   [(set_attr "type" "multi")
1214    (set_attr "unit" "i387")
1215    (set (attr "mode")
1216      (cond [(match_operand:SF 1 "" "")
1217               (const_string "SF")
1218             (match_operand:DF 1 "" "")
1219               (const_string "DF")
1220            ]
1221            (const_string "XF")))])
1222
1223 (define_insn_and_split "*cmpfp_0_cc"
1224   [(set (reg:CCFP FLAGS_REG)
1225         (compare:CCFP
1226           (match_operand 1 "register_operand" "f")
1227           (match_operand 2 "const0_operand" "")))
1228    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1229   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1230    && TARGET_SAHF && !TARGET_CMOVE
1231    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1232   "#"
1233   "&& reload_completed"
1234   [(set (match_dup 0)
1235         (unspec:HI
1236           [(compare:CCFP (match_dup 1)(match_dup 2))]
1237         UNSPEC_FNSTSW))
1238    (set (reg:CC FLAGS_REG)
1239         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1240   ""
1241   [(set_attr "type" "multi")
1242    (set_attr "unit" "i387")
1243    (set (attr "mode")
1244      (cond [(match_operand:SF 1 "" "")
1245               (const_string "SF")
1246             (match_operand:DF 1 "" "")
1247               (const_string "DF")
1248            ]
1249            (const_string "XF")))])
1250
1251 (define_insn "*cmpfp_xf"
1252   [(set (match_operand:HI 0 "register_operand" "=a")
1253         (unspec:HI
1254           [(compare:CCFP
1255              (match_operand:XF 1 "register_operand" "f")
1256              (match_operand:XF 2 "register_operand" "f"))]
1257           UNSPEC_FNSTSW))]
1258   "TARGET_80387"
1259   "* return output_fp_compare (insn, operands, 0, 0);"
1260   [(set_attr "type" "multi")
1261    (set_attr "unit" "i387")
1262    (set_attr "mode" "XF")])
1263
1264 (define_insn_and_split "*cmpfp_xf_cc"
1265   [(set (reg:CCFP FLAGS_REG)
1266         (compare:CCFP
1267           (match_operand:XF 1 "register_operand" "f")
1268           (match_operand:XF 2 "register_operand" "f")))
1269    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1270   "TARGET_80387
1271    && TARGET_SAHF && !TARGET_CMOVE"
1272   "#"
1273   "&& reload_completed"
1274   [(set (match_dup 0)
1275         (unspec:HI
1276           [(compare:CCFP (match_dup 1)(match_dup 2))]
1277         UNSPEC_FNSTSW))
1278    (set (reg:CC FLAGS_REG)
1279         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1280   ""
1281   [(set_attr "type" "multi")
1282    (set_attr "unit" "i387")
1283    (set_attr "mode" "XF")])
1284
1285 (define_insn "*cmpfp_<mode>"
1286   [(set (match_operand:HI 0 "register_operand" "=a")
1287         (unspec:HI
1288           [(compare:CCFP
1289              (match_operand:MODEF 1 "register_operand" "f")
1290              (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1291           UNSPEC_FNSTSW))]
1292   "TARGET_80387"
1293   "* return output_fp_compare (insn, operands, 0, 0);"
1294   [(set_attr "type" "multi")
1295    (set_attr "unit" "i387")
1296    (set_attr "mode" "<MODE>")])
1297
1298 (define_insn_and_split "*cmpfp_<mode>_cc"
1299   [(set (reg:CCFP FLAGS_REG)
1300         (compare:CCFP
1301           (match_operand:MODEF 1 "register_operand" "f")
1302           (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1303    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1304   "TARGET_80387
1305    && TARGET_SAHF && !TARGET_CMOVE"
1306   "#"
1307   "&& reload_completed"
1308   [(set (match_dup 0)
1309         (unspec:HI
1310           [(compare:CCFP (match_dup 1)(match_dup 2))]
1311         UNSPEC_FNSTSW))
1312    (set (reg:CC FLAGS_REG)
1313         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1314   ""
1315   [(set_attr "type" "multi")
1316    (set_attr "unit" "i387")
1317    (set_attr "mode" "<MODE>")])
1318
1319 (define_insn "*cmpfp_u"
1320   [(set (match_operand:HI 0 "register_operand" "=a")
1321         (unspec:HI
1322           [(compare:CCFPU
1323              (match_operand 1 "register_operand" "f")
1324              (match_operand 2 "register_operand" "f"))]
1325           UNSPEC_FNSTSW))]
1326   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1327    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1328   "* return output_fp_compare (insn, operands, 0, 1);"
1329   [(set_attr "type" "multi")
1330    (set_attr "unit" "i387")
1331    (set (attr "mode")
1332      (cond [(match_operand:SF 1 "" "")
1333               (const_string "SF")
1334             (match_operand:DF 1 "" "")
1335               (const_string "DF")
1336            ]
1337            (const_string "XF")))])
1338
1339 (define_insn_and_split "*cmpfp_u_cc"
1340   [(set (reg:CCFPU FLAGS_REG)
1341         (compare:CCFPU
1342           (match_operand 1 "register_operand" "f")
1343           (match_operand 2 "register_operand" "f")))
1344    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1345   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1346    && TARGET_SAHF && !TARGET_CMOVE
1347    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1348   "#"
1349   "&& reload_completed"
1350   [(set (match_dup 0)
1351         (unspec:HI
1352           [(compare:CCFPU (match_dup 1)(match_dup 2))]
1353         UNSPEC_FNSTSW))
1354    (set (reg:CC FLAGS_REG)
1355         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1356   ""
1357   [(set_attr "type" "multi")
1358    (set_attr "unit" "i387")
1359    (set (attr "mode")
1360      (cond [(match_operand:SF 1 "" "")
1361               (const_string "SF")
1362             (match_operand:DF 1 "" "")
1363               (const_string "DF")
1364            ]
1365            (const_string "XF")))])
1366
1367 (define_insn "*cmpfp_<mode>"
1368   [(set (match_operand:HI 0 "register_operand" "=a")
1369         (unspec:HI
1370           [(compare:CCFP
1371              (match_operand 1 "register_operand" "f")
1372              (match_operator 3 "float_operator"
1373                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1374           UNSPEC_FNSTSW))]
1375   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1376    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1377    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1378   "* return output_fp_compare (insn, operands, 0, 0);"
1379   [(set_attr "type" "multi")
1380    (set_attr "unit" "i387")
1381    (set_attr "fp_int_src" "true")
1382    (set_attr "mode" "<MODE>")])
1383
1384 (define_insn_and_split "*cmpfp_<mode>_cc"
1385   [(set (reg:CCFP FLAGS_REG)
1386         (compare:CCFP
1387           (match_operand 1 "register_operand" "f")
1388           (match_operator 3 "float_operator"
1389             [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1390    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1391   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1392    && TARGET_SAHF && !TARGET_CMOVE
1393    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1394    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1395   "#"
1396   "&& reload_completed"
1397   [(set (match_dup 0)
1398         (unspec:HI
1399           [(compare:CCFP
1400              (match_dup 1)
1401              (match_op_dup 3 [(match_dup 2)]))]
1402         UNSPEC_FNSTSW))
1403    (set (reg:CC FLAGS_REG)
1404         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1405   ""
1406   [(set_attr "type" "multi")
1407    (set_attr "unit" "i387")
1408    (set_attr "fp_int_src" "true")
1409    (set_attr "mode" "<MODE>")])
1410
1411 ;; FP compares, step 2
1412 ;; Move the fpsw to ax.
1413
1414 (define_insn "x86_fnstsw_1"
1415   [(set (match_operand:HI 0 "register_operand" "=a")
1416         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1417   "TARGET_80387"
1418   "fnstsw\t%0"
1419   [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1420    (set_attr "mode" "SI")
1421    (set_attr "unit" "i387")])
1422
1423 ;; FP compares, step 3
1424 ;; Get ax into flags, general case.
1425
1426 (define_insn "x86_sahf_1"
1427   [(set (reg:CC FLAGS_REG)
1428         (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1429                    UNSPEC_SAHF))]
1430   "TARGET_SAHF"
1431 {
1432 #ifndef HAVE_AS_IX86_SAHF
1433   if (TARGET_64BIT)
1434     return ASM_BYTE "0x9e";
1435   else
1436 #endif
1437   return "sahf";
1438 }
1439   [(set_attr "length" "1")
1440    (set_attr "athlon_decode" "vector")
1441    (set_attr "amdfam10_decode" "direct")
1442    (set_attr "mode" "SI")])
1443
1444 ;; Pentium Pro can do steps 1 through 3 in one go.
1445 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1446 (define_insn "*cmpfp_i_mixed"
1447   [(set (reg:CCFP FLAGS_REG)
1448         (compare:CCFP (match_operand 0 "register_operand" "f,x")
1449                       (match_operand 1 "nonimmediate_operand" "f,xm")))]
1450   "TARGET_MIX_SSE_I387
1451    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1452    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1453   "* return output_fp_compare (insn, operands, 1, 0);"
1454   [(set_attr "type" "fcmp,ssecomi")
1455    (set_attr "prefix" "orig,maybe_vex")
1456    (set (attr "mode")
1457      (if_then_else (match_operand:SF 1 "" "")
1458         (const_string "SF")
1459         (const_string "DF")))
1460    (set (attr "prefix_rep")
1461         (if_then_else (eq_attr "type" "ssecomi")
1462                       (const_string "0")
1463                       (const_string "*")))
1464    (set (attr "prefix_data16")
1465         (cond [(eq_attr "type" "fcmp")
1466                  (const_string "*")
1467                (eq_attr "mode" "DF")
1468                  (const_string "1")
1469               ]
1470               (const_string "0")))
1471    (set_attr "athlon_decode" "vector")
1472    (set_attr "amdfam10_decode" "direct")])
1473
1474 (define_insn "*cmpfp_i_sse"
1475   [(set (reg:CCFP FLAGS_REG)
1476         (compare:CCFP (match_operand 0 "register_operand" "x")
1477                       (match_operand 1 "nonimmediate_operand" "xm")))]
1478   "TARGET_SSE_MATH
1479    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1480    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1481   "* return output_fp_compare (insn, operands, 1, 0);"
1482   [(set_attr "type" "ssecomi")
1483    (set_attr "prefix" "maybe_vex")
1484    (set (attr "mode")
1485      (if_then_else (match_operand:SF 1 "" "")
1486         (const_string "SF")
1487         (const_string "DF")))
1488    (set_attr "prefix_rep" "0")
1489    (set (attr "prefix_data16")
1490         (if_then_else (eq_attr "mode" "DF")
1491                       (const_string "1")
1492                       (const_string "0")))
1493    (set_attr "athlon_decode" "vector")
1494    (set_attr "amdfam10_decode" "direct")])
1495
1496 (define_insn "*cmpfp_i_i387"
1497   [(set (reg:CCFP FLAGS_REG)
1498         (compare:CCFP (match_operand 0 "register_operand" "f")
1499                       (match_operand 1 "register_operand" "f")))]
1500   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1501    && TARGET_CMOVE
1502    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1503    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1504   "* return output_fp_compare (insn, operands, 1, 0);"
1505   [(set_attr "type" "fcmp")
1506    (set (attr "mode")
1507      (cond [(match_operand:SF 1 "" "")
1508               (const_string "SF")
1509             (match_operand:DF 1 "" "")
1510               (const_string "DF")
1511            ]
1512            (const_string "XF")))
1513    (set_attr "athlon_decode" "vector")
1514    (set_attr "amdfam10_decode" "direct")])
1515
1516 (define_insn "*cmpfp_iu_mixed"
1517   [(set (reg:CCFPU FLAGS_REG)
1518         (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1519                        (match_operand 1 "nonimmediate_operand" "f,xm")))]
1520   "TARGET_MIX_SSE_I387
1521    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1522    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1523   "* return output_fp_compare (insn, operands, 1, 1);"
1524   [(set_attr "type" "fcmp,ssecomi")
1525    (set_attr "prefix" "orig,maybe_vex")
1526    (set (attr "mode")
1527      (if_then_else (match_operand:SF 1 "" "")
1528         (const_string "SF")
1529         (const_string "DF")))
1530    (set (attr "prefix_rep")
1531         (if_then_else (eq_attr "type" "ssecomi")
1532                       (const_string "0")
1533                       (const_string "*")))
1534    (set (attr "prefix_data16")
1535         (cond [(eq_attr "type" "fcmp")
1536                  (const_string "*")
1537                (eq_attr "mode" "DF")
1538                  (const_string "1")
1539               ]
1540               (const_string "0")))
1541    (set_attr "athlon_decode" "vector")
1542    (set_attr "amdfam10_decode" "direct")])
1543
1544 (define_insn "*cmpfp_iu_sse"
1545   [(set (reg:CCFPU FLAGS_REG)
1546         (compare:CCFPU (match_operand 0 "register_operand" "x")
1547                        (match_operand 1 "nonimmediate_operand" "xm")))]
1548   "TARGET_SSE_MATH
1549    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1550    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1551   "* return output_fp_compare (insn, operands, 1, 1);"
1552   [(set_attr "type" "ssecomi")
1553    (set_attr "prefix" "maybe_vex")
1554    (set (attr "mode")
1555      (if_then_else (match_operand:SF 1 "" "")
1556         (const_string "SF")
1557         (const_string "DF")))
1558    (set_attr "prefix_rep" "0")
1559    (set (attr "prefix_data16")
1560         (if_then_else (eq_attr "mode" "DF")
1561                       (const_string "1")
1562                       (const_string "0")))
1563    (set_attr "athlon_decode" "vector")
1564    (set_attr "amdfam10_decode" "direct")])
1565
1566 (define_insn "*cmpfp_iu_387"
1567   [(set (reg:CCFPU FLAGS_REG)
1568         (compare:CCFPU (match_operand 0 "register_operand" "f")
1569                        (match_operand 1 "register_operand" "f")))]
1570   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1571    && TARGET_CMOVE
1572    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1573    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1574   "* return output_fp_compare (insn, operands, 1, 1);"
1575   [(set_attr "type" "fcmp")
1576    (set (attr "mode")
1577      (cond [(match_operand:SF 1 "" "")
1578               (const_string "SF")
1579             (match_operand:DF 1 "" "")
1580               (const_string "DF")
1581            ]
1582            (const_string "XF")))
1583    (set_attr "athlon_decode" "vector")
1584    (set_attr "amdfam10_decode" "direct")])
1585 \f
1586 ;; Move instructions.
1587
1588 ;; General case of fullword move.
1589
1590 (define_expand "movsi"
1591   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1592         (match_operand:SI 1 "general_operand" ""))]
1593   ""
1594   "ix86_expand_move (SImode, operands); DONE;")
1595
1596 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1597 ;; general_operand.
1598 ;;
1599 ;; %%% We don't use a post-inc memory reference because x86 is not a
1600 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1601 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1602 ;; targets without our curiosities, and it is just as easy to represent
1603 ;; this differently.
1604
1605 (define_insn "*pushsi2"
1606   [(set (match_operand:SI 0 "push_operand" "=<")
1607         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1608   "!TARGET_64BIT"
1609   "push{l}\t%1"
1610   [(set_attr "type" "push")
1611    (set_attr "mode" "SI")])
1612
1613 ;; For 64BIT abi we always round up to 8 bytes.
1614 (define_insn "*pushsi2_rex64"
1615   [(set (match_operand:SI 0 "push_operand" "=X")
1616         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1617   "TARGET_64BIT"
1618   "push{q}\t%q1"
1619   [(set_attr "type" "push")
1620    (set_attr "mode" "SI")])
1621
1622 (define_insn "*pushsi2_prologue"
1623   [(set (match_operand:SI 0 "push_operand" "=<")
1624         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1625    (clobber (mem:BLK (scratch)))]
1626   "!TARGET_64BIT"
1627   "push{l}\t%1"
1628   [(set_attr "type" "push")
1629    (set_attr "mode" "SI")])
1630
1631 (define_insn "*popsi1_epilogue"
1632   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1633         (mem:SI (reg:SI SP_REG)))
1634    (set (reg:SI SP_REG)
1635         (plus:SI (reg:SI SP_REG) (const_int 4)))
1636    (clobber (mem:BLK (scratch)))]
1637   "!TARGET_64BIT"
1638   "pop{l}\t%0"
1639   [(set_attr "type" "pop")
1640    (set_attr "mode" "SI")])
1641
1642 (define_insn "popsi1"
1643   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1644         (mem:SI (reg:SI SP_REG)))
1645    (set (reg:SI SP_REG)
1646         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1647   "!TARGET_64BIT"
1648   "pop{l}\t%0"
1649   [(set_attr "type" "pop")
1650    (set_attr "mode" "SI")])
1651
1652 (define_insn "*movsi_xor"
1653   [(set (match_operand:SI 0 "register_operand" "=r")
1654         (match_operand:SI 1 "const0_operand" ""))
1655    (clobber (reg:CC FLAGS_REG))]
1656   "reload_completed"
1657   "xor{l}\t%0, %0"
1658   [(set_attr "type" "alu1")
1659    (set_attr "mode" "SI")
1660    (set_attr "length_immediate" "0")])
1661
1662 (define_insn "*movsi_or"
1663   [(set (match_operand:SI 0 "register_operand" "=r")
1664         (match_operand:SI 1 "immediate_operand" "i"))
1665    (clobber (reg:CC FLAGS_REG))]
1666   "reload_completed
1667    && operands[1] == constm1_rtx"
1668 {
1669   operands[1] = constm1_rtx;
1670   return "or{l}\t{%1, %0|%0, %1}";
1671 }
1672   [(set_attr "type" "alu1")
1673    (set_attr "mode" "SI")
1674    (set_attr "length_immediate" "1")])
1675
1676 (define_insn "*movsi_1"
1677   [(set (match_operand:SI 0 "nonimmediate_operand"
1678                         "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1679         (match_operand:SI 1 "general_operand"
1680                         "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r   ,m "))]
1681   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1682 {
1683   switch (get_attr_type (insn))
1684     {
1685     case TYPE_SSELOG1:
1686       if (get_attr_mode (insn) == MODE_TI)
1687         return "%vpxor\t%0, %d0";
1688       return "%vxorps\t%0, %d0";
1689
1690     case TYPE_SSEMOV:
1691       switch (get_attr_mode (insn))
1692         {
1693         case MODE_TI:
1694           return "%vmovdqa\t{%1, %0|%0, %1}";
1695         case MODE_V4SF:
1696           return "%vmovaps\t{%1, %0|%0, %1}";
1697         case MODE_SI:
1698           return "%vmovd\t{%1, %0|%0, %1}";
1699         case MODE_SF:
1700           return "%vmovss\t{%1, %0|%0, %1}";
1701         default:
1702           gcc_unreachable ();
1703         }
1704
1705     case TYPE_MMX:
1706       return "pxor\t%0, %0";
1707
1708     case TYPE_MMXMOV:
1709       if (get_attr_mode (insn) == MODE_DI)
1710         return "movq\t{%1, %0|%0, %1}";
1711       return "movd\t{%1, %0|%0, %1}";
1712
1713     case TYPE_LEA:
1714       return "lea{l}\t{%a1, %0|%0, %a1}";
1715
1716     default:
1717       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1718       return "mov{l}\t{%1, %0|%0, %1}";
1719     }
1720 }
1721   [(set (attr "type")
1722      (cond [(eq_attr "alternative" "2")
1723               (const_string "mmx")
1724             (eq_attr "alternative" "3,4,5")
1725               (const_string "mmxmov")
1726             (eq_attr "alternative" "6")
1727               (const_string "sselog1")
1728             (eq_attr "alternative" "7,8,9,10,11")
1729               (const_string "ssemov")
1730             (match_operand:DI 1 "pic_32bit_operand" "")
1731               (const_string "lea")
1732            ]
1733            (const_string "imov")))
1734    (set (attr "prefix")
1735      (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
1736        (const_string "orig")
1737        (const_string "maybe_vex")))
1738    (set (attr "prefix_data16")
1739      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
1740        (const_string "1")
1741        (const_string "*")))
1742    (set (attr "mode")
1743      (cond [(eq_attr "alternative" "2,3")
1744               (const_string "DI")
1745             (eq_attr "alternative" "6,7")
1746               (if_then_else
1747                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1748                 (const_string "V4SF")
1749                 (const_string "TI"))
1750             (and (eq_attr "alternative" "8,9,10,11")
1751                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1752               (const_string "SF")
1753            ]
1754            (const_string "SI")))])
1755
1756 ;; Stores and loads of ax to arbitrary constant address.
1757 ;; We fake an second form of instruction to force reload to load address
1758 ;; into register when rax is not available
1759 (define_insn "*movabssi_1_rex64"
1760   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1761         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1762   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1763   "@
1764    movabs{l}\t{%1, %P0|%P0, %1}
1765    mov{l}\t{%1, %a0|%a0, %1}"
1766   [(set_attr "type" "imov")
1767    (set_attr "modrm" "0,*")
1768    (set_attr "length_address" "8,0")
1769    (set_attr "length_immediate" "0,*")
1770    (set_attr "memory" "store")
1771    (set_attr "mode" "SI")])
1772
1773 (define_insn "*movabssi_2_rex64"
1774   [(set (match_operand:SI 0 "register_operand" "=a,r")
1775         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1776   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1777   "@
1778    movabs{l}\t{%P1, %0|%0, %P1}
1779    mov{l}\t{%a1, %0|%0, %a1}"
1780   [(set_attr "type" "imov")
1781    (set_attr "modrm" "0,*")
1782    (set_attr "length_address" "8,0")
1783    (set_attr "length_immediate" "0")
1784    (set_attr "memory" "load")
1785    (set_attr "mode" "SI")])
1786
1787 (define_insn "*swapsi"
1788   [(set (match_operand:SI 0 "register_operand" "+r")
1789         (match_operand:SI 1 "register_operand" "+r"))
1790    (set (match_dup 1)
1791         (match_dup 0))]
1792   ""
1793   "xchg{l}\t%1, %0"
1794   [(set_attr "type" "imov")
1795    (set_attr "mode" "SI")
1796    (set_attr "pent_pair" "np")
1797    (set_attr "athlon_decode" "vector")
1798    (set_attr "amdfam10_decode" "double")])
1799
1800 (define_expand "movhi"
1801   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1802         (match_operand:HI 1 "general_operand" ""))]
1803   ""
1804   "ix86_expand_move (HImode, operands); DONE;")
1805
1806 (define_insn "*pushhi2"
1807   [(set (match_operand:HI 0 "push_operand" "=X")
1808         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1809   "!TARGET_64BIT"
1810   "push{l}\t%k1"
1811   [(set_attr "type" "push")
1812    (set_attr "mode" "SI")])
1813
1814 ;; For 64BIT abi we always round up to 8 bytes.
1815 (define_insn "*pushhi2_rex64"
1816   [(set (match_operand:HI 0 "push_operand" "=X")
1817         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1818   "TARGET_64BIT"
1819   "push{q}\t%q1"
1820   [(set_attr "type" "push")
1821    (set_attr "mode" "DI")])
1822
1823 (define_insn "*movhi_1"
1824   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1825         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1826   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1827 {
1828   switch (get_attr_type (insn))
1829     {
1830     case TYPE_IMOVX:
1831       /* movzwl is faster than movw on p2 due to partial word stalls,
1832          though not as fast as an aligned movl.  */
1833       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1834     default:
1835       if (get_attr_mode (insn) == MODE_SI)
1836         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1837       else
1838         return "mov{w}\t{%1, %0|%0, %1}";
1839     }
1840 }
1841   [(set (attr "type")
1842      (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
1843               (const_string "imov")
1844             (and (eq_attr "alternative" "0")
1845                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1846                           (const_int 0))
1847                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1848                           (const_int 0))))
1849               (const_string "imov")
1850             (and (eq_attr "alternative" "1,2")
1851                  (match_operand:HI 1 "aligned_operand" ""))
1852               (const_string "imov")
1853             (and (ne (symbol_ref "TARGET_MOVX")
1854                      (const_int 0))
1855                  (eq_attr "alternative" "0,2"))
1856               (const_string "imovx")
1857            ]
1858            (const_string "imov")))
1859     (set (attr "mode")
1860       (cond [(eq_attr "type" "imovx")
1861                (const_string "SI")
1862              (and (eq_attr "alternative" "1,2")
1863                   (match_operand:HI 1 "aligned_operand" ""))
1864                (const_string "SI")
1865              (and (eq_attr "alternative" "0")
1866                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1867                            (const_int 0))
1868                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1869                            (const_int 0))))
1870                (const_string "SI")
1871             ]
1872             (const_string "HI")))])
1873
1874 ;; Stores and loads of ax to arbitrary constant address.
1875 ;; We fake an second form of instruction to force reload to load address
1876 ;; into register when rax is not available
1877 (define_insn "*movabshi_1_rex64"
1878   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1879         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1880   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1881   "@
1882    movabs{w}\t{%1, %P0|%P0, %1}
1883    mov{w}\t{%1, %a0|%a0, %1}"
1884   [(set_attr "type" "imov")
1885    (set_attr "modrm" "0,*")
1886    (set_attr "length_address" "8,0")
1887    (set_attr "length_immediate" "0,*")
1888    (set_attr "memory" "store")
1889    (set_attr "mode" "HI")])
1890
1891 (define_insn "*movabshi_2_rex64"
1892   [(set (match_operand:HI 0 "register_operand" "=a,r")
1893         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1894   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1895   "@
1896    movabs{w}\t{%P1, %0|%0, %P1}
1897    mov{w}\t{%a1, %0|%0, %a1}"
1898   [(set_attr "type" "imov")
1899    (set_attr "modrm" "0,*")
1900    (set_attr "length_address" "8,0")
1901    (set_attr "length_immediate" "0")
1902    (set_attr "memory" "load")
1903    (set_attr "mode" "HI")])
1904
1905 (define_insn "*swaphi_1"
1906   [(set (match_operand:HI 0 "register_operand" "+r")
1907         (match_operand:HI 1 "register_operand" "+r"))
1908    (set (match_dup 1)
1909         (match_dup 0))]
1910   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
1911   "xchg{l}\t%k1, %k0"
1912   [(set_attr "type" "imov")
1913    (set_attr "mode" "SI")
1914    (set_attr "pent_pair" "np")
1915    (set_attr "athlon_decode" "vector")
1916    (set_attr "amdfam10_decode" "double")])
1917
1918 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1919 (define_insn "*swaphi_2"
1920   [(set (match_operand:HI 0 "register_operand" "+r")
1921         (match_operand:HI 1 "register_operand" "+r"))
1922    (set (match_dup 1)
1923         (match_dup 0))]
1924   "TARGET_PARTIAL_REG_STALL"
1925   "xchg{w}\t%1, %0"
1926   [(set_attr "type" "imov")
1927    (set_attr "mode" "HI")
1928    (set_attr "pent_pair" "np")
1929    (set_attr "athlon_decode" "vector")])
1930
1931 (define_expand "movstricthi"
1932   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1933         (match_operand:HI 1 "general_operand" ""))]
1934   ""
1935 {
1936   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
1937     FAIL;
1938   /* Don't generate memory->memory moves, go through a register */
1939   if (MEM_P (operands[0]) && MEM_P (operands[1]))
1940     operands[1] = force_reg (HImode, operands[1]);
1941 })
1942
1943 (define_insn "*movstricthi_1"
1944   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1945         (match_operand:HI 1 "general_operand" "rn,m"))]
1946   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
1947    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1948   "mov{w}\t{%1, %0|%0, %1}"
1949   [(set_attr "type" "imov")
1950    (set_attr "mode" "HI")])
1951
1952 (define_insn "*movstricthi_xor"
1953   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1954         (match_operand:HI 1 "const0_operand" ""))
1955    (clobber (reg:CC FLAGS_REG))]
1956   "reload_completed"
1957   "xor{w}\t%0, %0"
1958   [(set_attr "type" "alu1")
1959    (set_attr "mode" "HI")
1960    (set_attr "length_immediate" "0")])
1961
1962 (define_expand "movqi"
1963   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1964         (match_operand:QI 1 "general_operand" ""))]
1965   ""
1966   "ix86_expand_move (QImode, operands); DONE;")
1967
1968 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1969 ;; "push a byte".  But actually we use pushl, which has the effect
1970 ;; of rounding the amount pushed up to a word.
1971
1972 (define_insn "*pushqi2"
1973   [(set (match_operand:QI 0 "push_operand" "=X")
1974         (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1975   "!TARGET_64BIT"
1976   "push{l}\t%k1"
1977   [(set_attr "type" "push")
1978    (set_attr "mode" "SI")])
1979
1980 ;; For 64BIT abi we always round up to 8 bytes.
1981 (define_insn "*pushqi2_rex64"
1982   [(set (match_operand:QI 0 "push_operand" "=X")
1983         (match_operand:QI 1 "nonmemory_no_elim_operand" "qn"))]
1984   "TARGET_64BIT"
1985   "push{q}\t%q1"
1986   [(set_attr "type" "push")
1987    (set_attr "mode" "DI")])
1988
1989 ;; Situation is quite tricky about when to choose full sized (SImode) move
1990 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1991 ;; partial register dependency machines (such as AMD Athlon), where QImode
1992 ;; moves issue extra dependency and for partial register stalls machines
1993 ;; that don't use QImode patterns (and QImode move cause stall on the next
1994 ;; instruction).
1995 ;;
1996 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1997 ;; register stall machines with, where we use QImode instructions, since
1998 ;; partial register stall can be caused there.  Then we use movzx.
1999 (define_insn "*movqi_1"
2000   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2001         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
2002   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2003 {
2004   switch (get_attr_type (insn))
2005     {
2006     case TYPE_IMOVX:
2007       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2008       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2009     default:
2010       if (get_attr_mode (insn) == MODE_SI)
2011         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2012       else
2013         return "mov{b}\t{%1, %0|%0, %1}";
2014     }
2015 }
2016   [(set (attr "type")
2017      (cond [(and (eq_attr "alternative" "5")
2018                  (not (match_operand:QI 1 "aligned_operand" "")))
2019               (const_string "imovx")
2020             (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
2021               (const_string "imov")
2022             (and (eq_attr "alternative" "3")
2023                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2024                           (const_int 0))
2025                       (eq (symbol_ref "TARGET_QIMODE_MATH")
2026                           (const_int 0))))
2027               (const_string "imov")
2028             (eq_attr "alternative" "3,5")
2029               (const_string "imovx")
2030             (and (ne (symbol_ref "TARGET_MOVX")
2031                      (const_int 0))
2032                  (eq_attr "alternative" "2"))
2033               (const_string "imovx")
2034            ]
2035            (const_string "imov")))
2036    (set (attr "mode")
2037       (cond [(eq_attr "alternative" "3,4,5")
2038                (const_string "SI")
2039              (eq_attr "alternative" "6")
2040                (const_string "QI")
2041              (eq_attr "type" "imovx")
2042                (const_string "SI")
2043              (and (eq_attr "type" "imov")
2044                   (and (eq_attr "alternative" "0,1")
2045                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
2046                                 (const_int 0))
2047                             (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2048                                      (const_int 0))
2049                                  (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2050                                      (const_int 0))))))
2051                (const_string "SI")
2052              ;; Avoid partial register stalls when not using QImode arithmetic
2053              (and (eq_attr "type" "imov")
2054                   (and (eq_attr "alternative" "0,1")
2055                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
2056                                 (const_int 0))
2057                             (eq (symbol_ref "TARGET_QIMODE_MATH")
2058                                 (const_int 0)))))
2059                (const_string "SI")
2060            ]
2061            (const_string "QI")))])
2062
2063 (define_insn "*swapqi_1"
2064   [(set (match_operand:QI 0 "register_operand" "+r")
2065         (match_operand:QI 1 "register_operand" "+r"))
2066    (set (match_dup 1)
2067         (match_dup 0))]
2068   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2069   "xchg{l}\t%k1, %k0"
2070   [(set_attr "type" "imov")
2071    (set_attr "mode" "SI")
2072    (set_attr "pent_pair" "np")
2073    (set_attr "athlon_decode" "vector")
2074    (set_attr "amdfam10_decode" "vector")])
2075
2076 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
2077 (define_insn "*swapqi_2"
2078   [(set (match_operand:QI 0 "register_operand" "+q")
2079         (match_operand:QI 1 "register_operand" "+q"))
2080    (set (match_dup 1)
2081         (match_dup 0))]
2082   "TARGET_PARTIAL_REG_STALL"
2083   "xchg{b}\t%1, %0"
2084   [(set_attr "type" "imov")
2085    (set_attr "mode" "QI")
2086    (set_attr "pent_pair" "np")
2087    (set_attr "athlon_decode" "vector")])
2088
2089 (define_expand "movstrictqi"
2090   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
2091         (match_operand:QI 1 "general_operand" ""))]
2092   ""
2093 {
2094   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2095     FAIL;
2096   /* Don't generate memory->memory moves, go through a register.  */
2097   if (MEM_P (operands[0]) && MEM_P (operands[1]))
2098     operands[1] = force_reg (QImode, operands[1]);
2099 })
2100
2101 (define_insn "*movstrictqi_1"
2102   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
2103         (match_operand:QI 1 "general_operand" "*qn,m"))]
2104   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2105    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2106   "mov{b}\t{%1, %0|%0, %1}"
2107   [(set_attr "type" "imov")
2108    (set_attr "mode" "QI")])
2109
2110 (define_insn "*movstrictqi_xor"
2111   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
2112         (match_operand:QI 1 "const0_operand" ""))
2113    (clobber (reg:CC FLAGS_REG))]
2114   "reload_completed"
2115   "xor{b}\t%0, %0"
2116   [(set_attr "type" "alu1")
2117    (set_attr "mode" "QI")
2118    (set_attr "length_immediate" "0")])
2119
2120 (define_insn "*movsi_extv_1"
2121   [(set (match_operand:SI 0 "register_operand" "=R")
2122         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
2123                          (const_int 8)
2124                          (const_int 8)))]
2125   ""
2126   "movs{bl|x}\t{%h1, %0|%0, %h1}"
2127   [(set_attr "type" "imovx")
2128    (set_attr "mode" "SI")])
2129
2130 (define_insn "*movhi_extv_1"
2131   [(set (match_operand:HI 0 "register_operand" "=R")
2132         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
2133                          (const_int 8)
2134                          (const_int 8)))]
2135   ""
2136   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2137   [(set_attr "type" "imovx")
2138    (set_attr "mode" "SI")])
2139
2140 (define_insn "*movqi_extv_1"
2141   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2142         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2143                          (const_int 8)
2144                          (const_int 8)))]
2145   "!TARGET_64BIT"
2146 {
2147   switch (get_attr_type (insn))
2148     {
2149     case TYPE_IMOVX:
2150       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2151     default:
2152       return "mov{b}\t{%h1, %0|%0, %h1}";
2153     }
2154 }
2155   [(set (attr "type")
2156      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2157                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2158                              (ne (symbol_ref "TARGET_MOVX")
2159                                  (const_int 0))))
2160         (const_string "imovx")
2161         (const_string "imov")))
2162    (set (attr "mode")
2163      (if_then_else (eq_attr "type" "imovx")
2164         (const_string "SI")
2165         (const_string "QI")))])
2166
2167 (define_insn "*movqi_extv_1_rex64"
2168   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2169         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2170                          (const_int 8)
2171                          (const_int 8)))]
2172   "TARGET_64BIT"
2173 {
2174   switch (get_attr_type (insn))
2175     {
2176     case TYPE_IMOVX:
2177       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2178     default:
2179       return "mov{b}\t{%h1, %0|%0, %h1}";
2180     }
2181 }
2182   [(set (attr "type")
2183      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2184                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2185                              (ne (symbol_ref "TARGET_MOVX")
2186                                  (const_int 0))))
2187         (const_string "imovx")
2188         (const_string "imov")))
2189    (set (attr "mode")
2190      (if_then_else (eq_attr "type" "imovx")
2191         (const_string "SI")
2192         (const_string "QI")))])
2193
2194 ;; Stores and loads of ax to arbitrary constant address.
2195 ;; We fake an second form of instruction to force reload to load address
2196 ;; into register when rax is not available
2197 (define_insn "*movabsqi_1_rex64"
2198   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2199         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
2200   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2201   "@
2202    movabs{b}\t{%1, %P0|%P0, %1}
2203    mov{b}\t{%1, %a0|%a0, %1}"
2204   [(set_attr "type" "imov")
2205    (set_attr "modrm" "0,*")
2206    (set_attr "length_address" "8,0")
2207    (set_attr "length_immediate" "0,*")
2208    (set_attr "memory" "store")
2209    (set_attr "mode" "QI")])
2210
2211 (define_insn "*movabsqi_2_rex64"
2212   [(set (match_operand:QI 0 "register_operand" "=a,r")
2213         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2214   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2215   "@
2216    movabs{b}\t{%P1, %0|%0, %P1}
2217    mov{b}\t{%a1, %0|%0, %a1}"
2218   [(set_attr "type" "imov")
2219    (set_attr "modrm" "0,*")
2220    (set_attr "length_address" "8,0")
2221    (set_attr "length_immediate" "0")
2222    (set_attr "memory" "load")
2223    (set_attr "mode" "QI")])
2224
2225 (define_insn "*movdi_extzv_1"
2226   [(set (match_operand:DI 0 "register_operand" "=R")
2227         (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
2228                          (const_int 8)
2229                          (const_int 8)))]
2230   "TARGET_64BIT"
2231   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2232   [(set_attr "type" "imovx")
2233    (set_attr "mode" "SI")])
2234
2235 (define_insn "*movsi_extzv_1"
2236   [(set (match_operand:SI 0 "register_operand" "=R")
2237         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
2238                          (const_int 8)
2239                          (const_int 8)))]
2240   ""
2241   "movz{bl|x}\t{%h1, %0|%0, %h1}"
2242   [(set_attr "type" "imovx")
2243    (set_attr "mode" "SI")])
2244
2245 (define_insn "*movqi_extzv_2"
2246   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2247         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2248                                     (const_int 8)
2249                                     (const_int 8)) 0))]
2250   "!TARGET_64BIT"
2251 {
2252   switch (get_attr_type (insn))
2253     {
2254     case TYPE_IMOVX:
2255       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2256     default:
2257       return "mov{b}\t{%h1, %0|%0, %h1}";
2258     }
2259 }
2260   [(set (attr "type")
2261      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2262                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2263                              (ne (symbol_ref "TARGET_MOVX")
2264                                  (const_int 0))))
2265         (const_string "imovx")
2266         (const_string "imov")))
2267    (set (attr "mode")
2268      (if_then_else (eq_attr "type" "imovx")
2269         (const_string "SI")
2270         (const_string "QI")))])
2271
2272 (define_insn "*movqi_extzv_2_rex64"
2273   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2274         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2275                                     (const_int 8)
2276                                     (const_int 8)) 0))]
2277   "TARGET_64BIT"
2278 {
2279   switch (get_attr_type (insn))
2280     {
2281     case TYPE_IMOVX:
2282       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2283     default:
2284       return "mov{b}\t{%h1, %0|%0, %h1}";
2285     }
2286 }
2287   [(set (attr "type")
2288      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2289                         (ne (symbol_ref "TARGET_MOVX")
2290                             (const_int 0)))
2291         (const_string "imovx")
2292         (const_string "imov")))
2293    (set (attr "mode")
2294      (if_then_else (eq_attr "type" "imovx")
2295         (const_string "SI")
2296         (const_string "QI")))])
2297
2298 (define_insn "movsi_insv_1"
2299   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2300                          (const_int 8)
2301                          (const_int 8))
2302         (match_operand:SI 1 "general_operand" "Qmn"))]
2303   "!TARGET_64BIT"
2304   "mov{b}\t{%b1, %h0|%h0, %b1}"
2305   [(set_attr "type" "imov")
2306    (set_attr "mode" "QI")])
2307
2308 (define_insn "*movsi_insv_1_rex64"
2309   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2310                          (const_int 8)
2311                          (const_int 8))
2312         (match_operand:SI 1 "nonmemory_operand" "Qn"))]
2313   "TARGET_64BIT"
2314   "mov{b}\t{%b1, %h0|%h0, %b1}"
2315   [(set_attr "type" "imov")
2316    (set_attr "mode" "QI")])
2317
2318 (define_insn "movdi_insv_1_rex64"
2319   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
2320                          (const_int 8)
2321                          (const_int 8))
2322         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
2323   "TARGET_64BIT"
2324   "mov{b}\t{%b1, %h0|%h0, %b1}"
2325   [(set_attr "type" "imov")
2326    (set_attr "mode" "QI")])
2327
2328 (define_insn "*movqi_insv_2"
2329   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2330                          (const_int 8)
2331                          (const_int 8))
2332         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2333                      (const_int 8)))]
2334   ""
2335   "mov{b}\t{%h1, %h0|%h0, %h1}"
2336   [(set_attr "type" "imov")
2337    (set_attr "mode" "QI")])
2338
2339 (define_expand "movdi"
2340   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2341         (match_operand:DI 1 "general_operand" ""))]
2342   ""
2343   "ix86_expand_move (DImode, operands); DONE;")
2344
2345 (define_insn "*pushdi"
2346   [(set (match_operand:DI 0 "push_operand" "=<")
2347         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
2348   "!TARGET_64BIT"
2349   "#")
2350
2351 (define_insn "*pushdi2_rex64"
2352   [(set (match_operand:DI 0 "push_operand" "=<,!<")
2353         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
2354   "TARGET_64BIT"
2355   "@
2356    push{q}\t%1
2357    #"
2358   [(set_attr "type" "push,multi")
2359    (set_attr "mode" "DI")])
2360
2361 ;; Convert impossible pushes of immediate to existing instructions.
2362 ;; First try to get scratch register and go through it.  In case this
2363 ;; fails, push sign extended lower part first and then overwrite
2364 ;; upper part by 32bit move.
2365 (define_peephole2
2366   [(match_scratch:DI 2 "r")
2367    (set (match_operand:DI 0 "push_operand" "")
2368         (match_operand:DI 1 "immediate_operand" ""))]
2369   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2370    && !x86_64_immediate_operand (operands[1], DImode)"
2371   [(set (match_dup 2) (match_dup 1))
2372    (set (match_dup 0) (match_dup 2))]
2373   "")
2374
2375 ;; We need to define this as both peepholer and splitter for case
2376 ;; peephole2 pass is not run.
2377 ;; "&& 1" is needed to keep it from matching the previous pattern.
2378 (define_peephole2
2379   [(set (match_operand:DI 0 "push_operand" "")
2380         (match_operand:DI 1 "immediate_operand" ""))]
2381   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2382    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2383   [(set (match_dup 0) (match_dup 1))
2384    (set (match_dup 2) (match_dup 3))]
2385 {
2386   split_di (&operands[1], 1, &operands[2], &operands[3]);
2387
2388   operands[1] = gen_lowpart (DImode, operands[2]);
2389   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2390                                                    GEN_INT (4)));
2391 })
2392
2393 (define_split
2394   [(set (match_operand:DI 0 "push_operand" "")
2395         (match_operand:DI 1 "immediate_operand" ""))]
2396   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2397                     ? epilogue_completed : reload_completed)
2398    && !symbolic_operand (operands[1], DImode)
2399    && !x86_64_immediate_operand (operands[1], DImode)"
2400   [(set (match_dup 0) (match_dup 1))
2401    (set (match_dup 2) (match_dup 3))]
2402 {
2403   split_di (&operands[1], 1, &operands[2], &operands[3]);
2404
2405   operands[1] = gen_lowpart (DImode, operands[2]);
2406   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2407                                                    GEN_INT (4)));
2408 })
2409
2410 (define_insn "*pushdi2_prologue_rex64"
2411   [(set (match_operand:DI 0 "push_operand" "=<")
2412         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
2413    (clobber (mem:BLK (scratch)))]
2414   "TARGET_64BIT"
2415   "push{q}\t%1"
2416   [(set_attr "type" "push")
2417    (set_attr "mode" "DI")])
2418
2419 (define_insn "*popdi1_epilogue_rex64"
2420   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2421         (mem:DI (reg:DI SP_REG)))
2422    (set (reg:DI SP_REG)
2423         (plus:DI (reg:DI SP_REG) (const_int 8)))
2424    (clobber (mem:BLK (scratch)))]
2425   "TARGET_64BIT"
2426   "pop{q}\t%0"
2427   [(set_attr "type" "pop")
2428    (set_attr "mode" "DI")])
2429
2430 (define_insn "popdi1"
2431   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2432         (mem:DI (reg:DI SP_REG)))
2433    (set (reg:DI SP_REG)
2434         (plus:DI (reg:DI SP_REG) (const_int 8)))]
2435   "TARGET_64BIT"
2436   "pop{q}\t%0"
2437   [(set_attr "type" "pop")
2438    (set_attr "mode" "DI")])
2439
2440 (define_insn "*movdi_xor_rex64"
2441   [(set (match_operand:DI 0 "register_operand" "=r")
2442         (match_operand:DI 1 "const0_operand" ""))
2443    (clobber (reg:CC FLAGS_REG))]
2444   "TARGET_64BIT
2445    && reload_completed"
2446   "xor{l}\t%k0, %k0";
2447   [(set_attr "type" "alu1")
2448    (set_attr "mode" "SI")
2449    (set_attr "length_immediate" "0")])
2450
2451 (define_insn "*movdi_or_rex64"
2452   [(set (match_operand:DI 0 "register_operand" "=r")
2453         (match_operand:DI 1 "const_int_operand" "i"))
2454    (clobber (reg:CC FLAGS_REG))]
2455   "TARGET_64BIT
2456    && reload_completed
2457    && operands[1] == constm1_rtx"
2458 {
2459   operands[1] = constm1_rtx;
2460   return "or{q}\t{%1, %0|%0, %1}";
2461 }
2462   [(set_attr "type" "alu1")
2463    (set_attr "mode" "DI")
2464    (set_attr "length_immediate" "1")])
2465
2466 (define_insn "*movdi_2"
2467   [(set (match_operand:DI 0 "nonimmediate_operand"
2468                         "=r  ,o  ,*y,m*y,*y,*Y2,m  ,*Y2,*Y2,*x,m ,*x,*x")
2469         (match_operand:DI 1 "general_operand"
2470                         "riFo,riF,C ,*y ,m ,C  ,*Y2,*Y2,m  ,C ,*x,*x,m "))]
2471   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2472   "@
2473    #
2474    #
2475    pxor\t%0, %0
2476    movq\t{%1, %0|%0, %1}
2477    movq\t{%1, %0|%0, %1}
2478    %vpxor\t%0, %d0
2479    %vmovq\t{%1, %0|%0, %1}
2480    %vmovdqa\t{%1, %0|%0, %1}
2481    %vmovq\t{%1, %0|%0, %1}
2482    xorps\t%0, %0
2483    movlps\t{%1, %0|%0, %1}
2484    movaps\t{%1, %0|%0, %1}
2485    movlps\t{%1, %0|%0, %1}"
2486   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2487    (set (attr "prefix")
2488      (if_then_else (eq_attr "alternative" "5,6,7,8")
2489        (const_string "vex")
2490        (const_string "orig")))
2491    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2492
2493 (define_split
2494   [(set (match_operand:DI 0 "push_operand" "")
2495         (match_operand:DI 1 "general_operand" ""))]
2496   "!TARGET_64BIT && reload_completed
2497    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2498   [(const_int 0)]
2499   "ix86_split_long_move (operands); DONE;")
2500
2501 ;; %%% This multiword shite has got to go.
2502 (define_split
2503   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2504         (match_operand:DI 1 "general_operand" ""))]
2505   "!TARGET_64BIT && reload_completed
2506    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2507    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2508   [(const_int 0)]
2509   "ix86_split_long_move (operands); DONE;")
2510
2511 (define_insn "*movdi_1_rex64"
2512   [(set (match_operand:DI 0 "nonimmediate_operand"
2513           "=r,r  ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2514         (match_operand:DI 1 "general_operand"
2515           "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r   ,m  ,C ,*x,*Yi,*x,r  ,m ,*Ym,*x"))]
2516   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2517 {
2518   switch (get_attr_type (insn))
2519     {
2520     case TYPE_SSECVT:
2521       if (SSE_REG_P (operands[0]))
2522         return "movq2dq\t{%1, %0|%0, %1}";
2523       else
2524         return "movdq2q\t{%1, %0|%0, %1}";
2525
2526     case TYPE_SSEMOV:
2527       if (TARGET_AVX)
2528         {
2529           if (get_attr_mode (insn) == MODE_TI)
2530             return "vmovdqa\t{%1, %0|%0, %1}";
2531           else
2532             return "vmovq\t{%1, %0|%0, %1}";
2533         }
2534
2535       if (get_attr_mode (insn) == MODE_TI)
2536         return "movdqa\t{%1, %0|%0, %1}";
2537       /* FALLTHRU */
2538
2539     case TYPE_MMXMOV:
2540       /* Moves from and into integer register is done using movd
2541          opcode with REX prefix.  */
2542       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2543         return "movd\t{%1, %0|%0, %1}";
2544       return "movq\t{%1, %0|%0, %1}";
2545
2546     case TYPE_SSELOG1:
2547       return "%vpxor\t%0, %d0";
2548
2549     case TYPE_MMX:
2550       return "pxor\t%0, %0";
2551
2552     case TYPE_MULTI:
2553       return "#";
2554
2555     case TYPE_LEA:
2556       return "lea{q}\t{%a1, %0|%0, %a1}";
2557
2558     default:
2559       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2560       if (get_attr_mode (insn) == MODE_SI)
2561         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2562       else if (which_alternative == 2)
2563         return "movabs{q}\t{%1, %0|%0, %1}";
2564       else
2565         return "mov{q}\t{%1, %0|%0, %1}";
2566     }
2567 }
2568   [(set (attr "type")
2569      (cond [(eq_attr "alternative" "5")
2570               (const_string "mmx")
2571             (eq_attr "alternative" "6,7,8,9,10")
2572               (const_string "mmxmov")
2573             (eq_attr "alternative" "11")
2574               (const_string "sselog1")
2575             (eq_attr "alternative" "12,13,14,15,16")
2576               (const_string "ssemov")
2577             (eq_attr "alternative" "17,18")
2578               (const_string "ssecvt")
2579             (eq_attr "alternative" "4")
2580               (const_string "multi")
2581             (match_operand:DI 1 "pic_32bit_operand" "")
2582               (const_string "lea")
2583            ]
2584            (const_string "imov")))
2585    (set (attr "modrm")
2586      (if_then_else
2587        (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2588          (const_string "0")
2589          (const_string "*")))
2590    (set (attr "length_immediate")
2591      (if_then_else
2592        (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2593          (const_string "8")
2594          (const_string "*")))
2595    (set_attr "prefix_rex" "*,*,*,*,*,*,*,1,*,1,*,*,*,*,*,*,*,*,*")
2596    (set_attr "prefix_data16" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,1,*,*,*")
2597    (set (attr "prefix")
2598      (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
2599        (const_string "maybe_vex")
2600        (const_string "orig")))
2601    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2602
2603 ;; Stores and loads of ax to arbitrary constant address.
2604 ;; We fake an second form of instruction to force reload to load address
2605 ;; into register when rax is not available
2606 (define_insn "*movabsdi_1_rex64"
2607   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2608         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2609   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2610   "@
2611    movabs{q}\t{%1, %P0|%P0, %1}
2612    mov{q}\t{%1, %a0|%a0, %1}"
2613   [(set_attr "type" "imov")
2614    (set_attr "modrm" "0,*")
2615    (set_attr "length_address" "8,0")
2616    (set_attr "length_immediate" "0,*")
2617    (set_attr "memory" "store")
2618    (set_attr "mode" "DI")])
2619
2620 (define_insn "*movabsdi_2_rex64"
2621   [(set (match_operand:DI 0 "register_operand" "=a,r")
2622         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2623   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2624   "@
2625    movabs{q}\t{%P1, %0|%0, %P1}
2626    mov{q}\t{%a1, %0|%0, %a1}"
2627   [(set_attr "type" "imov")
2628    (set_attr "modrm" "0,*")
2629    (set_attr "length_address" "8,0")
2630    (set_attr "length_immediate" "0")
2631    (set_attr "memory" "load")
2632    (set_attr "mode" "DI")])
2633
2634 ;; Convert impossible stores of immediate to existing instructions.
2635 ;; First try to get scratch register and go through it.  In case this
2636 ;; fails, move by 32bit parts.
2637 (define_peephole2
2638   [(match_scratch:DI 2 "r")
2639    (set (match_operand:DI 0 "memory_operand" "")
2640         (match_operand:DI 1 "immediate_operand" ""))]
2641   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2642    && !x86_64_immediate_operand (operands[1], DImode)"
2643   [(set (match_dup 2) (match_dup 1))
2644    (set (match_dup 0) (match_dup 2))]
2645   "")
2646
2647 ;; We need to define this as both peepholer and splitter for case
2648 ;; peephole2 pass is not run.
2649 ;; "&& 1" is needed to keep it from matching the previous pattern.
2650 (define_peephole2
2651   [(set (match_operand:DI 0 "memory_operand" "")
2652         (match_operand:DI 1 "immediate_operand" ""))]
2653   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2654    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2655   [(set (match_dup 2) (match_dup 3))
2656    (set (match_dup 4) (match_dup 5))]
2657   "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2658
2659 (define_split
2660   [(set (match_operand:DI 0 "memory_operand" "")
2661         (match_operand:DI 1 "immediate_operand" ""))]
2662   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2663                     ? epilogue_completed : reload_completed)
2664    && !symbolic_operand (operands[1], DImode)
2665    && !x86_64_immediate_operand (operands[1], DImode)"
2666   [(set (match_dup 2) (match_dup 3))
2667    (set (match_dup 4) (match_dup 5))]
2668   "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2669
2670 (define_insn "*swapdi_rex64"
2671   [(set (match_operand:DI 0 "register_operand" "+r")
2672         (match_operand:DI 1 "register_operand" "+r"))
2673    (set (match_dup 1)
2674         (match_dup 0))]
2675   "TARGET_64BIT"
2676   "xchg{q}\t%1, %0"
2677   [(set_attr "type" "imov")
2678    (set_attr "mode" "DI")
2679    (set_attr "pent_pair" "np")
2680    (set_attr "athlon_decode" "vector")
2681    (set_attr "amdfam10_decode" "double")])
2682
2683 (define_expand "movoi"
2684   [(set (match_operand:OI 0 "nonimmediate_operand" "")
2685         (match_operand:OI 1 "general_operand" ""))]
2686   "TARGET_AVX"
2687   "ix86_expand_move (OImode, operands); DONE;")
2688
2689 (define_insn "*movoi_internal"
2690   [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
2691         (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
2692   "TARGET_AVX
2693    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2694 {
2695   switch (which_alternative)
2696     {
2697     case 0:
2698       return "vxorps\t%0, %0, %0";
2699     case 1:
2700     case 2:
2701       if (misaligned_operand (operands[0], OImode)
2702           || misaligned_operand (operands[1], OImode))
2703         return "vmovdqu\t{%1, %0|%0, %1}";
2704       else
2705         return "vmovdqa\t{%1, %0|%0, %1}";
2706     default:
2707       gcc_unreachable ();
2708     }
2709 }
2710   [(set_attr "type" "sselog1,ssemov,ssemov")
2711    (set_attr "prefix" "vex")
2712    (set_attr "mode" "OI")])
2713
2714 (define_expand "movti"
2715   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2716         (match_operand:TI 1 "nonimmediate_operand" ""))]
2717   "TARGET_SSE || TARGET_64BIT"
2718 {
2719   if (TARGET_64BIT)
2720     ix86_expand_move (TImode, operands);
2721   else if (push_operand (operands[0], TImode))
2722     ix86_expand_push (TImode, operands[1]);
2723   else
2724     ix86_expand_vector_move (TImode, operands);
2725   DONE;
2726 })
2727
2728 (define_insn "*movti_internal"
2729   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2730         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2731   "TARGET_SSE && !TARGET_64BIT
2732    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2733 {
2734   switch (which_alternative)
2735     {
2736     case 0:
2737       if (get_attr_mode (insn) == MODE_V4SF)
2738         return "%vxorps\t%0, %d0";
2739       else
2740         return "%vpxor\t%0, %d0";
2741     case 1:
2742     case 2:
2743       /* TDmode values are passed as TImode on the stack.  Moving them
2744          to stack may result in unaligned memory access.  */
2745       if (misaligned_operand (operands[0], TImode)
2746           || misaligned_operand (operands[1], TImode))
2747         {
2748           if (get_attr_mode (insn) == MODE_V4SF)
2749             return "%vmovups\t{%1, %0|%0, %1}";
2750          else
2751            return "%vmovdqu\t{%1, %0|%0, %1}";
2752         }
2753       else
2754         {
2755           if (get_attr_mode (insn) == MODE_V4SF)
2756             return "%vmovaps\t{%1, %0|%0, %1}";
2757          else
2758            return "%vmovdqa\t{%1, %0|%0, %1}";
2759         }
2760     default:
2761       gcc_unreachable ();
2762     }
2763 }
2764   [(set_attr "type" "sselog1,ssemov,ssemov")
2765    (set_attr "prefix" "maybe_vex")
2766    (set (attr "mode")
2767         (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2768                     (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0)))
2769                  (const_string "V4SF")
2770                (and (eq_attr "alternative" "2")
2771                     (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2772                         (const_int 0)))
2773                  (const_string "V4SF")]
2774               (const_string "TI")))])
2775
2776 (define_insn "*movti_rex64"
2777   [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
2778         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2779   "TARGET_64BIT
2780    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2781 {
2782   switch (which_alternative)
2783     {
2784     case 0:
2785     case 1:
2786       return "#";
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       /* TDmode values are passed as TImode on the stack.  Moving them
2795          to stack may result in unaligned memory access.  */
2796       if (misaligned_operand (operands[0], TImode)
2797           || misaligned_operand (operands[1], TImode))
2798         {
2799           if (get_attr_mode (insn) == MODE_V4SF)
2800             return "%vmovups\t{%1, %0|%0, %1}";
2801          else
2802            return "%vmovdqu\t{%1, %0|%0, %1}";
2803         }
2804       else
2805         {
2806           if (get_attr_mode (insn) == MODE_V4SF)
2807             return "%vmovaps\t{%1, %0|%0, %1}";
2808          else
2809            return "%vmovdqa\t{%1, %0|%0, %1}";
2810         }
2811     default:
2812       gcc_unreachable ();
2813     }
2814 }
2815   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2816    (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
2817    (set (attr "mode")
2818         (cond [(eq_attr "alternative" "2,3")
2819                  (if_then_else
2820                    (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2821                        (const_int 0))
2822                    (const_string "V4SF")
2823                    (const_string "TI"))
2824                (eq_attr "alternative" "4")
2825                  (if_then_else
2826                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2827                             (const_int 0))
2828                         (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2829                             (const_int 0)))
2830                    (const_string "V4SF")
2831                    (const_string "TI"))]
2832                (const_string "DI")))])
2833
2834 (define_split
2835   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2836         (match_operand:TI 1 "general_operand" ""))]
2837   "reload_completed && !SSE_REG_P (operands[0])
2838    && !SSE_REG_P (operands[1])"
2839   [(const_int 0)]
2840   "ix86_split_long_move (operands); DONE;")
2841
2842 ;; This expands to what emit_move_complex would generate if we didn't
2843 ;; have a movti pattern.  Having this avoids problems with reload on
2844 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2845 ;; to have around all the time.
2846 (define_expand "movcdi"
2847   [(set (match_operand:CDI 0 "nonimmediate_operand" "")
2848         (match_operand:CDI 1 "general_operand" ""))]
2849   ""
2850 {
2851   if (push_operand (operands[0], CDImode))
2852     emit_move_complex_push (CDImode, operands[0], operands[1]);
2853   else
2854     emit_move_complex_parts (operands[0], operands[1]);
2855   DONE;
2856 })
2857
2858 (define_expand "movsf"
2859   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2860         (match_operand:SF 1 "general_operand" ""))]
2861   ""
2862   "ix86_expand_move (SFmode, operands); DONE;")
2863
2864 (define_insn "*pushsf"
2865   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2866         (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2867   "!TARGET_64BIT"
2868 {
2869   /* Anything else should be already split before reg-stack.  */
2870   gcc_assert (which_alternative == 1);
2871   return "push{l}\t%1";
2872 }
2873   [(set_attr "type" "multi,push,multi")
2874    (set_attr "unit" "i387,*,*")
2875    (set_attr "mode" "SF,SI,SF")])
2876
2877 (define_insn "*pushsf_rex64"
2878   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2879         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2880   "TARGET_64BIT"
2881 {
2882   /* Anything else should be already split before reg-stack.  */
2883   gcc_assert (which_alternative == 1);
2884   return "push{q}\t%q1";
2885 }
2886   [(set_attr "type" "multi,push,multi")
2887    (set_attr "unit" "i387,*,*")
2888    (set_attr "mode" "SF,DI,SF")])
2889
2890 (define_split
2891   [(set (match_operand:SF 0 "push_operand" "")
2892         (match_operand:SF 1 "memory_operand" ""))]
2893   "reload_completed
2894    && MEM_P (operands[1])
2895    && (operands[2] = find_constant_src (insn))"
2896   [(set (match_dup 0)
2897         (match_dup 2))])
2898
2899 ;; %%% Kill this when call knows how to work this out.
2900 (define_split
2901   [(set (match_operand:SF 0 "push_operand" "")
2902         (match_operand:SF 1 "any_fp_register_operand" ""))]
2903   "!TARGET_64BIT"
2904   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2905    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2906
2907 (define_split
2908   [(set (match_operand:SF 0 "push_operand" "")
2909         (match_operand:SF 1 "any_fp_register_operand" ""))]
2910   "TARGET_64BIT"
2911   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2912    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2913
2914 (define_insn "*movsf_1"
2915   [(set (match_operand:SF 0 "nonimmediate_operand"
2916           "=f,m,f,r  ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
2917         (match_operand:SF 1 "general_operand"
2918           "fm,f,G,rmF,Fr,C,x,xm,x,m  ,*y,*y ,r  ,Yi,r   ,*Ym"))]
2919   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2920    && (reload_in_progress || reload_completed
2921        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2922        || (!TARGET_SSE_MATH && optimize_function_for_size_p (cfun)
2923            && standard_80387_constant_p (operands[1]))
2924        || GET_CODE (operands[1]) != CONST_DOUBLE
2925        || memory_operand (operands[0], SFmode))"
2926 {
2927   switch (which_alternative)
2928     {
2929     case 0:
2930     case 1:
2931       return output_387_reg_move (insn, operands);
2932
2933     case 2:
2934       return standard_80387_constant_opcode (operands[1]);
2935
2936     case 3:
2937     case 4:
2938       return "mov{l}\t{%1, %0|%0, %1}";
2939     case 5:
2940       if (get_attr_mode (insn) == MODE_TI)
2941         return "%vpxor\t%0, %d0";
2942       else
2943         return "%vxorps\t%0, %d0";
2944     case 6:
2945       if (get_attr_mode (insn) == MODE_V4SF)
2946         return "%vmovaps\t{%1, %0|%0, %1}";
2947       else
2948         return "%vmovss\t{%1, %d0|%d0, %1}";
2949     case 7:
2950       if (TARGET_AVX)
2951         return REG_P (operands[1]) ? "vmovss\t{%1, %0, %0|%0, %0, %1}"
2952                                    : "vmovss\t{%1, %0|%0, %1}";
2953       else
2954         return "movss\t{%1, %0|%0, %1}";
2955     case 8:
2956       return "%vmovss\t{%1, %0|%0, %1}";
2957
2958     case 9: case 10: case 14: case 15:
2959       return "movd\t{%1, %0|%0, %1}";
2960     case 12: case 13:
2961       return "%vmovd\t{%1, %0|%0, %1}";
2962
2963     case 11:
2964       return "movq\t{%1, %0|%0, %1}";
2965
2966     default:
2967       gcc_unreachable ();
2968     }
2969 }
2970   [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2971    (set (attr "prefix")
2972      (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
2973        (const_string "maybe_vex")
2974        (const_string "orig")))
2975    (set (attr "mode")
2976         (cond [(eq_attr "alternative" "3,4,9,10")
2977                  (const_string "SI")
2978                (eq_attr "alternative" "5")
2979                  (if_then_else
2980                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2981                                  (const_int 0))
2982                              (ne (symbol_ref "TARGET_SSE2")
2983                                  (const_int 0)))
2984                         (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2985                             (const_int 0)))
2986                    (const_string "TI")
2987                    (const_string "V4SF"))
2988                /* For architectures resolving dependencies on
2989                   whole SSE registers use APS move to break dependency
2990                   chains, otherwise use short move to avoid extra work.
2991
2992                   Do the same for architectures resolving dependencies on
2993                   the parts.  While in DF mode it is better to always handle
2994                   just register parts, the SF mode is different due to lack
2995                   of instructions to load just part of the register.  It is
2996                   better to maintain the whole registers in single format
2997                   to avoid problems on using packed logical operations.  */
2998                (eq_attr "alternative" "6")
2999                  (if_then_else
3000                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3001                             (const_int 0))
3002                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3003                             (const_int 0)))
3004                    (const_string "V4SF")
3005                    (const_string "SF"))
3006                (eq_attr "alternative" "11")
3007                  (const_string "DI")]
3008                (const_string "SF")))])
3009
3010 (define_insn "*swapsf"
3011   [(set (match_operand:SF 0 "fp_register_operand" "+f")
3012         (match_operand:SF 1 "fp_register_operand" "+f"))
3013    (set (match_dup 1)
3014         (match_dup 0))]
3015   "reload_completed || TARGET_80387"
3016 {
3017   if (STACK_TOP_P (operands[0]))
3018     return "fxch\t%1";
3019   else
3020     return "fxch\t%0";
3021 }
3022   [(set_attr "type" "fxch")
3023    (set_attr "mode" "SF")])
3024
3025 (define_expand "movdf"
3026   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3027         (match_operand:DF 1 "general_operand" ""))]
3028   ""
3029   "ix86_expand_move (DFmode, operands); DONE;")
3030
3031 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3032 ;; Size of pushdf using integer instructions is 2+2*memory operand size
3033 ;; On the average, pushdf using integers can be still shorter.  Allow this
3034 ;; pattern for optimize_size too.
3035
3036 (define_insn "*pushdf_nointeger"
3037   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
3038         (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
3039   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
3040 {
3041   /* This insn should be already split before reg-stack.  */
3042   gcc_unreachable ();
3043 }
3044   [(set_attr "type" "multi")
3045    (set_attr "unit" "i387,*,*,*")
3046    (set_attr "mode" "DF,SI,SI,DF")])
3047
3048 (define_insn "*pushdf_integer"
3049   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
3050         (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
3051   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
3052 {
3053   /* This insn should be already split before reg-stack.  */
3054   gcc_unreachable ();
3055 }
3056   [(set_attr "type" "multi")
3057    (set_attr "unit" "i387,*,*")
3058    (set_attr "mode" "DF,SI,DF")])
3059
3060 ;; %%% Kill this when call knows how to work this out.
3061 (define_split
3062   [(set (match_operand:DF 0 "push_operand" "")
3063         (match_operand:DF 1 "any_fp_register_operand" ""))]
3064   "reload_completed"
3065   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3066    (set (mem:DF (reg:P SP_REG)) (match_dup 1))]
3067   "")
3068
3069 (define_split
3070   [(set (match_operand:DF 0 "push_operand" "")
3071         (match_operand:DF 1 "general_operand" ""))]
3072   "reload_completed"
3073   [(const_int 0)]
3074   "ix86_split_long_move (operands); DONE;")
3075
3076 ;; Moving is usually shorter when only FP registers are used. This separate
3077 ;; movdf pattern avoids the use of integer registers for FP operations
3078 ;; when optimizing for size.
3079
3080 (define_insn "*movdf_nointeger"
3081   [(set (match_operand:DF 0 "nonimmediate_operand"
3082                         "=f,m,f,*r  ,o  ,Y2*x,Y2*x,Y2*x ,m  ")
3083         (match_operand:DF 1 "general_operand"
3084                         "fm,f,G,*roF,*Fr,C   ,Y2*x,mY2*x,Y2*x"))]
3085   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3086    && ((optimize_function_for_size_p (cfun)
3087        || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
3088    && (reload_in_progress || reload_completed
3089        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3090        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3091            && optimize_function_for_size_p (cfun)
3092            && !memory_operand (operands[0], DFmode)
3093            && standard_80387_constant_p (operands[1]))
3094        || GET_CODE (operands[1]) != CONST_DOUBLE
3095        || ((optimize_function_for_size_p (cfun)
3096             || !TARGET_MEMORY_MISMATCH_STALL
3097             || reload_in_progress || reload_completed)
3098            && memory_operand (operands[0], DFmode)))"
3099 {
3100   switch (which_alternative)
3101     {
3102     case 0:
3103     case 1:
3104       return output_387_reg_move (insn, operands);
3105
3106     case 2:
3107       return standard_80387_constant_opcode (operands[1]);
3108
3109     case 3:
3110     case 4:
3111       return "#";
3112     case 5:
3113       switch (get_attr_mode (insn))
3114         {
3115         case MODE_V4SF:
3116           return "%vxorps\t%0, %d0";
3117         case MODE_V2DF:
3118           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3119             return "%vxorps\t%0, %d0";
3120           else
3121             return "%vxorpd\t%0, %d0";
3122         case MODE_TI:
3123           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3124             return "%vxorps\t%0, %d0";
3125           else
3126             return "%vpxor\t%0, %d0";
3127         default:
3128           gcc_unreachable ();
3129         }
3130     case 6:
3131     case 7:
3132     case 8:
3133       switch (get_attr_mode (insn))
3134         {
3135         case MODE_V4SF:
3136           return "%vmovaps\t{%1, %0|%0, %1}";
3137         case MODE_V2DF:
3138           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3139             return "%vmovaps\t{%1, %0|%0, %1}";
3140           else
3141             return "%vmovapd\t{%1, %0|%0, %1}";
3142         case MODE_TI:
3143           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3144             return "%vmovaps\t{%1, %0|%0, %1}";
3145           else
3146             return "%vmovdqa\t{%1, %0|%0, %1}";
3147         case MODE_DI:
3148           return "%vmovq\t{%1, %0|%0, %1}";
3149         case MODE_DF:
3150           if (TARGET_AVX)
3151             {
3152               if (REG_P (operands[0]) && REG_P (operands[1]))
3153                 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3154               else
3155                 return "vmovsd\t{%1, %0|%0, %1}";
3156             }
3157           else
3158             return "movsd\t{%1, %0|%0, %1}";
3159         case MODE_V1DF:
3160           if (TARGET_AVX)
3161             {
3162               if (REG_P (operands[0]))
3163                 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
3164               else
3165                 return "vmovlpd\t{%1, %0|%0, %1}";
3166             }
3167           else
3168             return "movlpd\t{%1, %0|%0, %1}";
3169         case MODE_V2SF:
3170           if (TARGET_AVX)
3171             {
3172               if (REG_P (operands[0]))
3173                 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
3174               else
3175                 return "vmovlps\t{%1, %0|%0, %1}";
3176             }
3177           else
3178             return "movlps\t{%1, %0|%0, %1}";
3179         default:
3180           gcc_unreachable ();
3181         }
3182
3183     default:
3184       gcc_unreachable ();
3185     }
3186 }
3187   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3188    (set (attr "prefix")
3189      (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3190        (const_string "orig")
3191        (const_string "maybe_vex")))
3192    (set (attr "prefix_data16")
3193      (if_then_else (eq_attr "mode" "V1DF")
3194        (const_string "1")
3195        (const_string "*")))
3196    (set (attr "mode")
3197         (cond [(eq_attr "alternative" "0,1,2")
3198                  (const_string "DF")
3199                (eq_attr "alternative" "3,4")
3200                  (const_string "SI")
3201
3202                /* For SSE1, we have many fewer alternatives.  */
3203                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3204                  (cond [(eq_attr "alternative" "5,6")
3205                           (const_string "V4SF")
3206                        ]
3207                    (const_string "V2SF"))
3208
3209                /* xorps is one byte shorter.  */
3210                (eq_attr "alternative" "5")
3211                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3212                             (const_int 0))
3213                           (const_string "V4SF")
3214                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3215                             (const_int 0))
3216                           (const_string "TI")
3217                        ]
3218                        (const_string "V2DF"))
3219
3220                /* For architectures resolving dependencies on
3221                   whole SSE registers use APD move to break dependency
3222                   chains, otherwise use short move to avoid extra work.
3223
3224                   movaps encodes one byte shorter.  */
3225                (eq_attr "alternative" "6")
3226                  (cond
3227                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3228                         (const_int 0))
3229                       (const_string "V4SF")
3230                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3231                         (const_int 0))
3232                       (const_string "V2DF")
3233                    ]
3234                    (const_string "DF"))
3235                /* For architectures resolving dependencies on register
3236                   parts we may avoid extra work to zero out upper part
3237                   of register.  */
3238                (eq_attr "alternative" "7")
3239                  (if_then_else
3240                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3241                        (const_int 0))
3242                    (const_string "V1DF")
3243                    (const_string "DF"))
3244               ]
3245               (const_string "DF")))])
3246
3247 (define_insn "*movdf_integer_rex64"
3248   [(set (match_operand:DF 0 "nonimmediate_operand"
3249                 "=f,m,f,r  ,m ,Y2*x,Y2*x,Y2*x,m   ,Yi,r ")
3250         (match_operand:DF 1 "general_operand"
3251                 "fm,f,G,rmF,Fr,C   ,Y2*x,m   ,Y2*x,r ,Yi"))]
3252   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3253    && (reload_in_progress || reload_completed
3254        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3255        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3256            && optimize_function_for_size_p (cfun)
3257            && standard_80387_constant_p (operands[1]))
3258        || GET_CODE (operands[1]) != CONST_DOUBLE
3259        || memory_operand (operands[0], DFmode))"
3260 {
3261   switch (which_alternative)
3262     {
3263     case 0:
3264     case 1:
3265       return output_387_reg_move (insn, operands);
3266
3267     case 2:
3268       return standard_80387_constant_opcode (operands[1]);
3269
3270     case 3:
3271     case 4:
3272       return "#";
3273
3274     case 5:
3275       switch (get_attr_mode (insn))
3276         {
3277         case MODE_V4SF:
3278           return "%vxorps\t%0, %d0";
3279         case MODE_V2DF:
3280           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3281             return "%vxorps\t%0, %d0";
3282           else
3283             return "%vxorpd\t%0, %d0";
3284         case MODE_TI:
3285           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3286             return "%vxorps\t%0, %d0";
3287           else
3288             return "%vpxor\t%0, %d0";
3289         default:
3290           gcc_unreachable ();
3291         }
3292     case 6:
3293     case 7:
3294     case 8:
3295       switch (get_attr_mode (insn))
3296         {
3297         case MODE_V4SF:
3298           return "%vmovaps\t{%1, %0|%0, %1}";
3299         case MODE_V2DF:
3300           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3301             return "%vmovaps\t{%1, %0|%0, %1}";
3302           else
3303             return "%vmovapd\t{%1, %0|%0, %1}";
3304         case MODE_TI:
3305           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3306             return "%vmovaps\t{%1, %0|%0, %1}";
3307           else
3308             return "%vmovdqa\t{%1, %0|%0, %1}";
3309         case MODE_DI:
3310           return "%vmovq\t{%1, %0|%0, %1}";
3311         case MODE_DF:
3312           if (TARGET_AVX)
3313             {
3314               if (REG_P (operands[0]) && REG_P (operands[1]))
3315                 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3316               else
3317                 return "vmovsd\t{%1, %0|%0, %1}";
3318             }
3319           else
3320             return "movsd\t{%1, %0|%0, %1}";
3321         case MODE_V1DF:
3322           return "%vmovlpd\t{%1, %d0|%d0, %1}";
3323         case MODE_V2SF:
3324           return "%vmovlps\t{%1, %d0|%d0, %1}";
3325         default:
3326           gcc_unreachable ();
3327         }
3328
3329     case 9:
3330     case 10:
3331     return "%vmovd\t{%1, %0|%0, %1}";
3332
3333     default:
3334       gcc_unreachable();
3335     }
3336 }
3337   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
3338    (set (attr "prefix")
3339      (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3340        (const_string "orig")
3341        (const_string "maybe_vex")))
3342    (set (attr "prefix_data16")
3343      (if_then_else (eq_attr "mode" "V1DF")
3344        (const_string "1")
3345        (const_string "*")))
3346    (set (attr "mode")
3347         (cond [(eq_attr "alternative" "0,1,2")
3348                  (const_string "DF")
3349                (eq_attr "alternative" "3,4,9,10")
3350                  (const_string "DI")
3351
3352                /* For SSE1, we have many fewer alternatives.  */
3353                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3354                  (cond [(eq_attr "alternative" "5,6")
3355                           (const_string "V4SF")
3356                        ]
3357                    (const_string "V2SF"))
3358
3359                /* xorps is one byte shorter.  */
3360                (eq_attr "alternative" "5")
3361                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3362                             (const_int 0))
3363                           (const_string "V4SF")
3364                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3365                             (const_int 0))
3366                           (const_string "TI")
3367                        ]
3368                        (const_string "V2DF"))
3369
3370                /* For architectures resolving dependencies on
3371                   whole SSE registers use APD move to break dependency
3372                   chains, otherwise use short move to avoid extra work.
3373
3374                   movaps encodes one byte shorter.  */
3375                (eq_attr "alternative" "6")
3376                  (cond
3377                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3378                         (const_int 0))
3379                       (const_string "V4SF")
3380                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3381                         (const_int 0))
3382                       (const_string "V2DF")
3383                    ]
3384                    (const_string "DF"))
3385                /* For architectures resolving dependencies on register
3386                   parts we may avoid extra work to zero out upper part
3387                   of register.  */
3388                (eq_attr "alternative" "7")
3389                  (if_then_else
3390                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3391                        (const_int 0))
3392                    (const_string "V1DF")
3393                    (const_string "DF"))
3394               ]
3395               (const_string "DF")))])
3396
3397 (define_insn "*movdf_integer"
3398   [(set (match_operand:DF 0 "nonimmediate_operand"
3399                 "=f,m,f,r  ,o ,Y2*x,Y2*x,Y2*x,m   ")
3400         (match_operand:DF 1 "general_operand"
3401                 "fm,f,G,roF,Fr,C   ,Y2*x,m   ,Y2*x"))]
3402   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3403    && optimize_function_for_speed_p (cfun)
3404    && TARGET_INTEGER_DFMODE_MOVES
3405    && (reload_in_progress || reload_completed
3406        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3407        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3408            && optimize_function_for_size_p (cfun)
3409            && standard_80387_constant_p (operands[1]))
3410        || GET_CODE (operands[1]) != CONST_DOUBLE
3411        || memory_operand (operands[0], DFmode))"
3412 {
3413   switch (which_alternative)
3414     {
3415     case 0:
3416     case 1:
3417       return output_387_reg_move (insn, operands);
3418
3419     case 2:
3420       return standard_80387_constant_opcode (operands[1]);
3421
3422     case 3:
3423     case 4:
3424       return "#";
3425
3426     case 5:
3427       switch (get_attr_mode (insn))
3428         {
3429         case MODE_V4SF:
3430           return "xorps\t%0, %0";
3431         case MODE_V2DF:
3432           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3433             return "xorps\t%0, %0";
3434           else
3435             return "xorpd\t%0, %0";
3436         case MODE_TI:
3437           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3438             return "xorps\t%0, %0";
3439           else
3440             return "pxor\t%0, %0";
3441         default:
3442           gcc_unreachable ();
3443         }
3444     case 6:
3445     case 7:
3446     case 8:
3447       switch (get_attr_mode (insn))
3448         {
3449         case MODE_V4SF:
3450           return "movaps\t{%1, %0|%0, %1}";
3451         case MODE_V2DF:
3452           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3453             return "movaps\t{%1, %0|%0, %1}";
3454           else
3455             return "movapd\t{%1, %0|%0, %1}";
3456         case MODE_TI:
3457           if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3458             return "movaps\t{%1, %0|%0, %1}";
3459           else
3460             return "movdqa\t{%1, %0|%0, %1}";
3461         case MODE_DI:
3462           return "movq\t{%1, %0|%0, %1}";
3463         case MODE_DF:
3464           return "movsd\t{%1, %0|%0, %1}";
3465         case MODE_V1DF:
3466           return "movlpd\t{%1, %0|%0, %1}";
3467         case MODE_V2SF:
3468           return "movlps\t{%1, %0|%0, %1}";
3469         default:
3470           gcc_unreachable ();
3471         }
3472
3473     default:
3474       gcc_unreachable();
3475     }
3476 }
3477   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3478    (set (attr "prefix_data16")
3479      (if_then_else (eq_attr "mode" "V1DF")
3480        (const_string "1")
3481        (const_string "*")))
3482    (set (attr "mode")
3483         (cond [(eq_attr "alternative" "0,1,2")
3484                  (const_string "DF")
3485                (eq_attr "alternative" "3,4")
3486                  (const_string "SI")
3487
3488                /* For SSE1, we have many fewer alternatives.  */
3489                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3490                  (cond [(eq_attr "alternative" "5,6")
3491                           (const_string "V4SF")
3492                        ]
3493                    (const_string "V2SF"))
3494
3495                /* xorps is one byte shorter.  */
3496                (eq_attr "alternative" "5")
3497                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3498                             (const_int 0))
3499                           (const_string "V4SF")
3500                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3501                             (const_int 0))
3502                           (const_string "TI")
3503                        ]
3504                        (const_string "V2DF"))
3505
3506                /* For architectures resolving dependencies on
3507                   whole SSE registers use APD move to break dependency
3508                   chains, otherwise use short move to avoid extra work.
3509
3510                   movaps encodes one byte shorter.  */
3511                (eq_attr "alternative" "6")
3512                  (cond
3513                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3514                         (const_int 0))
3515                       (const_string "V4SF")
3516                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3517                         (const_int 0))
3518                       (const_string "V2DF")
3519                    ]
3520                    (const_string "DF"))
3521                /* For architectures resolving dependencies on register
3522                   parts we may avoid extra work to zero out upper part
3523                   of register.  */
3524                (eq_attr "alternative" "7")
3525                  (if_then_else
3526                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3527                        (const_int 0))
3528                    (const_string "V1DF")
3529                    (const_string "DF"))
3530               ]
3531               (const_string "DF")))])
3532
3533 (define_split
3534   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3535         (match_operand:DF 1 "general_operand" ""))]
3536   "reload_completed
3537    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3538    && ! (ANY_FP_REG_P (operands[0]) ||
3539          (GET_CODE (operands[0]) == SUBREG
3540           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3541    && ! (ANY_FP_REG_P (operands[1]) ||
3542          (GET_CODE (operands[1]) == SUBREG
3543           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3544   [(const_int 0)]
3545   "ix86_split_long_move (operands); DONE;")
3546
3547 (define_insn "*swapdf"
3548   [(set (match_operand:DF 0 "fp_register_operand" "+f")
3549         (match_operand:DF 1 "fp_register_operand" "+f"))
3550    (set (match_dup 1)
3551         (match_dup 0))]
3552   "reload_completed || TARGET_80387"
3553 {
3554   if (STACK_TOP_P (operands[0]))
3555     return "fxch\t%1";
3556   else
3557     return "fxch\t%0";
3558 }
3559   [(set_attr "type" "fxch")
3560    (set_attr "mode" "DF")])
3561
3562 (define_expand "movxf"
3563   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3564         (match_operand:XF 1 "general_operand" ""))]
3565   ""
3566   "ix86_expand_move (XFmode, operands); DONE;")
3567
3568 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3569 ;; Size of pushdf using integer instructions is 3+3*memory operand size
3570 ;; Pushing using integer instructions is longer except for constants
3571 ;; and direct memory references.
3572 ;; (assuming that any given constant is pushed only once, but this ought to be
3573 ;;  handled elsewhere).
3574
3575 (define_insn "*pushxf_nointeger"
3576   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
3577         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
3578   "optimize_function_for_size_p (cfun)"
3579 {
3580   /* This insn should be already split before reg-stack.  */
3581   gcc_unreachable ();
3582 }
3583   [(set_attr "type" "multi")
3584    (set_attr "unit" "i387,*,*")
3585    (set_attr "mode" "XF,SI,SI")])
3586
3587 (define_insn "*pushxf_integer"
3588   [(set (match_operand:XF 0 "push_operand" "=<,<")
3589         (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
3590   "optimize_function_for_speed_p (cfun)"
3591 {
3592   /* This insn should be already split before reg-stack.  */
3593   gcc_unreachable ();
3594 }
3595   [(set_attr "type" "multi")
3596    (set_attr "unit" "i387,*")
3597    (set_attr "mode" "XF,SI")])
3598
3599 (define_split
3600   [(set (match_operand 0 "push_operand" "")
3601         (match_operand 1 "general_operand" ""))]
3602   "reload_completed
3603    && (GET_MODE (operands[0]) == XFmode
3604        || GET_MODE (operands[0]) == DFmode)
3605    && !ANY_FP_REG_P (operands[1])"
3606   [(const_int 0)]
3607   "ix86_split_long_move (operands); DONE;")
3608
3609 (define_split
3610   [(set (match_operand:XF 0 "push_operand" "")
3611         (match_operand:XF 1 "any_fp_register_operand" ""))]
3612   ""
3613   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3614    (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
3615   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3616
3617 ;; Do not use integer registers when optimizing for size
3618 (define_insn "*movxf_nointeger"
3619   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3620         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3621   "optimize_function_for_size_p (cfun)
3622    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3623    && (reload_in_progress || reload_completed
3624        || standard_80387_constant_p (operands[1])
3625        || GET_CODE (operands[1]) != CONST_DOUBLE
3626        || memory_operand (operands[0], XFmode))"
3627 {
3628   switch (which_alternative)
3629     {
3630     case 0:
3631     case 1:
3632       return output_387_reg_move (insn, operands);
3633
3634     case 2:
3635       return standard_80387_constant_opcode (operands[1]);
3636
3637     case 3: case 4:
3638       return "#";
3639     default:
3640       gcc_unreachable ();
3641     }
3642 }
3643   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3644    (set_attr "mode" "XF,XF,XF,SI,SI")])
3645
3646 (define_insn "*movxf_integer"
3647   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
3648         (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
3649   "optimize_function_for_speed_p (cfun)
3650    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3651    && (reload_in_progress || reload_completed
3652        || GET_CODE (operands[1]) != CONST_DOUBLE
3653        || memory_operand (operands[0], XFmode))"
3654 {
3655   switch (which_alternative)
3656     {
3657     case 0:
3658     case 1:
3659       return output_387_reg_move (insn, operands);
3660
3661     case 2:
3662       return standard_80387_constant_opcode (operands[1]);
3663
3664     case 3: case 4:
3665       return "#";
3666
3667     default:
3668       gcc_unreachable ();
3669     }
3670 }
3671   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3672    (set_attr "mode" "XF,XF,XF,SI,SI")])
3673
3674 (define_expand "movtf"
3675   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3676         (match_operand:TF 1 "nonimmediate_operand" ""))]
3677   "TARGET_SSE2"
3678 {
3679   ix86_expand_move (TFmode, operands);
3680   DONE;
3681 })
3682
3683 (define_insn "*movtf_internal"
3684   [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
3685         (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
3686   "TARGET_SSE2
3687    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3688 {
3689   switch (which_alternative)
3690     {
3691     case 0:
3692     case 1:
3693       if (get_attr_mode (insn) == MODE_V4SF)
3694         return "%vmovaps\t{%1, %0|%0, %1}";
3695       else
3696         return "%vmovdqa\t{%1, %0|%0, %1}";
3697     case 2:
3698       if (get_attr_mode (insn) == MODE_V4SF)
3699         return "%vxorps\t%0, %d0";
3700       else
3701         return "%vpxor\t%0, %d0";
3702     case 3:
3703     case 4:
3704         return "#";
3705     default:
3706       gcc_unreachable ();
3707     }
3708 }
3709   [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
3710    (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
3711    (set (attr "mode")
3712         (cond [(eq_attr "alternative" "0,2")
3713                  (if_then_else
3714                    (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3715                        (const_int 0))
3716                    (const_string "V4SF")
3717                    (const_string "TI"))
3718                (eq_attr "alternative" "1")
3719                  (if_then_else
3720                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3721                             (const_int 0))
3722                         (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3723                             (const_int 0)))
3724                    (const_string "V4SF")
3725                    (const_string "TI"))]
3726                (const_string "DI")))])
3727
3728 (define_insn "*pushtf_sse"
3729   [(set (match_operand:TF 0 "push_operand" "=<,<,<")
3730         (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
3731   "TARGET_SSE2"
3732 {
3733   /* This insn should be already split before reg-stack.  */
3734   gcc_unreachable ();
3735 }
3736   [(set_attr "type" "multi")
3737    (set_attr "unit" "sse,*,*")
3738    (set_attr "mode" "TF,SI,SI")])
3739
3740 (define_split
3741   [(set (match_operand:TF 0 "push_operand" "")
3742         (match_operand:TF 1 "general_operand" ""))]
3743   "TARGET_SSE2 && reload_completed
3744    && !SSE_REG_P (operands[1])"
3745   [(const_int 0)]
3746   "ix86_split_long_move (operands); DONE;")
3747
3748 (define_split
3749   [(set (match_operand:TF 0 "push_operand" "")
3750         (match_operand:TF 1 "any_fp_register_operand" ""))]
3751   "TARGET_SSE2"
3752   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3753    (set (mem:TF (reg:P SP_REG)) (match_dup 1))]
3754   "")
3755
3756 (define_split
3757   [(set (match_operand 0 "nonimmediate_operand" "")
3758         (match_operand 1 "general_operand" ""))]
3759   "reload_completed
3760    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3761    && GET_MODE (operands[0]) == XFmode
3762    && ! (ANY_FP_REG_P (operands[0]) ||
3763          (GET_CODE (operands[0]) == SUBREG
3764           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3765    && ! (ANY_FP_REG_P (operands[1]) ||
3766          (GET_CODE (operands[1]) == SUBREG
3767           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3768   [(const_int 0)]
3769   "ix86_split_long_move (operands); DONE;")
3770
3771 (define_split
3772   [(set (match_operand 0 "register_operand" "")
3773         (match_operand 1 "memory_operand" ""))]
3774   "reload_completed
3775    && MEM_P (operands[1])
3776    && (GET_MODE (operands[0]) == TFmode
3777        || GET_MODE (operands[0]) == XFmode
3778        || GET_MODE (operands[0]) == SFmode
3779        || GET_MODE (operands[0]) == DFmode)
3780    && (operands[2] = find_constant_src (insn))"
3781   [(set (match_dup 0) (match_dup 2))]
3782 {
3783   rtx c = operands[2];
3784   rtx r = operands[0];
3785
3786   if (GET_CODE (r) == SUBREG)
3787     r = SUBREG_REG (r);
3788
3789   if (SSE_REG_P (r))
3790     {
3791       if (!standard_sse_constant_p (c))
3792         FAIL;
3793     }
3794   else if (FP_REG_P (r))
3795     {
3796       if (!standard_80387_constant_p (c))
3797         FAIL;
3798     }
3799   else if (MMX_REG_P (r))
3800     FAIL;
3801 })
3802
3803 (define_split
3804   [(set (match_operand 0 "register_operand" "")
3805         (float_extend (match_operand 1 "memory_operand" "")))]
3806   "reload_completed
3807    && MEM_P (operands[1])
3808    && (GET_MODE (operands[0]) == TFmode
3809        || GET_MODE (operands[0]) == XFmode
3810        || GET_MODE (operands[0]) == SFmode
3811        || GET_MODE (operands[0]) == DFmode)
3812    && (operands[2] = find_constant_src (insn))"
3813   [(set (match_dup 0) (match_dup 2))]
3814 {
3815   rtx c = operands[2];
3816   rtx r = operands[0];
3817
3818   if (GET_CODE (r) == SUBREG)
3819     r = SUBREG_REG (r);
3820
3821   if (SSE_REG_P (r))
3822     {
3823       if (!standard_sse_constant_p (c))
3824         FAIL;
3825     }
3826   else if (FP_REG_P (r))
3827     {
3828       if (!standard_80387_constant_p (c))
3829         FAIL;
3830     }
3831   else if (MMX_REG_P (r))
3832     FAIL;
3833 })
3834
3835 (define_insn "swapxf"
3836   [(set (match_operand:XF 0 "register_operand" "+f")
3837         (match_operand:XF 1 "register_operand" "+f"))
3838    (set (match_dup 1)
3839         (match_dup 0))]
3840   "TARGET_80387"
3841 {
3842   if (STACK_TOP_P (operands[0]))
3843     return "fxch\t%1";
3844   else
3845     return "fxch\t%0";
3846 }
3847   [(set_attr "type" "fxch")
3848    (set_attr "mode" "XF")])
3849
3850 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3851 (define_split
3852   [(set (match_operand:X87MODEF 0 "register_operand" "")
3853         (match_operand:X87MODEF 1 "immediate_operand" ""))]
3854   "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3855    && (standard_80387_constant_p (operands[1]) == 8
3856        || standard_80387_constant_p (operands[1]) == 9)"
3857   [(set (match_dup 0)(match_dup 1))
3858    (set (match_dup 0)
3859         (neg:X87MODEF (match_dup 0)))]
3860 {
3861   REAL_VALUE_TYPE r;
3862
3863   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3864   if (real_isnegzero (&r))
3865     operands[1] = CONST0_RTX (<MODE>mode);
3866   else
3867     operands[1] = CONST1_RTX (<MODE>mode);
3868 })
3869
3870 (define_split
3871   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3872         (match_operand:TF 1 "general_operand" ""))]
3873   "reload_completed
3874    && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
3875   [(const_int 0)]
3876   "ix86_split_long_move (operands); DONE;")
3877 \f
3878 ;; Zero extension instructions
3879
3880 (define_expand "zero_extendhisi2"
3881   [(set (match_operand:SI 0 "register_operand" "")
3882      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3883   ""
3884 {
3885   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3886     {
3887       operands[1] = force_reg (HImode, operands[1]);
3888       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3889       DONE;
3890     }
3891 })
3892
3893 (define_insn "zero_extendhisi2_and"
3894   [(set (match_operand:SI 0 "register_operand" "=r")
3895      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3896    (clobber (reg:CC FLAGS_REG))]
3897   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3898   "#"
3899   [(set_attr "type" "alu1")
3900    (set_attr "mode" "SI")])
3901
3902 (define_split
3903   [(set (match_operand:SI 0 "register_operand" "")
3904         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3905    (clobber (reg:CC FLAGS_REG))]
3906   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND
3907    && optimize_function_for_speed_p (cfun)"
3908   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3909               (clobber (reg:CC FLAGS_REG))])]
3910   "")
3911
3912 (define_insn "*zero_extendhisi2_movzwl"
3913   [(set (match_operand:SI 0 "register_operand" "=r")
3914      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3915   "!TARGET_ZERO_EXTEND_WITH_AND
3916    || optimize_function_for_size_p (cfun)"
3917   "movz{wl|x}\t{%1, %0|%0, %1}"
3918   [(set_attr "type" "imovx")
3919    (set_attr "mode" "SI")])
3920
3921 (define_expand "zero_extendqihi2"
3922   [(parallel
3923     [(set (match_operand:HI 0 "register_operand" "")
3924        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3925      (clobber (reg:CC FLAGS_REG))])]
3926   ""
3927   "")
3928
3929 (define_insn "*zero_extendqihi2_and"
3930   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3931      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3932    (clobber (reg:CC FLAGS_REG))]
3933   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3934   "#"
3935   [(set_attr "type" "alu1")
3936    (set_attr "mode" "HI")])
3937
3938 (define_insn "*zero_extendqihi2_movzbw_and"
3939   [(set (match_operand:HI 0 "register_operand" "=r,r")
3940      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3941    (clobber (reg:CC FLAGS_REG))]
3942   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3943   "#"
3944   [(set_attr "type" "imovx,alu1")
3945    (set_attr "mode" "HI")])
3946
3947 ; zero extend to SImode here to avoid partial register stalls
3948 (define_insn "*zero_extendqihi2_movzbl"
3949   [(set (match_operand:HI 0 "register_operand" "=r")
3950      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3951   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3952    && reload_completed"
3953   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3954   [(set_attr "type" "imovx")
3955    (set_attr "mode" "SI")])
3956
3957 ;; For the movzbw case strip only the clobber
3958 (define_split
3959   [(set (match_operand:HI 0 "register_operand" "")
3960         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3961    (clobber (reg:CC FLAGS_REG))]
3962   "reload_completed
3963    && (!TARGET_ZERO_EXTEND_WITH_AND
3964        || optimize_function_for_size_p (cfun))
3965    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3966   [(set (match_operand:HI 0 "register_operand" "")
3967         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3968
3969 ;; When source and destination does not overlap, clear destination
3970 ;; first and then do the movb
3971 (define_split
3972   [(set (match_operand:HI 0 "register_operand" "")
3973         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3974    (clobber (reg:CC FLAGS_REG))]
3975   "reload_completed
3976    && ANY_QI_REG_P (operands[0])
3977    && (TARGET_ZERO_EXTEND_WITH_AND
3978        && optimize_function_for_speed_p (cfun))
3979    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3980   [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3981 {
3982   operands[2] = gen_lowpart (QImode, operands[0]);
3983   ix86_expand_clear (operands[0]);
3984 })
3985
3986 ;; Rest is handled by single and.
3987 (define_split
3988   [(set (match_operand:HI 0 "register_operand" "")
3989         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3990    (clobber (reg:CC FLAGS_REG))]
3991   "reload_completed
3992    && true_regnum (operands[0]) == true_regnum (operands[1])"
3993   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3994               (clobber (reg:CC FLAGS_REG))])]
3995   "")
3996
3997 (define_expand "zero_extendqisi2"
3998   [(parallel
3999     [(set (match_operand:SI 0 "register_operand" "")
4000        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
4001      (clobber (reg:CC FLAGS_REG))])]
4002   ""
4003   "")
4004
4005 (define_insn "*zero_extendqisi2_and"
4006   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
4007      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
4008    (clobber (reg:CC FLAGS_REG))]
4009   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4010   "#"
4011   [(set_attr "type" "alu1")
4012    (set_attr "mode" "SI")])
4013
4014 (define_insn "*zero_extendqisi2_movzbl_and"
4015   [(set (match_operand:SI 0 "register_operand" "=r,r")
4016      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
4017    (clobber (reg:CC FLAGS_REG))]
4018   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
4019   "#"
4020   [(set_attr "type" "imovx,alu1")
4021    (set_attr "mode" "SI")])
4022
4023 (define_insn "*zero_extendqisi2_movzbl"
4024   [(set (match_operand:SI 0 "register_operand" "=r")
4025      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4026   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
4027    && reload_completed"
4028   "movz{bl|x}\t{%1, %0|%0, %1}"
4029   [(set_attr "type" "imovx")
4030    (set_attr "mode" "SI")])
4031
4032 ;; For the movzbl case strip only the clobber
4033 (define_split
4034   [(set (match_operand:SI 0 "register_operand" "")
4035         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
4036    (clobber (reg:CC FLAGS_REG))]
4037   "reload_completed
4038    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
4039    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
4040   [(set (match_dup 0)
4041         (zero_extend:SI (match_dup 1)))])
4042
4043 ;; When source and destination does not overlap, clear destination
4044 ;; first and then do the movb
4045 (define_split
4046   [(set (match_operand:SI 0 "register_operand" "")
4047         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
4048    (clobber (reg:CC FLAGS_REG))]
4049   "reload_completed
4050    && ANY_QI_REG_P (operands[0])
4051    && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
4052    && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
4053    && !reg_overlap_mentioned_p (operands[0], operands[1])"
4054   [(set (strict_low_part (match_dup 2)) (match_dup 1))]
4055 {
4056   operands[2] = gen_lowpart (QImode, operands[0]);
4057   ix86_expand_clear (operands[0]);
4058 })
4059
4060 ;; Rest is handled by single and.
4061 (define_split
4062   [(set (match_operand:SI 0 "register_operand" "")
4063         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
4064    (clobber (reg:CC FLAGS_REG))]
4065   "reload_completed
4066    && true_regnum (operands[0]) == true_regnum (operands[1])"
4067   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
4068               (clobber (reg:CC FLAGS_REG))])]
4069   "")
4070
4071 ;; %%% Kill me once multi-word ops are sane.
4072 (define_expand "zero_extendsidi2"
4073   [(set (match_operand:DI 0 "register_operand" "")
4074      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
4075   ""
4076 {
4077   if (!TARGET_64BIT)
4078     {
4079       emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
4080       DONE;
4081     }
4082 })
4083
4084 (define_insn "zero_extendsidi2_32"
4085   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
4086         (zero_extend:DI
4087          (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r   ,m  ,r   ,m")))
4088    (clobber (reg:CC FLAGS_REG))]
4089   "!TARGET_64BIT"
4090   "@
4091    #
4092    #
4093    #
4094    movd\t{%1, %0|%0, %1}
4095    movd\t{%1, %0|%0, %1}
4096    %vmovd\t{%1, %0|%0, %1}
4097    %vmovd\t{%1, %0|%0, %1}"
4098   [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
4099    (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
4100    (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
4101
4102 (define_insn "zero_extendsidi2_rex64"
4103   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
4104      (zero_extend:DI
4105        (match_operand:SI 1 "nonimmediate_operand"  "rm,0,r   ,m  ,r   ,m")))]
4106   "TARGET_64BIT"
4107   "@
4108    mov\t{%k1, %k0|%k0, %k1}
4109    #
4110    movd\t{%1, %0|%0, %1}
4111    movd\t{%1, %0|%0, %1}
4112    %vmovd\t{%1, %0|%0, %1}
4113    %vmovd\t{%1, %0|%0, %1}"
4114   [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
4115    (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
4116    (set_attr "prefix_0f" "0,*,*,*,*,*")
4117    (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
4118
4119 (define_split
4120   [(set (match_operand:DI 0 "memory_operand" "")
4121      (zero_extend:DI (match_dup 0)))]
4122   "TARGET_64BIT"
4123   [(set (match_dup 4) (const_int 0))]
4124   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4125
4126 (define_split
4127   [(set (match_operand:DI 0 "register_operand" "")
4128         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
4129    (clobber (reg:CC FLAGS_REG))]
4130   "!TARGET_64BIT && reload_completed
4131    && true_regnum (operands[0]) == true_regnum (operands[1])"
4132   [(set (match_dup 4) (const_int 0))]
4133   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4134
4135 (define_split
4136   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4137         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
4138    (clobber (reg:CC FLAGS_REG))]
4139   "!TARGET_64BIT && reload_completed
4140    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
4141   [(set (match_dup 3) (match_dup 1))
4142    (set (match_dup 4) (const_int 0))]
4143   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4144
4145 (define_insn "zero_extendhidi2"
4146   [(set (match_operand:DI 0 "register_operand" "=r")
4147      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
4148   "TARGET_64BIT"
4149   "movz{wl|x}\t{%1, %k0|%k0, %1}"
4150   [(set_attr "type" "imovx")
4151    (set_attr "mode" "SI")])
4152
4153 (define_insn "zero_extendqidi2"
4154   [(set (match_operand:DI 0 "register_operand" "=r")
4155      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
4156   "TARGET_64BIT"
4157   "movz{bl|x}\t{%1, %k0|%k0, %1}"
4158   [(set_attr "type" "imovx")
4159    (set_attr "mode" "SI")])
4160 \f
4161 ;; Sign extension instructions
4162
4163 (define_expand "extendsidi2"
4164   [(parallel [(set (match_operand:DI 0 "register_operand" "")
4165                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4166               (clobber (reg:CC FLAGS_REG))
4167               (clobber (match_scratch:SI 2 ""))])]
4168   ""
4169 {
4170   if (TARGET_64BIT)
4171     {
4172       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
4173       DONE;
4174     }
4175 })
4176
4177 (define_insn "*extendsidi2_1"
4178   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
4179         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
4180    (clobber (reg:CC FLAGS_REG))
4181    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
4182   "!TARGET_64BIT"
4183   "#")
4184
4185 (define_insn "extendsidi2_rex64"
4186   [(set (match_operand:DI 0 "register_operand" "=*a,r")
4187         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
4188   "TARGET_64BIT"
4189   "@
4190    {cltq|cdqe}
4191    movs{lq|x}\t{%1, %0|%0, %1}"
4192   [(set_attr "type" "imovx")
4193    (set_attr "mode" "DI")
4194    (set_attr "prefix_0f" "0")
4195    (set_attr "modrm" "0,1")])
4196
4197 (define_insn "extendhidi2"
4198   [(set (match_operand:DI 0 "register_operand" "=r")
4199         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
4200   "TARGET_64BIT"
4201   "movs{wq|x}\t{%1, %0|%0, %1}"
4202   [(set_attr "type" "imovx")
4203    (set_attr "mode" "DI")])
4204
4205 (define_insn "extendqidi2"
4206   [(set (match_operand:DI 0 "register_operand" "=r")
4207         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4208   "TARGET_64BIT"
4209   "movs{bq|x}\t{%1, %0|%0, %1}"
4210    [(set_attr "type" "imovx")
4211     (set_attr "mode" "DI")])
4212
4213 ;; Extend to memory case when source register does die.
4214 (define_split
4215   [(set (match_operand:DI 0 "memory_operand" "")
4216         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4217    (clobber (reg:CC FLAGS_REG))
4218    (clobber (match_operand:SI 2 "register_operand" ""))]
4219   "(reload_completed
4220     && dead_or_set_p (insn, operands[1])
4221     && !reg_mentioned_p (operands[1], operands[0]))"
4222   [(set (match_dup 3) (match_dup 1))
4223    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4224               (clobber (reg:CC FLAGS_REG))])
4225    (set (match_dup 4) (match_dup 1))]
4226   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4227
4228 ;; Extend to memory case when source register does not die.
4229 (define_split
4230   [(set (match_operand:DI 0 "memory_operand" "")
4231         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4232    (clobber (reg:CC FLAGS_REG))
4233    (clobber (match_operand:SI 2 "register_operand" ""))]
4234   "reload_completed"
4235   [(const_int 0)]
4236 {
4237   split_di (&operands[0], 1, &operands[3], &operands[4]);
4238
4239   emit_move_insn (operands[3], operands[1]);
4240
4241   /* Generate a cltd if possible and doing so it profitable.  */
4242   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4243       && true_regnum (operands[1]) == AX_REG
4244       && true_regnum (operands[2]) == DX_REG)
4245     {
4246       emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
4247     }
4248   else
4249     {
4250       emit_move_insn (operands[2], operands[1]);
4251       emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
4252     }
4253   emit_move_insn (operands[4], operands[2]);
4254   DONE;
4255 })
4256
4257 ;; Extend to register case.  Optimize case where source and destination
4258 ;; registers match and cases where we can use cltd.
4259 (define_split
4260   [(set (match_operand:DI 0 "register_operand" "")
4261         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4262    (clobber (reg:CC FLAGS_REG))
4263    (clobber (match_scratch:SI 2 ""))]
4264   "reload_completed"
4265   [(const_int 0)]
4266 {
4267   split_di (&operands[0], 1, &operands[3], &operands[4]);
4268
4269   if (true_regnum (operands[3]) != true_regnum (operands[1]))
4270     emit_move_insn (operands[3], operands[1]);
4271
4272   /* Generate a cltd if possible and doing so it profitable.  */
4273   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4274       && true_regnum (operands[3]) == AX_REG
4275       && true_regnum (operands[4]) == DX_REG)
4276     {
4277       emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
4278       DONE;
4279     }
4280
4281   if (true_regnum (operands[4]) != true_regnum (operands[1]))
4282     emit_move_insn (operands[4], operands[1]);
4283
4284   emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
4285   DONE;
4286 })
4287
4288 (define_insn "extendhisi2"
4289   [(set (match_operand:SI 0 "register_operand" "=*a,r")
4290         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4291   ""
4292 {
4293   switch (get_attr_prefix_0f (insn))
4294     {
4295     case 0:
4296       return "{cwtl|cwde}";
4297     default:
4298       return "movs{wl|x}\t{%1, %0|%0, %1}";
4299     }
4300 }
4301   [(set_attr "type" "imovx")
4302    (set_attr "mode" "SI")
4303    (set (attr "prefix_0f")
4304      ;; movsx is short decodable while cwtl is vector decoded.
4305      (if_then_else (and (eq_attr "cpu" "!k6")
4306                         (eq_attr "alternative" "0"))
4307         (const_string "0")
4308         (const_string "1")))
4309    (set (attr "modrm")
4310      (if_then_else (eq_attr "prefix_0f" "0")
4311         (const_string "0")
4312         (const_string "1")))])
4313
4314 (define_insn "*extendhisi2_zext"
4315   [(set (match_operand:DI 0 "register_operand" "=*a,r")
4316         (zero_extend:DI
4317           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4318   "TARGET_64BIT"
4319 {
4320   switch (get_attr_prefix_0f (insn))
4321     {
4322     case 0:
4323       return "{cwtl|cwde}";
4324     default:
4325       return "movs{wl|x}\t{%1, %k0|%k0, %1}";
4326     }
4327 }
4328   [(set_attr "type" "imovx")
4329    (set_attr "mode" "SI")
4330    (set (attr "prefix_0f")
4331      ;; movsx is short decodable while cwtl is vector decoded.
4332      (if_then_else (and (eq_attr "cpu" "!k6")
4333                         (eq_attr "alternative" "0"))
4334         (const_string "0")
4335         (const_string "1")))
4336    (set (attr "modrm")
4337      (if_then_else (eq_attr "prefix_0f" "0")
4338         (const_string "0")
4339         (const_string "1")))])
4340
4341 (define_insn "extendqihi2"
4342   [(set (match_operand:HI 0 "register_operand" "=*a,r")
4343         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4344   ""
4345 {
4346   switch (get_attr_prefix_0f (insn))
4347     {
4348     case 0:
4349       return "{cbtw|cbw}";
4350     default:
4351       return "movs{bw|x}\t{%1, %0|%0, %1}";
4352     }
4353 }
4354   [(set_attr "type" "imovx")
4355    (set_attr "mode" "HI")
4356    (set (attr "prefix_0f")
4357      ;; movsx is short decodable while cwtl is vector decoded.
4358      (if_then_else (and (eq_attr "cpu" "!k6")
4359                         (eq_attr "alternative" "0"))
4360         (const_string "0")
4361         (const_string "1")))
4362    (set (attr "modrm")
4363      (if_then_else (eq_attr "prefix_0f" "0")
4364         (const_string "0")
4365         (const_string "1")))])
4366
4367 (define_insn "extendqisi2"
4368   [(set (match_operand:SI 0 "register_operand" "=r")
4369         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4370   ""
4371   "movs{bl|x}\t{%1, %0|%0, %1}"
4372    [(set_attr "type" "imovx")
4373     (set_attr "mode" "SI")])
4374
4375 (define_insn "*extendqisi2_zext"
4376   [(set (match_operand:DI 0 "register_operand" "=r")
4377         (zero_extend:DI
4378           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4379   "TARGET_64BIT"
4380   "movs{bl|x}\t{%1, %k0|%k0, %1}"
4381    [(set_attr "type" "imovx")
4382     (set_attr "mode" "SI")])
4383 \f
4384 ;; Conversions between float and double.
4385
4386 ;; These are all no-ops in the model used for the 80387.  So just
4387 ;; emit moves.
4388
4389 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4390 (define_insn "*dummy_extendsfdf2"
4391   [(set (match_operand:DF 0 "push_operand" "=<")
4392         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY2")))]
4393   "0"
4394   "#")
4395
4396 (define_split
4397   [(set (match_operand:DF 0 "push_operand" "")
4398         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
4399   ""
4400   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4401    (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4402
4403 (define_insn "*dummy_extendsfxf2"
4404   [(set (match_operand:XF 0 "push_operand" "=<")
4405         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
4406   "0"
4407   "#")
4408
4409 (define_split
4410   [(set (match_operand:XF 0 "push_operand" "")
4411         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
4412   ""
4413   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4414    (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4415   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4416
4417 (define_split
4418   [(set (match_operand:XF 0 "push_operand" "")
4419         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
4420   ""
4421   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4422    (set (mem:DF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4423   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4424
4425 (define_expand "extendsfdf2"
4426   [(set (match_operand:DF 0 "nonimmediate_operand" "")
4427         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
4428   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4429 {
4430   /* ??? Needed for compress_float_constant since all fp constants
4431      are LEGITIMATE_CONSTANT_P.  */
4432   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4433     {
4434       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4435           && standard_80387_constant_p (operands[1]) > 0)
4436         {
4437           operands[1] = simplify_const_unary_operation
4438             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4439           emit_move_insn_1 (operands[0], operands[1]);
4440           DONE;
4441         }
4442       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4443     }
4444 })
4445
4446 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4447    cvtss2sd:
4448       unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4449       cvtps2pd xmm2,xmm1
4450    We do the conversion post reload to avoid producing of 128bit spills
4451    that might lead to ICE on 32bit target.  The sequence unlikely combine
4452    anyway.  */
4453 (define_split
4454   [(set (match_operand:DF 0 "register_operand" "")
4455         (float_extend:DF
4456           (match_operand:SF 1 "nonimmediate_operand" "")))]
4457   "TARGET_USE_VECTOR_FP_CONVERTS
4458    && optimize_insn_for_speed_p ()
4459    && reload_completed && SSE_REG_P (operands[0])"
4460    [(set (match_dup 2)
4461          (float_extend:V2DF
4462            (vec_select:V2SF
4463              (match_dup 3)
4464              (parallel [(const_int 0) (const_int 1)]))))]
4465 {
4466   operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4467   operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4468   /* Use movss for loading from memory, unpcklps reg, reg for registers.
4469      Try to avoid move when unpacking can be done in source.  */
4470   if (REG_P (operands[1]))
4471     {
4472       /* If it is unsafe to overwrite upper half of source, we need
4473          to move to destination and unpack there.  */
4474       if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4475            || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4476           && true_regnum (operands[0]) != true_regnum (operands[1]))
4477         {
4478           rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4479           emit_move_insn (tmp, operands[1]);
4480         }
4481       else
4482         operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4483       emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4484                                              operands[3]));
4485     }
4486   else
4487     emit_insn (gen_vec_setv4sf_0 (operands[3],
4488                                   CONST0_RTX (V4SFmode), operands[1]));
4489 })
4490
4491 (define_insn "*extendsfdf2_mixed"
4492   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4493         (float_extend:DF
4494           (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4495   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4496 {
4497   switch (which_alternative)
4498     {
4499     case 0:
4500     case 1:
4501       return output_387_reg_move (insn, operands);
4502
4503     case 2:
4504       return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4505
4506     default:
4507       gcc_unreachable ();
4508     }
4509 }
4510   [(set_attr "type" "fmov,fmov,ssecvt")
4511    (set_attr "prefix" "orig,orig,maybe_vex")
4512    (set_attr "mode" "SF,XF,DF")])
4513
4514 (define_insn "*extendsfdf2_sse"
4515   [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4516         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4517   "TARGET_SSE2 && TARGET_SSE_MATH"
4518   "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4519   [(set_attr "type" "ssecvt")
4520    (set_attr "prefix" "maybe_vex")
4521    (set_attr "mode" "DF")])
4522
4523 (define_insn "*extendsfdf2_i387"
4524   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4525         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4526   "TARGET_80387"
4527   "* return output_387_reg_move (insn, operands);"
4528   [(set_attr "type" "fmov")
4529    (set_attr "mode" "SF,XF")])
4530
4531 (define_expand "extend<mode>xf2"
4532   [(set (match_operand:XF 0 "nonimmediate_operand" "")
4533         (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4534   "TARGET_80387"
4535 {
4536   /* ??? Needed for compress_float_constant since all fp constants
4537      are LEGITIMATE_CONSTANT_P.  */
4538   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4539     {
4540       if (standard_80387_constant_p (operands[1]) > 0)
4541         {
4542           operands[1] = simplify_const_unary_operation
4543             (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4544           emit_move_insn_1 (operands[0], operands[1]);
4545           DONE;
4546         }
4547       operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4548     }
4549 })
4550
4551 (define_insn "*extend<mode>xf2_i387"
4552   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4553         (float_extend:XF
4554           (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4555   "TARGET_80387"
4556   "* return output_387_reg_move (insn, operands);"
4557   [(set_attr "type" "fmov")
4558    (set_attr "mode" "<MODE>,XF")])
4559
4560 ;; %%% This seems bad bad news.
4561 ;; This cannot output into an f-reg because there is no way to be sure
4562 ;; of truncating in that case.  Otherwise this is just like a simple move
4563 ;; insn.  So we pretend we can output to a reg in order to get better
4564 ;; register preferencing, but we really use a stack slot.
4565
4566 ;; Conversion from DFmode to SFmode.
4567
4568 (define_expand "truncdfsf2"
4569   [(set (match_operand:SF 0 "nonimmediate_operand" "")
4570         (float_truncate:SF
4571           (match_operand:DF 1 "nonimmediate_operand" "")))]
4572   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4573 {
4574   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4575     ;
4576   else if (flag_unsafe_math_optimizations)
4577     ;
4578   else
4579     {
4580       enum ix86_stack_slot slot = (virtuals_instantiated
4581                                    ? SLOT_TEMP
4582                                    : SLOT_VIRTUAL);
4583       rtx temp = assign_386_stack_local (SFmode, slot);
4584       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4585       DONE;
4586     }
4587 })
4588
4589 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4590    cvtsd2ss:
4591       unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4592       cvtpd2ps xmm2,xmm1
4593    We do the conversion post reload to avoid producing of 128bit spills
4594    that might lead to ICE on 32bit target.  The sequence unlikely combine
4595    anyway.  */
4596 (define_split
4597   [(set (match_operand:SF 0 "register_operand" "")
4598         (float_truncate:SF
4599           (match_operand:DF 1 "nonimmediate_operand" "")))]
4600   "TARGET_USE_VECTOR_FP_CONVERTS
4601    && optimize_insn_for_speed_p ()
4602    && reload_completed && SSE_REG_P (operands[0])"
4603    [(set (match_dup 2)
4604          (vec_concat:V4SF
4605            (float_truncate:V2SF
4606              (match_dup 4))
4607            (match_dup 3)))]
4608 {
4609   operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4610   operands[3] = CONST0_RTX (V2SFmode);
4611   operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4612   /* Use movsd for loading from memory, unpcklpd for registers.
4613      Try to avoid move when unpacking can be done in source, or SSE3
4614      movddup is available.  */
4615   if (REG_P (operands[1]))
4616     {
4617       if (!TARGET_SSE3
4618           && true_regnum (operands[0]) != true_regnum (operands[1])
4619           && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4620               || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4621         {
4622           rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4623           emit_move_insn (tmp, operands[1]);
4624           operands[1] = tmp;
4625         }
4626       else if (!TARGET_SSE3)
4627         operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4628       emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4629     }
4630   else
4631     emit_insn (gen_sse2_loadlpd (operands[4],
4632                                  CONST0_RTX (V2DFmode), operands[1]));
4633 })
4634
4635 (define_expand "truncdfsf2_with_temp"
4636   [(parallel [(set (match_operand:SF 0 "" "")
4637                    (float_truncate:SF (match_operand:DF 1 "" "")))
4638               (clobber (match_operand:SF 2 "" ""))])]
4639   "")
4640
4641 (define_insn "*truncdfsf_fast_mixed"
4642   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm,x")
4643         (float_truncate:SF
4644           (match_operand:DF 1 "nonimmediate_operand" "f  ,xm")))]
4645   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4646 {
4647   switch (which_alternative)
4648     {
4649     case 0:
4650       return output_387_reg_move (insn, operands);
4651     case 1:
4652       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4653     default:
4654       gcc_unreachable ();
4655     }
4656 }
4657   [(set_attr "type" "fmov,ssecvt")
4658    (set_attr "prefix" "orig,maybe_vex")
4659    (set_attr "mode" "SF")])
4660
4661 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4662 ;; because nothing we do here is unsafe.
4663 (define_insn "*truncdfsf_fast_sse"
4664   [(set (match_operand:SF 0 "nonimmediate_operand"   "=x")
4665         (float_truncate:SF
4666           (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4667   "TARGET_SSE2 && TARGET_SSE_MATH"
4668   "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4669   [(set_attr "type" "ssecvt")
4670    (set_attr "prefix" "maybe_vex")
4671    (set_attr "mode" "SF")])
4672
4673 (define_insn "*truncdfsf_fast_i387"
4674   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
4675         (float_truncate:SF
4676           (match_operand:DF 1 "nonimmediate_operand" "f")))]
4677   "TARGET_80387 && flag_unsafe_math_optimizations"
4678   "* return output_387_reg_move (insn, operands);"
4679   [(set_attr "type" "fmov")
4680    (set_attr "mode" "SF")])
4681
4682 (define_insn "*truncdfsf_mixed"
4683   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,Y2 ,?f,?x,?*r")
4684         (float_truncate:SF
4685           (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4686    (clobber (match_operand:SF 2 "memory_operand"     "=X,X  ,m ,m ,m"))]
4687   "TARGET_MIX_SSE_I387"
4688 {
4689   switch (which_alternative)
4690     {
4691     case 0:
4692       return output_387_reg_move (insn, operands);
4693     case 1:
4694       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4695
4696     default:
4697       return "#";
4698     }
4699 }
4700   [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4701    (set_attr "unit" "*,*,i387,i387,i387")
4702    (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4703    (set_attr "mode" "SF")])
4704
4705 (define_insn "*truncdfsf_i387"
4706   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?f,?x,?*r")
4707         (float_truncate:SF
4708           (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4709    (clobber (match_operand:SF 2 "memory_operand"     "=X,m ,m ,m"))]
4710   "TARGET_80387"
4711 {
4712   switch (which_alternative)
4713     {
4714     case 0:
4715       return output_387_reg_move (insn, operands);
4716
4717     default:
4718       return "#";
4719     }
4720 }
4721   [(set_attr "type" "fmov,multi,multi,multi")
4722    (set_attr "unit" "*,i387,i387,i387")
4723    (set_attr "mode" "SF")])
4724
4725 (define_insn "*truncdfsf2_i387_1"
4726   [(set (match_operand:SF 0 "memory_operand" "=m")
4727         (float_truncate:SF
4728           (match_operand:DF 1 "register_operand" "f")))]
4729   "TARGET_80387
4730    && !(TARGET_SSE2 && TARGET_SSE_MATH)
4731    && !TARGET_MIX_SSE_I387"
4732   "* return output_387_reg_move (insn, operands);"
4733   [(set_attr "type" "fmov")
4734    (set_attr "mode" "SF")])
4735
4736 (define_split
4737   [(set (match_operand:SF 0 "register_operand" "")
4738         (float_truncate:SF
4739          (match_operand:DF 1 "fp_register_operand" "")))
4740    (clobber (match_operand 2 "" ""))]
4741   "reload_completed"
4742   [(set (match_dup 2) (match_dup 1))
4743    (set (match_dup 0) (match_dup 2))]
4744 {
4745   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4746 })
4747
4748 ;; Conversion from XFmode to {SF,DF}mode
4749
4750 (define_expand "truncxf<mode>2"
4751   [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4752                    (float_truncate:MODEF
4753                      (match_operand:XF 1 "register_operand" "")))
4754               (clobber (match_dup 2))])]
4755   "TARGET_80387"
4756 {
4757   if (flag_unsafe_math_optimizations)
4758     {
4759       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4760       emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4761       if (reg != operands[0])
4762         emit_move_insn (operands[0], reg);
4763       DONE;
4764     }
4765   else
4766     {
4767      enum ix86_stack_slot slot = (virtuals_instantiated
4768                                   ? SLOT_TEMP
4769                                   : SLOT_VIRTUAL);
4770       operands[2] = assign_386_stack_local (<MODE>mode, slot);
4771     }
4772 })
4773
4774 (define_insn "*truncxfsf2_mixed"
4775   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4776         (float_truncate:SF
4777           (match_operand:XF 1 "register_operand"   "f ,f ,f ,f")))
4778    (clobber (match_operand:SF 2 "memory_operand"   "=X,m ,m ,m"))]
4779   "TARGET_80387"
4780 {
4781   gcc_assert (!which_alternative);
4782   return output_387_reg_move (insn, operands);
4783 }
4784   [(set_attr "type" "fmov,multi,multi,multi")
4785    (set_attr "unit" "*,i387,i387,i387")
4786    (set_attr "mode" "SF")])
4787
4788 (define_insn "*truncxfdf2_mixed"
4789   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4790         (float_truncate:DF
4791           (match_operand:XF 1 "register_operand"   "f ,f ,f  ,f")))
4792    (clobber (match_operand:DF 2 "memory_operand"   "=X,m ,m  ,m"))]
4793   "TARGET_80387"
4794 {
4795   gcc_assert (!which_alternative);
4796   return output_387_reg_move (insn, operands);
4797 }
4798   [(set_attr "type" "fmov,multi,multi,multi")
4799    (set_attr "unit" "*,i387,i387,i387")
4800    (set_attr "mode" "DF")])
4801
4802 (define_insn "truncxf<mode>2_i387_noop"
4803   [(set (match_operand:MODEF 0 "register_operand" "=f")
4804         (float_truncate:MODEF
4805           (match_operand:XF 1 "register_operand" "f")))]
4806   "TARGET_80387 && flag_unsafe_math_optimizations"
4807   "* return output_387_reg_move (insn, operands);"
4808   [(set_attr "type" "fmov")
4809    (set_attr "mode" "<MODE>")])
4810
4811 (define_insn "*truncxf<mode>2_i387"
4812   [(set (match_operand:MODEF 0 "memory_operand" "=m")
4813         (float_truncate:MODEF
4814           (match_operand:XF 1 "register_operand" "f")))]
4815   "TARGET_80387"
4816   "* return output_387_reg_move (insn, operands);"
4817   [(set_attr "type" "fmov")
4818    (set_attr "mode" "<MODE>")])
4819
4820 (define_split
4821   [(set (match_operand:MODEF 0 "register_operand" "")
4822         (float_truncate:MODEF
4823           (match_operand:XF 1 "register_operand" "")))
4824    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4825   "TARGET_80387 && reload_completed"
4826   [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4827    (set (match_dup 0) (match_dup 2))]
4828   "")
4829
4830 (define_split
4831   [(set (match_operand:MODEF 0 "memory_operand" "")
4832         (float_truncate:MODEF
4833           (match_operand:XF 1 "register_operand" "")))
4834    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4835   "TARGET_80387"
4836   [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]
4837   "")
4838 \f
4839 ;; Signed conversion to DImode.
4840
4841 (define_expand "fix_truncxfdi2"
4842   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4843                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4844               (clobber (reg:CC FLAGS_REG))])]
4845   "TARGET_80387"
4846 {
4847   if (TARGET_FISTTP)
4848    {
4849      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4850      DONE;
4851    }
4852 })
4853
4854 (define_expand "fix_trunc<mode>di2"
4855   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4856                    (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4857               (clobber (reg:CC FLAGS_REG))])]
4858   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4859 {
4860   if (TARGET_FISTTP
4861       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4862    {
4863      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4864      DONE;
4865    }
4866   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4867    {
4868      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4869      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4870      if (out != operands[0])
4871         emit_move_insn (operands[0], out);
4872      DONE;
4873    }
4874 })
4875
4876 ;; Signed conversion to SImode.
4877
4878 (define_expand "fix_truncxfsi2"
4879   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4880                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4881               (clobber (reg:CC FLAGS_REG))])]
4882   "TARGET_80387"
4883 {
4884   if (TARGET_FISTTP)
4885    {
4886      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4887      DONE;
4888    }
4889 })
4890
4891 (define_expand "fix_trunc<mode>si2"
4892   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4893                    (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4894               (clobber (reg:CC FLAGS_REG))])]
4895   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4896 {
4897   if (TARGET_FISTTP
4898       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4899    {
4900      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4901      DONE;
4902    }
4903   if (SSE_FLOAT_MODE_P (<MODE>mode))
4904    {
4905      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4906      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4907      if (out != operands[0])
4908         emit_move_insn (operands[0], out);
4909      DONE;
4910    }
4911 })
4912
4913 ;; Signed conversion to HImode.
4914
4915 (define_expand "fix_trunc<mode>hi2"
4916   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4917                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4918               (clobber (reg:CC FLAGS_REG))])]
4919   "TARGET_80387
4920    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4921 {
4922   if (TARGET_FISTTP)
4923    {
4924      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4925      DONE;
4926    }
4927 })
4928
4929 ;; Unsigned conversion to SImode.
4930
4931 (define_expand "fixuns_trunc<mode>si2"
4932   [(parallel
4933     [(set (match_operand:SI 0 "register_operand" "")
4934           (unsigned_fix:SI
4935             (match_operand:MODEF 1 "nonimmediate_operand" "")))
4936      (use (match_dup 2))
4937      (clobber (match_scratch:<ssevecmode> 3 ""))
4938      (clobber (match_scratch:<ssevecmode> 4 ""))])]
4939   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4940 {
4941   enum machine_mode mode = <MODE>mode;
4942   enum machine_mode vecmode = <ssevecmode>mode;
4943   REAL_VALUE_TYPE TWO31r;
4944   rtx two31;
4945
4946   if (optimize_insn_for_size_p ())
4947     FAIL;
4948
4949   real_ldexp (&TWO31r, &dconst1, 31);
4950   two31 = const_double_from_real_value (TWO31r, mode);
4951   two31 = ix86_build_const_vector (mode, true, two31);
4952   operands[2] = force_reg (vecmode, two31);
4953 })
4954
4955 (define_insn_and_split "*fixuns_trunc<mode>_1"
4956   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4957         (unsigned_fix:SI
4958           (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4959    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
4960    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4961    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4962   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4963    && optimize_function_for_speed_p (cfun)"
4964   "#"
4965   "&& reload_completed"
4966   [(const_int 0)]
4967 {
4968   ix86_split_convert_uns_si_sse (operands);
4969   DONE;
4970 })
4971
4972 ;; Unsigned conversion to HImode.
4973 ;; Without these patterns, we'll try the unsigned SI conversion which
4974 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4975
4976 (define_expand "fixuns_trunc<mode>hi2"
4977   [(set (match_dup 2)
4978         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4979    (set (match_operand:HI 0 "nonimmediate_operand" "")
4980         (subreg:HI (match_dup 2) 0))]
4981   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4982   "operands[2] = gen_reg_rtx (SImode);")
4983
4984 ;; When SSE is available, it is always faster to use it!
4985 (define_insn "fix_trunc<mode>di_sse"
4986   [(set (match_operand:DI 0 "register_operand" "=r,r")
4987         (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4988   "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4989    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4990   "%vcvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4991   [(set_attr "type" "sseicvt")
4992    (set_attr "prefix" "maybe_vex")
4993    (set_attr "prefix_rex" "1")
4994    (set_attr "mode" "<MODE>")
4995    (set_attr "athlon_decode" "double,vector")
4996    (set_attr "amdfam10_decode" "double,double")])
4997
4998 (define_insn "fix_trunc<mode>si_sse"
4999   [(set (match_operand:SI 0 "register_operand" "=r,r")
5000         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
5001   "SSE_FLOAT_MODE_P (<MODE>mode)
5002    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
5003   "%vcvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
5004   [(set_attr "type" "sseicvt")
5005    (set_attr "prefix" "maybe_vex")
5006    (set_attr "mode" "<MODE>")
5007    (set_attr "athlon_decode" "double,vector")
5008    (set_attr "amdfam10_decode" "double,double")])
5009
5010 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
5011 (define_peephole2
5012   [(set (match_operand:MODEF 0 "register_operand" "")
5013         (match_operand:MODEF 1 "memory_operand" ""))
5014    (set (match_operand:SSEMODEI24 2 "register_operand" "")
5015         (fix:SSEMODEI24 (match_dup 0)))]
5016   "TARGET_SHORTEN_X87_SSE
5017    && peep2_reg_dead_p (2, operands[0])"
5018   [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
5019   "")
5020
5021 ;; Avoid vector decoded forms of the instruction.
5022 (define_peephole2
5023   [(match_scratch:DF 2 "Y2")
5024    (set (match_operand:SSEMODEI24 0 "register_operand" "")
5025         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
5026   "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
5027   [(set (match_dup 2) (match_dup 1))
5028    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
5029   "")
5030
5031 (define_peephole2
5032   [(match_scratch:SF 2 "x")
5033    (set (match_operand:SSEMODEI24 0 "register_operand" "")
5034         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
5035   "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
5036   [(set (match_dup 2) (match_dup 1))
5037    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
5038   "")
5039
5040 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
5041   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
5042         (fix:X87MODEI (match_operand 1 "register_operand" "")))]
5043   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5044    && TARGET_FISTTP
5045    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5046          && (TARGET_64BIT || <MODE>mode != DImode))
5047         && TARGET_SSE_MATH)
5048    && can_create_pseudo_p ()"
5049   "#"
5050   "&& 1"
5051   [(const_int 0)]
5052 {
5053   if (memory_operand (operands[0], VOIDmode))
5054     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
5055   else
5056     {
5057       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
5058       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
5059                                                             operands[1],
5060                                                             operands[2]));
5061     }
5062   DONE;
5063 }
5064   [(set_attr "type" "fisttp")
5065    (set_attr "mode" "<MODE>")])
5066
5067 (define_insn "fix_trunc<mode>_i387_fisttp"
5068   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
5069         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
5070    (clobber (match_scratch:XF 2 "=&1f"))]
5071   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5072    && TARGET_FISTTP
5073    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5074          && (TARGET_64BIT || <MODE>mode != DImode))
5075         && TARGET_SSE_MATH)"
5076   "* return output_fix_trunc (insn, operands, 1);"
5077   [(set_attr "type" "fisttp")
5078    (set_attr "mode" "<MODE>")])
5079
5080 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
5081   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
5082         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
5083    (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
5084    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
5085   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5086    && TARGET_FISTTP
5087    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5088         && (TARGET_64BIT || <MODE>mode != DImode))
5089         && TARGET_SSE_MATH)"
5090   "#"
5091   [(set_attr "type" "fisttp")
5092    (set_attr "mode" "<MODE>")])
5093
5094 (define_split
5095   [(set (match_operand:X87MODEI 0 "register_operand" "")
5096         (fix:X87MODEI (match_operand 1 "register_operand" "")))
5097    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
5098    (clobber (match_scratch 3 ""))]
5099   "reload_completed"
5100   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
5101               (clobber (match_dup 3))])
5102    (set (match_dup 0) (match_dup 2))]
5103   "")
5104
5105 (define_split
5106   [(set (match_operand:X87MODEI 0 "memory_operand" "")
5107         (fix:X87MODEI (match_operand 1 "register_operand" "")))
5108    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
5109    (clobber (match_scratch 3 ""))]
5110   "reload_completed"
5111   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
5112               (clobber (match_dup 3))])]
5113   "")
5114
5115 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
5116 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
5117 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
5118 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
5119 ;; function in i386.c.
5120 (define_insn_and_split "*fix_trunc<mode>_i387_1"
5121   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
5122         (fix:X87MODEI (match_operand 1 "register_operand" "")))
5123    (clobber (reg:CC FLAGS_REG))]
5124   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5125    && !TARGET_FISTTP
5126    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5127          && (TARGET_64BIT || <MODE>mode != DImode))
5128    && can_create_pseudo_p ()"
5129   "#"
5130   "&& 1"
5131   [(const_int 0)]
5132 {
5133   ix86_optimize_mode_switching[I387_TRUNC] = 1;
5134
5135   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
5136   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
5137   if (memory_operand (operands[0], VOIDmode))
5138     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
5139                                          operands[2], operands[3]));
5140   else
5141     {
5142       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
5143       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
5144                                                      operands[2], operands[3],
5145                                                      operands[4]));
5146     }
5147   DONE;
5148 }
5149   [(set_attr "type" "fistp")
5150    (set_attr "i387_cw" "trunc")
5151    (set_attr "mode" "<MODE>")])
5152
5153 (define_insn "fix_truncdi_i387"
5154   [(set (match_operand:DI 0 "memory_operand" "=m")
5155         (fix:DI (match_operand 1 "register_operand" "f")))
5156    (use (match_operand:HI 2 "memory_operand" "m"))
5157    (use (match_operand:HI 3 "memory_operand" "m"))
5158    (clobber (match_scratch:XF 4 "=&1f"))]
5159   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5160    && !TARGET_FISTTP
5161    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5162   "* return output_fix_trunc (insn, operands, 0);"
5163   [(set_attr "type" "fistp")
5164    (set_attr "i387_cw" "trunc")
5165    (set_attr "mode" "DI")])
5166
5167 (define_insn "fix_truncdi_i387_with_temp"
5168   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
5169         (fix:DI (match_operand 1 "register_operand" "f,f")))
5170    (use (match_operand:HI 2 "memory_operand" "m,m"))
5171    (use (match_operand:HI 3 "memory_operand" "m,m"))
5172    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
5173    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
5174   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5175    && !TARGET_FISTTP
5176    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5177   "#"
5178   [(set_attr "type" "fistp")
5179    (set_attr "i387_cw" "trunc")
5180    (set_attr "mode" "DI")])
5181
5182 (define_split
5183   [(set (match_operand:DI 0 "register_operand" "")
5184         (fix:DI (match_operand 1 "register_operand" "")))
5185    (use (match_operand:HI 2 "memory_operand" ""))
5186    (use (match_operand:HI 3 "memory_operand" ""))
5187    (clobber (match_operand:DI 4 "memory_operand" ""))
5188    (clobber (match_scratch 5 ""))]
5189   "reload_completed"
5190   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
5191               (use (match_dup 2))
5192               (use (match_dup 3))
5193               (clobber (match_dup 5))])
5194    (set (match_dup 0) (match_dup 4))]
5195   "")
5196
5197 (define_split
5198   [(set (match_operand:DI 0 "memory_operand" "")
5199         (fix:DI (match_operand 1 "register_operand" "")))
5200    (use (match_operand:HI 2 "memory_operand" ""))
5201    (use (match_operand:HI 3 "memory_operand" ""))
5202    (clobber (match_operand:DI 4 "memory_operand" ""))
5203    (clobber (match_scratch 5 ""))]
5204   "reload_completed"
5205   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
5206               (use (match_dup 2))
5207               (use (match_dup 3))
5208               (clobber (match_dup 5))])]
5209   "")
5210
5211 (define_insn "fix_trunc<mode>_i387"
5212   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
5213         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
5214    (use (match_operand:HI 2 "memory_operand" "m"))
5215    (use (match_operand:HI 3 "memory_operand" "m"))]
5216   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5217    && !TARGET_FISTTP
5218    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5219   "* return output_fix_trunc (insn, operands, 0);"
5220   [(set_attr "type" "fistp")
5221    (set_attr "i387_cw" "trunc")
5222    (set_attr "mode" "<MODE>")])
5223
5224 (define_insn "fix_trunc<mode>_i387_with_temp"
5225   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
5226         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
5227    (use (match_operand:HI 2 "memory_operand" "m,m"))
5228    (use (match_operand:HI 3 "memory_operand" "m,m"))
5229    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
5230   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5231    && !TARGET_FISTTP
5232    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5233   "#"
5234   [(set_attr "type" "fistp")
5235    (set_attr "i387_cw" "trunc")
5236    (set_attr "mode" "<MODE>")])
5237
5238 (define_split
5239   [(set (match_operand:X87MODEI12 0 "register_operand" "")
5240         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5241    (use (match_operand:HI 2 "memory_operand" ""))
5242    (use (match_operand:HI 3 "memory_operand" ""))
5243    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5244   "reload_completed"
5245   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
5246               (use (match_dup 2))
5247               (use (match_dup 3))])
5248    (set (match_dup 0) (match_dup 4))]
5249   "")
5250
5251 (define_split
5252   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
5253         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5254    (use (match_operand:HI 2 "memory_operand" ""))
5255    (use (match_operand:HI 3 "memory_operand" ""))
5256    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5257   "reload_completed"
5258   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
5259               (use (match_dup 2))
5260               (use (match_dup 3))])]
5261   "")
5262
5263 (define_insn "x86_fnstcw_1"
5264   [(set (match_operand:HI 0 "memory_operand" "=m")
5265         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
5266   "TARGET_80387"
5267   "fnstcw\t%0"
5268   [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5269    (set_attr "mode" "HI")
5270    (set_attr "unit" "i387")])
5271
5272 (define_insn "x86_fldcw_1"
5273   [(set (reg:HI FPCR_REG)
5274         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
5275   "TARGET_80387"
5276   "fldcw\t%0"
5277   [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5278    (set_attr "mode" "HI")
5279    (set_attr "unit" "i387")
5280    (set_attr "athlon_decode" "vector")
5281    (set_attr "amdfam10_decode" "vector")])
5282 \f
5283 ;; Conversion between fixed point and floating point.
5284
5285 ;; Even though we only accept memory inputs, the backend _really_
5286 ;; wants to be able to do this between registers.
5287
5288 (define_expand "floathi<mode>2"
5289   [(set (match_operand:X87MODEF 0 "register_operand" "")
5290         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
5291   "TARGET_80387
5292    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5293        || TARGET_MIX_SSE_I387)"
5294   "")
5295
5296 ;; Pre-reload splitter to add memory clobber to the pattern.
5297 (define_insn_and_split "*floathi<mode>2_1"
5298   [(set (match_operand:X87MODEF 0 "register_operand" "")
5299         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
5300   "TARGET_80387
5301    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5302        || TARGET_MIX_SSE_I387)
5303    && can_create_pseudo_p ()"
5304   "#"
5305   "&& 1"
5306   [(parallel [(set (match_dup 0)
5307               (float:X87MODEF (match_dup 1)))
5308    (clobber (match_dup 2))])]
5309   "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
5310
5311 (define_insn "*floathi<mode>2_i387_with_temp"
5312   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5313         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
5314   (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
5315   "TARGET_80387
5316    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5317        || TARGET_MIX_SSE_I387)"
5318   "#"
5319   [(set_attr "type" "fmov,multi")
5320    (set_attr "mode" "<MODE>")
5321    (set_attr "unit" "*,i387")
5322    (set_attr "fp_int_src" "true")])
5323
5324 (define_insn "*floathi<mode>2_i387"
5325   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5326         (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
5327   "TARGET_80387
5328    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5329        || TARGET_MIX_SSE_I387)"
5330   "fild%Z1\t%1"
5331   [(set_attr "type" "fmov")
5332    (set_attr "mode" "<MODE>")
5333    (set_attr "fp_int_src" "true")])
5334
5335 (define_split
5336   [(set (match_operand:X87MODEF 0 "register_operand" "")
5337         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
5338    (clobber (match_operand:HI 2 "memory_operand" ""))]
5339   "TARGET_80387
5340    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5341        || TARGET_MIX_SSE_I387)
5342    && reload_completed"
5343   [(set (match_dup 2) (match_dup 1))
5344    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5345   "")
5346
5347 (define_split
5348   [(set (match_operand:X87MODEF 0 "register_operand" "")
5349         (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
5350    (clobber (match_operand:HI 2 "memory_operand" ""))]
5351    "TARGET_80387
5352     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5353         || TARGET_MIX_SSE_I387)
5354     && reload_completed"
5355   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5356   "")
5357
5358 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
5359   [(set (match_operand:X87MODEF 0 "register_operand" "")
5360         (float:X87MODEF
5361           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
5362   "TARGET_80387
5363    || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5364        && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
5365 {
5366   if (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5367         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5368       && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode))
5369     {
5370       rtx reg = gen_reg_rtx (XFmode);
5371       rtx insn;
5372
5373       emit_insn (gen_float<SSEMODEI24:mode>xf2 (reg, operands[1]));
5374
5375       if (<X87MODEF:MODE>mode == SFmode)
5376         insn = gen_truncxfsf2 (operands[0], reg);
5377       else if (<X87MODEF:MODE>mode == DFmode)
5378         insn = gen_truncxfdf2 (operands[0], reg);
5379       else
5380         gcc_unreachable ();
5381
5382       emit_insn (insn);
5383       DONE;
5384     }
5385 })
5386
5387 ;; Pre-reload splitter to add memory clobber to the pattern.
5388 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
5389   [(set (match_operand:X87MODEF 0 "register_operand" "")
5390         (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
5391   "((TARGET_80387
5392      && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5393      && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5394            && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5395          || TARGET_MIX_SSE_I387))
5396     || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5397         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
5398         && ((<SSEMODEI24:MODE>mode == SImode
5399              && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
5400              && optimize_function_for_speed_p (cfun)
5401              && flag_trapping_math)
5402             || !(TARGET_INTER_UNIT_CONVERSIONS
5403                  || optimize_function_for_size_p (cfun)))))
5404    && can_create_pseudo_p ()"
5405   "#"
5406   "&& 1"
5407   [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
5408               (clobber (match_dup 2))])]
5409 {
5410   operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
5411
5412   /* Avoid store forwarding (partial memory) stall penalty
5413      by passing DImode value through XMM registers.  */
5414   if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
5415       && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5416       && optimize_function_for_speed_p (cfun))
5417     {
5418       emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
5419                                                             operands[1],
5420                                                             operands[2]));
5421       DONE;
5422     }
5423 })
5424
5425 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
5426   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
5427         (float:MODEF
5428           (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
5429    (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
5430   "TARGET_SSE2 && TARGET_MIX_SSE_I387
5431    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5432   "#"
5433   [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
5434    (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
5435    (set_attr "unit" "*,i387,*,*,*")
5436    (set_attr "athlon_decode" "*,*,double,direct,double")
5437    (set_attr "amdfam10_decode" "*,*,vector,double,double")
5438    (set_attr "fp_int_src" "true")])
5439
5440 (define_insn "*floatsi<mode>2_vector_mixed"
5441   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5442         (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
5443   "TARGET_SSE2 && TARGET_MIX_SSE_I387
5444    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5445   "@
5446    fild%Z1\t%1
5447    #"
5448   [(set_attr "type" "fmov,sseicvt")
5449    (set_attr "mode" "<MODE>,<ssevecmode>")
5450    (set_attr "unit" "i387,*")
5451    (set_attr "athlon_decode" "*,direct")
5452    (set_attr "amdfam10_decode" "*,double")
5453    (set_attr "fp_int_src" "true")])
5454
5455 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
5456   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
5457         (float:MODEF
5458           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
5459   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
5460   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5461    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
5462   "#"
5463   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5464    (set_attr "mode" "<MODEF:MODE>")
5465    (set_attr "unit" "*,i387,*,*")
5466    (set_attr "athlon_decode" "*,*,double,direct")
5467    (set_attr "amdfam10_decode" "*,*,vector,double")
5468    (set_attr "fp_int_src" "true")])
5469
5470 (define_split
5471   [(set (match_operand:MODEF 0 "register_operand" "")
5472         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5473    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5474   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5475    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5476    && TARGET_INTER_UNIT_CONVERSIONS
5477    && reload_completed
5478    && (SSE_REG_P (operands[0])
5479        || (GET_CODE (operands[0]) == SUBREG
5480            && SSE_REG_P (operands[0])))"
5481   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5482   "")
5483
5484 (define_split
5485   [(set (match_operand:MODEF 0 "register_operand" "")
5486         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5487    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5488   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5489    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5490    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5491    && reload_completed
5492    && (SSE_REG_P (operands[0])
5493        || (GET_CODE (operands[0]) == SUBREG
5494            && SSE_REG_P (operands[0])))"
5495   [(set (match_dup 2) (match_dup 1))
5496    (set (match_dup 0) (float:MODEF (match_dup 2)))]
5497   "")
5498
5499 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5500   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5501         (float:MODEF
5502           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
5503   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5504    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5505    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5506   "@
5507    fild%Z1\t%1
5508    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
5509    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5510   [(set_attr "type" "fmov,sseicvt,sseicvt")
5511    (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5512    (set_attr "mode" "<MODEF:MODE>")
5513    (set (attr "prefix_rex")
5514      (if_then_else
5515        (and (eq_attr "prefix" "maybe_vex")
5516             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5517        (const_string "1")
5518        (const_string "*")))
5519    (set_attr "unit" "i387,*,*")
5520    (set_attr "athlon_decode" "*,double,direct")
5521    (set_attr "amdfam10_decode" "*,vector,double")
5522    (set_attr "fp_int_src" "true")])
5523
5524 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5525   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5526         (float:MODEF
5527           (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5528   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5529    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5530    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5531   "@
5532    fild%Z1\t%1
5533    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5534   [(set_attr "type" "fmov,sseicvt")
5535    (set_attr "prefix" "orig,maybe_vex")
5536    (set_attr "mode" "<MODEF:MODE>")
5537    (set (attr "prefix_rex")
5538      (if_then_else
5539        (and (eq_attr "prefix" "maybe_vex")
5540             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5541        (const_string "1")
5542        (const_string "*")))
5543    (set_attr "athlon_decode" "*,direct")
5544    (set_attr "amdfam10_decode" "*,double")
5545    (set_attr "fp_int_src" "true")])
5546
5547 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5548   [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5549         (float:MODEF
5550           (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5551    (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5552   "TARGET_SSE2 && TARGET_SSE_MATH
5553    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5554   "#"
5555   [(set_attr "type" "sseicvt")
5556    (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5557    (set_attr "athlon_decode" "double,direct,double")
5558    (set_attr "amdfam10_decode" "vector,double,double")
5559    (set_attr "fp_int_src" "true")])
5560
5561 (define_insn "*floatsi<mode>2_vector_sse"
5562   [(set (match_operand:MODEF 0 "register_operand" "=x")
5563         (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5564   "TARGET_SSE2 && TARGET_SSE_MATH
5565    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5566   "#"
5567   [(set_attr "type" "sseicvt")
5568    (set_attr "mode" "<MODE>")
5569    (set_attr "athlon_decode" "direct")
5570    (set_attr "amdfam10_decode" "double")
5571    (set_attr "fp_int_src" "true")])
5572
5573 (define_split
5574   [(set (match_operand:MODEF 0 "register_operand" "")
5575         (float:MODEF (match_operand:SI 1 "register_operand" "")))
5576    (clobber (match_operand:SI 2 "memory_operand" ""))]
5577   "TARGET_SSE2 && TARGET_SSE_MATH
5578    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5579    && reload_completed
5580    && (SSE_REG_P (operands[0])
5581        || (GET_CODE (operands[0]) == SUBREG
5582            && SSE_REG_P (operands[0])))"
5583   [(const_int 0)]
5584 {
5585   rtx op1 = operands[1];
5586
5587   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5588                                      <MODE>mode, 0);
5589   if (GET_CODE (op1) == SUBREG)
5590     op1 = SUBREG_REG (op1);
5591
5592   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5593     {
5594       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5595       emit_insn (gen_sse2_loadld (operands[4],
5596                                   CONST0_RTX (V4SImode), operands[1]));
5597     }
5598   /* We can ignore possible trapping value in the
5599      high part of SSE register for non-trapping math. */
5600   else if (SSE_REG_P (op1) && !flag_trapping_math)
5601     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5602   else
5603     {
5604       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5605       emit_move_insn (operands[2], operands[1]);
5606       emit_insn (gen_sse2_loadld (operands[4],
5607                                   CONST0_RTX (V4SImode), operands[2]));
5608     }
5609   emit_insn
5610     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5611   DONE;
5612 })
5613
5614 (define_split
5615   [(set (match_operand:MODEF 0 "register_operand" "")
5616         (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5617    (clobber (match_operand:SI 2 "memory_operand" ""))]
5618   "TARGET_SSE2 && TARGET_SSE_MATH
5619    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5620    && reload_completed
5621    && (SSE_REG_P (operands[0])
5622        || (GET_CODE (operands[0]) == SUBREG
5623            && SSE_REG_P (operands[0])))"
5624   [(const_int 0)]
5625 {
5626   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5627                                      <MODE>mode, 0);
5628   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5629
5630   emit_insn (gen_sse2_loadld (operands[4],
5631                               CONST0_RTX (V4SImode), operands[1]));
5632   emit_insn
5633     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5634   DONE;
5635 })
5636
5637 (define_split
5638   [(set (match_operand:MODEF 0 "register_operand" "")
5639         (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5640   "TARGET_SSE2 && TARGET_SSE_MATH
5641    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5642    && reload_completed
5643    && (SSE_REG_P (operands[0])
5644        || (GET_CODE (operands[0]) == SUBREG
5645            && SSE_REG_P (operands[0])))"
5646   [(const_int 0)]
5647 {
5648   rtx op1 = operands[1];
5649
5650   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5651                                      <MODE>mode, 0);
5652   if (GET_CODE (op1) == SUBREG)
5653     op1 = SUBREG_REG (op1);
5654
5655   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5656     {
5657       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5658       emit_insn (gen_sse2_loadld (operands[4],
5659                                   CONST0_RTX (V4SImode), operands[1]));
5660     }
5661   /* We can ignore possible trapping value in the
5662      high part of SSE register for non-trapping math. */
5663   else if (SSE_REG_P (op1) && !flag_trapping_math)
5664     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5665   else
5666     gcc_unreachable ();
5667   emit_insn
5668     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5669   DONE;
5670 })
5671
5672 (define_split
5673   [(set (match_operand:MODEF 0 "register_operand" "")
5674         (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5675   "TARGET_SSE2 && TARGET_SSE_MATH
5676    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5677    && reload_completed
5678    && (SSE_REG_P (operands[0])
5679        || (GET_CODE (operands[0]) == SUBREG
5680            && SSE_REG_P (operands[0])))"
5681   [(const_int 0)]
5682 {
5683   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5684                                      <MODE>mode, 0);
5685   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5686
5687   emit_insn (gen_sse2_loadld (operands[4],
5688                               CONST0_RTX (V4SImode), operands[1]));
5689   emit_insn
5690     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5691   DONE;
5692 })
5693
5694 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5695   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5696         (float:MODEF
5697           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5698   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5699   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5700    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5701   "#"
5702   [(set_attr "type" "sseicvt")
5703    (set_attr "mode" "<MODEF:MODE>")
5704    (set_attr "athlon_decode" "double,direct")
5705    (set_attr "amdfam10_decode" "vector,double")
5706    (set_attr "fp_int_src" "true")])
5707
5708 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5709   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5710         (float:MODEF
5711           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5712   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5713    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5714    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5715   "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5716   [(set_attr "type" "sseicvt")
5717    (set_attr "prefix" "maybe_vex")
5718    (set_attr "mode" "<MODEF:MODE>")
5719    (set (attr "prefix_rex")
5720      (if_then_else
5721        (and (eq_attr "prefix" "maybe_vex")
5722             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5723        (const_string "1")
5724        (const_string "*")))
5725    (set_attr "athlon_decode" "double,direct")
5726    (set_attr "amdfam10_decode" "vector,double")
5727    (set_attr "fp_int_src" "true")])
5728
5729 (define_split
5730   [(set (match_operand:MODEF 0 "register_operand" "")
5731         (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5732    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5733   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5734    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5735    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5736    && reload_completed
5737    && (SSE_REG_P (operands[0])
5738        || (GET_CODE (operands[0]) == SUBREG
5739            && SSE_REG_P (operands[0])))"
5740   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5741   "")
5742
5743 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5744   [(set (match_operand:MODEF 0 "register_operand" "=x")
5745         (float:MODEF
5746           (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5747   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5748    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5749    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5750   "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5751   [(set_attr "type" "sseicvt")
5752    (set_attr "prefix" "maybe_vex")
5753    (set_attr "mode" "<MODEF:MODE>")
5754    (set (attr "prefix_rex")
5755      (if_then_else
5756        (and (eq_attr "prefix" "maybe_vex")
5757             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5758        (const_string "1")
5759        (const_string "*")))
5760    (set_attr "athlon_decode" "direct")
5761    (set_attr "amdfam10_decode" "double")
5762    (set_attr "fp_int_src" "true")])
5763
5764 (define_split
5765   [(set (match_operand:MODEF 0 "register_operand" "")
5766         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5767    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5768   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5769    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5770    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5771    && reload_completed
5772    && (SSE_REG_P (operands[0])
5773        || (GET_CODE (operands[0]) == SUBREG
5774            && SSE_REG_P (operands[0])))"
5775   [(set (match_dup 2) (match_dup 1))
5776    (set (match_dup 0) (float:MODEF (match_dup 2)))]
5777   "")
5778
5779 (define_split
5780   [(set (match_operand:MODEF 0 "register_operand" "")
5781         (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5782    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5783   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5784    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5785    && reload_completed
5786    && (SSE_REG_P (operands[0])
5787        || (GET_CODE (operands[0]) == SUBREG
5788            && SSE_REG_P (operands[0])))"
5789   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5790   "")
5791
5792 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5793   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5794         (float:X87MODEF
5795           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5796   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5797   "TARGET_80387
5798    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5799   "@
5800    fild%Z1\t%1
5801    #"
5802   [(set_attr "type" "fmov,multi")
5803    (set_attr "mode" "<X87MODEF:MODE>")
5804    (set_attr "unit" "*,i387")
5805    (set_attr "fp_int_src" "true")])
5806
5807 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5808   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5809         (float:X87MODEF
5810           (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5811   "TARGET_80387
5812    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5813   "fild%Z1\t%1"
5814   [(set_attr "type" "fmov")
5815    (set_attr "mode" "<X87MODEF:MODE>")
5816    (set_attr "fp_int_src" "true")])
5817
5818 (define_split
5819   [(set (match_operand:X87MODEF 0 "register_operand" "")
5820         (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5821    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5822   "TARGET_80387
5823    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5824    && reload_completed
5825    && FP_REG_P (operands[0])"
5826   [(set (match_dup 2) (match_dup 1))
5827    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5828   "")
5829
5830 (define_split
5831   [(set (match_operand:X87MODEF 0 "register_operand" "")
5832         (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5833    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5834   "TARGET_80387
5835    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5836    && reload_completed
5837    && FP_REG_P (operands[0])"
5838   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5839   "")
5840
5841 ;; Avoid store forwarding (partial memory) stall penalty
5842 ;; by passing DImode value through XMM registers.  */
5843
5844 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5845   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5846         (float:X87MODEF
5847           (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5848    (clobber (match_scratch:V4SI 3 "=X,x"))
5849    (clobber (match_scratch:V4SI 4 "=X,x"))
5850    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5851   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5852    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5853    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5854   "#"
5855   [(set_attr "type" "multi")
5856    (set_attr "mode" "<X87MODEF:MODE>")
5857    (set_attr "unit" "i387")
5858    (set_attr "fp_int_src" "true")])
5859
5860 (define_split
5861   [(set (match_operand:X87MODEF 0 "register_operand" "")
5862         (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5863    (clobber (match_scratch:V4SI 3 ""))
5864    (clobber (match_scratch:V4SI 4 ""))
5865    (clobber (match_operand:DI 2 "memory_operand" ""))]
5866   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5867    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5868    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5869    && reload_completed
5870    && FP_REG_P (operands[0])"
5871   [(set (match_dup 2) (match_dup 3))
5872    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5873 {
5874   /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5875      Assemble the 64-bit DImode value in an xmm register.  */
5876   emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5877                               gen_rtx_SUBREG (SImode, operands[1], 0)));
5878   emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5879                               gen_rtx_SUBREG (SImode, operands[1], 4)));
5880   emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5881                                          operands[4]));
5882
5883   operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5884 })
5885
5886 (define_split
5887   [(set (match_operand:X87MODEF 0 "register_operand" "")
5888         (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5889    (clobber (match_scratch:V4SI 3 ""))
5890    (clobber (match_scratch:V4SI 4 ""))
5891    (clobber (match_operand:DI 2 "memory_operand" ""))]
5892   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5893    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5894    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5895    && reload_completed
5896    && FP_REG_P (operands[0])"
5897   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5898   "")
5899
5900 ;; Avoid store forwarding (partial memory) stall penalty by extending
5901 ;; SImode value to DImode through XMM register instead of pushing two
5902 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5903 ;; targets benefit from this optimization. Also note that fild
5904 ;; loads from memory only.
5905
5906 (define_insn "*floatunssi<mode>2_1"
5907   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5908         (unsigned_float:X87MODEF
5909           (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5910    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5911    (clobber (match_scratch:SI 3 "=X,x"))]
5912   "!TARGET_64BIT
5913    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5914    && TARGET_SSE"
5915   "#"
5916   [(set_attr "type" "multi")
5917    (set_attr "mode" "<MODE>")])
5918
5919 (define_split
5920   [(set (match_operand:X87MODEF 0 "register_operand" "")
5921         (unsigned_float:X87MODEF
5922           (match_operand:SI 1 "register_operand" "")))
5923    (clobber (match_operand:DI 2 "memory_operand" ""))
5924    (clobber (match_scratch:SI 3 ""))]
5925   "!TARGET_64BIT
5926    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5927    && TARGET_SSE
5928    && reload_completed"
5929   [(set (match_dup 2) (match_dup 1))
5930    (set (match_dup 0)
5931         (float:X87MODEF (match_dup 2)))]
5932   "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5933
5934 (define_split
5935   [(set (match_operand:X87MODEF 0 "register_operand" "")
5936         (unsigned_float:X87MODEF
5937           (match_operand:SI 1 "memory_operand" "")))
5938    (clobber (match_operand:DI 2 "memory_operand" ""))
5939    (clobber (match_scratch:SI 3 ""))]
5940   "!TARGET_64BIT
5941    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5942    && TARGET_SSE
5943    && reload_completed"
5944   [(set (match_dup 2) (match_dup 3))
5945    (set (match_dup 0)
5946         (float:X87MODEF (match_dup 2)))]
5947 {
5948   emit_move_insn (operands[3], operands[1]);
5949   operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5950 })
5951
5952 (define_expand "floatunssi<mode>2"
5953   [(parallel
5954      [(set (match_operand:X87MODEF 0 "register_operand" "")
5955            (unsigned_float:X87MODEF
5956              (match_operand:SI 1 "nonimmediate_operand" "")))
5957       (clobber (match_dup 2))
5958       (clobber (match_scratch:SI 3 ""))])]
5959   "!TARGET_64BIT
5960    && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5961         && TARGET_SSE)
5962        || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5963 {
5964   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5965     {
5966       ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5967       DONE;
5968     }
5969   else
5970     {
5971       enum ix86_stack_slot slot = (virtuals_instantiated
5972                                    ? SLOT_TEMP
5973                                    : SLOT_VIRTUAL);
5974       operands[2] = assign_386_stack_local (DImode, slot);
5975     }
5976 })
5977
5978 (define_expand "floatunsdisf2"
5979   [(use (match_operand:SF 0 "register_operand" ""))
5980    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5981   "TARGET_64BIT && TARGET_SSE_MATH"
5982   "x86_emit_floatuns (operands); DONE;")
5983
5984 (define_expand "floatunsdidf2"
5985   [(use (match_operand:DF 0 "register_operand" ""))
5986    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5987   "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5988    && TARGET_SSE2 && TARGET_SSE_MATH"
5989 {
5990   if (TARGET_64BIT)
5991     x86_emit_floatuns (operands);
5992   else
5993     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5994   DONE;
5995 })
5996 \f
5997 ;; Add instructions
5998
5999 (define_expand "add<mode>3"
6000   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
6001         (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6002                     (match_operand:SDWIM 2 "<general_operand>" "")))]
6003   ""
6004   "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
6005
6006 (define_insn_and_split "*add<dwi>3_doubleword"
6007   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6008         (plus:<DWI>
6009           (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
6010           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6011    (clobber (reg:CC FLAGS_REG))]
6012   "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
6013   "#"
6014   "reload_completed"
6015   [(parallel [(set (reg:CC FLAGS_REG)
6016                    (unspec:CC [(match_dup 1) (match_dup 2)]
6017                               UNSPEC_ADD_CARRY))
6018               (set (match_dup 0)
6019                    (plus:DWIH (match_dup 1) (match_dup 2)))])
6020    (parallel [(set (match_dup 3)
6021                    (plus:DWIH
6022                      (match_dup 4)
6023                      (plus:DWIH
6024                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6025                        (match_dup 5))))
6026               (clobber (reg:CC FLAGS_REG))])]
6027   "split_<dwi> (&operands[0], 3, &operands[0], &operands[3]);")
6028
6029 (define_insn "*add<mode>3_cc"
6030   [(set (reg:CC FLAGS_REG)
6031         (unspec:CC
6032           [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
6033            (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
6034           UNSPEC_ADD_CARRY))
6035    (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
6036         (plus:SWI48 (match_dup 1) (match_dup 2)))]
6037   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6038   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6039   [(set_attr "type" "alu")
6040    (set_attr "mode" "<MODE>")])
6041
6042 (define_insn "addqi3_cc"
6043   [(set (reg:CC FLAGS_REG)
6044         (unspec:CC
6045           [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
6046            (match_operand:QI 2 "general_operand" "qn,qm")]
6047           UNSPEC_ADD_CARRY))
6048    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6049         (plus:QI (match_dup 1) (match_dup 2)))]
6050   "ix86_binary_operator_ok (PLUS, QImode, operands)"
6051   "add{b}\t{%2, %0|%0, %2}"
6052   [(set_attr "type" "alu")
6053    (set_attr "mode" "QI")])
6054
6055 (define_insn "*lea_1"
6056   [(set (match_operand:DWIH 0 "register_operand" "=r")
6057         (match_operand:DWIH 1 "no_seg_address_operand" "p"))]
6058   ""
6059   "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
6060   [(set_attr "type" "lea")
6061    (set_attr "mode" "<MODE>")])
6062
6063 (define_insn "*lea_2"
6064   [(set (match_operand:SI 0 "register_operand" "=r")
6065         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
6066   "TARGET_64BIT"
6067   "lea{l}\t{%a1, %0|%0, %a1}"
6068   [(set_attr "type" "lea")
6069    (set_attr "mode" "SI")])
6070
6071 (define_insn "*lea_2_zext"
6072   [(set (match_operand:DI 0 "register_operand" "=r")
6073         (zero_extend:DI
6074           (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
6075   "TARGET_64BIT"
6076   "lea{l}\t{%a1, %k0|%k0, %a1}"
6077   [(set_attr "type" "lea")
6078    (set_attr "mode" "SI")])
6079
6080 (define_insn "*add<mode>_1"
6081   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
6082         (plus:SWI48
6083           (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
6084           (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,0,l<i>")))
6085    (clobber (reg:CC FLAGS_REG))]
6086   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6087 {
6088   switch (get_attr_type (insn))
6089     {
6090     case TYPE_LEA:
6091       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6092       return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
6093
6094     case TYPE_INCDEC:
6095       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6096       if (operands[2] == const1_rtx)
6097         return "inc{<imodesuffix>}\t%0";
6098       else
6099         {
6100           gcc_assert (operands[2] == constm1_rtx);
6101           return "dec{<imodesuffix>}\t%0";
6102         }
6103
6104     default:
6105       /* Use add as much as possible to replace lea for AGU optimization. */
6106       if (which_alternative == 2 && TARGET_OPT_AGU)
6107         return "add{<imodesuffix>}\t{%1, %0|%0, %1}";
6108         
6109       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6110       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6111         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6112
6113       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6114     }
6115 }
6116   [(set (attr "type")
6117      (cond [(and (eq_attr "alternative" "2") 
6118                  (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
6119               (const_string "lea")
6120             (eq_attr "alternative" "3")
6121               (const_string "lea")
6122             (match_operand:SWI48 2 "incdec_operand" "")
6123               (const_string "incdec")
6124            ]
6125            (const_string "alu")))
6126    (set (attr "length_immediate")
6127       (if_then_else
6128         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6129         (const_string "1")
6130         (const_string "*")))
6131    (set_attr "mode" "<MODE>")])
6132
6133 ;; It may seem that nonimmediate operand is proper one for operand 1.
6134 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6135 ;; we take care in ix86_binary_operator_ok to not allow two memory
6136 ;; operands so proper swapping will be done in reload.  This allow
6137 ;; patterns constructed from addsi_1 to match.
6138
6139 (define_insn "*addsi_1_zext"
6140   [(set (match_operand:DI 0 "register_operand" "=r,r")
6141         (zero_extend:DI
6142           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6143                    (match_operand:SI 2 "general_operand" "g,li"))))
6144    (clobber (reg:CC FLAGS_REG))]
6145   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6146 {
6147   switch (get_attr_type (insn))
6148     {
6149     case TYPE_LEA:
6150       operands[2] = XEXP (SET_SRC (XVECEXP (PATTERN (insn), 0, 0)), 0);
6151       return "lea{l}\t{%a2, %k0|%k0, %a2}";
6152
6153     case TYPE_INCDEC:
6154       if (operands[2] == const1_rtx)
6155         return "inc{l}\t%k0";
6156       else
6157         {
6158           gcc_assert (operands[2] == constm1_rtx);
6159           return "dec{l}\t%k0";
6160         }
6161
6162     default:
6163       if (x86_maybe_negate_const_int (&operands[2], SImode))
6164         return "sub{l}\t{%2, %k0|%k0, %2}";
6165
6166       return "add{l}\t{%2, %k0|%k0, %2}";
6167     }
6168 }
6169   [(set (attr "type")
6170      (cond [(eq_attr "alternative" "1")
6171               (const_string "lea")
6172             (match_operand:SI 2 "incdec_operand" "")
6173               (const_string "incdec")
6174            ]
6175            (const_string "alu")))
6176    (set (attr "length_immediate")
6177       (if_then_else
6178         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6179         (const_string "1")
6180         (const_string "*")))
6181    (set_attr "mode" "SI")])
6182
6183 (define_insn "*addhi_1"
6184   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6185         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6186                  (match_operand:HI 2 "general_operand" "rn,rm")))
6187    (clobber (reg:CC FLAGS_REG))]
6188   "TARGET_PARTIAL_REG_STALL
6189    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6190 {
6191   switch (get_attr_type (insn))
6192     {
6193     case TYPE_INCDEC:
6194       if (operands[2] == const1_rtx)
6195         return "inc{w}\t%0";
6196       else
6197         {
6198           gcc_assert (operands[2] == constm1_rtx);
6199           return "dec{w}\t%0";
6200         }
6201
6202     default:
6203       if (x86_maybe_negate_const_int (&operands[2], HImode))
6204         return "sub{w}\t{%2, %0|%0, %2}";
6205
6206       return "add{w}\t{%2, %0|%0, %2}";
6207     }
6208 }
6209   [(set (attr "type")
6210      (if_then_else (match_operand:HI 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" "HI")])
6219
6220 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6221 ;; type optimizations enabled by define-splits.  This is not important
6222 ;; for PII, and in fact harmful because of partial register stalls.
6223
6224 (define_insn "*addhi_1_lea"
6225   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6226         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6227                  (match_operand:HI 2 "general_operand" "rn,rm,ln")))
6228    (clobber (reg:CC FLAGS_REG))]
6229   "!TARGET_PARTIAL_REG_STALL
6230    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6231 {
6232   switch (get_attr_type (insn))
6233     {
6234     case TYPE_LEA:
6235       return "#";
6236
6237     case TYPE_INCDEC:
6238       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6239       if (operands[2] == const1_rtx)
6240         return "inc{w}\t%0";
6241       else
6242         {
6243           gcc_assert (operands[2] == constm1_rtx);
6244           return "dec{w}\t%0";
6245         }
6246
6247     default:
6248       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6249       if (x86_maybe_negate_const_int (&operands[2], HImode))
6250         return "sub{w}\t{%2, %0|%0, %2}";
6251
6252       return "add{w}\t{%2, %0|%0, %2}";
6253     }
6254 }
6255   [(set (attr "type")
6256      (if_then_else (eq_attr "alternative" "2")
6257         (const_string "lea")
6258         (if_then_else (match_operand:HI 2 "incdec_operand" "")
6259            (const_string "incdec")
6260            (const_string "alu"))))
6261    (set (attr "length_immediate")
6262       (if_then_else
6263         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6264         (const_string "1")
6265         (const_string "*")))
6266    (set_attr "mode" "HI,HI,SI")])
6267
6268 (define_insn "*addqi_1"
6269   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6270         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6271                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6272    (clobber (reg:CC FLAGS_REG))]
6273   "TARGET_PARTIAL_REG_STALL
6274    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6275 {
6276   int widen = (which_alternative == 2);
6277   switch (get_attr_type (insn))
6278     {
6279     case TYPE_INCDEC:
6280       if (operands[2] == const1_rtx)
6281         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6282       else
6283         {
6284           gcc_assert (operands[2] == constm1_rtx);
6285           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6286         }
6287
6288     default:
6289       if (x86_maybe_negate_const_int (&operands[2], QImode))
6290         {
6291           if (widen)
6292             return "sub{l}\t{%2, %k0|%k0, %2}";
6293           else
6294             return "sub{b}\t{%2, %0|%0, %2}";
6295         }
6296       if (widen)
6297         return "add{l}\t{%k2, %k0|%k0, %k2}";
6298       else
6299         return "add{b}\t{%2, %0|%0, %2}";
6300     }
6301 }
6302   [(set (attr "type")
6303      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6304         (const_string "incdec")
6305         (const_string "alu")))
6306    (set (attr "length_immediate")
6307       (if_then_else
6308         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6309         (const_string "1")
6310         (const_string "*")))
6311    (set_attr "mode" "QI,QI,SI")])
6312
6313 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6314 (define_insn "*addqi_1_lea"
6315   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6316         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6317                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6318    (clobber (reg:CC FLAGS_REG))]
6319   "!TARGET_PARTIAL_REG_STALL
6320    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6321 {
6322   int widen = (which_alternative == 2);
6323   switch (get_attr_type (insn))
6324     {
6325     case TYPE_LEA:
6326       return "#";
6327
6328     case TYPE_INCDEC:
6329       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6330       if (operands[2] == const1_rtx)
6331         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6332       else
6333         {
6334           gcc_assert (operands[2] == constm1_rtx);
6335           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6336         }
6337
6338     default:
6339       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6340       if (x86_maybe_negate_const_int (&operands[2], QImode))
6341         {
6342           if (widen)
6343             return "sub{l}\t{%2, %k0|%k0, %2}";
6344           else
6345             return "sub{b}\t{%2, %0|%0, %2}";
6346         }
6347       if (widen)
6348         return "add{l}\t{%k2, %k0|%k0, %k2}";
6349       else
6350         return "add{b}\t{%2, %0|%0, %2}";
6351     }
6352 }
6353   [(set (attr "type")
6354      (if_then_else (eq_attr "alternative" "3")
6355         (const_string "lea")
6356         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6357            (const_string "incdec")
6358            (const_string "alu"))))
6359    (set (attr "length_immediate")
6360       (if_then_else
6361         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6362         (const_string "1")
6363         (const_string "*")))
6364    (set_attr "mode" "QI,QI,SI,SI")])
6365
6366 (define_insn "*addqi_1_slp"
6367   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6368         (plus:QI (match_dup 0)
6369                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6370    (clobber (reg:CC FLAGS_REG))]
6371   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6372    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6373 {
6374   switch (get_attr_type (insn))
6375     {
6376     case TYPE_INCDEC:
6377       if (operands[1] == const1_rtx)
6378         return "inc{b}\t%0";
6379       else
6380         {
6381           gcc_assert (operands[1] == constm1_rtx);
6382           return "dec{b}\t%0";
6383         }
6384
6385     default:
6386       if (x86_maybe_negate_const_int (&operands[1], QImode))
6387         return "sub{b}\t{%1, %0|%0, %1}";
6388
6389       return "add{b}\t{%1, %0|%0, %1}";
6390     }
6391 }
6392   [(set (attr "type")
6393      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6394         (const_string "incdec")
6395         (const_string "alu1")))
6396    (set (attr "memory")
6397      (if_then_else (match_operand 1 "memory_operand" "")
6398         (const_string "load")
6399         (const_string "none")))
6400    (set_attr "mode" "QI")])
6401
6402 (define_insn "*add<mode>_2"
6403   [(set (reg FLAGS_REG)
6404         (compare
6405           (plus:SWI
6406             (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6407             (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
6408           (const_int 0)))
6409    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
6410         (plus:SWI (match_dup 1) (match_dup 2)))]
6411   "ix86_match_ccmode (insn, CCGOCmode)
6412    && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6413 {
6414   switch (get_attr_type (insn))
6415     {
6416     case TYPE_INCDEC:
6417       if (operands[2] == const1_rtx)
6418         return "inc{<imodesuffix>}\t%0";
6419       else
6420         {
6421           gcc_assert (operands[2] == constm1_rtx);
6422           return "dec{<imodesuffix>}\t%0";
6423         }
6424
6425     default:
6426       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6427         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6428
6429       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6430     }
6431 }
6432   [(set (attr "type")
6433      (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6434         (const_string "incdec")
6435         (const_string "alu")))
6436    (set (attr "length_immediate")
6437       (if_then_else
6438         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6439         (const_string "1")
6440         (const_string "*")))
6441    (set_attr "mode" "<MODE>")])
6442
6443 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6444 (define_insn "*addsi_2_zext"
6445   [(set (reg FLAGS_REG)
6446         (compare
6447           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6448                    (match_operand:SI 2 "general_operand" "g"))
6449           (const_int 0)))
6450    (set (match_operand:DI 0 "register_operand" "=r")
6451         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6452   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6453    && ix86_binary_operator_ok (PLUS, SImode, operands)"
6454 {
6455   switch (get_attr_type (insn))
6456     {
6457     case TYPE_INCDEC:
6458       if (operands[2] == const1_rtx)
6459         return "inc{l}\t%k0";
6460       else
6461         {
6462           gcc_assert (operands[2] == constm1_rtx);
6463           return "dec{l}\t%k0";
6464         }
6465
6466     default:
6467       if (x86_maybe_negate_const_int (&operands[2], SImode))
6468         return "sub{l}\t{%2, %k0|%k0, %2}";
6469
6470       return "add{l}\t{%2, %k0|%k0, %2}";
6471     }
6472 }
6473   [(set (attr "type")
6474      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6475         (const_string "incdec")
6476         (const_string "alu")))
6477    (set (attr "length_immediate")
6478       (if_then_else
6479         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6480         (const_string "1")
6481         (const_string "*")))
6482    (set_attr "mode" "SI")])
6483
6484 (define_insn "*add<mode>_3"
6485   [(set (reg FLAGS_REG)
6486         (compare
6487           (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>"))
6488           (match_operand:SWI 1 "nonimmediate_operand" "%0")))
6489    (clobber (match_scratch:SWI 0 "=<r>"))]
6490   "ix86_match_ccmode (insn, CCZmode)
6491    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6492 {
6493   switch (get_attr_type (insn))
6494     {
6495     case TYPE_INCDEC:
6496       if (operands[2] == const1_rtx)
6497         return "inc{<imodesuffix>}\t%0";
6498       else
6499         {
6500           gcc_assert (operands[2] == constm1_rtx);
6501           return "dec{<imodesuffix>}\t%0";
6502         }
6503
6504     default:
6505       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6506         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6507
6508       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6509     }
6510 }
6511   [(set (attr "type")
6512      (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6513         (const_string "incdec")
6514         (const_string "alu")))
6515    (set (attr "length_immediate")
6516       (if_then_else
6517         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6518         (const_string "1")
6519         (const_string "*")))
6520    (set_attr "mode" "<MODE>")])
6521
6522 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6523 (define_insn "*addsi_3_zext"
6524   [(set (reg FLAGS_REG)
6525         (compare
6526           (neg:SI (match_operand:SI 2 "general_operand" "g"))
6527           (match_operand:SI 1 "nonimmediate_operand" "%0")))
6528    (set (match_operand:DI 0 "register_operand" "=r")
6529         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6530   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6531    && ix86_binary_operator_ok (PLUS, SImode, operands)"
6532 {
6533   switch (get_attr_type (insn))
6534     {
6535     case TYPE_INCDEC:
6536       if (operands[2] == const1_rtx)
6537         return "inc{l}\t%k0";
6538       else
6539         {
6540           gcc_assert (operands[2] == constm1_rtx);
6541           return "dec{l}\t%k0";
6542         }
6543
6544     default:
6545       if (x86_maybe_negate_const_int (&operands[2], SImode))
6546         return "sub{l}\t{%2, %k0|%k0, %2}";
6547
6548       return "add{l}\t{%2, %k0|%k0, %2}";
6549     }
6550 }
6551   [(set (attr "type")
6552      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6553         (const_string "incdec")
6554         (const_string "alu")))
6555    (set (attr "length_immediate")
6556       (if_then_else
6557         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6558         (const_string "1")
6559         (const_string "*")))
6560    (set_attr "mode" "SI")])
6561
6562 ; For comparisons against 1, -1 and 128, we may generate better code
6563 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6564 ; is matched then.  We can't accept general immediate, because for
6565 ; case of overflows,  the result is messed up.
6566 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6567 ; only for comparisons not depending on it.
6568
6569 (define_insn "*adddi_4"
6570   [(set (reg FLAGS_REG)
6571         (compare
6572           (match_operand:DI 1 "nonimmediate_operand" "0")
6573           (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6574    (clobber (match_scratch:DI 0 "=rm"))]
6575   "TARGET_64BIT
6576    && ix86_match_ccmode (insn, CCGCmode)"
6577 {
6578   switch (get_attr_type (insn))
6579     {
6580     case TYPE_INCDEC:
6581       if (operands[2] == constm1_rtx)
6582         return "inc{q}\t%0";
6583       else
6584         {
6585           gcc_assert (operands[2] == const1_rtx);
6586           return "dec{q}\t%0";
6587         }
6588
6589     default:
6590       if (x86_maybe_negate_const_int (&operands[2], DImode))
6591         return "add{q}\t{%2, %0|%0, %2}";
6592
6593       return "sub{q}\t{%2, %0|%0, %2}";
6594     }
6595 }
6596   [(set (attr "type")
6597      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6598         (const_string "incdec")
6599         (const_string "alu")))
6600    (set (attr "length_immediate")
6601       (if_then_else
6602         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6603         (const_string "1")
6604         (const_string "*")))
6605    (set_attr "mode" "DI")])
6606
6607 ; For comparisons against 1, -1 and 128, we may generate better code
6608 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6609 ; is matched then.  We can't accept general immediate, because for
6610 ; case of overflows,  the result is messed up.
6611 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6612 ; only for comparisons not depending on it.
6613
6614 (define_insn "*add<mode>_4"
6615   [(set (reg FLAGS_REG)
6616         (compare
6617           (match_operand:SWI124 1 "nonimmediate_operand" "0")
6618           (match_operand:SWI124 2 "const_int_operand" "n")))
6619    (clobber (match_scratch:SWI124 0 "=<r>m"))]
6620   "ix86_match_ccmode (insn, CCGCmode)"
6621 {
6622   switch (get_attr_type (insn))
6623     {
6624     case TYPE_INCDEC:
6625       if (operands[2] == constm1_rtx)
6626         return "inc{<imodesuffix>}\t%0";
6627       else
6628         {
6629           gcc_assert (operands[2] == const1_rtx);
6630           return "dec{<imodesuffix>}\t%0";
6631         }
6632
6633     default:
6634       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6635         return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6636
6637       return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6638     }
6639 }
6640   [(set (attr "type")
6641      (if_then_else (match_operand:<MODE> 2 "incdec_operand" "")
6642         (const_string "incdec")
6643         (const_string "alu")))
6644    (set (attr "length_immediate")
6645       (if_then_else
6646         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6647         (const_string "1")
6648         (const_string "*")))
6649    (set_attr "mode" "<MODE>")])
6650
6651 (define_insn "*add<mode>_5"
6652   [(set (reg FLAGS_REG)
6653         (compare
6654           (plus:SWI
6655             (match_operand:SWI 1 "nonimmediate_operand" "%0")
6656             (match_operand:SWI 2 "<general_operand>" "<g>"))
6657           (const_int 0)))
6658    (clobber (match_scratch:SWI 0 "=<r>"))]
6659   "ix86_match_ccmode (insn, CCGOCmode)
6660    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6661 {
6662   switch (get_attr_type (insn))
6663     {
6664     case TYPE_INCDEC:
6665       if (operands[2] == const1_rtx)
6666         return "inc{<imodesuffix>}\t%0";
6667       else
6668         {
6669           gcc_assert (operands[2] == constm1_rtx);
6670           return "dec{<imodesuffix>}\t%0";
6671         }
6672
6673     default:
6674       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6675         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6676
6677       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6678     }
6679 }
6680   [(set (attr "type")
6681      (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6682         (const_string "incdec")
6683         (const_string "alu")))
6684    (set (attr "length_immediate")
6685       (if_then_else
6686         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6687         (const_string "1")
6688         (const_string "*")))
6689    (set_attr "mode" "<MODE>")])
6690
6691 (define_insn "*addqi_ext_1_rex64"
6692   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6693                          (const_int 8)
6694                          (const_int 8))
6695         (plus:SI
6696           (zero_extract:SI
6697             (match_operand 1 "ext_register_operand" "0")
6698             (const_int 8)
6699             (const_int 8))
6700           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6701    (clobber (reg:CC FLAGS_REG))]
6702   "TARGET_64BIT"
6703 {
6704   switch (get_attr_type (insn))
6705     {
6706     case TYPE_INCDEC:
6707       if (operands[2] == const1_rtx)
6708         return "inc{b}\t%h0";
6709       else
6710         {
6711           gcc_assert (operands[2] == constm1_rtx);
6712           return "dec{b}\t%h0";
6713         }
6714
6715     default:
6716       return "add{b}\t{%2, %h0|%h0, %2}";
6717     }
6718 }
6719   [(set (attr "type")
6720      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6721         (const_string "incdec")
6722         (const_string "alu")))
6723    (set_attr "modrm" "1")
6724    (set_attr "mode" "QI")])
6725
6726 (define_insn "addqi_ext_1"
6727   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6728                          (const_int 8)
6729                          (const_int 8))
6730         (plus:SI
6731           (zero_extract:SI
6732             (match_operand 1 "ext_register_operand" "0")
6733             (const_int 8)
6734             (const_int 8))
6735           (match_operand:QI 2 "general_operand" "Qmn")))
6736    (clobber (reg:CC FLAGS_REG))]
6737   "!TARGET_64BIT"
6738 {
6739   switch (get_attr_type (insn))
6740     {
6741     case TYPE_INCDEC:
6742       if (operands[2] == const1_rtx)
6743         return "inc{b}\t%h0";
6744       else
6745         {
6746           gcc_assert (operands[2] == constm1_rtx);
6747           return "dec{b}\t%h0";
6748         }
6749
6750     default:
6751       return "add{b}\t{%2, %h0|%h0, %2}";
6752     }
6753 }
6754   [(set (attr "type")
6755      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6756         (const_string "incdec")
6757         (const_string "alu")))
6758    (set_attr "modrm" "1")
6759    (set_attr "mode" "QI")])
6760
6761 (define_insn "*addqi_ext_2"
6762   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6763                          (const_int 8)
6764                          (const_int 8))
6765         (plus:SI
6766           (zero_extract:SI
6767             (match_operand 1 "ext_register_operand" "%0")
6768             (const_int 8)
6769             (const_int 8))
6770           (zero_extract:SI
6771             (match_operand 2 "ext_register_operand" "Q")
6772             (const_int 8)
6773             (const_int 8))))
6774    (clobber (reg:CC FLAGS_REG))]
6775   ""
6776   "add{b}\t{%h2, %h0|%h0, %h2}"
6777   [(set_attr "type" "alu")
6778    (set_attr "mode" "QI")])
6779
6780 ;; The lea patterns for non-Pmodes needs to be matched by
6781 ;; several insns converted to real lea by splitters.
6782
6783 (define_insn_and_split "*lea_general_1"
6784   [(set (match_operand 0 "register_operand" "=r")
6785         (plus (plus (match_operand 1 "index_register_operand" "l")
6786                     (match_operand 2 "register_operand" "r"))
6787               (match_operand 3 "immediate_operand" "i")))]
6788   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6789     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6790    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6791    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6792    && GET_MODE (operands[0]) == GET_MODE (operands[2])
6793    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6794        || GET_MODE (operands[3]) == VOIDmode)"
6795   "#"
6796   "&& reload_completed"
6797   [(const_int 0)]
6798 {
6799   rtx pat;
6800   operands[0] = gen_lowpart (SImode, operands[0]);
6801   operands[1] = gen_lowpart (Pmode, operands[1]);
6802   operands[2] = gen_lowpart (Pmode, operands[2]);
6803   operands[3] = gen_lowpart (Pmode, operands[3]);
6804   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
6805                       operands[3]);
6806   if (Pmode != SImode)
6807     pat = gen_rtx_SUBREG (SImode, pat, 0);
6808   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6809   DONE;
6810 }
6811   [(set_attr "type" "lea")
6812    (set_attr "mode" "SI")])
6813
6814 (define_insn_and_split "*lea_general_1_zext"
6815   [(set (match_operand:DI 0 "register_operand" "=r")
6816         (zero_extend:DI
6817           (plus:SI (plus:SI
6818                      (match_operand:SI 1 "index_register_operand" "l")
6819                      (match_operand:SI 2 "register_operand" "r"))
6820                    (match_operand:SI 3 "immediate_operand" "i"))))]
6821   "TARGET_64BIT"
6822   "#"
6823   "&& reload_completed"
6824   [(set (match_dup 0)
6825         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
6826                                                      (match_dup 2))
6827                                             (match_dup 3)) 0)))]
6828 {
6829   operands[1] = gen_lowpart (Pmode, operands[1]);
6830   operands[2] = gen_lowpart (Pmode, operands[2]);
6831   operands[3] = gen_lowpart (Pmode, operands[3]);
6832 }
6833   [(set_attr "type" "lea")
6834    (set_attr "mode" "SI")])
6835
6836 (define_insn_and_split "*lea_general_2"
6837   [(set (match_operand 0 "register_operand" "=r")
6838         (plus (mult (match_operand 1 "index_register_operand" "l")
6839                     (match_operand 2 "const248_operand" "i"))
6840               (match_operand 3 "nonmemory_operand" "ri")))]
6841   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6842     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6843    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6844    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6845    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6846        || GET_MODE (operands[3]) == VOIDmode)"
6847   "#"
6848   "&& reload_completed"
6849   [(const_int 0)]
6850 {
6851   rtx pat;
6852   operands[0] = gen_lowpart (SImode, operands[0]);
6853   operands[1] = gen_lowpart (Pmode, operands[1]);
6854   operands[3] = gen_lowpart (Pmode, operands[3]);
6855   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
6856                       operands[3]);
6857   if (Pmode != SImode)
6858     pat = gen_rtx_SUBREG (SImode, pat, 0);
6859   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6860   DONE;
6861 }
6862   [(set_attr "type" "lea")
6863    (set_attr "mode" "SI")])
6864
6865 (define_insn_and_split "*lea_general_2_zext"
6866   [(set (match_operand:DI 0 "register_operand" "=r")
6867         (zero_extend:DI
6868           (plus:SI (mult:SI
6869                      (match_operand:SI 1 "index_register_operand" "l")
6870                      (match_operand:SI 2 "const248_operand" "n"))
6871                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
6872   "TARGET_64BIT"
6873   "#"
6874   "&& reload_completed"
6875   [(set (match_dup 0)
6876         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
6877                                                      (match_dup 2))
6878                                             (match_dup 3)) 0)))]
6879 {
6880   operands[1] = gen_lowpart (Pmode, operands[1]);
6881   operands[3] = gen_lowpart (Pmode, operands[3]);
6882 }
6883   [(set_attr "type" "lea")
6884    (set_attr "mode" "SI")])
6885
6886 (define_insn_and_split "*lea_general_3"
6887   [(set (match_operand 0 "register_operand" "=r")
6888         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6889                           (match_operand 2 "const248_operand" "i"))
6890                     (match_operand 3 "register_operand" "r"))
6891               (match_operand 4 "immediate_operand" "i")))]
6892   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6893     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6894    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6895    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6896    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6897   "#"
6898   "&& reload_completed"
6899   [(const_int 0)]
6900 {
6901   rtx pat;
6902   operands[0] = gen_lowpart (SImode, operands[0]);
6903   operands[1] = gen_lowpart (Pmode, operands[1]);
6904   operands[3] = gen_lowpart (Pmode, operands[3]);
6905   operands[4] = gen_lowpart (Pmode, operands[4]);
6906   pat = gen_rtx_PLUS (Pmode,
6907                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
6908                                                          operands[2]),
6909                                     operands[3]),
6910                       operands[4]);
6911   if (Pmode != SImode)
6912     pat = gen_rtx_SUBREG (SImode, pat, 0);
6913   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6914   DONE;
6915 }
6916   [(set_attr "type" "lea")
6917    (set_attr "mode" "SI")])
6918
6919 (define_insn_and_split "*lea_general_3_zext"
6920   [(set (match_operand:DI 0 "register_operand" "=r")
6921         (zero_extend:DI
6922           (plus:SI (plus:SI
6923                      (mult:SI
6924                        (match_operand:SI 1 "index_register_operand" "l")
6925                        (match_operand:SI 2 "const248_operand" "n"))
6926                      (match_operand:SI 3 "register_operand" "r"))
6927                    (match_operand:SI 4 "immediate_operand" "i"))))]
6928   "TARGET_64BIT"
6929   "#"
6930   "&& reload_completed"
6931   [(set (match_dup 0)
6932         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
6933                                                               (match_dup 2))
6934                                                      (match_dup 3))
6935                                             (match_dup 4)) 0)))]
6936 {
6937   operands[1] = gen_lowpart (Pmode, operands[1]);
6938   operands[3] = gen_lowpart (Pmode, operands[3]);
6939   operands[4] = gen_lowpart (Pmode, operands[4]);
6940 }
6941   [(set_attr "type" "lea")
6942    (set_attr "mode" "SI")])
6943
6944 ;; Convert lea to the lea pattern to avoid flags dependency.
6945 (define_split
6946   [(set (match_operand:DI 0 "register_operand" "")
6947         (plus:DI (match_operand:DI 1 "register_operand" "")
6948                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
6949    (clobber (reg:CC FLAGS_REG))]
6950   "TARGET_64BIT && reload_completed 
6951    && ix86_lea_for_add_ok (PLUS, insn, operands)"
6952   [(set (match_dup 0)
6953         (plus:DI (match_dup 1)
6954                  (match_dup 2)))]
6955   "")
6956
6957 ;; Convert lea to the lea pattern to avoid flags dependency.
6958 (define_split
6959   [(set (match_operand 0 "register_operand" "")
6960         (plus (match_operand 1 "register_operand" "")
6961               (match_operand 2 "nonmemory_operand" "")))
6962    (clobber (reg:CC FLAGS_REG))]
6963   "reload_completed && ix86_lea_for_add_ok (PLUS, insn, operands)" 
6964   [(const_int 0)]
6965 {
6966   rtx pat;
6967   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
6968      may confuse gen_lowpart.  */
6969   if (GET_MODE (operands[0]) != Pmode)
6970     {
6971       operands[1] = gen_lowpart (Pmode, operands[1]);
6972       operands[2] = gen_lowpart (Pmode, operands[2]);
6973     }
6974   operands[0] = gen_lowpart (SImode, operands[0]);
6975   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
6976   if (Pmode != SImode)
6977     pat = gen_rtx_SUBREG (SImode, pat, 0);
6978   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6979   DONE;
6980 })
6981
6982 ;; Convert lea to the lea pattern to avoid flags dependency.
6983 (define_split
6984   [(set (match_operand:DI 0 "register_operand" "")
6985         (zero_extend:DI
6986           (plus:SI (match_operand:SI 1 "register_operand" "")
6987                    (match_operand:SI 2 "nonmemory_operand" ""))))
6988    (clobber (reg:CC FLAGS_REG))]
6989   "TARGET_64BIT && reload_completed
6990    && true_regnum (operands[0]) != true_regnum (operands[1])"
6991   [(set (match_dup 0)
6992         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
6993 {
6994   operands[1] = gen_lowpart (Pmode, operands[1]);
6995   operands[2] = gen_lowpart (Pmode, operands[2]);
6996 })
6997 \f
6998 ;; Subtract instructions
6999
7000 (define_expand "sub<mode>3"
7001   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
7002         (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
7003                      (match_operand:SDWIM 2 "<general_operand>" "")))]
7004   ""
7005   "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
7006
7007 (define_insn_and_split "*sub<dwi>3_doubleword"
7008   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
7009         (minus:<DWI>
7010           (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
7011           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
7012    (clobber (reg:CC FLAGS_REG))]
7013   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7014   "#"
7015   "reload_completed"
7016   [(parallel [(set (reg:CC FLAGS_REG)
7017                    (compare:CC (match_dup 1) (match_dup 2)))
7018               (set (match_dup 0)
7019                    (minus:DWIH (match_dup 1) (match_dup 2)))])
7020    (parallel [(set (match_dup 3)
7021                    (minus:DWIH
7022                      (match_dup 4)
7023                      (plus:DWIH
7024                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7025                        (match_dup 5))))
7026               (clobber (reg:CC FLAGS_REG))])]
7027   "split_<dwi> (&operands[0], 3, &operands[0], &operands[3]);")
7028
7029 (define_insn "*sub<mode>_1"
7030   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7031         (minus:SWI
7032           (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7033           (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
7034    (clobber (reg:CC FLAGS_REG))]
7035   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7036   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7037   [(set_attr "type" "alu")
7038    (set_attr "mode" "<MODE>")])
7039
7040 (define_insn "*subsi_1_zext"
7041   [(set (match_operand:DI 0 "register_operand" "=r")
7042         (zero_extend:DI
7043           (minus:SI (match_operand:SI 1 "register_operand" "0")
7044                     (match_operand:SI 2 "general_operand" "g"))))
7045    (clobber (reg:CC FLAGS_REG))]
7046   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7047   "sub{l}\t{%2, %k0|%k0, %2}"
7048   [(set_attr "type" "alu")
7049    (set_attr "mode" "SI")])
7050
7051 (define_insn "*subqi_1_slp"
7052   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7053         (minus:QI (match_dup 0)
7054                   (match_operand:QI 1 "general_operand" "qn,qm")))
7055    (clobber (reg:CC FLAGS_REG))]
7056   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7057    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7058   "sub{b}\t{%1, %0|%0, %1}"
7059   [(set_attr "type" "alu1")
7060    (set_attr "mode" "QI")])
7061
7062 (define_insn "*sub<mode>_2"
7063   [(set (reg FLAGS_REG)
7064         (compare
7065           (minus:SWI
7066             (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7067             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
7068           (const_int 0)))
7069    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7070         (minus:SWI (match_dup 1) (match_dup 2)))]
7071   "ix86_match_ccmode (insn, CCGOCmode)
7072    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7073   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7074   [(set_attr "type" "alu")
7075    (set_attr "mode" "<MODE>")])
7076
7077 (define_insn "*subsi_2_zext"
7078   [(set (reg FLAGS_REG)
7079         (compare
7080           (minus:SI (match_operand:SI 1 "register_operand" "0")
7081                     (match_operand:SI 2 "general_operand" "g"))
7082           (const_int 0)))
7083    (set (match_operand:DI 0 "register_operand" "=r")
7084         (zero_extend:DI
7085           (minus:SI (match_dup 1)
7086                     (match_dup 2))))]
7087   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7088    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7089   "sub{l}\t{%2, %k0|%k0, %2}"
7090   [(set_attr "type" "alu")
7091    (set_attr "mode" "SI")])
7092
7093 (define_insn "*sub<mode>_3"
7094   [(set (reg FLAGS_REG)
7095         (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7096                  (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
7097    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7098         (minus:SWI (match_dup 1) (match_dup 2)))]
7099   "ix86_match_ccmode (insn, CCmode)
7100    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7101   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7102   [(set_attr "type" "alu")
7103    (set_attr "mode" "<MODE>")])
7104
7105 (define_insn "*subsi_3_zext"
7106   [(set (reg FLAGS_REG)
7107         (compare (match_operand:SI 1 "register_operand" "0")
7108                  (match_operand:SI 2 "general_operand" "g")))
7109    (set (match_operand:DI 0 "register_operand" "=r")
7110         (zero_extend:DI
7111           (minus:SI (match_dup 1)
7112                     (match_dup 2))))]
7113   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7114    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7115   "sub{l}\t{%2, %1|%1, %2}"
7116   [(set_attr "type" "alu")
7117    (set_attr "mode" "SI")])
7118 \f
7119 ;; Add with carry and subtract with borrow
7120
7121 (define_expand "<plusminus_insn><mode>3_carry"
7122   [(parallel
7123     [(set (match_operand:SWI 0 "nonimmediate_operand" "")
7124           (plusminus:SWI
7125             (match_operand:SWI 1 "nonimmediate_operand" "")
7126             (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
7127                        [(match_operand 3 "flags_reg_operand" "")
7128                         (const_int 0)])
7129                       (match_operand:SWI 2 "<general_operand>" ""))))
7130      (clobber (reg:CC FLAGS_REG))])]
7131   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
7132   "")
7133
7134 (define_insn "*<plusminus_insn><mode>3_carry"
7135   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7136         (plusminus:SWI
7137           (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
7138           (plus:SWI
7139             (match_operator 3 "ix86_carry_flag_operator"
7140              [(reg FLAGS_REG) (const_int 0)])
7141             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
7142    (clobber (reg:CC FLAGS_REG))]
7143   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7144   "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
7145   [(set_attr "type" "alu")
7146    (set_attr "use_carry" "1")
7147    (set_attr "pent_pair" "pu")
7148    (set_attr "mode" "<MODE>")])
7149
7150 (define_insn "*addsi3_carry_zext"
7151   [(set (match_operand:DI 0 "register_operand" "=r")
7152         (zero_extend:DI
7153           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7154                    (plus:SI (match_operator 3 "ix86_carry_flag_operator"
7155                              [(reg FLAGS_REG) (const_int 0)])
7156                             (match_operand:SI 2 "general_operand" "g")))))
7157    (clobber (reg:CC FLAGS_REG))]
7158   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
7159   "adc{l}\t{%2, %k0|%k0, %2}"
7160   [(set_attr "type" "alu")
7161    (set_attr "use_carry" "1")
7162    (set_attr "pent_pair" "pu")
7163    (set_attr "mode" "SI")])
7164
7165 (define_insn "*subsi3_carry_zext"
7166   [(set (match_operand:DI 0 "register_operand" "=r")
7167         (zero_extend:DI
7168           (minus:SI (match_operand:SI 1 "register_operand" "0")
7169                     (plus:SI (match_operator 3 "ix86_carry_flag_operator"
7170                               [(reg FLAGS_REG) (const_int 0)])
7171                              (match_operand:SI 2 "general_operand" "g")))))
7172    (clobber (reg:CC FLAGS_REG))]
7173   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7174   "sbb{l}\t{%2, %k0|%k0, %2}"
7175   [(set_attr "type" "alu")
7176    (set_attr "pent_pair" "pu")
7177    (set_attr "mode" "SI")])
7178 \f
7179 ;; Overflow setting add and subtract instructions
7180
7181 (define_insn "*add<mode>3_cconly_overflow"
7182   [(set (reg:CCC FLAGS_REG)
7183         (compare:CCC
7184           (plus:SWI
7185             (match_operand:SWI 1 "nonimmediate_operand" "%0")
7186             (match_operand:SWI 2 "<general_operand>" "<r><i>m"))
7187           (match_dup 1)))
7188    (clobber (match_scratch:SWI 0 "=<r>"))]
7189   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7190   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7191   [(set_attr "type" "alu")
7192    (set_attr "mode" "<MODE>")])
7193
7194 (define_insn "*sub<mode>3_cconly_overflow"
7195   [(set (reg:CCC FLAGS_REG)
7196         (compare:CCC
7197           (minus:SWI
7198             (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
7199             (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
7200           (match_dup 0)))]
7201   ""
7202   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
7203   [(set_attr "type" "icmp")
7204    (set_attr "mode" "<MODE>")])
7205
7206 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
7207   [(set (reg:CCC FLAGS_REG)
7208         (compare:CCC
7209             (plusminus:SWI
7210                 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
7211                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
7212             (match_dup 1)))
7213    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7214         (plusminus:SWI (match_dup 1) (match_dup 2)))]
7215   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
7216   "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
7217   [(set_attr "type" "alu")
7218    (set_attr "mode" "<MODE>")])
7219
7220 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
7221   [(set (reg:CCC FLAGS_REG)
7222         (compare:CCC
7223           (plusminus:SI
7224             (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
7225             (match_operand:SI 2 "general_operand" "g"))
7226           (match_dup 1)))
7227    (set (match_operand:DI 0 "register_operand" "=r")
7228         (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
7229   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
7230   "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
7231   [(set_attr "type" "alu")
7232    (set_attr "mode" "SI")])
7233
7234 ;; The patterns that match these are at the end of this file.
7235
7236 (define_expand "<plusminus_insn>xf3"
7237   [(set (match_operand:XF 0 "register_operand" "")
7238         (plusminus:XF
7239           (match_operand:XF 1 "register_operand" "")
7240           (match_operand:XF 2 "register_operand" "")))]
7241   "TARGET_80387"
7242   "")
7243
7244 (define_expand "<plusminus_insn><mode>3"
7245   [(set (match_operand:MODEF 0 "register_operand" "")
7246         (plusminus:MODEF
7247           (match_operand:MODEF 1 "register_operand" "")
7248           (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7249   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7250     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7251   "")
7252 \f
7253 ;; Multiply instructions
7254
7255 (define_expand "mul<mode>3"
7256   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7257                    (mult:SWIM248
7258                      (match_operand:SWIM248 1 "register_operand" "")
7259                      (match_operand:SWIM248 2 "<general_operand>" "")))
7260               (clobber (reg:CC FLAGS_REG))])]
7261   ""
7262   "")
7263
7264 (define_expand "mulqi3"
7265   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7266                    (mult:QI
7267                      (match_operand:QI 1 "register_operand" "")
7268                      (match_operand:QI 2 "nonimmediate_operand" "")))
7269               (clobber (reg:CC FLAGS_REG))])]
7270   "TARGET_QIMODE_MATH"
7271   "")
7272
7273 ;; On AMDFAM10
7274 ;; IMUL reg32/64, reg32/64, imm8        Direct
7275 ;; IMUL reg32/64, mem32/64, imm8        VectorPath
7276 ;; IMUL reg32/64, reg32/64, imm32       Direct
7277 ;; IMUL reg32/64, mem32/64, imm32       VectorPath
7278 ;; IMUL reg32/64, reg32/64              Direct
7279 ;; IMUL reg32/64, mem32/64              Direct
7280
7281 (define_insn "*mul<mode>3_1"
7282   [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
7283         (mult:SWI48
7284           (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
7285           (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
7286    (clobber (reg:CC FLAGS_REG))]
7287   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7288   "@
7289    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7290    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7291    imul{<imodesuffix>}\t{%2, %0|%0, %2}"
7292   [(set_attr "type" "imul")
7293    (set_attr "prefix_0f" "0,0,1")
7294    (set (attr "athlon_decode")
7295         (cond [(eq_attr "cpu" "athlon")
7296                   (const_string "vector")
7297                (eq_attr "alternative" "1")
7298                   (const_string "vector")
7299                (and (eq_attr "alternative" "2")
7300                     (match_operand 1 "memory_operand" ""))
7301                   (const_string "vector")]
7302               (const_string "direct")))
7303    (set (attr "amdfam10_decode")
7304         (cond [(and (eq_attr "alternative" "0,1")
7305                     (match_operand 1 "memory_operand" ""))
7306                   (const_string "vector")]
7307               (const_string "direct")))
7308    (set_attr "mode" "<MODE>")])
7309
7310 (define_insn "*mulsi3_1_zext"
7311   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7312         (zero_extend:DI
7313           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7314                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
7315    (clobber (reg:CC FLAGS_REG))]
7316   "TARGET_64BIT
7317    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7318   "@
7319    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7320    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7321    imul{l}\t{%2, %k0|%k0, %2}"
7322   [(set_attr "type" "imul")
7323    (set_attr "prefix_0f" "0,0,1")
7324    (set (attr "athlon_decode")
7325         (cond [(eq_attr "cpu" "athlon")
7326                   (const_string "vector")
7327                (eq_attr "alternative" "1")
7328                   (const_string "vector")
7329                (and (eq_attr "alternative" "2")
7330                     (match_operand 1 "memory_operand" ""))
7331                   (const_string "vector")]
7332               (const_string "direct")))
7333    (set (attr "amdfam10_decode")
7334         (cond [(and (eq_attr "alternative" "0,1")
7335                     (match_operand 1 "memory_operand" ""))
7336                   (const_string "vector")]
7337               (const_string "direct")))
7338    (set_attr "mode" "SI")])
7339
7340 ;; On AMDFAM10
7341 ;; IMUL reg16, reg16, imm8      VectorPath
7342 ;; IMUL reg16, mem16, imm8      VectorPath
7343 ;; IMUL reg16, reg16, imm16     VectorPath
7344 ;; IMUL reg16, mem16, imm16     VectorPath
7345 ;; IMUL reg16, reg16            Direct
7346 ;; IMUL reg16, mem16            Direct
7347
7348 (define_insn "*mulhi3_1"
7349   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7350         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7351                  (match_operand:HI 2 "general_operand" "K,n,mr")))
7352    (clobber (reg:CC FLAGS_REG))]
7353   "TARGET_HIMODE_MATH
7354    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7355   "@
7356    imul{w}\t{%2, %1, %0|%0, %1, %2}
7357    imul{w}\t{%2, %1, %0|%0, %1, %2}
7358    imul{w}\t{%2, %0|%0, %2}"
7359   [(set_attr "type" "imul")
7360    (set_attr "prefix_0f" "0,0,1")
7361    (set (attr "athlon_decode")
7362         (cond [(eq_attr "cpu" "athlon")
7363                   (const_string "vector")
7364                (eq_attr "alternative" "1,2")
7365                   (const_string "vector")]
7366               (const_string "direct")))
7367    (set (attr "amdfam10_decode")
7368         (cond [(eq_attr "alternative" "0,1")
7369                   (const_string "vector")]
7370               (const_string "direct")))
7371    (set_attr "mode" "HI")])
7372
7373 ;;On AMDFAM10
7374 ;; MUL reg8     Direct
7375 ;; MUL mem8     Direct
7376
7377 (define_insn "*mulqi3_1"
7378   [(set (match_operand:QI 0 "register_operand" "=a")
7379         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7380                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7381    (clobber (reg:CC FLAGS_REG))]
7382   "TARGET_QIMODE_MATH
7383    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7384   "mul{b}\t%2"
7385   [(set_attr "type" "imul")
7386    (set_attr "length_immediate" "0")
7387    (set (attr "athlon_decode")
7388      (if_then_else (eq_attr "cpu" "athlon")
7389         (const_string "vector")
7390         (const_string "direct")))
7391    (set_attr "amdfam10_decode" "direct")
7392    (set_attr "mode" "QI")])
7393
7394 (define_expand "<u>mul<mode><dwi>3"
7395   [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
7396                    (mult:<DWI>
7397                      (any_extend:<DWI>
7398                        (match_operand:DWIH 1 "nonimmediate_operand" ""))
7399                      (any_extend:<DWI>
7400                        (match_operand:DWIH 2 "register_operand" ""))))
7401               (clobber (reg:CC FLAGS_REG))])]
7402   ""
7403   "")
7404
7405 (define_expand "<u>mulqihi3"
7406   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7407                    (mult:HI
7408                      (any_extend:HI
7409                        (match_operand:QI 1 "nonimmediate_operand" ""))
7410                      (any_extend:HI
7411                        (match_operand:QI 2 "register_operand" ""))))
7412               (clobber (reg:CC FLAGS_REG))])]
7413   "TARGET_QIMODE_MATH"
7414   "")
7415
7416 (define_insn "*<u>mul<mode><dwi>3_1"
7417   [(set (match_operand:<DWI> 0 "register_operand" "=A")
7418         (mult:<DWI>
7419           (any_extend:<DWI>
7420             (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
7421           (any_extend:<DWI>
7422             (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7423    (clobber (reg:CC FLAGS_REG))]
7424   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7425   "<sgnprefix>mul{<imodesuffix>}\t%2"
7426   [(set_attr "type" "imul")
7427    (set_attr "length_immediate" "0")
7428    (set (attr "athlon_decode")
7429      (if_then_else (eq_attr "cpu" "athlon")
7430         (const_string "vector")
7431         (const_string "double")))
7432    (set_attr "amdfam10_decode" "double")
7433    (set_attr "mode" "<MODE>")])
7434
7435 (define_insn "*<u>mulqihi3_1"
7436   [(set (match_operand:HI 0 "register_operand" "=a")
7437         (mult:HI
7438           (any_extend:HI
7439             (match_operand:QI 1 "nonimmediate_operand" "%0"))
7440           (any_extend:HI
7441             (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7442    (clobber (reg:CC FLAGS_REG))]
7443   "TARGET_QIMODE_MATH
7444    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7445   "<sgnprefix>mul{b}\t%2"
7446   [(set_attr "type" "imul")
7447    (set_attr "length_immediate" "0")
7448    (set (attr "athlon_decode")
7449      (if_then_else (eq_attr "cpu" "athlon")
7450         (const_string "vector")
7451         (const_string "direct")))
7452    (set_attr "amdfam10_decode" "direct")
7453    (set_attr "mode" "QI")])
7454
7455 (define_expand "<s>mul<mode>3_highpart"
7456   [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
7457                    (truncate:SWI48
7458                      (lshiftrt:<DWI>
7459                        (mult:<DWI>
7460                          (any_extend:<DWI>
7461                            (match_operand:SWI48 1 "nonimmediate_operand" ""))
7462                          (any_extend:<DWI>
7463                            (match_operand:SWI48 2 "register_operand" "")))
7464                        (match_dup 4))))
7465               (clobber (match_scratch:SWI48 3 ""))
7466               (clobber (reg:CC FLAGS_REG))])]
7467   ""
7468   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7469
7470 (define_insn "*<s>muldi3_highpart_1"
7471   [(set (match_operand:DI 0 "register_operand" "=d")
7472         (truncate:DI
7473           (lshiftrt:TI
7474             (mult:TI
7475               (any_extend:TI
7476                 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7477               (any_extend:TI
7478                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7479             (const_int 64))))
7480    (clobber (match_scratch:DI 3 "=1"))
7481    (clobber (reg:CC FLAGS_REG))]
7482   "TARGET_64BIT
7483    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7484   "<sgnprefix>mul{q}\t%2"
7485   [(set_attr "type" "imul")
7486    (set_attr "length_immediate" "0")
7487    (set (attr "athlon_decode")
7488      (if_then_else (eq_attr "cpu" "athlon")
7489         (const_string "vector")
7490         (const_string "double")))
7491    (set_attr "amdfam10_decode" "double")
7492    (set_attr "mode" "DI")])
7493
7494 (define_insn "*<s>mulsi3_highpart_1"
7495   [(set (match_operand:SI 0 "register_operand" "=d")
7496         (truncate:SI
7497           (lshiftrt:DI
7498             (mult:DI
7499               (any_extend:DI
7500                 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7501               (any_extend:DI
7502                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7503             (const_int 32))))
7504    (clobber (match_scratch:SI 3 "=1"))
7505    (clobber (reg:CC FLAGS_REG))]
7506   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7507   "<sgnprefix>mul{l}\t%2"
7508   [(set_attr "type" "imul")
7509    (set_attr "length_immediate" "0")
7510    (set (attr "athlon_decode")
7511      (if_then_else (eq_attr "cpu" "athlon")
7512         (const_string "vector")
7513         (const_string "double")))
7514    (set_attr "amdfam10_decode" "double")
7515    (set_attr "mode" "SI")])
7516
7517 (define_insn "*<s>mulsi3_highpart_zext"
7518   [(set (match_operand:DI 0 "register_operand" "=d")
7519         (zero_extend:DI (truncate:SI
7520           (lshiftrt:DI
7521             (mult:DI (any_extend:DI
7522                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7523                      (any_extend:DI
7524                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7525             (const_int 32)))))
7526    (clobber (match_scratch:SI 3 "=1"))
7527    (clobber (reg:CC FLAGS_REG))]
7528   "TARGET_64BIT
7529    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7530   "<sgnprefix>mul{l}\t%2"
7531   [(set_attr "type" "imul")
7532    (set_attr "length_immediate" "0")
7533    (set (attr "athlon_decode")
7534      (if_then_else (eq_attr "cpu" "athlon")
7535         (const_string "vector")
7536         (const_string "double")))
7537    (set_attr "amdfam10_decode" "double")
7538    (set_attr "mode" "SI")])
7539
7540 ;; The patterns that match these are at the end of this file.
7541
7542 (define_expand "mulxf3"
7543   [(set (match_operand:XF 0 "register_operand" "")
7544         (mult:XF (match_operand:XF 1 "register_operand" "")
7545                  (match_operand:XF 2 "register_operand" "")))]
7546   "TARGET_80387"
7547   "")
7548
7549 (define_expand "mul<mode>3"
7550   [(set (match_operand:MODEF 0 "register_operand" "")
7551         (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
7552                     (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7553   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7554     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7555   "")
7556 \f
7557 ;; Divide instructions
7558
7559 (define_insn "<u>divqi3"
7560   [(set (match_operand:QI 0 "register_operand" "=a")
7561         (any_div:QI
7562           (match_operand:HI 1 "register_operand" "0")
7563           (match_operand:QI 2 "nonimmediate_operand" "qm")))
7564    (clobber (reg:CC FLAGS_REG))]
7565   "TARGET_QIMODE_MATH"
7566   "<sgnprefix>div{b}\t%2"
7567   [(set_attr "type" "idiv")
7568    (set_attr "mode" "QI")])
7569
7570 ;; The patterns that match these are at the end of this file.
7571
7572 (define_expand "divxf3"
7573   [(set (match_operand:XF 0 "register_operand" "")
7574         (div:XF (match_operand:XF 1 "register_operand" "")
7575                 (match_operand:XF 2 "register_operand" "")))]
7576   "TARGET_80387"
7577   "")
7578
7579 (define_expand "divdf3"
7580   [(set (match_operand:DF 0 "register_operand" "")
7581         (div:DF (match_operand:DF 1 "register_operand" "")
7582                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7583    "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7584     || (TARGET_SSE2 && TARGET_SSE_MATH)"
7585    "")
7586
7587 (define_expand "divsf3"
7588   [(set (match_operand:SF 0 "register_operand" "")
7589         (div:SF (match_operand:SF 1 "register_operand" "")
7590                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7591   "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7592     || TARGET_SSE_MATH"
7593 {
7594   if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
7595       && flag_finite_math_only && !flag_trapping_math
7596       && flag_unsafe_math_optimizations)
7597     {
7598       ix86_emit_swdivsf (operands[0], operands[1],
7599                          operands[2], SFmode);
7600       DONE;
7601     }
7602 })
7603 \f
7604 ;; Divmod instructions.
7605
7606 (define_expand "divmod<mode>4"
7607   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7608                    (div:SWIM248
7609                      (match_operand:SWIM248 1 "register_operand" "")
7610                      (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7611               (set (match_operand:SWIM248 3 "register_operand" "")
7612                    (mod:SWIM248 (match_dup 1) (match_dup 2)))
7613               (clobber (reg:CC FLAGS_REG))])]
7614   ""
7615   "")
7616
7617 (define_insn_and_split "*divmod<mode>4"
7618   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7619         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7620                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7621    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7622         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7623    (clobber (reg:CC FLAGS_REG))]
7624   ""
7625   "#"
7626   "reload_completed"
7627   [(parallel [(set (match_dup 1)
7628                    (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7629               (clobber (reg:CC FLAGS_REG))])
7630    (parallel [(set (match_dup 0)
7631                    (div:SWIM248 (match_dup 2) (match_dup 3)))
7632               (set (match_dup 1)
7633                    (mod:SWIM248 (match_dup 2) (match_dup 3)))
7634               (use (match_dup 1))
7635               (clobber (reg:CC FLAGS_REG))])]
7636 {
7637   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7638
7639   if (<MODE>mode != HImode
7640       && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7641     operands[4] = operands[2];
7642   else
7643     {
7644       /* Avoid use of cltd in favor of a mov+shift.  */
7645       emit_move_insn (operands[1], operands[2]);
7646       operands[4] = operands[1];
7647     }
7648 }
7649   [(set_attr "type" "multi")
7650    (set_attr "mode" "<MODE>")])
7651
7652 (define_insn "*divmod<mode>4_noext"
7653   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7654         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7655                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7656    (set (match_operand:SWIM248 1 "register_operand" "=d")
7657         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7658    (use (match_operand:SWIM248 4 "register_operand" "1"))
7659    (clobber (reg:CC FLAGS_REG))]
7660   ""
7661   "idiv{<imodesuffix>}\t%3"
7662   [(set_attr "type" "idiv")
7663    (set_attr "mode" "<MODE>")])
7664
7665 (define_expand "udivmod<mode>4"
7666   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7667                    (udiv:SWIM248
7668                      (match_operand:SWIM248 1 "register_operand" "")
7669                      (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7670               (set (match_operand:SWIM248 3 "register_operand" "")
7671                    (umod:SWIM248 (match_dup 1) (match_dup 2)))
7672               (clobber (reg:CC FLAGS_REG))])]
7673   ""
7674   "")
7675
7676 (define_insn_and_split "*udivmod<mode>4"
7677   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7678         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7679                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7680    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7681         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7682    (clobber (reg:CC FLAGS_REG))]
7683   ""
7684   "#"
7685   "reload_completed"
7686   [(set (match_dup 1) (const_int 0))
7687    (parallel [(set (match_dup 0)
7688                    (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7689               (set (match_dup 1)
7690                    (umod:SWIM248 (match_dup 2) (match_dup 3)))
7691               (use (match_dup 1))
7692               (clobber (reg:CC FLAGS_REG))])]
7693   ""
7694   [(set_attr "type" "multi")
7695    (set_attr "mode" "<MODE>")])
7696
7697 (define_insn "*udivmod<mode>4_noext"
7698   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7699         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7700                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7701    (set (match_operand:SWIM248 1 "register_operand" "=d")
7702         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7703    (use (match_operand:SWIM248 4 "register_operand" "1"))
7704    (clobber (reg:CC FLAGS_REG))]
7705   ""
7706   "div{<imodesuffix>}\t%3"
7707   [(set_attr "type" "idiv")
7708    (set_attr "mode" "<MODE>")])
7709
7710 ;; We cannot use div/idiv for double division, because it causes
7711 ;; "division by zero" on the overflow and that's not what we expect
7712 ;; from truncate.  Because true (non truncating) double division is
7713 ;; never generated, we can't create this insn anyway.
7714 ;
7715 ;(define_insn ""
7716 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7717 ;       (truncate:SI
7718 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7719 ;                  (zero_extend:DI
7720 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7721 ;   (set (match_operand:SI 3 "register_operand" "=d")
7722 ;       (truncate:SI
7723 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7724 ;   (clobber (reg:CC FLAGS_REG))]
7725 ;  ""
7726 ;  "div{l}\t{%2, %0|%0, %2}"
7727 ;  [(set_attr "type" "idiv")])
7728 \f
7729 ;;- Logical AND instructions
7730
7731 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7732 ;; Note that this excludes ah.
7733
7734 (define_expand "testsi_ccno_1"
7735   [(set (reg:CCNO FLAGS_REG)
7736         (compare:CCNO
7737           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7738                   (match_operand:SI 1 "nonmemory_operand" ""))
7739           (const_int 0)))]
7740   ""
7741   "")
7742
7743 (define_expand "testqi_ccz_1"
7744   [(set (reg:CCZ FLAGS_REG)
7745         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7746                              (match_operand:QI 1 "nonmemory_operand" ""))
7747                  (const_int 0)))]
7748   ""
7749   "")
7750
7751 (define_insn "*testdi_1"
7752   [(set (reg FLAGS_REG)
7753         (compare
7754          (and:DI
7755           (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7756           (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7757          (const_int 0)))]
7758   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7759    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7760   "@
7761    test{l}\t{%k1, %k0|%k0, %k1}
7762    test{l}\t{%k1, %k0|%k0, %k1}
7763    test{q}\t{%1, %0|%0, %1}
7764    test{q}\t{%1, %0|%0, %1}
7765    test{q}\t{%1, %0|%0, %1}"
7766   [(set_attr "type" "test")
7767    (set_attr "modrm" "0,1,0,1,1")
7768    (set_attr "mode" "SI,SI,DI,DI,DI")])
7769
7770 (define_insn "*testqi_1_maybe_si"
7771   [(set (reg FLAGS_REG)
7772         (compare
7773           (and:QI
7774             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7775             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7776           (const_int 0)))]
7777    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7778     && ix86_match_ccmode (insn,
7779                          CONST_INT_P (operands[1])
7780                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7781 {
7782   if (which_alternative == 3)
7783     {
7784       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7785         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7786       return "test{l}\t{%1, %k0|%k0, %1}";
7787     }
7788   return "test{b}\t{%1, %0|%0, %1}";
7789 }
7790   [(set_attr "type" "test")
7791    (set_attr "modrm" "0,1,1,1")
7792    (set_attr "mode" "QI,QI,QI,SI")
7793    (set_attr "pent_pair" "uv,np,uv,np")])
7794
7795 (define_insn "*test<mode>_1"
7796   [(set (reg FLAGS_REG)
7797         (compare
7798          (and:SWI124
7799           (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7800           (match_operand:SWI124 1 "general_operand" "<i>,<i>,<r><i>"))
7801          (const_int 0)))]
7802   "ix86_match_ccmode (insn, CCNOmode)
7803    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7804   "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7805   [(set_attr "type" "test")
7806    (set_attr "modrm" "0,1,1")
7807    (set_attr "mode" "<MODE>")
7808    (set_attr "pent_pair" "uv,np,uv")])
7809
7810 (define_expand "testqi_ext_ccno_0"
7811   [(set (reg:CCNO FLAGS_REG)
7812         (compare:CCNO
7813           (and:SI
7814             (zero_extract:SI
7815               (match_operand 0 "ext_register_operand" "")
7816               (const_int 8)
7817               (const_int 8))
7818             (match_operand 1 "const_int_operand" ""))
7819           (const_int 0)))]
7820   ""
7821   "")
7822
7823 (define_insn "*testqi_ext_0"
7824   [(set (reg FLAGS_REG)
7825         (compare
7826           (and:SI
7827             (zero_extract:SI
7828               (match_operand 0 "ext_register_operand" "Q")
7829               (const_int 8)
7830               (const_int 8))
7831             (match_operand 1 "const_int_operand" "n"))
7832           (const_int 0)))]
7833   "ix86_match_ccmode (insn, CCNOmode)"
7834   "test{b}\t{%1, %h0|%h0, %1}"
7835   [(set_attr "type" "test")
7836    (set_attr "mode" "QI")
7837    (set_attr "length_immediate" "1")
7838    (set_attr "modrm" "1")
7839    (set_attr "pent_pair" "np")])
7840
7841 (define_insn "*testqi_ext_1_rex64"
7842   [(set (reg FLAGS_REG)
7843         (compare
7844           (and:SI
7845             (zero_extract:SI
7846               (match_operand 0 "ext_register_operand" "Q")
7847               (const_int 8)
7848               (const_int 8))
7849             (zero_extend:SI
7850               (match_operand:QI 1 "register_operand" "Q")))
7851           (const_int 0)))]
7852   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7853   "test{b}\t{%1, %h0|%h0, %1}"
7854   [(set_attr "type" "test")
7855    (set_attr "mode" "QI")])
7856
7857 (define_insn "*testqi_ext_1"
7858   [(set (reg FLAGS_REG)
7859         (compare
7860           (and:SI
7861             (zero_extract:SI
7862               (match_operand 0 "ext_register_operand" "Q")
7863               (const_int 8)
7864               (const_int 8))
7865             (zero_extend:SI
7866               (match_operand:QI 1 "general_operand" "Qm")))
7867           (const_int 0)))]
7868   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7869   "test{b}\t{%1, %h0|%h0, %1}"
7870   [(set_attr "type" "test")
7871    (set_attr "mode" "QI")])
7872
7873 (define_insn "*testqi_ext_2"
7874   [(set (reg FLAGS_REG)
7875         (compare
7876           (and:SI
7877             (zero_extract:SI
7878               (match_operand 0 "ext_register_operand" "Q")
7879               (const_int 8)
7880               (const_int 8))
7881             (zero_extract:SI
7882               (match_operand 1 "ext_register_operand" "Q")
7883               (const_int 8)
7884               (const_int 8)))
7885           (const_int 0)))]
7886   "ix86_match_ccmode (insn, CCNOmode)"
7887   "test{b}\t{%h1, %h0|%h0, %h1}"
7888   [(set_attr "type" "test")
7889    (set_attr "mode" "QI")])
7890
7891 (define_insn "*testqi_ext_3_rex64"
7892   [(set (reg FLAGS_REG)
7893         (compare (zero_extract:DI
7894                    (match_operand 0 "nonimmediate_operand" "rm")
7895                    (match_operand:DI 1 "const_int_operand" "")
7896                    (match_operand:DI 2 "const_int_operand" ""))
7897                  (const_int 0)))]
7898   "TARGET_64BIT
7899    && ix86_match_ccmode (insn, CCNOmode)
7900    && INTVAL (operands[1]) > 0
7901    && INTVAL (operands[2]) >= 0
7902    /* Ensure that resulting mask is zero or sign extended operand.  */
7903    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7904        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7905            && INTVAL (operands[1]) > 32))
7906    && (GET_MODE (operands[0]) == SImode
7907        || GET_MODE (operands[0]) == DImode
7908        || GET_MODE (operands[0]) == HImode
7909        || GET_MODE (operands[0]) == QImode)"
7910   "#")
7911
7912 ;; Combine likes to form bit extractions for some tests.  Humor it.
7913 (define_insn "*testqi_ext_3"
7914   [(set (reg FLAGS_REG)
7915         (compare (zero_extract:SI
7916                    (match_operand 0 "nonimmediate_operand" "rm")
7917                    (match_operand:SI 1 "const_int_operand" "")
7918                    (match_operand:SI 2 "const_int_operand" ""))
7919                  (const_int 0)))]
7920   "ix86_match_ccmode (insn, CCNOmode)
7921    && INTVAL (operands[1]) > 0
7922    && INTVAL (operands[2]) >= 0
7923    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7924    && (GET_MODE (operands[0]) == SImode
7925        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7926        || GET_MODE (operands[0]) == HImode
7927        || GET_MODE (operands[0]) == QImode)"
7928   "#")
7929
7930 (define_split
7931   [(set (match_operand 0 "flags_reg_operand" "")
7932         (match_operator 1 "compare_operator"
7933           [(zero_extract
7934              (match_operand 2 "nonimmediate_operand" "")
7935              (match_operand 3 "const_int_operand" "")
7936              (match_operand 4 "const_int_operand" ""))
7937            (const_int 0)]))]
7938   "ix86_match_ccmode (insn, CCNOmode)"
7939   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7940 {
7941   rtx val = operands[2];
7942   HOST_WIDE_INT len = INTVAL (operands[3]);
7943   HOST_WIDE_INT pos = INTVAL (operands[4]);
7944   HOST_WIDE_INT mask;
7945   enum machine_mode mode, submode;
7946
7947   mode = GET_MODE (val);
7948   if (MEM_P (val))
7949     {
7950       /* ??? Combine likes to put non-volatile mem extractions in QImode
7951          no matter the size of the test.  So find a mode that works.  */
7952       if (! MEM_VOLATILE_P (val))
7953         {
7954           mode = smallest_mode_for_size (pos + len, MODE_INT);
7955           val = adjust_address (val, mode, 0);
7956         }
7957     }
7958   else if (GET_CODE (val) == SUBREG
7959            && (submode = GET_MODE (SUBREG_REG (val)),
7960                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7961            && pos + len <= GET_MODE_BITSIZE (submode)
7962            && GET_MODE_CLASS (submode) == MODE_INT)
7963     {
7964       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
7965       mode = submode;
7966       val = SUBREG_REG (val);
7967     }
7968   else if (mode == HImode && pos + len <= 8)
7969     {
7970       /* Small HImode tests can be converted to QImode.  */
7971       mode = QImode;
7972       val = gen_lowpart (QImode, val);
7973     }
7974
7975   if (len == HOST_BITS_PER_WIDE_INT)
7976     mask = -1;
7977   else
7978     mask = ((HOST_WIDE_INT)1 << len) - 1;
7979   mask <<= pos;
7980
7981   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7982 })
7983
7984 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7985 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7986 ;; this is relatively important trick.
7987 ;; Do the conversion only post-reload to avoid limiting of the register class
7988 ;; to QI regs.
7989 (define_split
7990   [(set (match_operand 0 "flags_reg_operand" "")
7991         (match_operator 1 "compare_operator"
7992           [(and (match_operand 2 "register_operand" "")
7993                 (match_operand 3 "const_int_operand" ""))
7994            (const_int 0)]))]
7995    "reload_completed
7996     && QI_REG_P (operands[2])
7997     && GET_MODE (operands[2]) != QImode
7998     && ((ix86_match_ccmode (insn, CCZmode)
7999          && !(INTVAL (operands[3]) & ~(255 << 8)))
8000         || (ix86_match_ccmode (insn, CCNOmode)
8001             && !(INTVAL (operands[3]) & ~(127 << 8))))"
8002   [(set (match_dup 0)
8003         (match_op_dup 1
8004           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8005                    (match_dup 3))
8006            (const_int 0)]))]
8007   "operands[2] = gen_lowpart (SImode, operands[2]);
8008    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8009
8010 (define_split
8011   [(set (match_operand 0 "flags_reg_operand" "")
8012         (match_operator 1 "compare_operator"
8013           [(and (match_operand 2 "nonimmediate_operand" "")
8014                 (match_operand 3 "const_int_operand" ""))
8015            (const_int 0)]))]
8016    "reload_completed
8017     && GET_MODE (operands[2]) != QImode
8018     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8019     && ((ix86_match_ccmode (insn, CCZmode)
8020          && !(INTVAL (operands[3]) & ~255))
8021         || (ix86_match_ccmode (insn, CCNOmode)
8022             && !(INTVAL (operands[3]) & ~127)))"
8023   [(set (match_dup 0)
8024         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8025                          (const_int 0)]))]
8026   "operands[2] = gen_lowpart (QImode, operands[2]);
8027    operands[3] = gen_lowpart (QImode, operands[3]);")
8028
8029 ;; %%% This used to optimize known byte-wide and operations to memory,
8030 ;; and sometimes to QImode registers.  If this is considered useful,
8031 ;; it should be done with splitters.
8032
8033 (define_expand "and<mode>3"
8034   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8035         (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8036                   (match_operand:SWIM 2 "<general_szext_operand>" "")))]
8037   ""
8038   "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
8039
8040 (define_insn "*anddi_1"
8041   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8042         (and:DI
8043          (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8044          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8045    (clobber (reg:CC FLAGS_REG))]
8046   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8047 {
8048   switch (get_attr_type (insn))
8049     {
8050     case TYPE_IMOVX:
8051       {
8052         enum machine_mode mode;
8053
8054         gcc_assert (CONST_INT_P (operands[2]));
8055         if (INTVAL (operands[2]) == 0xff)
8056           mode = QImode;
8057         else
8058           {
8059             gcc_assert (INTVAL (operands[2]) == 0xffff);
8060             mode = HImode;
8061           }
8062
8063         operands[1] = gen_lowpart (mode, operands[1]);
8064         if (mode == QImode)
8065           return "movz{bl|x}\t{%1, %k0|%k0, %1}";
8066         else
8067           return "movz{wl|x}\t{%1, %k0|%k0, %1}";
8068       }
8069
8070     default:
8071       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8072       if (get_attr_mode (insn) == MODE_SI)
8073         return "and{l}\t{%k2, %k0|%k0, %k2}";
8074       else
8075         return "and{q}\t{%2, %0|%0, %2}";
8076     }
8077 }
8078   [(set_attr "type" "alu,alu,alu,imovx")
8079    (set_attr "length_immediate" "*,*,*,0")
8080    (set (attr "prefix_rex")
8081      (if_then_else
8082        (and (eq_attr "type" "imovx")
8083             (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
8084                  (match_operand 1 "ext_QIreg_nomode_operand" "")))
8085        (const_string "1")
8086        (const_string "*")))
8087    (set_attr "mode" "SI,DI,DI,SI")])
8088
8089 (define_insn "*andsi_1"
8090   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8091         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8092                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8093    (clobber (reg:CC FLAGS_REG))]
8094   "ix86_binary_operator_ok (AND, SImode, operands)"
8095 {
8096   switch (get_attr_type (insn))
8097     {
8098     case TYPE_IMOVX:
8099       {
8100         enum machine_mode mode;
8101
8102         gcc_assert (CONST_INT_P (operands[2]));
8103         if (INTVAL (operands[2]) == 0xff)
8104           mode = QImode;
8105         else
8106           {
8107             gcc_assert (INTVAL (operands[2]) == 0xffff);
8108             mode = HImode;
8109           }
8110
8111         operands[1] = gen_lowpart (mode, operands[1]);
8112         if (mode == QImode)
8113           return "movz{bl|x}\t{%1, %0|%0, %1}";
8114         else
8115           return "movz{wl|x}\t{%1, %0|%0, %1}";
8116       }
8117
8118     default:
8119       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8120       return "and{l}\t{%2, %0|%0, %2}";
8121     }
8122 }
8123   [(set_attr "type" "alu,alu,imovx")
8124    (set (attr "prefix_rex")
8125      (if_then_else
8126        (and (eq_attr "type" "imovx")
8127             (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
8128                  (match_operand 1 "ext_QIreg_nomode_operand" "")))
8129        (const_string "1")
8130        (const_string "*")))
8131    (set_attr "length_immediate" "*,*,0")
8132    (set_attr "mode" "SI")])
8133
8134 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8135 (define_insn "*andsi_1_zext"
8136   [(set (match_operand:DI 0 "register_operand" "=r")
8137         (zero_extend:DI
8138           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8139                   (match_operand:SI 2 "general_operand" "g"))))
8140    (clobber (reg:CC FLAGS_REG))]
8141   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8142   "and{l}\t{%2, %k0|%k0, %2}"
8143   [(set_attr "type" "alu")
8144    (set_attr "mode" "SI")])
8145
8146 (define_insn "*andhi_1"
8147   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8148         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8149                 (match_operand:HI 2 "general_operand" "rn,rm,L")))
8150    (clobber (reg:CC FLAGS_REG))]
8151   "ix86_binary_operator_ok (AND, HImode, operands)"
8152 {
8153   switch (get_attr_type (insn))
8154     {
8155     case TYPE_IMOVX:
8156       gcc_assert (CONST_INT_P (operands[2]));
8157       gcc_assert (INTVAL (operands[2]) == 0xff);
8158       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8159
8160     default:
8161       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8162
8163       return "and{w}\t{%2, %0|%0, %2}";
8164     }
8165 }
8166   [(set_attr "type" "alu,alu,imovx")
8167    (set_attr "length_immediate" "*,*,0")
8168    (set (attr "prefix_rex")
8169      (if_then_else
8170        (and (eq_attr "type" "imovx")
8171             (match_operand 1 "ext_QIreg_nomode_operand" ""))
8172        (const_string "1")
8173        (const_string "*")))
8174    (set_attr "mode" "HI,HI,SI")])
8175
8176 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8177 (define_insn "*andqi_1"
8178   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8179         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8180                 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
8181    (clobber (reg:CC FLAGS_REG))]
8182   "ix86_binary_operator_ok (AND, QImode, operands)"
8183   "@
8184    and{b}\t{%2, %0|%0, %2}
8185    and{b}\t{%2, %0|%0, %2}
8186    and{l}\t{%k2, %k0|%k0, %k2}"
8187   [(set_attr "type" "alu")
8188    (set_attr "mode" "QI,QI,SI")])
8189
8190 (define_insn "*andqi_1_slp"
8191   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8192         (and:QI (match_dup 0)
8193                 (match_operand:QI 1 "general_operand" "qn,qmn")))
8194    (clobber (reg:CC FLAGS_REG))]
8195   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8196    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8197   "and{b}\t{%1, %0|%0, %1}"
8198   [(set_attr "type" "alu1")
8199    (set_attr "mode" "QI")])
8200
8201 (define_split
8202   [(set (match_operand 0 "register_operand" "")
8203         (and (match_dup 0)
8204              (const_int -65536)))
8205    (clobber (reg:CC FLAGS_REG))]
8206   "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
8207     || optimize_function_for_size_p (cfun)"
8208   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8209   "operands[1] = gen_lowpart (HImode, operands[0]);")
8210
8211 (define_split
8212   [(set (match_operand 0 "ext_register_operand" "")
8213         (and (match_dup 0)
8214              (const_int -256)))
8215    (clobber (reg:CC FLAGS_REG))]
8216   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8217    && reload_completed"
8218   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8219   "operands[1] = gen_lowpart (QImode, operands[0]);")
8220
8221 (define_split
8222   [(set (match_operand 0 "ext_register_operand" "")
8223         (and (match_dup 0)
8224              (const_int -65281)))
8225    (clobber (reg:CC FLAGS_REG))]
8226   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8227    && reload_completed"
8228   [(parallel [(set (zero_extract:SI (match_dup 0)
8229                                     (const_int 8)
8230                                     (const_int 8))
8231                    (xor:SI
8232                      (zero_extract:SI (match_dup 0)
8233                                       (const_int 8)
8234                                       (const_int 8))
8235                      (zero_extract:SI (match_dup 0)
8236                                       (const_int 8)
8237                                       (const_int 8))))
8238               (clobber (reg:CC FLAGS_REG))])]
8239   "operands[0] = gen_lowpart (SImode, operands[0]);")
8240
8241 (define_insn "*anddi_2"
8242   [(set (reg FLAGS_REG)
8243         (compare
8244          (and:DI
8245           (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8246           (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8247          (const_int 0)))
8248    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8249         (and:DI (match_dup 1) (match_dup 2)))]
8250   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8251    && ix86_binary_operator_ok (AND, DImode, operands)"
8252   "@
8253    and{l}\t{%k2, %k0|%k0, %k2}
8254    and{q}\t{%2, %0|%0, %2}
8255    and{q}\t{%2, %0|%0, %2}"
8256   [(set_attr "type" "alu")
8257    (set_attr "mode" "SI,DI,DI")])
8258
8259 (define_insn "*andqi_2_maybe_si"
8260   [(set (reg FLAGS_REG)
8261         (compare (and:QI
8262                   (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8263                   (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8264                  (const_int 0)))
8265    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8266         (and:QI (match_dup 1) (match_dup 2)))]
8267   "ix86_binary_operator_ok (AND, QImode, operands)
8268    && ix86_match_ccmode (insn,
8269                          CONST_INT_P (operands[2])
8270                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8271 {
8272   if (which_alternative == 2)
8273     {
8274       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8275         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8276       return "and{l}\t{%2, %k0|%k0, %2}";
8277     }
8278   return "and{b}\t{%2, %0|%0, %2}";
8279 }
8280   [(set_attr "type" "alu")
8281    (set_attr "mode" "QI,QI,SI")])
8282
8283 (define_insn "*and<mode>_2"
8284   [(set (reg FLAGS_REG)
8285         (compare (and:SWI124
8286                   (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8287                   (match_operand:SWI124 2 "general_operand" "<g>,<r><i>"))
8288                  (const_int 0)))
8289    (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8290         (and:SWI124 (match_dup 1) (match_dup 2)))]
8291   "ix86_match_ccmode (insn, CCNOmode)
8292    && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8293   "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8294   [(set_attr "type" "alu")
8295    (set_attr "mode" "<MODE>")])
8296
8297 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8298 (define_insn "*andsi_2_zext"
8299   [(set (reg FLAGS_REG)
8300         (compare (and:SI
8301                   (match_operand:SI 1 "nonimmediate_operand" "%0")
8302                   (match_operand:SI 2 "general_operand" "g"))
8303                  (const_int 0)))
8304    (set (match_operand:DI 0 "register_operand" "=r")
8305         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8306   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8307    && ix86_binary_operator_ok (AND, SImode, operands)"
8308   "and{l}\t{%2, %k0|%k0, %2}"
8309   [(set_attr "type" "alu")
8310    (set_attr "mode" "SI")])
8311
8312 (define_insn "*andqi_2_slp"
8313   [(set (reg FLAGS_REG)
8314         (compare (and:QI
8315                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8316                    (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8317                  (const_int 0)))
8318    (set (strict_low_part (match_dup 0))
8319         (and:QI (match_dup 0) (match_dup 1)))]
8320   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8321    && ix86_match_ccmode (insn, CCNOmode)
8322    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8323   "and{b}\t{%1, %0|%0, %1}"
8324   [(set_attr "type" "alu1")
8325    (set_attr "mode" "QI")])
8326
8327 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8328 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8329 ;; for a QImode operand, which of course failed.
8330 (define_insn "andqi_ext_0"
8331   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8332                          (const_int 8)
8333                          (const_int 8))
8334         (and:SI
8335           (zero_extract:SI
8336             (match_operand 1 "ext_register_operand" "0")
8337             (const_int 8)
8338             (const_int 8))
8339           (match_operand 2 "const_int_operand" "n")))
8340    (clobber (reg:CC FLAGS_REG))]
8341   ""
8342   "and{b}\t{%2, %h0|%h0, %2}"
8343   [(set_attr "type" "alu")
8344    (set_attr "length_immediate" "1")
8345    (set_attr "modrm" "1")
8346    (set_attr "mode" "QI")])
8347
8348 ;; Generated by peephole translating test to and.  This shows up
8349 ;; often in fp comparisons.
8350 (define_insn "*andqi_ext_0_cc"
8351   [(set (reg FLAGS_REG)
8352         (compare
8353           (and:SI
8354             (zero_extract:SI
8355               (match_operand 1 "ext_register_operand" "0")
8356               (const_int 8)
8357               (const_int 8))
8358             (match_operand 2 "const_int_operand" "n"))
8359           (const_int 0)))
8360    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8361                          (const_int 8)
8362                          (const_int 8))
8363         (and:SI
8364           (zero_extract:SI
8365             (match_dup 1)
8366             (const_int 8)
8367             (const_int 8))
8368           (match_dup 2)))]
8369   "ix86_match_ccmode (insn, CCNOmode)"
8370   "and{b}\t{%2, %h0|%h0, %2}"
8371   [(set_attr "type" "alu")
8372    (set_attr "length_immediate" "1")
8373    (set_attr "modrm" "1")
8374    (set_attr "mode" "QI")])
8375
8376 (define_insn "*andqi_ext_1_rex64"
8377   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8378                          (const_int 8)
8379                          (const_int 8))
8380         (and:SI
8381           (zero_extract:SI
8382             (match_operand 1 "ext_register_operand" "0")
8383             (const_int 8)
8384             (const_int 8))
8385           (zero_extend:SI
8386             (match_operand 2 "ext_register_operand" "Q"))))
8387    (clobber (reg:CC FLAGS_REG))]
8388   "TARGET_64BIT"
8389   "and{b}\t{%2, %h0|%h0, %2}"
8390   [(set_attr "type" "alu")
8391    (set_attr "length_immediate" "0")
8392    (set_attr "mode" "QI")])
8393
8394 (define_insn "*andqi_ext_1"
8395   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8396                          (const_int 8)
8397                          (const_int 8))
8398         (and:SI
8399           (zero_extract:SI
8400             (match_operand 1 "ext_register_operand" "0")
8401             (const_int 8)
8402             (const_int 8))
8403           (zero_extend:SI
8404             (match_operand:QI 2 "general_operand" "Qm"))))
8405    (clobber (reg:CC FLAGS_REG))]
8406   "!TARGET_64BIT"
8407   "and{b}\t{%2, %h0|%h0, %2}"
8408   [(set_attr "type" "alu")
8409    (set_attr "length_immediate" "0")
8410    (set_attr "mode" "QI")])
8411
8412 (define_insn "*andqi_ext_2"
8413   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8414                          (const_int 8)
8415                          (const_int 8))
8416         (and:SI
8417           (zero_extract:SI
8418             (match_operand 1 "ext_register_operand" "%0")
8419             (const_int 8)
8420             (const_int 8))
8421           (zero_extract:SI
8422             (match_operand 2 "ext_register_operand" "Q")
8423             (const_int 8)
8424             (const_int 8))))
8425    (clobber (reg:CC FLAGS_REG))]
8426   ""
8427   "and{b}\t{%h2, %h0|%h0, %h2}"
8428   [(set_attr "type" "alu")
8429    (set_attr "length_immediate" "0")
8430    (set_attr "mode" "QI")])
8431
8432 ;; Convert wide AND instructions with immediate operand to shorter QImode
8433 ;; equivalents when possible.
8434 ;; Don't do the splitting with memory operands, since it introduces risk
8435 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8436 ;; for size, but that can (should?) be handled by generic code instead.
8437 (define_split
8438   [(set (match_operand 0 "register_operand" "")
8439         (and (match_operand 1 "register_operand" "")
8440              (match_operand 2 "const_int_operand" "")))
8441    (clobber (reg:CC FLAGS_REG))]
8442    "reload_completed
8443     && QI_REG_P (operands[0])
8444     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8445     && !(~INTVAL (operands[2]) & ~(255 << 8))
8446     && GET_MODE (operands[0]) != QImode"
8447   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8448                    (and:SI (zero_extract:SI (match_dup 1)
8449                                             (const_int 8) (const_int 8))
8450                            (match_dup 2)))
8451               (clobber (reg:CC FLAGS_REG))])]
8452   "operands[0] = gen_lowpart (SImode, operands[0]);
8453    operands[1] = gen_lowpart (SImode, operands[1]);
8454    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8455
8456 ;; Since AND can be encoded with sign extended immediate, this is only
8457 ;; profitable when 7th bit is not set.
8458 (define_split
8459   [(set (match_operand 0 "register_operand" "")
8460         (and (match_operand 1 "general_operand" "")
8461              (match_operand 2 "const_int_operand" "")))
8462    (clobber (reg:CC FLAGS_REG))]
8463    "reload_completed
8464     && ANY_QI_REG_P (operands[0])
8465     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8466     && !(~INTVAL (operands[2]) & ~255)
8467     && !(INTVAL (operands[2]) & 128)
8468     && GET_MODE (operands[0]) != QImode"
8469   [(parallel [(set (strict_low_part (match_dup 0))
8470                    (and:QI (match_dup 1)
8471                            (match_dup 2)))
8472               (clobber (reg:CC FLAGS_REG))])]
8473   "operands[0] = gen_lowpart (QImode, operands[0]);
8474    operands[1] = gen_lowpart (QImode, operands[1]);
8475    operands[2] = gen_lowpart (QImode, operands[2]);")
8476 \f
8477 ;; Logical inclusive and exclusive OR instructions
8478
8479 ;; %%% This used to optimize known byte-wide and operations to memory.
8480 ;; If this is considered useful, it should be done with splitters.
8481
8482 (define_expand "<code><mode>3"
8483   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8484         (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8485                      (match_operand:SWIM 2 "<general_operand>" "")))]
8486   ""
8487   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8488
8489 (define_insn "*<code><mode>_1"
8490   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8491         (any_or:SWI248
8492          (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8493          (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8494    (clobber (reg:CC FLAGS_REG))]
8495   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8496   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8497   [(set_attr "type" "alu")
8498    (set_attr "mode" "<MODE>")])
8499
8500 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8501 (define_insn "*<code>qi_1"
8502   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8503         (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8504                    (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8505    (clobber (reg:CC FLAGS_REG))]
8506   "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8507   "@
8508    <logic>{b}\t{%2, %0|%0, %2}
8509    <logic>{b}\t{%2, %0|%0, %2}
8510    <logic>{l}\t{%k2, %k0|%k0, %k2}"
8511   [(set_attr "type" "alu")
8512    (set_attr "mode" "QI,QI,SI")])
8513
8514 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8515 (define_insn "*<code>si_1_zext"
8516   [(set (match_operand:DI 0 "register_operand" "=r")
8517         (zero_extend:DI
8518          (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8519                     (match_operand:SI 2 "general_operand" "g"))))
8520    (clobber (reg:CC FLAGS_REG))]
8521   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8522   "<logic>{l}\t{%2, %k0|%k0, %2}"
8523   [(set_attr "type" "alu")
8524    (set_attr "mode" "SI")])
8525
8526 (define_insn "*<code>si_1_zext_imm"
8527   [(set (match_operand:DI 0 "register_operand" "=r")
8528         (any_or:DI
8529          (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8530          (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8531    (clobber (reg:CC FLAGS_REG))]
8532   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8533   "<logic>{l}\t{%2, %k0|%k0, %2}"
8534   [(set_attr "type" "alu")
8535    (set_attr "mode" "SI")])
8536
8537 (define_insn "*<code>qi_1_slp"
8538   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8539         (any_or:QI (match_dup 0)
8540                    (match_operand:QI 1 "general_operand" "qmn,qn")))
8541    (clobber (reg:CC FLAGS_REG))]
8542   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8543    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8544   "<logic>{b}\t{%1, %0|%0, %1}"
8545   [(set_attr "type" "alu1")
8546    (set_attr "mode" "QI")])
8547
8548 (define_insn "*<code><mode>_2"
8549   [(set (reg FLAGS_REG)
8550         (compare (any_or:SWI
8551                   (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8552                   (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8553                  (const_int 0)))
8554    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8555         (any_or:SWI (match_dup 1) (match_dup 2)))]
8556   "ix86_match_ccmode (insn, CCNOmode)
8557    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8558   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8559   [(set_attr "type" "alu")
8560    (set_attr "mode" "<MODE>")])
8561
8562 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8563 ;; ??? Special case for immediate operand is missing - it is tricky.
8564 (define_insn "*<code>si_2_zext"
8565   [(set (reg FLAGS_REG)
8566         (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8567                             (match_operand:SI 2 "general_operand" "g"))
8568                  (const_int 0)))
8569    (set (match_operand:DI 0 "register_operand" "=r")
8570         (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8571   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8572    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8573   "<logic>{l}\t{%2, %k0|%k0, %2}"
8574   [(set_attr "type" "alu")
8575    (set_attr "mode" "SI")])
8576
8577 (define_insn "*<code>si_2_zext_imm"
8578   [(set (reg FLAGS_REG)
8579         (compare (any_or:SI
8580                   (match_operand:SI 1 "nonimmediate_operand" "%0")
8581                   (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8582                  (const_int 0)))
8583    (set (match_operand:DI 0 "register_operand" "=r")
8584         (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8585   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8586    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8587   "<logic>{l}\t{%2, %k0|%k0, %2}"
8588   [(set_attr "type" "alu")
8589    (set_attr "mode" "SI")])
8590
8591 (define_insn "*<code>qi_2_slp"
8592   [(set (reg FLAGS_REG)
8593         (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8594                             (match_operand:QI 1 "general_operand" "qmn,qn"))
8595                  (const_int 0)))
8596    (set (strict_low_part (match_dup 0))
8597         (any_or:QI (match_dup 0) (match_dup 1)))]
8598   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8599    && ix86_match_ccmode (insn, CCNOmode)
8600    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8601   "<logic>{b}\t{%1, %0|%0, %1}"
8602   [(set_attr "type" "alu1")
8603    (set_attr "mode" "QI")])
8604
8605 (define_insn "*<code><mode>_3"
8606   [(set (reg FLAGS_REG)
8607         (compare (any_or:SWI
8608                   (match_operand:SWI 1 "nonimmediate_operand" "%0")
8609                   (match_operand:SWI 2 "<general_operand>" "<g>"))
8610                  (const_int 0)))
8611    (clobber (match_scratch:SWI 0 "=<r>"))]
8612   "ix86_match_ccmode (insn, CCNOmode)
8613    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8614   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8615   [(set_attr "type" "alu")
8616    (set_attr "mode" "<MODE>")])
8617
8618 (define_insn "*<code>qi_ext_0"
8619   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8620                          (const_int 8)
8621                          (const_int 8))
8622         (any_or:SI
8623           (zero_extract:SI
8624             (match_operand 1 "ext_register_operand" "0")
8625             (const_int 8)
8626             (const_int 8))
8627           (match_operand 2 "const_int_operand" "n")))
8628    (clobber (reg:CC FLAGS_REG))]
8629   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8630   "<logic>{b}\t{%2, %h0|%h0, %2}"
8631   [(set_attr "type" "alu")
8632    (set_attr "length_immediate" "1")
8633    (set_attr "modrm" "1")
8634    (set_attr "mode" "QI")])
8635
8636 (define_insn "*<code>qi_ext_1_rex64"
8637   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8638                          (const_int 8)
8639                          (const_int 8))
8640         (any_or:SI
8641           (zero_extract:SI
8642             (match_operand 1 "ext_register_operand" "0")
8643             (const_int 8)
8644             (const_int 8))
8645           (zero_extend:SI
8646             (match_operand 2 "ext_register_operand" "Q"))))
8647    (clobber (reg:CC FLAGS_REG))]
8648   "TARGET_64BIT
8649    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8650   "<logic>{b}\t{%2, %h0|%h0, %2}"
8651   [(set_attr "type" "alu")
8652    (set_attr "length_immediate" "0")
8653    (set_attr "mode" "QI")])
8654
8655 (define_insn "*<code>qi_ext_1"
8656   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8657                          (const_int 8)
8658                          (const_int 8))
8659         (any_or:SI
8660           (zero_extract:SI
8661             (match_operand 1 "ext_register_operand" "0")
8662             (const_int 8)
8663             (const_int 8))
8664           (zero_extend:SI
8665             (match_operand:QI 2 "general_operand" "Qm"))))
8666    (clobber (reg:CC FLAGS_REG))]
8667   "!TARGET_64BIT
8668    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8669   "<logic>{b}\t{%2, %h0|%h0, %2}"
8670   [(set_attr "type" "alu")
8671    (set_attr "length_immediate" "0")
8672    (set_attr "mode" "QI")])
8673
8674 (define_insn "*<code>qi_ext_2"
8675   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8676                          (const_int 8)
8677                          (const_int 8))
8678         (any_or:SI
8679           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8680                            (const_int 8)
8681                            (const_int 8))
8682           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8683                            (const_int 8)
8684                            (const_int 8))))
8685    (clobber (reg:CC FLAGS_REG))]
8686   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8687   "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8688   [(set_attr "type" "alu")
8689    (set_attr "length_immediate" "0")
8690    (set_attr "mode" "QI")])
8691
8692 (define_split
8693   [(set (match_operand 0 "register_operand" "")
8694         (any_or (match_operand 1 "register_operand" "")
8695                 (match_operand 2 "const_int_operand" "")))
8696    (clobber (reg:CC FLAGS_REG))]
8697    "reload_completed
8698     && QI_REG_P (operands[0])
8699     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8700     && !(INTVAL (operands[2]) & ~(255 << 8))
8701     && GET_MODE (operands[0]) != QImode"
8702   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8703                    (any_or:SI (zero_extract:SI (match_dup 1)
8704                                                (const_int 8) (const_int 8))
8705                               (match_dup 2)))
8706               (clobber (reg:CC FLAGS_REG))])]
8707   "operands[0] = gen_lowpart (SImode, operands[0]);
8708    operands[1] = gen_lowpart (SImode, operands[1]);
8709    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8710
8711 ;; Since OR can be encoded with sign extended immediate, this is only
8712 ;; profitable when 7th bit is set.
8713 (define_split
8714   [(set (match_operand 0 "register_operand" "")
8715         (any_or (match_operand 1 "general_operand" "")
8716                 (match_operand 2 "const_int_operand" "")))
8717    (clobber (reg:CC FLAGS_REG))]
8718    "reload_completed
8719     && ANY_QI_REG_P (operands[0])
8720     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8721     && !(INTVAL (operands[2]) & ~255)
8722     && (INTVAL (operands[2]) & 128)
8723     && GET_MODE (operands[0]) != QImode"
8724   [(parallel [(set (strict_low_part (match_dup 0))
8725                    (any_or:QI (match_dup 1)
8726                               (match_dup 2)))
8727               (clobber (reg:CC FLAGS_REG))])]
8728   "operands[0] = gen_lowpart (QImode, operands[0]);
8729    operands[1] = gen_lowpart (QImode, operands[1]);
8730    operands[2] = gen_lowpart (QImode, operands[2]);")
8731
8732 (define_expand "xorqi_cc_ext_1"
8733   [(parallel [
8734      (set (reg:CCNO FLAGS_REG)
8735           (compare:CCNO
8736             (xor:SI
8737               (zero_extract:SI
8738                 (match_operand 1 "ext_register_operand" "")
8739                 (const_int 8)
8740                 (const_int 8))
8741               (match_operand:QI 2 "general_operand" ""))
8742             (const_int 0)))
8743      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8744                            (const_int 8)
8745                            (const_int 8))
8746           (xor:SI
8747             (zero_extract:SI
8748              (match_dup 1)
8749              (const_int 8)
8750              (const_int 8))
8751             (match_dup 2)))])]
8752   ""
8753   "")
8754
8755 (define_insn "*xorqi_cc_ext_1_rex64"
8756   [(set (reg FLAGS_REG)
8757         (compare
8758           (xor:SI
8759             (zero_extract:SI
8760               (match_operand 1 "ext_register_operand" "0")
8761               (const_int 8)
8762               (const_int 8))
8763             (match_operand:QI 2 "nonmemory_operand" "Qn"))
8764           (const_int 0)))
8765    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8766                          (const_int 8)
8767                          (const_int 8))
8768         (xor:SI
8769           (zero_extract:SI
8770            (match_dup 1)
8771            (const_int 8)
8772            (const_int 8))
8773           (match_dup 2)))]
8774   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8775   "xor{b}\t{%2, %h0|%h0, %2}"
8776   [(set_attr "type" "alu")
8777    (set_attr "modrm" "1")
8778    (set_attr "mode" "QI")])
8779
8780 (define_insn "*xorqi_cc_ext_1"
8781   [(set (reg FLAGS_REG)
8782         (compare
8783           (xor:SI
8784             (zero_extract:SI
8785               (match_operand 1 "ext_register_operand" "0")
8786               (const_int 8)
8787               (const_int 8))
8788             (match_operand:QI 2 "general_operand" "qmn"))
8789           (const_int 0)))
8790    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8791                          (const_int 8)
8792                          (const_int 8))
8793         (xor:SI
8794           (zero_extract:SI
8795            (match_dup 1)
8796            (const_int 8)
8797            (const_int 8))
8798           (match_dup 2)))]
8799   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8800   "xor{b}\t{%2, %h0|%h0, %2}"
8801   [(set_attr "type" "alu")
8802    (set_attr "modrm" "1")
8803    (set_attr "mode" "QI")])
8804 \f
8805 ;; Negation instructions
8806
8807 (define_expand "neg<mode>2"
8808   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
8809         (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
8810   ""
8811   "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8812
8813 (define_insn_and_split "*neg<dwi>2_doubleword"
8814   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8815         (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8816    (clobber (reg:CC FLAGS_REG))]
8817   "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8818   "#"
8819   "reload_completed"
8820   [(parallel
8821     [(set (reg:CCZ FLAGS_REG)
8822           (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8823      (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8824    (parallel
8825     [(set (match_dup 2)
8826           (plus:DWIH (match_dup 3)
8827                      (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8828                                 (const_int 0))))
8829      (clobber (reg:CC FLAGS_REG))])
8830    (parallel
8831     [(set (match_dup 2)
8832           (neg:DWIH (match_dup 2)))
8833      (clobber (reg:CC FLAGS_REG))])]
8834   "split_<dwi> (&operands[0], 2, &operands[0], &operands[2]);")
8835
8836 (define_insn "*neg<mode>2_1"
8837   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8838         (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8839    (clobber (reg:CC FLAGS_REG))]
8840   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8841   "neg{<imodesuffix>}\t%0"
8842   [(set_attr "type" "negnot")
8843    (set_attr "mode" "<MODE>")])
8844
8845 ;; Combine is quite creative about this pattern.
8846 (define_insn "*negsi2_1_zext"
8847   [(set (match_operand:DI 0 "register_operand" "=r")
8848         (lshiftrt:DI
8849           (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8850                              (const_int 32)))
8851         (const_int 32)))
8852    (clobber (reg:CC FLAGS_REG))]
8853   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8854   "neg{l}\t%k0"
8855   [(set_attr "type" "negnot")
8856    (set_attr "mode" "SI")])
8857
8858 ;; The problem with neg is that it does not perform (compare x 0),
8859 ;; it really performs (compare 0 x), which leaves us with the zero
8860 ;; flag being the only useful item.
8861
8862 (define_insn "*neg<mode>2_cmpz"
8863   [(set (reg:CCZ FLAGS_REG)
8864         (compare:CCZ
8865           (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8866                    (const_int 0)))
8867    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8868         (neg:SWI (match_dup 1)))]
8869   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8870   "neg{<imodesuffix>}\t%0"
8871   [(set_attr "type" "negnot")
8872    (set_attr "mode" "<MODE>")])
8873
8874 (define_insn "*negsi2_cmpz_zext"
8875   [(set (reg:CCZ FLAGS_REG)
8876         (compare:CCZ
8877           (lshiftrt:DI
8878             (neg:DI (ashift:DI
8879                       (match_operand:DI 1 "register_operand" "0")
8880                       (const_int 32)))
8881             (const_int 32))
8882           (const_int 0)))
8883    (set (match_operand:DI 0 "register_operand" "=r")
8884         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8885                                         (const_int 32)))
8886                      (const_int 32)))]
8887   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8888   "neg{l}\t%k0"
8889   [(set_attr "type" "negnot")
8890    (set_attr "mode" "SI")])
8891
8892 ;; Changing of sign for FP values is doable using integer unit too.
8893
8894 (define_expand "<code><mode>2"
8895   [(set (match_operand:X87MODEF 0 "register_operand" "")
8896         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
8897   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8898   "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8899
8900 (define_insn "*absneg<mode>2_mixed"
8901   [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8902         (match_operator:MODEF 3 "absneg_operator"
8903           [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8904    (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8905    (clobber (reg:CC FLAGS_REG))]
8906   "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8907   "#")
8908
8909 (define_insn "*absneg<mode>2_sse"
8910   [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8911         (match_operator:MODEF 3 "absneg_operator"
8912           [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8913    (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8914    (clobber (reg:CC FLAGS_REG))]
8915   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8916   "#")
8917
8918 (define_insn "*absneg<mode>2_i387"
8919   [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8920         (match_operator:X87MODEF 3 "absneg_operator"
8921           [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8922    (use (match_operand 2 "" ""))
8923    (clobber (reg:CC FLAGS_REG))]
8924   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8925   "#")
8926
8927 (define_expand "<code>tf2"
8928   [(set (match_operand:TF 0 "register_operand" "")
8929         (absneg:TF (match_operand:TF 1 "register_operand" "")))]
8930   "TARGET_SSE2"
8931   "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8932
8933 (define_insn "*absnegtf2_sse"
8934   [(set (match_operand:TF 0 "register_operand" "=x,x")
8935         (match_operator:TF 3 "absneg_operator"
8936           [(match_operand:TF 1 "register_operand" "0,x")]))
8937    (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8938    (clobber (reg:CC FLAGS_REG))]
8939   "TARGET_SSE2"
8940   "#")
8941
8942 ;; Splitters for fp abs and neg.
8943
8944 (define_split
8945   [(set (match_operand 0 "fp_register_operand" "")
8946         (match_operator 1 "absneg_operator" [(match_dup 0)]))
8947    (use (match_operand 2 "" ""))
8948    (clobber (reg:CC FLAGS_REG))]
8949   "reload_completed"
8950   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8951
8952 (define_split
8953   [(set (match_operand 0 "register_operand" "")
8954         (match_operator 3 "absneg_operator"
8955           [(match_operand 1 "register_operand" "")]))
8956    (use (match_operand 2 "nonimmediate_operand" ""))
8957    (clobber (reg:CC FLAGS_REG))]
8958   "reload_completed && SSE_REG_P (operands[0])"
8959   [(set (match_dup 0) (match_dup 3))]
8960 {
8961   enum machine_mode mode = GET_MODE (operands[0]);
8962   enum machine_mode vmode = GET_MODE (operands[2]);
8963   rtx tmp;
8964
8965   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8966   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8967   if (operands_match_p (operands[0], operands[2]))
8968     {
8969       tmp = operands[1];
8970       operands[1] = operands[2];
8971       operands[2] = tmp;
8972     }
8973   if (GET_CODE (operands[3]) == ABS)
8974     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8975   else
8976     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8977   operands[3] = tmp;
8978 })
8979
8980 (define_split
8981   [(set (match_operand:SF 0 "register_operand" "")
8982         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8983    (use (match_operand:V4SF 2 "" ""))
8984    (clobber (reg:CC FLAGS_REG))]
8985   "reload_completed"
8986   [(parallel [(set (match_dup 0) (match_dup 1))
8987               (clobber (reg:CC FLAGS_REG))])]
8988 {
8989   rtx tmp;
8990   operands[0] = gen_lowpart (SImode, operands[0]);
8991   if (GET_CODE (operands[1]) == ABS)
8992     {
8993       tmp = gen_int_mode (0x7fffffff, SImode);
8994       tmp = gen_rtx_AND (SImode, operands[0], tmp);
8995     }
8996   else
8997     {
8998       tmp = gen_int_mode (0x80000000, SImode);
8999       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9000     }
9001   operands[1] = tmp;
9002 })
9003
9004 (define_split
9005   [(set (match_operand:DF 0 "register_operand" "")
9006         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9007    (use (match_operand 2 "" ""))
9008    (clobber (reg:CC FLAGS_REG))]
9009   "reload_completed"
9010   [(parallel [(set (match_dup 0) (match_dup 1))
9011               (clobber (reg:CC FLAGS_REG))])]
9012 {
9013   rtx tmp;
9014   if (TARGET_64BIT)
9015     {
9016       tmp = gen_lowpart (DImode, operands[0]);
9017       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9018       operands[0] = tmp;
9019
9020       if (GET_CODE (operands[1]) == ABS)
9021         tmp = const0_rtx;
9022       else
9023         tmp = gen_rtx_NOT (DImode, tmp);
9024     }
9025   else
9026     {
9027       operands[0] = gen_highpart (SImode, operands[0]);
9028       if (GET_CODE (operands[1]) == ABS)
9029         {
9030           tmp = gen_int_mode (0x7fffffff, SImode);
9031           tmp = gen_rtx_AND (SImode, operands[0], tmp);
9032         }
9033       else
9034         {
9035           tmp = gen_int_mode (0x80000000, SImode);
9036           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9037         }
9038     }
9039   operands[1] = tmp;
9040 })
9041
9042 (define_split
9043   [(set (match_operand:XF 0 "register_operand" "")
9044         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9045    (use (match_operand 2 "" ""))
9046    (clobber (reg:CC FLAGS_REG))]
9047   "reload_completed"
9048   [(parallel [(set (match_dup 0) (match_dup 1))
9049               (clobber (reg:CC FLAGS_REG))])]
9050 {
9051   rtx tmp;
9052   operands[0] = gen_rtx_REG (SImode,
9053                              true_regnum (operands[0])
9054                              + (TARGET_64BIT ? 1 : 2));
9055   if (GET_CODE (operands[1]) == ABS)
9056     {
9057       tmp = GEN_INT (0x7fff);
9058       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9059     }
9060   else
9061     {
9062       tmp = GEN_INT (0x8000);
9063       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9064     }
9065   operands[1] = tmp;
9066 })
9067
9068 ;; Conditionalize these after reload. If they match before reload, we
9069 ;; lose the clobber and ability to use integer instructions.
9070
9071 (define_insn "*<code><mode>2_1"
9072   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
9073         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
9074   "TARGET_80387
9075    && (reload_completed
9076        || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
9077   "f<absneg_mnemonic>"
9078   [(set_attr "type" "fsgn")
9079    (set_attr "mode" "<MODE>")])
9080
9081 (define_insn "*<code>extendsfdf2"
9082   [(set (match_operand:DF 0 "register_operand" "=f")
9083         (absneg:DF (float_extend:DF
9084                      (match_operand:SF 1 "register_operand" "0"))))]
9085   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9086   "f<absneg_mnemonic>"
9087   [(set_attr "type" "fsgn")
9088    (set_attr "mode" "DF")])
9089
9090 (define_insn "*<code>extendsfxf2"
9091   [(set (match_operand:XF 0 "register_operand" "=f")
9092         (absneg:XF (float_extend:XF
9093                      (match_operand:SF 1 "register_operand" "0"))))]
9094   "TARGET_80387"
9095   "f<absneg_mnemonic>"
9096   [(set_attr "type" "fsgn")
9097    (set_attr "mode" "XF")])
9098
9099 (define_insn "*<code>extenddfxf2"
9100   [(set (match_operand:XF 0 "register_operand" "=f")
9101         (absneg:XF (float_extend:XF
9102                      (match_operand:DF 1 "register_operand" "0"))))]
9103   "TARGET_80387"
9104   "f<absneg_mnemonic>"
9105   [(set_attr "type" "fsgn")
9106    (set_attr "mode" "XF")])
9107
9108 ;; Copysign instructions
9109
9110 (define_mode_iterator CSGNMODE [SF DF TF])
9111 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
9112
9113 (define_expand "copysign<mode>3"
9114   [(match_operand:CSGNMODE 0 "register_operand" "")
9115    (match_operand:CSGNMODE 1 "nonmemory_operand" "")
9116    (match_operand:CSGNMODE 2 "register_operand" "")]
9117   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9118    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
9119 {
9120   ix86_expand_copysign (operands);
9121   DONE;
9122 })
9123
9124 (define_insn_and_split "copysign<mode>3_const"
9125   [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
9126         (unspec:CSGNMODE
9127           [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
9128            (match_operand:CSGNMODE 2 "register_operand" "0")
9129            (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
9130           UNSPEC_COPYSIGN))]
9131   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9132    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
9133   "#"
9134   "&& reload_completed"
9135   [(const_int 0)]
9136 {
9137   ix86_split_copysign_const (operands);
9138   DONE;
9139 })
9140
9141 (define_insn "copysign<mode>3_var"
9142   [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
9143         (unspec:CSGNMODE
9144           [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
9145            (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
9146            (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
9147            (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
9148           UNSPEC_COPYSIGN))
9149    (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
9150   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9151    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
9152   "#")
9153
9154 (define_split
9155   [(set (match_operand:CSGNMODE 0 "register_operand" "")
9156         (unspec:CSGNMODE
9157           [(match_operand:CSGNMODE 2 "register_operand" "")
9158            (match_operand:CSGNMODE 3 "register_operand" "")
9159            (match_operand:<CSGNVMODE> 4 "" "")
9160            (match_operand:<CSGNVMODE> 5 "" "")]
9161           UNSPEC_COPYSIGN))
9162    (clobber (match_scratch:<CSGNVMODE> 1 ""))]
9163   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9164     || (TARGET_SSE2 && (<MODE>mode == TFmode)))
9165    && reload_completed"
9166   [(const_int 0)]
9167 {
9168   ix86_split_copysign_var (operands);
9169   DONE;
9170 })
9171 \f
9172 ;; One complement instructions
9173
9174 (define_expand "one_cmpl<mode>2"
9175   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
9176         (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
9177   ""
9178   "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
9179
9180 (define_insn "*one_cmpl<mode>2_1"
9181   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
9182         (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
9183   "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9184   "not{<imodesuffix>}\t%0"
9185   [(set_attr "type" "negnot")
9186    (set_attr "mode" "<MODE>")])
9187
9188 ;; %%% Potential partial reg stall on alternative 1.  What to do?
9189 (define_insn "*one_cmplqi2_1"
9190   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9191         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
9192   "ix86_unary_operator_ok (NOT, QImode, operands)"
9193   "@
9194    not{b}\t%0
9195    not{l}\t%k0"
9196   [(set_attr "type" "negnot")
9197    (set_attr "mode" "QI,SI")])
9198
9199 ;; ??? Currently never generated - xor is used instead.
9200 (define_insn "*one_cmplsi2_1_zext"
9201   [(set (match_operand:DI 0 "register_operand" "=r")
9202         (zero_extend:DI
9203           (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9204   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9205   "not{l}\t%k0"
9206   [(set_attr "type" "negnot")
9207    (set_attr "mode" "SI")])
9208
9209 (define_insn "*one_cmpl<mode>2_2"
9210   [(set (reg FLAGS_REG)
9211         (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9212                  (const_int 0)))
9213    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9214         (not:SWI (match_dup 1)))]
9215   "ix86_match_ccmode (insn, CCNOmode)
9216    && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9217   "#"
9218   [(set_attr "type" "alu1")
9219    (set_attr "mode" "<MODE>")])
9220
9221 (define_split
9222   [(set (match_operand 0 "flags_reg_operand" "")
9223         (match_operator 2 "compare_operator"
9224           [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
9225            (const_int 0)]))
9226    (set (match_operand:SWI 1 "nonimmediate_operand" "")
9227         (not:SWI (match_dup 3)))]
9228   "ix86_match_ccmode (insn, CCNOmode)"
9229   [(parallel [(set (match_dup 0)
9230                    (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9231                                     (const_int 0)]))
9232               (set (match_dup 1)
9233                    (xor:SWI (match_dup 3) (const_int -1)))])]
9234   "")
9235
9236 ;; ??? Currently never generated - xor is used instead.
9237 (define_insn "*one_cmplsi2_2_zext"
9238   [(set (reg FLAGS_REG)
9239         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9240                  (const_int 0)))
9241    (set (match_operand:DI 0 "register_operand" "=r")
9242         (zero_extend:DI (not:SI (match_dup 1))))]
9243   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9244    && ix86_unary_operator_ok (NOT, SImode, operands)"
9245   "#"
9246   [(set_attr "type" "alu1")
9247    (set_attr "mode" "SI")])
9248
9249 (define_split
9250   [(set (match_operand 0 "flags_reg_operand" "")
9251         (match_operator 2 "compare_operator"
9252           [(not:SI (match_operand:SI 3 "register_operand" ""))
9253            (const_int 0)]))
9254    (set (match_operand:DI 1 "register_operand" "")
9255         (zero_extend:DI (not:SI (match_dup 3))))]
9256   "ix86_match_ccmode (insn, CCNOmode)"
9257   [(parallel [(set (match_dup 0)
9258                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9259                                     (const_int 0)]))
9260               (set (match_dup 1)
9261                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
9262   "")
9263 \f
9264 ;; Shift instructions
9265
9266 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9267 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
9268 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9269 ;; from the assembler input.
9270 ;;
9271 ;; This instruction shifts the target reg/mem as usual, but instead of
9272 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
9273 ;; is a left shift double, bits are taken from the high order bits of
9274 ;; reg, else if the insn is a shift right double, bits are taken from the
9275 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
9276 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9277 ;;
9278 ;; Since sh[lr]d does not change the `reg' operand, that is done
9279 ;; separately, making all shifts emit pairs of shift double and normal
9280 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
9281 ;; support a 63 bit shift, each shift where the count is in a reg expands
9282 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9283 ;;
9284 ;; If the shift count is a constant, we need never emit more than one
9285 ;; shift pair, instead using moves and sign extension for counts greater
9286 ;; than 31.
9287
9288 (define_expand "ashl<mode>3"
9289   [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9290         (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
9291                       (match_operand:QI 2 "nonmemory_operand" "")))]
9292   ""
9293   "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9294
9295 (define_insn "*ashl<mode>3_doubleword"
9296   [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9297         (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9298                     (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9299    (clobber (reg:CC FLAGS_REG))]
9300   ""
9301   "#"
9302   [(set_attr "type" "multi")])
9303
9304 (define_split
9305   [(set (match_operand:DWI 0 "register_operand" "")
9306         (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
9307                     (match_operand:QI 2 "nonmemory_operand" "")))
9308    (clobber (reg:CC FLAGS_REG))]
9309   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9310   [(const_int 0)]
9311   "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9312
9313 ;; By default we don't ask for a scratch register, because when DWImode
9314 ;; values are manipulated, registers are already at a premium.  But if
9315 ;; we have one handy, we won't turn it away.
9316
9317 (define_peephole2
9318   [(match_scratch:DWIH 3 "r")
9319    (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9320                    (ashift:<DWI>
9321                      (match_operand:<DWI> 1 "nonmemory_operand" "")
9322                      (match_operand:QI 2 "nonmemory_operand" "")))
9323               (clobber (reg:CC FLAGS_REG))])
9324    (match_dup 3)]
9325   "TARGET_CMOVE"
9326   [(const_int 0)]
9327   "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9328
9329 (define_insn "x86_64_shld"
9330   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9331         (ior:DI (ashift:DI (match_dup 0)
9332                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
9333                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9334                   (minus:QI (const_int 64) (match_dup 2)))))
9335    (clobber (reg:CC FLAGS_REG))]
9336   "TARGET_64BIT"
9337   "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9338   [(set_attr "type" "ishift")
9339    (set_attr "prefix_0f" "1")
9340    (set_attr "mode" "DI")
9341    (set_attr "athlon_decode" "vector")
9342    (set_attr "amdfam10_decode" "vector")])
9343
9344 (define_insn "x86_shld"
9345   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9346         (ior:SI (ashift:SI (match_dup 0)
9347                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
9348                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9349                   (minus:QI (const_int 32) (match_dup 2)))))
9350    (clobber (reg:CC FLAGS_REG))]
9351   ""
9352   "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9353   [(set_attr "type" "ishift")
9354    (set_attr "prefix_0f" "1")
9355    (set_attr "mode" "SI")
9356    (set_attr "pent_pair" "np")
9357    (set_attr "athlon_decode" "vector")
9358    (set_attr "amdfam10_decode" "vector")])
9359
9360 (define_expand "x86_shift<mode>_adj_1"
9361   [(set (reg:CCZ FLAGS_REG)
9362         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
9363                              (match_dup 4))
9364                      (const_int 0)))
9365    (set (match_operand:SWI48 0 "register_operand" "")
9366         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9367                             (match_operand:SWI48 1 "register_operand" "")
9368                             (match_dup 0)))
9369    (set (match_dup 1)
9370         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9371                             (match_operand:SWI48 3 "register_operand" "r")
9372                             (match_dup 1)))]
9373   "TARGET_CMOVE"
9374   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9375
9376 (define_expand "x86_shift<mode>_adj_2"
9377   [(use (match_operand:SWI48 0 "register_operand" ""))
9378    (use (match_operand:SWI48 1 "register_operand" ""))
9379    (use (match_operand:QI 2 "register_operand" ""))]
9380   ""
9381 {
9382   rtx label = gen_label_rtx ();
9383   rtx tmp;
9384
9385   emit_insn (gen_testqi_ccz_1 (operands[2],
9386                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9387
9388   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9389   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9390   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9391                               gen_rtx_LABEL_REF (VOIDmode, label),
9392                               pc_rtx);
9393   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9394   JUMP_LABEL (tmp) = label;
9395
9396   emit_move_insn (operands[0], operands[1]);
9397   ix86_expand_clear (operands[1]);
9398
9399   emit_label (label);
9400   LABEL_NUSES (label) = 1;
9401
9402   DONE;
9403 })
9404
9405 (define_insn "*ashl<mode>3_1"
9406   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9407         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l")
9408                       (match_operand:QI 2 "nonmemory_operand" "c<S>,M")))
9409    (clobber (reg:CC FLAGS_REG))]
9410   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9411 {
9412   switch (get_attr_type (insn))
9413     {
9414     case TYPE_LEA:
9415       return "#";
9416
9417     case TYPE_ALU:
9418       gcc_assert (operands[2] == const1_rtx);
9419       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9420       return "add{<imodesuffix>}\t%0, %0";
9421
9422     default:
9423       if (operands[2] == const1_rtx
9424           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9425         return "sal{<imodesuffix>}\t%0";
9426       else
9427         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9428     }
9429 }
9430   [(set (attr "type")
9431      (cond [(eq_attr "alternative" "1")
9432               (const_string "lea")
9433             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9434                           (const_int 0))
9435                       (match_operand 0 "register_operand" ""))
9436                  (match_operand 2 "const1_operand" ""))
9437               (const_string "alu")
9438            ]
9439            (const_string "ishift")))
9440    (set (attr "length_immediate")
9441      (if_then_else
9442        (ior (eq_attr "type" "alu")
9443             (and (eq_attr "type" "ishift")
9444                  (and (match_operand 2 "const1_operand" "")
9445                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9446                           (const_int 0)))))
9447        (const_string "0")
9448        (const_string "*")))
9449    (set_attr "mode" "<MODE>")])
9450
9451 (define_insn "*ashlsi3_1_zext"
9452   [(set (match_operand:DI 0 "register_operand" "=r,r")
9453         (zero_extend:DI
9454           (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
9455                      (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
9456    (clobber (reg:CC FLAGS_REG))]
9457   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9458 {
9459   switch (get_attr_type (insn))
9460     {
9461     case TYPE_LEA:
9462       return "#";
9463
9464     case TYPE_ALU:
9465       gcc_assert (operands[2] == const1_rtx);
9466       return "add{l}\t%k0, %k0";
9467
9468     default:
9469       if (operands[2] == const1_rtx
9470           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9471         return "sal{l}\t%k0";
9472       else
9473         return "sal{l}\t{%2, %k0|%k0, %2}";
9474     }
9475 }
9476   [(set (attr "type")
9477      (cond [(eq_attr "alternative" "1")
9478               (const_string "lea")
9479             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9480                      (const_int 0))
9481                  (match_operand 2 "const1_operand" ""))
9482               (const_string "alu")
9483            ]
9484            (const_string "ishift")))
9485    (set (attr "length_immediate")
9486      (if_then_else
9487        (ior (eq_attr "type" "alu")
9488             (and (eq_attr "type" "ishift")
9489                  (and (match_operand 2 "const1_operand" "")
9490                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9491                           (const_int 0)))))
9492        (const_string "0")
9493        (const_string "*")))
9494    (set_attr "mode" "SI")])
9495
9496 (define_insn "*ashlhi3_1"
9497   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9498         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
9499                    (match_operand:QI 2 "nonmemory_operand" "cI")))
9500    (clobber (reg:CC FLAGS_REG))]
9501   "TARGET_PARTIAL_REG_STALL
9502    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9503 {
9504   switch (get_attr_type (insn))
9505     {
9506     case TYPE_ALU:
9507       gcc_assert (operands[2] == const1_rtx);
9508       return "add{w}\t%0, %0";
9509
9510     default:
9511       if (operands[2] == const1_rtx
9512           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9513         return "sal{w}\t%0";
9514       else
9515         return "sal{w}\t{%2, %0|%0, %2}";
9516     }
9517 }
9518   [(set (attr "type")
9519      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9520                           (const_int 0))
9521                       (match_operand 0 "register_operand" ""))
9522                  (match_operand 2 "const1_operand" ""))
9523               (const_string "alu")
9524            ]
9525            (const_string "ishift")))
9526    (set (attr "length_immediate")
9527      (if_then_else
9528        (ior (eq_attr "type" "alu")
9529             (and (eq_attr "type" "ishift")
9530                  (and (match_operand 2 "const1_operand" "")
9531                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9532                           (const_int 0)))))
9533        (const_string "0")
9534        (const_string "*")))
9535    (set_attr "mode" "HI")])
9536
9537 (define_insn "*ashlhi3_1_lea"
9538   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
9539         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9540                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9541    (clobber (reg:CC FLAGS_REG))]
9542   "!TARGET_PARTIAL_REG_STALL
9543    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9544 {
9545   switch (get_attr_type (insn))
9546     {
9547     case TYPE_LEA:
9548       return "#";
9549
9550     case TYPE_ALU:
9551       gcc_assert (operands[2] == const1_rtx);
9552       return "add{w}\t%0, %0";
9553
9554     default:
9555       if (operands[2] == const1_rtx
9556           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9557         return "sal{w}\t%0";
9558       else
9559         return "sal{w}\t{%2, %0|%0, %2}";
9560     }
9561 }
9562   [(set (attr "type")
9563      (cond [(eq_attr "alternative" "1")
9564               (const_string "lea")
9565             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9566                           (const_int 0))
9567                       (match_operand 0 "register_operand" ""))
9568                  (match_operand 2 "const1_operand" ""))
9569               (const_string "alu")
9570            ]
9571            (const_string "ishift")))
9572    (set (attr "length_immediate")
9573      (if_then_else
9574        (ior (eq_attr "type" "alu")
9575             (and (eq_attr "type" "ishift")
9576                  (and (match_operand 2 "const1_operand" "")
9577                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9578                           (const_int 0)))))
9579        (const_string "0")
9580        (const_string "*")))
9581    (set_attr "mode" "HI,SI")])
9582
9583 (define_insn "*ashlqi3_1"
9584   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9585         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
9586                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
9587    (clobber (reg:CC FLAGS_REG))]
9588   "TARGET_PARTIAL_REG_STALL
9589    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9590 {
9591   switch (get_attr_type (insn))
9592     {
9593     case TYPE_ALU:
9594       gcc_assert (operands[2] == const1_rtx);
9595       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9596         return "add{l}\t%k0, %k0";
9597       else
9598         return "add{b}\t%0, %0";
9599
9600     default:
9601       if (operands[2] == const1_rtx
9602           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9603         {
9604           if (get_attr_mode (insn) == MODE_SI)
9605             return "sal{l}\t%k0";
9606           else
9607             return "sal{b}\t%0";
9608         }
9609       else
9610         {
9611           if (get_attr_mode (insn) == MODE_SI)
9612             return "sal{l}\t{%2, %k0|%k0, %2}";
9613           else
9614             return "sal{b}\t{%2, %0|%0, %2}";
9615         }
9616     }
9617 }
9618   [(set (attr "type")
9619      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9620                           (const_int 0))
9621                       (match_operand 0 "register_operand" ""))
9622                  (match_operand 2 "const1_operand" ""))
9623               (const_string "alu")
9624            ]
9625            (const_string "ishift")))
9626    (set (attr "length_immediate")
9627      (if_then_else
9628        (ior (eq_attr "type" "alu")
9629             (and (eq_attr "type" "ishift")
9630                  (and (match_operand 2 "const1_operand" "")
9631                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9632                           (const_int 0)))))
9633        (const_string "0")
9634        (const_string "*")))
9635    (set_attr "mode" "QI,SI")])
9636
9637 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9638 (define_insn "*ashlqi3_1_lea"
9639   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
9640         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9641                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9642    (clobber (reg:CC FLAGS_REG))]
9643   "!TARGET_PARTIAL_REG_STALL
9644    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9645 {
9646   switch (get_attr_type (insn))
9647     {
9648     case TYPE_LEA:
9649       return "#";
9650
9651     case TYPE_ALU:
9652       gcc_assert (operands[2] == const1_rtx);
9653       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9654         return "add{l}\t%k0, %k0";
9655       else
9656         return "add{b}\t%0, %0";
9657
9658     default:
9659       if (operands[2] == const1_rtx
9660           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9661         {
9662           if (get_attr_mode (insn) == MODE_SI)
9663             return "sal{l}\t%k0";
9664           else
9665             return "sal{b}\t%0";
9666         }
9667       else
9668         {
9669           if (get_attr_mode (insn) == MODE_SI)
9670             return "sal{l}\t{%2, %k0|%k0, %2}";
9671           else
9672             return "sal{b}\t{%2, %0|%0, %2}";
9673         }
9674     }
9675 }
9676   [(set (attr "type")
9677      (cond [(eq_attr "alternative" "2")
9678               (const_string "lea")
9679             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9680                           (const_int 0))
9681                       (match_operand 0 "register_operand" ""))
9682                  (match_operand 2 "const1_operand" ""))
9683               (const_string "alu")
9684            ]
9685            (const_string "ishift")))
9686    (set (attr "length_immediate")
9687      (if_then_else
9688        (ior (eq_attr "type" "alu")
9689             (and (eq_attr "type" "ishift")
9690                  (and (match_operand 2 "const1_operand" "")
9691                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9692                           (const_int 0)))))
9693        (const_string "0")
9694        (const_string "*")))
9695    (set_attr "mode" "QI,SI,SI")])
9696
9697 (define_insn "*ashlqi3_1_slp"
9698   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9699         (ashift:QI (match_dup 0)
9700                    (match_operand:QI 1 "nonmemory_operand" "cI")))
9701    (clobber (reg:CC FLAGS_REG))]
9702   "(optimize_function_for_size_p (cfun)
9703     || !TARGET_PARTIAL_FLAG_REG_STALL
9704     || (operands[1] == const1_rtx
9705         && (TARGET_SHIFT1
9706             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9707 {
9708   switch (get_attr_type (insn))
9709     {
9710     case TYPE_ALU:
9711       gcc_assert (operands[1] == const1_rtx);
9712       return "add{b}\t%0, %0";
9713
9714     default:
9715       if (operands[1] == const1_rtx
9716           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9717         return "sal{b}\t%0";
9718       else
9719         return "sal{b}\t{%1, %0|%0, %1}";
9720     }
9721 }
9722   [(set (attr "type")
9723      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9724                           (const_int 0))
9725                       (match_operand 0 "register_operand" ""))
9726                  (match_operand 1 "const1_operand" ""))
9727               (const_string "alu")
9728            ]
9729            (const_string "ishift1")))
9730    (set (attr "length_immediate")
9731      (if_then_else
9732        (ior (eq_attr "type" "alu")
9733             (and (eq_attr "type" "ishift1")
9734                  (and (match_operand 1 "const1_operand" "")
9735                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9736                           (const_int 0)))))
9737        (const_string "0")
9738        (const_string "*")))
9739    (set_attr "mode" "QI")])
9740
9741 ;; Convert lea to the lea pattern to avoid flags dependency.
9742 (define_split
9743   [(set (match_operand:DI 0 "register_operand" "")
9744         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
9745                    (match_operand:QI 2 "const_int_operand" "")))
9746    (clobber (reg:CC FLAGS_REG))]
9747   "TARGET_64BIT && reload_completed
9748    && true_regnum (operands[0]) != true_regnum (operands[1])"
9749   [(set (match_dup 0)
9750         (mult:DI (match_dup 1)
9751                  (match_dup 2)))]
9752   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
9753
9754 ;; Convert lea to the lea pattern to avoid flags dependency.
9755 (define_split
9756   [(set (match_operand 0 "register_operand" "")
9757         (ashift (match_operand 1 "index_register_operand" "")
9758                 (match_operand:QI 2 "const_int_operand" "")))
9759    (clobber (reg:CC FLAGS_REG))]
9760   "reload_completed
9761    && true_regnum (operands[0]) != true_regnum (operands[1])
9762    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
9763   [(const_int 0)]
9764 {
9765   rtx pat;
9766   enum machine_mode mode = GET_MODE (operands[0]);
9767
9768   if (GET_MODE_SIZE (mode) < 4)
9769     operands[0] = gen_lowpart (SImode, operands[0]);
9770   if (mode != Pmode)
9771     operands[1] = gen_lowpart (Pmode, operands[1]);
9772   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
9773
9774   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
9775   if (Pmode != SImode)
9776     pat = gen_rtx_SUBREG (SImode, pat, 0);
9777   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9778   DONE;
9779 })
9780
9781 ;; Rare case of shifting RSP is handled by generating move and shift
9782 (define_split
9783   [(set (match_operand 0 "register_operand" "")
9784         (ashift (match_operand 1 "register_operand" "")
9785                 (match_operand:QI 2 "const_int_operand" "")))
9786    (clobber (reg:CC FLAGS_REG))]
9787   "reload_completed
9788    && true_regnum (operands[0]) != true_regnum (operands[1])"
9789   [(const_int 0)]
9790 {
9791   rtx pat, clob;
9792   emit_move_insn (operands[0], operands[1]);
9793   pat = gen_rtx_SET (VOIDmode, operands[0],
9794                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
9795                                      operands[0], operands[2]));
9796   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
9797   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
9798   DONE;
9799 })
9800
9801 ;; Convert lea to the lea pattern to avoid flags dependency.
9802 (define_split
9803   [(set (match_operand:DI 0 "register_operand" "")
9804         (zero_extend:DI
9805           (ashift:SI (match_operand:SI 1 "register_operand" "")
9806                      (match_operand:QI 2 "const_int_operand" ""))))
9807    (clobber (reg:CC FLAGS_REG))]
9808   "TARGET_64BIT && reload_completed
9809    && true_regnum (operands[0]) != true_regnum (operands[1])"
9810   [(set (match_dup 0)
9811         (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9812 {
9813   operands[1] = gen_lowpart (Pmode, operands[1]);
9814   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
9815 })
9816
9817 ;; This pattern can't accept a variable shift count, since shifts by
9818 ;; zero don't affect the flags.  We assume that shifts by constant
9819 ;; zero are optimized away.
9820 (define_insn "*ashl<mode>3_cmp"
9821   [(set (reg FLAGS_REG)
9822         (compare
9823           (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9824                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9825           (const_int 0)))
9826    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9827         (ashift:SWI (match_dup 1) (match_dup 2)))]
9828   "(optimize_function_for_size_p (cfun)
9829     || !TARGET_PARTIAL_FLAG_REG_STALL
9830     || (operands[2] == const1_rtx
9831         && (TARGET_SHIFT1
9832             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9833    && ix86_match_ccmode (insn, CCGOCmode)
9834    && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9835 {
9836   switch (get_attr_type (insn))
9837     {
9838     case TYPE_ALU:
9839       gcc_assert (operands[2] == const1_rtx);
9840       return "add{<imodesuffix>}\t%0, %0";
9841
9842     default:
9843       if (operands[2] == const1_rtx
9844           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9845         return "sal{<imodesuffix>}\t%0";
9846       else
9847         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9848     }
9849 }
9850   [(set (attr "type")
9851      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9852                           (const_int 0))
9853                       (match_operand 0 "register_operand" ""))
9854                  (match_operand 2 "const1_operand" ""))
9855               (const_string "alu")
9856            ]
9857            (const_string "ishift")))
9858    (set (attr "length_immediate")
9859      (if_then_else
9860        (ior (eq_attr "type" "alu")
9861             (and (eq_attr "type" "ishift")
9862                  (and (match_operand 2 "const1_operand" "")
9863                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9864                           (const_int 0)))))
9865        (const_string "0")
9866        (const_string "*")))
9867    (set_attr "mode" "<MODE>")])
9868
9869 (define_insn "*ashlsi3_cmp_zext"
9870   [(set (reg FLAGS_REG)
9871         (compare
9872           (ashift:SI (match_operand:SI 1 "register_operand" "0")
9873                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
9874           (const_int 0)))
9875    (set (match_operand:DI 0 "register_operand" "=r")
9876         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9877   "TARGET_64BIT
9878    && (optimize_function_for_size_p (cfun)
9879        || !TARGET_PARTIAL_FLAG_REG_STALL
9880        || (operands[2] == const1_rtx
9881            && (TARGET_SHIFT1
9882                || TARGET_DOUBLE_WITH_ADD)))
9883    && ix86_match_ccmode (insn, CCGOCmode)
9884    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9885 {
9886   switch (get_attr_type (insn))
9887     {
9888     case TYPE_ALU:
9889       gcc_assert (operands[2] == const1_rtx);
9890       return "add{l}\t%k0, %k0";
9891
9892     default:
9893       if (operands[2] == const1_rtx
9894           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9895         return "sal{l}\t%k0";
9896       else
9897         return "sal{l}\t{%2, %k0|%k0, %2}";
9898     }
9899 }
9900   [(set (attr "type")
9901      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9902                      (const_int 0))
9903                  (match_operand 2 "const1_operand" ""))
9904               (const_string "alu")
9905            ]
9906            (const_string "ishift")))
9907    (set (attr "length_immediate")
9908      (if_then_else
9909        (ior (eq_attr "type" "alu")
9910             (and (eq_attr "type" "ishift")
9911                  (and (match_operand 2 "const1_operand" "")
9912                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9913                           (const_int 0)))))
9914        (const_string "0")
9915        (const_string "*")))
9916    (set_attr "mode" "SI")])
9917
9918 (define_insn "*ashl<mode>3_cconly"
9919   [(set (reg FLAGS_REG)
9920         (compare
9921           (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9922                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9923           (const_int 0)))
9924    (clobber (match_scratch:SWI 0 "=<r>"))]
9925   "(optimize_function_for_size_p (cfun)
9926     || !TARGET_PARTIAL_FLAG_REG_STALL
9927     || (operands[2] == const1_rtx
9928         && (TARGET_SHIFT1
9929             || TARGET_DOUBLE_WITH_ADD)))
9930    && ix86_match_ccmode (insn, CCGOCmode)
9931    && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9932 {
9933   switch (get_attr_type (insn))
9934     {
9935     case TYPE_ALU:
9936       gcc_assert (operands[2] == const1_rtx);
9937       return "add{<imodesuffix>}\t%0, %0";
9938
9939     default:
9940       if (operands[2] == const1_rtx
9941           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9942         return "sal{<imodesuffix>}\t%0";
9943       else
9944         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9945     }
9946 }
9947   [(set (attr "type")
9948      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9949                           (const_int 0))
9950                       (match_operand 0 "register_operand" ""))
9951                  (match_operand 2 "const1_operand" ""))
9952               (const_string "alu")
9953            ]
9954            (const_string "ishift")))
9955    (set (attr "length_immediate")
9956      (if_then_else
9957        (ior (eq_attr "type" "alu")
9958             (and (eq_attr "type" "ishift")
9959                  (and (match_operand 2 "const1_operand" "")
9960                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9961                           (const_int 0)))))
9962        (const_string "0")
9963        (const_string "*")))
9964    (set_attr "mode" "<MODE>")])
9965
9966 ;; See comment above `ashl<mode>3' about how this works.
9967
9968 (define_expand "<shiftrt_insn><mode>3"
9969   [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9970         (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
9971                            (match_operand:QI 2 "nonmemory_operand" "")))]
9972   ""
9973   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9974
9975 (define_insn_and_split "*<shiftrt_insn><mode>3_doubleword"
9976   [(set (match_operand:DWI 0 "register_operand" "=r")
9977         (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9978                          (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9979    (clobber (reg:CC FLAGS_REG))]
9980   ""
9981   "#"
9982   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9983   [(const_int 0)]
9984   "ix86_split_<shiftrt_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9985   [(set_attr "type" "multi")])
9986
9987 ;; By default we don't ask for a scratch register, because when DWImode
9988 ;; values are manipulated, registers are already at a premium.  But if
9989 ;; we have one handy, we won't turn it away.
9990
9991 (define_peephole2
9992   [(match_scratch:DWIH 3 "r")
9993    (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9994                    (any_shiftrt:<DWI>
9995                      (match_operand:<DWI> 1 "register_operand" "")
9996                      (match_operand:QI 2 "nonmemory_operand" "")))
9997               (clobber (reg:CC FLAGS_REG))])
9998    (match_dup 3)]
9999   "TARGET_CMOVE"
10000   [(const_int 0)]
10001   "ix86_split_<shiftrt_insn> (operands, operands[3], <DWI>mode); DONE;")
10002
10003 (define_insn "x86_64_shrd"
10004   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
10005         (ior:DI (ashiftrt:DI (match_dup 0)
10006                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
10007                 (ashift:DI (match_operand:DI 1 "register_operand" "r")
10008                   (minus:QI (const_int 64) (match_dup 2)))))
10009    (clobber (reg:CC FLAGS_REG))]
10010   "TARGET_64BIT"
10011   "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
10012   [(set_attr "type" "ishift")
10013    (set_attr "prefix_0f" "1")
10014    (set_attr "mode" "DI")
10015    (set_attr "athlon_decode" "vector")
10016    (set_attr "amdfam10_decode" "vector")])
10017
10018 (define_insn "x86_shrd"
10019   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
10020         (ior:SI (ashiftrt:SI (match_dup 0)
10021                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
10022                 (ashift:SI (match_operand:SI 1 "register_operand" "r")
10023                   (minus:QI (const_int 32) (match_dup 2)))))
10024    (clobber (reg:CC FLAGS_REG))]
10025   ""
10026   "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
10027   [(set_attr "type" "ishift")
10028    (set_attr "prefix_0f" "1")
10029    (set_attr "mode" "SI")
10030    (set_attr "pent_pair" "np")
10031    (set_attr "athlon_decode" "vector")
10032    (set_attr "amdfam10_decode" "vector")])
10033
10034 (define_insn "ashrdi3_cvt"
10035   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
10036         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
10037                      (match_operand:QI 2 "const_int_operand" "")))
10038    (clobber (reg:CC FLAGS_REG))]
10039   "TARGET_64BIT && INTVAL (operands[2]) == 63
10040    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10041    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10042   "@
10043    {cqto|cqo}
10044    sar{q}\t{%2, %0|%0, %2}"
10045   [(set_attr "type" "imovx,ishift")
10046    (set_attr "prefix_0f" "0,*")
10047    (set_attr "length_immediate" "0,*")
10048    (set_attr "modrm" "0,1")
10049    (set_attr "mode" "DI")])
10050
10051 (define_insn "ashrsi3_cvt"
10052   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
10053         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
10054                      (match_operand:QI 2 "const_int_operand" "")))
10055    (clobber (reg:CC FLAGS_REG))]
10056   "INTVAL (operands[2]) == 31
10057    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10058    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10059   "@
10060    {cltd|cdq}
10061    sar{l}\t{%2, %0|%0, %2}"
10062   [(set_attr "type" "imovx,ishift")
10063    (set_attr "prefix_0f" "0,*")
10064    (set_attr "length_immediate" "0,*")
10065    (set_attr "modrm" "0,1")
10066    (set_attr "mode" "SI")])
10067
10068 (define_insn "*ashrsi3_cvt_zext"
10069   [(set (match_operand:DI 0 "register_operand" "=*d,r")
10070         (zero_extend:DI
10071           (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
10072                        (match_operand:QI 2 "const_int_operand" ""))))
10073    (clobber (reg:CC FLAGS_REG))]
10074   "TARGET_64BIT && INTVAL (operands[2]) == 31
10075    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10076    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10077   "@
10078    {cltd|cdq}
10079    sar{l}\t{%2, %k0|%k0, %2}"
10080   [(set_attr "type" "imovx,ishift")
10081    (set_attr "prefix_0f" "0,*")
10082    (set_attr "length_immediate" "0,*")
10083    (set_attr "modrm" "0,1")
10084    (set_attr "mode" "SI")])
10085
10086 (define_expand "x86_shift<mode>_adj_3"
10087   [(use (match_operand:SWI48 0 "register_operand" ""))
10088    (use (match_operand:SWI48 1 "register_operand" ""))
10089    (use (match_operand:QI 2 "register_operand" ""))]
10090   ""
10091 {
10092   rtx label = gen_label_rtx ();
10093   rtx tmp;
10094
10095   emit_insn (gen_testqi_ccz_1 (operands[2],
10096                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
10097
10098   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10099   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10100   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10101                               gen_rtx_LABEL_REF (VOIDmode, label),
10102                               pc_rtx);
10103   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10104   JUMP_LABEL (tmp) = label;
10105
10106   emit_move_insn (operands[0], operands[1]);
10107   emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
10108                                   GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
10109   emit_label (label);
10110   LABEL_NUSES (label) = 1;
10111
10112   DONE;
10113 })
10114
10115 (define_insn "*<shiftrt_insn><mode>3_1"
10116   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10117         (any_shiftrt:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10118                          (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10119    (clobber (reg:CC FLAGS_REG))]
10120   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10121 {
10122   if (operands[2] == const1_rtx
10123       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10124     return "<shiftrt>{<imodesuffix>}\t%0";
10125   else
10126     return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
10127 }
10128   [(set_attr "type" "ishift")
10129    (set (attr "length_immediate")
10130      (if_then_else
10131        (and (match_operand 2 "const1_operand" "")
10132             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10133                 (const_int 0)))
10134        (const_string "0")
10135        (const_string "*")))
10136    (set_attr "mode" "<MODE>")])
10137
10138 (define_insn "*<shiftrt_insn>si3_1_zext"
10139   [(set (match_operand:DI 0 "register_operand" "=r")
10140         (zero_extend:DI
10141           (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10142                           (match_operand:QI 2 "nonmemory_operand" "cI"))))
10143    (clobber (reg:CC FLAGS_REG))]
10144   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10145 {
10146   if (operands[2] == const1_rtx
10147       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10148     return "<shiftrt>{l}\t%k0";
10149   else
10150     return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
10151 }
10152   [(set_attr "type" "ishift")
10153    (set (attr "length_immediate")
10154      (if_then_else
10155        (and (match_operand 2 "const1_operand" "")
10156             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10157                 (const_int 0)))
10158        (const_string "0")
10159        (const_string "*")))
10160    (set_attr "mode" "SI")])
10161
10162 (define_insn "*<shiftrt_insn>qi3_1_slp"
10163   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10164         (any_shiftrt:QI (match_dup 0)
10165                         (match_operand:QI 1 "nonmemory_operand" "cI")))
10166    (clobber (reg:CC FLAGS_REG))]
10167   "(optimize_function_for_size_p (cfun)
10168     || !TARGET_PARTIAL_REG_STALL
10169     || (operands[1] == const1_rtx
10170         && TARGET_SHIFT1))"
10171 {
10172   if (operands[1] == const1_rtx
10173       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10174     return "<shiftrt>{b}\t%0";
10175   else
10176     return "<shiftrt>{b}\t{%1, %0|%0, %1}";
10177 }
10178   [(set_attr "type" "ishift1")
10179    (set (attr "length_immediate")
10180      (if_then_else
10181        (and (match_operand 1 "const1_operand" "")
10182             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10183                 (const_int 0)))
10184        (const_string "0")
10185        (const_string "*")))
10186    (set_attr "mode" "QI")])
10187
10188 ;; This pattern can't accept a variable shift count, since shifts by
10189 ;; zero don't affect the flags.  We assume that shifts by constant
10190 ;; zero are optimized away.
10191 (define_insn "*<shiftrt_insn><mode>3_cmp"
10192   [(set (reg FLAGS_REG)
10193         (compare
10194           (any_shiftrt:SWI
10195             (match_operand:SWI 1 "nonimmediate_operand" "0")
10196             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10197           (const_int 0)))
10198    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10199         (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
10200   "(optimize_function_for_size_p (cfun)
10201     || !TARGET_PARTIAL_FLAG_REG_STALL
10202     || (operands[2] == const1_rtx
10203         && TARGET_SHIFT1))
10204    && ix86_match_ccmode (insn, CCGOCmode)
10205    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10206 {
10207   if (operands[2] == const1_rtx
10208       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10209     return "<shiftrt>{<imodesuffix>}\t%0";
10210   else
10211     return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
10212 }
10213   [(set_attr "type" "ishift")
10214    (set (attr "length_immediate")
10215      (if_then_else
10216        (and (match_operand 2 "const1_operand" "")
10217             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10218                 (const_int 0)))
10219        (const_string "0")
10220        (const_string "*")))
10221    (set_attr "mode" "<MODE>")])
10222
10223 (define_insn "*<shiftrt_insn>si3_cmp_zext"
10224   [(set (reg FLAGS_REG)
10225         (compare
10226           (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10227                           (match_operand:QI 2 "const_1_to_31_operand" "I"))
10228           (const_int 0)))
10229    (set (match_operand:DI 0 "register_operand" "=r")
10230         (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10231   "TARGET_64BIT
10232    && (optimize_function_for_size_p (cfun)
10233        || !TARGET_PARTIAL_FLAG_REG_STALL
10234        || (operands[2] == const1_rtx
10235            && TARGET_SHIFT1))
10236    && ix86_match_ccmode (insn, CCGOCmode)
10237    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10238 {
10239   if (operands[2] == const1_rtx
10240       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10241     return "<shiftrt>{l}\t%k0";
10242   else
10243     return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
10244 }
10245   [(set_attr "type" "ishift")
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" "SI")])
10254
10255 (define_insn "*<shiftrt_insn><mode>3_cconly"
10256   [(set (reg FLAGS_REG)
10257         (compare
10258           (any_shiftrt:SWI
10259             (match_operand:SWI 1 "nonimmediate_operand" "0")
10260             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10261           (const_int 0)))
10262    (clobber (match_scratch:SWI 0 "=<r>"))]
10263   "(optimize_function_for_size_p (cfun)
10264     || !TARGET_PARTIAL_FLAG_REG_STALL
10265     || (operands[2] == const1_rtx
10266         && TARGET_SHIFT1))
10267    && ix86_match_ccmode (insn, CCGOCmode)
10268    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10269 {
10270   if (operands[2] == const1_rtx
10271       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10272     return "<shiftrt>{<imodesuffix>}\t%0";
10273   else
10274     return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
10275 }
10276   [(set_attr "type" "ishift")
10277    (set (attr "length_immediate")
10278      (if_then_else
10279        (and (match_operand 2 "const1_operand" "")
10280             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10281                 (const_int 0)))
10282        (const_string "0")
10283        (const_string "*")))
10284    (set_attr "mode" "<MODE>")])
10285 \f
10286 ;; Rotate instructions
10287
10288 (define_expand "<rotate_insn>ti3"
10289   [(set (match_operand:TI 0 "register_operand" "")
10290         (any_rotate:TI (match_operand:TI 1 "register_operand" "")
10291                        (match_operand:QI 2 "nonmemory_operand" "")))]
10292   "TARGET_64BIT"
10293 {
10294   if (const_1_to_63_operand (operands[2], VOIDmode))
10295     emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10296                 (operands[0], operands[1], operands[2]));
10297   else
10298     FAIL;
10299
10300   DONE;
10301 })
10302
10303 (define_expand "<rotate_insn>di3"
10304   [(set (match_operand:DI 0 "shiftdi_operand" "")
10305         (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
10306                        (match_operand:QI 2 "nonmemory_operand" "")))]
10307  ""
10308 {
10309   if (TARGET_64BIT)
10310     ix86_expand_binary_operator (<CODE>, DImode, operands);
10311   else if (const_1_to_31_operand (operands[2], VOIDmode))
10312     emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10313                 (operands[0], operands[1], operands[2]));
10314   else
10315     FAIL;
10316
10317   DONE;
10318 })
10319
10320 (define_expand "<rotate_insn><mode>3"
10321   [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
10322         (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
10323                             (match_operand:QI 2 "nonmemory_operand" "")))]
10324   ""
10325   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10326
10327 ;; Implement rotation using two double-precision
10328 ;; shift instructions and a scratch register.
10329
10330 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10331  [(set (match_operand:<DWI> 0 "register_operand" "=r")
10332        (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10333                      (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10334   (clobber (reg:CC FLAGS_REG))
10335   (clobber (match_scratch:DWIH 3 "=&r"))]
10336  ""
10337  "#"
10338  "reload_completed"
10339  [(set (match_dup 3) (match_dup 4))
10340   (parallel
10341    [(set (match_dup 4)
10342          (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10343                    (lshiftrt:DWIH (match_dup 5)
10344                                   (minus:QI (match_dup 6) (match_dup 2)))))
10345     (clobber (reg:CC FLAGS_REG))])
10346   (parallel
10347    [(set (match_dup 5)
10348          (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10349                    (lshiftrt:DWIH (match_dup 3)
10350                                   (minus:QI (match_dup 6) (match_dup 2)))))
10351     (clobber (reg:CC FLAGS_REG))])]
10352 {
10353   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10354
10355   split_<dwi> (&operands[0], 1, &operands[4], &operands[5]);
10356 })
10357
10358 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10359  [(set (match_operand:<DWI> 0 "register_operand" "=r")
10360        (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10361                        (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10362   (clobber (reg:CC FLAGS_REG))
10363   (clobber (match_scratch:DWIH 3 "=&r"))]
10364  ""
10365  "#"
10366  "reload_completed"
10367  [(set (match_dup 3) (match_dup 4))
10368   (parallel
10369    [(set (match_dup 4)
10370          (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10371                    (ashift:DWIH (match_dup 5)
10372                                 (minus:QI (match_dup 6) (match_dup 2)))))
10373     (clobber (reg:CC FLAGS_REG))])
10374   (parallel
10375    [(set (match_dup 5)
10376          (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10377                    (ashift:DWIH (match_dup 3)
10378                                 (minus:QI (match_dup 6) (match_dup 2)))))
10379     (clobber (reg:CC FLAGS_REG))])]
10380 {
10381   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10382
10383   split_<dwi> (&operands[0], 1, &operands[4], &operands[5]);
10384 })
10385
10386 (define_insn "*<rotate_insn><mode>3_1"
10387   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10388         (any_rotate:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10389                         (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10390    (clobber (reg:CC FLAGS_REG))]
10391   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10392 {
10393   if (operands[2] == const1_rtx
10394       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10395     return "<rotate>{<imodesuffix>}\t%0";
10396   else
10397     return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10398 }
10399   [(set_attr "type" "rotate")
10400    (set (attr "length_immediate")
10401      (if_then_else
10402        (and (match_operand 2 "const1_operand" "")
10403             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10404                 (const_int 0)))
10405        (const_string "0")
10406        (const_string "*")))
10407    (set_attr "mode" "<MODE>")])
10408
10409 (define_insn "*<rotate_insn>si3_1_zext"
10410   [(set (match_operand:DI 0 "register_operand" "=r")
10411         (zero_extend:DI
10412           (any_rotate:SI (match_operand:SI 1 "register_operand" "0")
10413                          (match_operand:QI 2 "nonmemory_operand" "cI"))))
10414    (clobber (reg:CC FLAGS_REG))]
10415   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10416 {
10417     if (operands[2] == const1_rtx
10418         && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10419     return "<rotate>{l}\t%k0";
10420   else
10421     return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10422 }
10423   [(set_attr "type" "rotate")
10424    (set (attr "length_immediate")
10425      (if_then_else
10426        (and (match_operand 2 "const1_operand" "")
10427             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10428                 (const_int 0)))
10429        (const_string "0")
10430        (const_string "*")))
10431    (set_attr "mode" "SI")])
10432
10433 (define_insn "*<rotate_insn>qi3_1_slp"
10434   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10435         (any_rotate:QI (match_dup 0)
10436                        (match_operand:QI 1 "nonmemory_operand" "cI")))
10437    (clobber (reg:CC FLAGS_REG))]
10438   "(optimize_function_for_size_p (cfun)
10439     || !TARGET_PARTIAL_REG_STALL
10440     || (operands[1] == const1_rtx
10441         && TARGET_SHIFT1))"
10442 {
10443   if (operands[1] == const1_rtx
10444       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10445     return "<rotate>{b}\t%0";
10446   else
10447     return "<rotate>{b}\t{%1, %0|%0, %1}";
10448 }
10449   [(set_attr "type" "rotate1")
10450    (set (attr "length_immediate")
10451      (if_then_else
10452        (and (match_operand 1 "const1_operand" "")
10453             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10454                 (const_int 0)))
10455        (const_string "0")
10456        (const_string "*")))
10457    (set_attr "mode" "QI")])
10458
10459 (define_split
10460  [(set (match_operand:HI 0 "register_operand" "")
10461        (any_rotate:HI (match_dup 0) (const_int 8)))
10462   (clobber (reg:CC FLAGS_REG))]
10463  "reload_completed
10464   && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10465  [(parallel [(set (strict_low_part (match_dup 0))
10466                   (bswap:HI (match_dup 0)))
10467              (clobber (reg:CC FLAGS_REG))])]
10468  "")
10469 \f
10470 ;; Bit set / bit test instructions
10471
10472 (define_expand "extv"
10473   [(set (match_operand:SI 0 "register_operand" "")
10474         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10475                          (match_operand:SI 2 "const8_operand" "")
10476                          (match_operand:SI 3 "const8_operand" "")))]
10477   ""
10478 {
10479   /* Handle extractions from %ah et al.  */
10480   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10481     FAIL;
10482
10483   /* From mips.md: extract_bit_field doesn't verify that our source
10484      matches the predicate, so check it again here.  */
10485   if (! ext_register_operand (operands[1], VOIDmode))
10486     FAIL;
10487 })
10488
10489 (define_expand "extzv"
10490   [(set (match_operand:SI 0 "register_operand" "")
10491         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10492                          (match_operand:SI 2 "const8_operand" "")
10493                          (match_operand:SI 3 "const8_operand" "")))]
10494   ""
10495 {
10496   /* Handle extractions from %ah et al.  */
10497   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10498     FAIL;
10499
10500   /* From mips.md: extract_bit_field doesn't verify that our source
10501      matches the predicate, so check it again here.  */
10502   if (! ext_register_operand (operands[1], VOIDmode))
10503     FAIL;
10504 })
10505
10506 (define_expand "insv"
10507   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
10508                       (match_operand 1 "const8_operand" "")
10509                       (match_operand 2 "const8_operand" ""))
10510         (match_operand 3 "register_operand" ""))]
10511   ""
10512 {
10513   /* Handle insertions to %ah et al.  */
10514   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10515     FAIL;
10516
10517   /* From mips.md: insert_bit_field doesn't verify that our source
10518      matches the predicate, so check it again here.  */
10519   if (! ext_register_operand (operands[0], VOIDmode))
10520     FAIL;
10521
10522   if (TARGET_64BIT)
10523     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
10524   else
10525     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
10526
10527   DONE;
10528 })
10529
10530 ;; %%% bts, btr, btc, bt.
10531 ;; In general these instructions are *slow* when applied to memory,
10532 ;; since they enforce atomic operation.  When applied to registers,
10533 ;; it depends on the cpu implementation.  They're never faster than
10534 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10535 ;; no point.  But in 64-bit, we can't hold the relevant immediates
10536 ;; within the instruction itself, so operating on bits in the high
10537 ;; 32-bits of a register becomes easier.
10538 ;;
10539 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
10540 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10541 ;; negdf respectively, so they can never be disabled entirely.
10542
10543 (define_insn "*btsq"
10544   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10545                          (const_int 1)
10546                          (match_operand:DI 1 "const_0_to_63_operand" ""))
10547         (const_int 1))
10548    (clobber (reg:CC FLAGS_REG))]
10549   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10550   "bts{q}\t{%1, %0|%0, %1}"
10551   [(set_attr "type" "alu1")
10552    (set_attr "prefix_0f" "1")
10553    (set_attr "mode" "DI")])
10554
10555 (define_insn "*btrq"
10556   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10557                          (const_int 1)
10558                          (match_operand:DI 1 "const_0_to_63_operand" ""))
10559         (const_int 0))
10560    (clobber (reg:CC FLAGS_REG))]
10561   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10562   "btr{q}\t{%1, %0|%0, %1}"
10563   [(set_attr "type" "alu1")
10564    (set_attr "prefix_0f" "1")
10565    (set_attr "mode" "DI")])
10566
10567 (define_insn "*btcq"
10568   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10569                          (const_int 1)
10570                          (match_operand:DI 1 "const_0_to_63_operand" ""))
10571         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10572    (clobber (reg:CC FLAGS_REG))]
10573   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10574   "btc{q}\t{%1, %0|%0, %1}"
10575   [(set_attr "type" "alu1")
10576    (set_attr "prefix_0f" "1")
10577    (set_attr "mode" "DI")])
10578
10579 ;; Allow Nocona to avoid these instructions if a register is available.
10580
10581 (define_peephole2
10582   [(match_scratch:DI 2 "r")
10583    (parallel [(set (zero_extract:DI
10584                      (match_operand:DI 0 "register_operand" "")
10585                      (const_int 1)
10586                      (match_operand:DI 1 "const_0_to_63_operand" ""))
10587                    (const_int 1))
10588               (clobber (reg:CC FLAGS_REG))])]
10589   "TARGET_64BIT && !TARGET_USE_BT"
10590   [(const_int 0)]
10591 {
10592   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10593   rtx op1;
10594
10595   if (HOST_BITS_PER_WIDE_INT >= 64)
10596     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10597   else if (i < HOST_BITS_PER_WIDE_INT)
10598     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10599   else
10600     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10601
10602   op1 = immed_double_const (lo, hi, DImode);
10603   if (i >= 31)
10604     {
10605       emit_move_insn (operands[2], op1);
10606       op1 = operands[2];
10607     }
10608
10609   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10610   DONE;
10611 })
10612
10613 (define_peephole2
10614   [(match_scratch:DI 2 "r")
10615    (parallel [(set (zero_extract:DI
10616                      (match_operand:DI 0 "register_operand" "")
10617                      (const_int 1)
10618                      (match_operand:DI 1 "const_0_to_63_operand" ""))
10619                    (const_int 0))
10620               (clobber (reg:CC FLAGS_REG))])]
10621   "TARGET_64BIT && !TARGET_USE_BT"
10622   [(const_int 0)]
10623 {
10624   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10625   rtx op1;
10626
10627   if (HOST_BITS_PER_WIDE_INT >= 64)
10628     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10629   else if (i < HOST_BITS_PER_WIDE_INT)
10630     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10631   else
10632     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10633
10634   op1 = immed_double_const (~lo, ~hi, DImode);
10635   if (i >= 32)
10636     {
10637       emit_move_insn (operands[2], op1);
10638       op1 = operands[2];
10639     }
10640
10641   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10642   DONE;
10643 })
10644
10645 (define_peephole2
10646   [(match_scratch:DI 2 "r")
10647    (parallel [(set (zero_extract:DI
10648                      (match_operand:DI 0 "register_operand" "")
10649                      (const_int 1)
10650                      (match_operand:DI 1 "const_0_to_63_operand" ""))
10651               (not:DI (zero_extract:DI
10652                         (match_dup 0) (const_int 1) (match_dup 1))))
10653               (clobber (reg:CC FLAGS_REG))])]
10654   "TARGET_64BIT && !TARGET_USE_BT"
10655   [(const_int 0)]
10656 {
10657   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10658   rtx op1;
10659
10660   if (HOST_BITS_PER_WIDE_INT >= 64)
10661     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10662   else if (i < HOST_BITS_PER_WIDE_INT)
10663     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10664   else
10665     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10666
10667   op1 = immed_double_const (lo, hi, DImode);
10668   if (i >= 31)
10669     {
10670       emit_move_insn (operands[2], op1);
10671       op1 = operands[2];
10672     }
10673
10674   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10675   DONE;
10676 })
10677
10678 (define_insn "*bt<mode>"
10679   [(set (reg:CCC FLAGS_REG)
10680         (compare:CCC
10681           (zero_extract:SWI48
10682             (match_operand:SWI48 0 "register_operand" "r")
10683             (const_int 1)
10684             (match_operand:SWI48 1 "nonmemory_operand" "rN"))
10685           (const_int 0)))]
10686   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10687   "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10688   [(set_attr "type" "alu1")
10689    (set_attr "prefix_0f" "1")
10690    (set_attr "mode" "<MODE>")])
10691 \f
10692 ;; Store-flag instructions.
10693
10694 ;; For all sCOND expanders, also expand the compare or test insn that
10695 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
10696
10697 (define_insn_and_split "*setcc_di_1"
10698   [(set (match_operand:DI 0 "register_operand" "=q")
10699         (match_operator:DI 1 "ix86_comparison_operator"
10700           [(reg FLAGS_REG) (const_int 0)]))]
10701   "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10702   "#"
10703   "&& reload_completed"
10704   [(set (match_dup 2) (match_dup 1))
10705    (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10706 {
10707   PUT_MODE (operands[1], QImode);
10708   operands[2] = gen_lowpart (QImode, operands[0]);
10709 })
10710
10711 (define_insn_and_split "*setcc_si_1_and"
10712   [(set (match_operand:SI 0 "register_operand" "=q")
10713         (match_operator:SI 1 "ix86_comparison_operator"
10714           [(reg FLAGS_REG) (const_int 0)]))
10715    (clobber (reg:CC FLAGS_REG))]
10716   "!TARGET_PARTIAL_REG_STALL
10717    && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10718   "#"
10719   "&& reload_completed"
10720   [(set (match_dup 2) (match_dup 1))
10721    (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10722               (clobber (reg:CC FLAGS_REG))])]
10723 {
10724   PUT_MODE (operands[1], QImode);
10725   operands[2] = gen_lowpart (QImode, operands[0]);
10726 })
10727
10728 (define_insn_and_split "*setcc_si_1_movzbl"
10729   [(set (match_operand:SI 0 "register_operand" "=q")
10730         (match_operator:SI 1 "ix86_comparison_operator"
10731           [(reg FLAGS_REG) (const_int 0)]))]
10732   "!TARGET_PARTIAL_REG_STALL
10733    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10734   "#"
10735   "&& reload_completed"
10736   [(set (match_dup 2) (match_dup 1))
10737    (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10738 {
10739   PUT_MODE (operands[1], QImode);
10740   operands[2] = gen_lowpart (QImode, operands[0]);
10741 })
10742
10743 (define_insn "*setcc_qi"
10744   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10745         (match_operator:QI 1 "ix86_comparison_operator"
10746           [(reg FLAGS_REG) (const_int 0)]))]
10747   ""
10748   "set%C1\t%0"
10749   [(set_attr "type" "setcc")
10750    (set_attr "mode" "QI")])
10751
10752 (define_insn "*setcc_qi_slp"
10753   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10754         (match_operator:QI 1 "ix86_comparison_operator"
10755           [(reg FLAGS_REG) (const_int 0)]))]
10756   ""
10757   "set%C1\t%0"
10758   [(set_attr "type" "setcc")
10759    (set_attr "mode" "QI")])
10760
10761 ;; In general it is not safe to assume too much about CCmode registers,
10762 ;; so simplify-rtx stops when it sees a second one.  Under certain
10763 ;; conditions this is safe on x86, so help combine not create
10764 ;;
10765 ;;      seta    %al
10766 ;;      testb   %al, %al
10767 ;;      sete    %al
10768
10769 (define_split
10770   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10771         (ne:QI (match_operator 1 "ix86_comparison_operator"
10772                  [(reg FLAGS_REG) (const_int 0)])
10773             (const_int 0)))]
10774   ""
10775   [(set (match_dup 0) (match_dup 1))]
10776 {
10777   PUT_MODE (operands[1], QImode);
10778 })
10779
10780 (define_split
10781   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10782         (ne:QI (match_operator 1 "ix86_comparison_operator"
10783                  [(reg FLAGS_REG) (const_int 0)])
10784             (const_int 0)))]
10785   ""
10786   [(set (match_dup 0) (match_dup 1))]
10787 {
10788   PUT_MODE (operands[1], QImode);
10789 })
10790
10791 (define_split
10792   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10793         (eq:QI (match_operator 1 "ix86_comparison_operator"
10794                  [(reg FLAGS_REG) (const_int 0)])
10795             (const_int 0)))]
10796   ""
10797   [(set (match_dup 0) (match_dup 1))]
10798 {
10799   rtx new_op1 = copy_rtx (operands[1]);
10800   operands[1] = new_op1;
10801   PUT_MODE (new_op1, QImode);
10802   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10803                                              GET_MODE (XEXP (new_op1, 0))));
10804
10805   /* Make sure that (a) the CCmode we have for the flags is strong
10806      enough for the reversed compare or (b) we have a valid FP compare.  */
10807   if (! ix86_comparison_operator (new_op1, VOIDmode))
10808     FAIL;
10809 })
10810
10811 (define_split
10812   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10813         (eq:QI (match_operator 1 "ix86_comparison_operator"
10814                  [(reg FLAGS_REG) (const_int 0)])
10815             (const_int 0)))]
10816   ""
10817   [(set (match_dup 0) (match_dup 1))]
10818 {
10819   rtx new_op1 = copy_rtx (operands[1]);
10820   operands[1] = new_op1;
10821   PUT_MODE (new_op1, QImode);
10822   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10823                                              GET_MODE (XEXP (new_op1, 0))));
10824
10825   /* Make sure that (a) the CCmode we have for the flags is strong
10826      enough for the reversed compare or (b) we have a valid FP compare.  */
10827   if (! ix86_comparison_operator (new_op1, VOIDmode))
10828     FAIL;
10829 })
10830
10831 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10832 ;; subsequent logical operations are used to imitate conditional moves.
10833 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10834 ;; it directly.
10835
10836 (define_insn "*avx_setcc<mode>"
10837   [(set (match_operand:MODEF 0 "register_operand" "=x")
10838         (match_operator:MODEF 1 "avx_comparison_float_operator"
10839           [(match_operand:MODEF 2 "register_operand" "x")
10840            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
10841   "TARGET_AVX"
10842   "vcmp%D1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
10843   [(set_attr "type" "ssecmp")
10844    (set_attr "prefix" "vex")
10845    (set_attr "length_immediate" "1")
10846    (set_attr "mode" "<MODE>")])
10847
10848 (define_insn "*sse_setcc<mode>"
10849   [(set (match_operand:MODEF 0 "register_operand" "=x")
10850         (match_operator:MODEF 1 "sse_comparison_operator"
10851           [(match_operand:MODEF 2 "register_operand" "0")
10852            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
10853   "SSE_FLOAT_MODE_P (<MODE>mode)"
10854   "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
10855   [(set_attr "type" "ssecmp")
10856    (set_attr "length_immediate" "1")
10857    (set_attr "mode" "<MODE>")])
10858 \f
10859 ;; Basic conditional jump instructions.
10860 ;; We ignore the overflow flag for signed branch instructions.
10861
10862 (define_insn "*jcc_1"
10863   [(set (pc)
10864         (if_then_else (match_operator 1 "ix86_comparison_operator"
10865                                       [(reg FLAGS_REG) (const_int 0)])
10866                       (label_ref (match_operand 0 "" ""))
10867                       (pc)))]
10868   ""
10869   "%+j%C1\t%l0"
10870   [(set_attr "type" "ibr")
10871    (set_attr "modrm" "0")
10872    (set (attr "length")
10873            (if_then_else (and (ge (minus (match_dup 0) (pc))
10874                                   (const_int -126))
10875                               (lt (minus (match_dup 0) (pc))
10876                                   (const_int 128)))
10877              (const_int 2)
10878              (const_int 6)))])
10879
10880 (define_insn "*jcc_2"
10881   [(set (pc)
10882         (if_then_else (match_operator 1 "ix86_comparison_operator"
10883                                       [(reg FLAGS_REG) (const_int 0)])
10884                       (pc)
10885                       (label_ref (match_operand 0 "" ""))))]
10886   ""
10887   "%+j%c1\t%l0"
10888   [(set_attr "type" "ibr")
10889    (set_attr "modrm" "0")
10890    (set (attr "length")
10891            (if_then_else (and (ge (minus (match_dup 0) (pc))
10892                                   (const_int -126))
10893                               (lt (minus (match_dup 0) (pc))
10894                                   (const_int 128)))
10895              (const_int 2)
10896              (const_int 6)))])
10897
10898 ;; In general it is not safe to assume too much about CCmode registers,
10899 ;; so simplify-rtx stops when it sees a second one.  Under certain
10900 ;; conditions this is safe on x86, so help combine not create
10901 ;;
10902 ;;      seta    %al
10903 ;;      testb   %al, %al
10904 ;;      je      Lfoo
10905
10906 (define_split
10907   [(set (pc)
10908         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10909                                       [(reg FLAGS_REG) (const_int 0)])
10910                           (const_int 0))
10911                       (label_ref (match_operand 1 "" ""))
10912                       (pc)))]
10913   ""
10914   [(set (pc)
10915         (if_then_else (match_dup 0)
10916                       (label_ref (match_dup 1))
10917                       (pc)))]
10918 {
10919   PUT_MODE (operands[0], VOIDmode);
10920 })
10921
10922 (define_split
10923   [(set (pc)
10924         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10925                                       [(reg FLAGS_REG) (const_int 0)])
10926                           (const_int 0))
10927                       (label_ref (match_operand 1 "" ""))
10928                       (pc)))]
10929   ""
10930   [(set (pc)
10931         (if_then_else (match_dup 0)
10932                       (label_ref (match_dup 1))
10933                       (pc)))]
10934 {
10935   rtx new_op0 = copy_rtx (operands[0]);
10936   operands[0] = new_op0;
10937   PUT_MODE (new_op0, VOIDmode);
10938   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10939                                              GET_MODE (XEXP (new_op0, 0))));
10940
10941   /* Make sure that (a) the CCmode we have for the flags is strong
10942      enough for the reversed compare or (b) we have a valid FP compare.  */
10943   if (! ix86_comparison_operator (new_op0, VOIDmode))
10944     FAIL;
10945 })
10946
10947 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10948 ;; pass generates from shift insn with QImode operand.  Actually, the mode
10949 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10950 ;; appropriate modulo of the bit offset value.
10951
10952 (define_insn_and_split "*jcc_bt<mode>"
10953   [(set (pc)
10954         (if_then_else (match_operator 0 "bt_comparison_operator"
10955                         [(zero_extract:SWI48
10956                            (match_operand:SWI48 1 "register_operand" "r")
10957                            (const_int 1)
10958                            (zero_extend:SI
10959                              (match_operand:QI 2 "register_operand" "r")))
10960                          (const_int 0)])
10961                       (label_ref (match_operand 3 "" ""))
10962                       (pc)))
10963    (clobber (reg:CC FLAGS_REG))]
10964   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10965   "#"
10966   "&& 1"
10967   [(set (reg:CCC FLAGS_REG)
10968         (compare:CCC
10969           (zero_extract:SWI48
10970             (match_dup 1)
10971             (const_int 1)
10972             (match_dup 2))
10973           (const_int 0)))
10974    (set (pc)
10975         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10976                       (label_ref (match_dup 3))
10977                       (pc)))]
10978 {
10979   operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10980
10981   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10982 })
10983
10984 ;; Avoid useless masking of bit offset operand.  "and" in SImode is correct
10985 ;; also for DImode, this is what combine produces.
10986 (define_insn_and_split "*jcc_bt<mode>_mask"
10987   [(set (pc)
10988         (if_then_else (match_operator 0 "bt_comparison_operator"
10989                         [(zero_extract:SWI48
10990                            (match_operand:SWI48 1 "register_operand" "r")
10991                            (const_int 1)
10992                            (and:SI
10993                              (match_operand:SI 2 "register_operand" "r")
10994                              (match_operand:SI 3 "const_int_operand" "n")))])
10995                       (label_ref (match_operand 4 "" ""))
10996                       (pc)))
10997    (clobber (reg:CC FLAGS_REG))]
10998   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10999    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11000       == GET_MODE_BITSIZE (<MODE>mode)-1"
11001   "#"
11002   "&& 1"
11003   [(set (reg:CCC FLAGS_REG)
11004         (compare:CCC
11005           (zero_extract:SWI48
11006             (match_dup 1)
11007             (const_int 1)
11008             (match_dup 2))
11009           (const_int 0)))
11010    (set (pc)
11011         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11012                       (label_ref (match_dup 4))
11013                       (pc)))]
11014 {
11015   operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
11016
11017   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11018 })
11019
11020 (define_insn_and_split "*jcc_btsi_1"
11021   [(set (pc)
11022         (if_then_else (match_operator 0 "bt_comparison_operator"
11023                         [(and:SI
11024                            (lshiftrt:SI
11025                              (match_operand:SI 1 "register_operand" "r")
11026                              (match_operand:QI 2 "register_operand" "r"))
11027                            (const_int 1))
11028                          (const_int 0)])
11029                       (label_ref (match_operand 3 "" ""))
11030                       (pc)))
11031    (clobber (reg:CC FLAGS_REG))]
11032   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
11033   "#"
11034   "&& 1"
11035   [(set (reg:CCC FLAGS_REG)
11036         (compare:CCC
11037           (zero_extract:SI
11038             (match_dup 1)
11039             (const_int 1)
11040             (match_dup 2))
11041           (const_int 0)))
11042    (set (pc)
11043         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11044                       (label_ref (match_dup 3))
11045                       (pc)))]
11046 {
11047   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
11048
11049   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11050 })
11051
11052 ;; avoid useless masking of bit offset operand
11053 (define_insn_and_split "*jcc_btsi_mask_1"
11054   [(set (pc)
11055         (if_then_else
11056           (match_operator 0 "bt_comparison_operator"
11057             [(and:SI
11058                (lshiftrt:SI
11059                  (match_operand:SI 1 "register_operand" "r")
11060                  (subreg:QI
11061                    (and:SI
11062                      (match_operand:SI 2 "register_operand" "r")
11063                      (match_operand:SI 3 "const_int_operand" "n")) 0))
11064                (const_int 1))
11065              (const_int 0)])
11066           (label_ref (match_operand 4 "" ""))
11067           (pc)))
11068    (clobber (reg:CC FLAGS_REG))]
11069   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11070    && (INTVAL (operands[3]) & 0x1f) == 0x1f"
11071   "#"
11072   "&& 1"
11073   [(set (reg:CCC FLAGS_REG)
11074         (compare:CCC
11075           (zero_extract:SI
11076             (match_dup 1)
11077             (const_int 1)
11078             (match_dup 2))
11079           (const_int 0)))
11080    (set (pc)
11081         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11082                       (label_ref (match_dup 4))
11083                       (pc)))]
11084   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
11085
11086 ;; Define combination compare-and-branch fp compare instructions to help
11087 ;; combine.
11088
11089 (define_insn "*fp_jcc_3_387"
11090   [(set (pc)
11091         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11092                         [(match_operand 1 "register_operand" "f")
11093                          (match_operand 2 "nonimmediate_operand" "fm")])
11094           (label_ref (match_operand 3 "" ""))
11095           (pc)))
11096    (clobber (reg:CCFP FPSR_REG))
11097    (clobber (reg:CCFP FLAGS_REG))
11098    (clobber (match_scratch:HI 4 "=a"))]
11099   "TARGET_80387
11100    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
11101    && GET_MODE (operands[1]) == GET_MODE (operands[2])
11102    && SELECT_CC_MODE (GET_CODE (operands[0]),
11103                       operands[1], operands[2]) == CCFPmode
11104    && !TARGET_CMOVE"
11105   "#")
11106
11107 (define_insn "*fp_jcc_4_387"
11108   [(set (pc)
11109         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11110                         [(match_operand 1 "register_operand" "f")
11111                          (match_operand 2 "nonimmediate_operand" "fm")])
11112           (pc)
11113           (label_ref (match_operand 3 "" ""))))
11114    (clobber (reg:CCFP FPSR_REG))
11115    (clobber (reg:CCFP FLAGS_REG))
11116    (clobber (match_scratch:HI 4 "=a"))]
11117   "TARGET_80387
11118    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
11119    && GET_MODE (operands[1]) == GET_MODE (operands[2])
11120    && SELECT_CC_MODE (GET_CODE (operands[0]),
11121                       operands[1], operands[2]) == CCFPmode
11122    && !TARGET_CMOVE"
11123   "#")
11124
11125 (define_insn "*fp_jcc_5_387"
11126   [(set (pc)
11127         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11128                         [(match_operand 1 "register_operand" "f")
11129                          (match_operand 2 "register_operand" "f")])
11130           (label_ref (match_operand 3 "" ""))
11131           (pc)))
11132    (clobber (reg:CCFP FPSR_REG))
11133    (clobber (reg:CCFP FLAGS_REG))
11134    (clobber (match_scratch:HI 4 "=a"))]
11135   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11136    && GET_MODE (operands[1]) == GET_MODE (operands[2])
11137    && !TARGET_CMOVE"
11138   "#")
11139
11140 (define_insn "*fp_jcc_6_387"
11141   [(set (pc)
11142         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11143                         [(match_operand 1 "register_operand" "f")
11144                          (match_operand 2 "register_operand" "f")])
11145           (pc)
11146           (label_ref (match_operand 3 "" ""))))
11147    (clobber (reg:CCFP FPSR_REG))
11148    (clobber (reg:CCFP FLAGS_REG))
11149    (clobber (match_scratch:HI 4 "=a"))]
11150   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11151    && GET_MODE (operands[1]) == GET_MODE (operands[2])
11152    && !TARGET_CMOVE"
11153   "#")
11154
11155 (define_insn "*fp_jcc_7_387"
11156   [(set (pc)
11157         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11158                         [(match_operand 1 "register_operand" "f")
11159                          (match_operand 2 "const0_operand" "")])
11160           (label_ref (match_operand 3 "" ""))
11161           (pc)))
11162    (clobber (reg:CCFP FPSR_REG))
11163    (clobber (reg:CCFP FLAGS_REG))
11164    (clobber (match_scratch:HI 4 "=a"))]
11165   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11166    && GET_MODE (operands[1]) == GET_MODE (operands[2])
11167    && SELECT_CC_MODE (GET_CODE (operands[0]),
11168                       operands[1], operands[2]) == CCFPmode
11169    && !TARGET_CMOVE"
11170   "#")
11171
11172 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
11173 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11174 ;; with a precedence over other operators and is always put in the first
11175 ;; place. Swap condition and operands to match ficom instruction.
11176
11177 (define_insn "*fp_jcc_8<mode>_387"
11178   [(set (pc)
11179         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11180                         [(match_operator 1 "float_operator"
11181                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
11182                            (match_operand 3 "register_operand" "f,f")])
11183           (label_ref (match_operand 4 "" ""))
11184           (pc)))
11185    (clobber (reg:CCFP FPSR_REG))
11186    (clobber (reg:CCFP FLAGS_REG))
11187    (clobber (match_scratch:HI 5 "=a,a"))]
11188   "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
11189    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
11190    && GET_MODE (operands[1]) == GET_MODE (operands[3])
11191    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
11192    && !TARGET_CMOVE"
11193   "#")
11194
11195 (define_split
11196   [(set (pc)
11197         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11198                         [(match_operand 1 "register_operand" "")
11199                          (match_operand 2 "nonimmediate_operand" "")])
11200           (match_operand 3 "" "")
11201           (match_operand 4 "" "")))
11202    (clobber (reg:CCFP FPSR_REG))
11203    (clobber (reg:CCFP FLAGS_REG))]
11204   "reload_completed"
11205   [(const_int 0)]
11206 {
11207   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11208                         operands[3], operands[4], NULL_RTX, NULL_RTX);
11209   DONE;
11210 })
11211
11212 (define_split
11213   [(set (pc)
11214         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11215                         [(match_operand 1 "register_operand" "")
11216                          (match_operand 2 "general_operand" "")])
11217           (match_operand 3 "" "")
11218           (match_operand 4 "" "")))
11219    (clobber (reg:CCFP FPSR_REG))
11220    (clobber (reg:CCFP FLAGS_REG))
11221    (clobber (match_scratch:HI 5 "=a"))]
11222   "reload_completed"
11223   [(const_int 0)]
11224 {
11225   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11226                         operands[3], operands[4], operands[5], NULL_RTX);
11227   DONE;
11228 })
11229
11230 (define_split
11231   [(set (pc)
11232         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11233                         [(match_operator 1 "float_operator"
11234                            [(match_operand:X87MODEI12 2 "memory_operand" "")])
11235                            (match_operand 3 "register_operand" "")])
11236           (match_operand 4 "" "")
11237           (match_operand 5 "" "")))
11238    (clobber (reg:CCFP FPSR_REG))
11239    (clobber (reg:CCFP FLAGS_REG))
11240    (clobber (match_scratch:HI 6 "=a"))]
11241   "reload_completed"
11242   [(const_int 0)]
11243 {
11244   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
11245
11246   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11247                         operands[3], operands[7],
11248                         operands[4], operands[5], operands[6], NULL_RTX);
11249   DONE;
11250 })
11251
11252 ;; %%% Kill this when reload knows how to do it.
11253 (define_split
11254   [(set (pc)
11255         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11256                         [(match_operator 1 "float_operator"
11257                            [(match_operand:X87MODEI12 2 "register_operand" "")])
11258                            (match_operand 3 "register_operand" "")])
11259           (match_operand 4 "" "")
11260           (match_operand 5 "" "")))
11261    (clobber (reg:CCFP FPSR_REG))
11262    (clobber (reg:CCFP FLAGS_REG))
11263    (clobber (match_scratch:HI 6 "=a"))]
11264   "reload_completed"
11265   [(const_int 0)]
11266 {
11267   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11268   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
11269
11270   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11271                         operands[3], operands[7],
11272                         operands[4], operands[5], operands[6], operands[2]);
11273   DONE;
11274 })
11275 \f
11276 ;; Unconditional and other jump instructions
11277
11278 (define_insn "jump"
11279   [(set (pc)
11280         (label_ref (match_operand 0 "" "")))]
11281   ""
11282   "jmp\t%l0"
11283   [(set_attr "type" "ibr")
11284    (set (attr "length")
11285            (if_then_else (and (ge (minus (match_dup 0) (pc))
11286                                   (const_int -126))
11287                               (lt (minus (match_dup 0) (pc))
11288                                   (const_int 128)))
11289              (const_int 2)
11290              (const_int 5)))
11291    (set_attr "modrm" "0")])
11292
11293 (define_expand "indirect_jump"
11294   [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
11295   ""
11296   "")
11297
11298 (define_insn "*indirect_jump"
11299   [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
11300   ""
11301   "jmp\t%A0"
11302   [(set_attr "type" "ibr")
11303    (set_attr "length_immediate" "0")])
11304
11305 (define_expand "tablejump"
11306   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
11307               (use (label_ref (match_operand 1 "" "")))])]
11308   ""
11309 {
11310   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11311      relative.  Convert the relative address to an absolute address.  */
11312   if (flag_pic)
11313     {
11314       rtx op0, op1;
11315       enum rtx_code code;
11316
11317       /* We can't use @GOTOFF for text labels on VxWorks;
11318          see gotoff_operand.  */
11319       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11320         {
11321           code = PLUS;
11322           op0 = operands[0];
11323           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11324         }
11325       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11326         {
11327           code = PLUS;
11328           op0 = operands[0];
11329           op1 = pic_offset_table_rtx;
11330         }
11331       else
11332         {
11333           code = MINUS;
11334           op0 = pic_offset_table_rtx;
11335           op1 = operands[0];
11336         }
11337
11338       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11339                                          OPTAB_DIRECT);
11340     }
11341 })
11342
11343 (define_insn "*tablejump_1"
11344   [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
11345    (use (label_ref (match_operand 1 "" "")))]
11346   ""
11347   "jmp\t%A0"
11348   [(set_attr "type" "ibr")
11349    (set_attr "length_immediate" "0")])
11350 \f
11351 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11352
11353 (define_peephole2
11354   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11355    (set (match_operand:QI 1 "register_operand" "")
11356         (match_operator:QI 2 "ix86_comparison_operator"
11357           [(reg FLAGS_REG) (const_int 0)]))
11358    (set (match_operand 3 "q_regs_operand" "")
11359         (zero_extend (match_dup 1)))]
11360   "(peep2_reg_dead_p (3, operands[1])
11361     || operands_match_p (operands[1], operands[3]))
11362    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11363   [(set (match_dup 4) (match_dup 0))
11364    (set (strict_low_part (match_dup 5))
11365         (match_dup 2))]
11366 {
11367   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11368   operands[5] = gen_lowpart (QImode, operands[3]);
11369   ix86_expand_clear (operands[3]);
11370 })
11371
11372 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
11373
11374 (define_peephole2
11375   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11376    (set (match_operand:QI 1 "register_operand" "")
11377         (match_operator:QI 2 "ix86_comparison_operator"
11378           [(reg FLAGS_REG) (const_int 0)]))
11379    (parallel [(set (match_operand 3 "q_regs_operand" "")
11380                    (zero_extend (match_dup 1)))
11381               (clobber (reg:CC FLAGS_REG))])]
11382   "(peep2_reg_dead_p (3, operands[1])
11383     || operands_match_p (operands[1], operands[3]))
11384    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11385   [(set (match_dup 4) (match_dup 0))
11386    (set (strict_low_part (match_dup 5))
11387         (match_dup 2))]
11388 {
11389   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11390   operands[5] = gen_lowpart (QImode, operands[3]);
11391   ix86_expand_clear (operands[3]);
11392 })
11393 \f
11394 ;; Call instructions.
11395
11396 ;; The predicates normally associated with named expanders are not properly
11397 ;; checked for calls.  This is a bug in the generic code, but it isn't that
11398 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
11399
11400 ;; P6 processors will jump to the address after the decrement when %esp
11401 ;; is used as a call operand, so they will execute return address as a code.
11402 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11403  
11404 ;; Call subroutine returning no value.
11405
11406 (define_expand "call_pop"
11407   [(parallel [(call (match_operand:QI 0 "" "")
11408                     (match_operand:SI 1 "" ""))
11409               (set (reg:SI SP_REG)
11410                    (plus:SI (reg:SI SP_REG)
11411                             (match_operand:SI 3 "" "")))])]
11412   "!TARGET_64BIT"
11413 {
11414   ix86_expand_call (NULL, operands[0], operands[1],
11415                     operands[2], operands[3], 0);
11416   DONE;
11417 })
11418
11419 (define_insn "*call_pop_0"
11420   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
11421          (match_operand:SI 1 "" ""))
11422    (set (reg:SI SP_REG)
11423         (plus:SI (reg:SI SP_REG)
11424                  (match_operand:SI 2 "immediate_operand" "")))]
11425   "!TARGET_64BIT"
11426 {
11427   if (SIBLING_CALL_P (insn))
11428     return "jmp\t%P0";
11429   else
11430     return "call\t%P0";
11431 }
11432   [(set_attr "type" "call")])
11433
11434 (define_insn "*call_pop_1"
11435   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11436          (match_operand:SI 1 "" ""))
11437    (set (reg:SI SP_REG)
11438         (plus:SI (reg:SI SP_REG)
11439                  (match_operand:SI 2 "immediate_operand" "i")))]
11440   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11441 {
11442   if (constant_call_address_operand (operands[0], Pmode))
11443     return "call\t%P0";
11444   return "call\t%A0";
11445 }
11446   [(set_attr "type" "call")])
11447
11448 (define_insn "*sibcall_pop_1"
11449   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11450          (match_operand:SI 1 "" ""))
11451    (set (reg:SI SP_REG)
11452         (plus:SI (reg:SI SP_REG)
11453                  (match_operand:SI 2 "immediate_operand" "i,i")))]
11454   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11455   "@
11456    jmp\t%P0
11457    jmp\t%A0"
11458   [(set_attr "type" "call")])
11459
11460 (define_expand "call"
11461   [(call (match_operand:QI 0 "" "")
11462          (match_operand 1 "" ""))
11463    (use (match_operand 2 "" ""))]
11464   ""
11465 {
11466   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
11467   DONE;
11468 })
11469
11470 (define_expand "sibcall"
11471   [(call (match_operand:QI 0 "" "")
11472          (match_operand 1 "" ""))
11473    (use (match_operand 2 "" ""))]
11474   ""
11475 {
11476   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
11477   DONE;
11478 })
11479
11480 (define_insn "*call_0"
11481   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
11482          (match_operand 1 "" ""))]
11483   ""
11484 {
11485   if (SIBLING_CALL_P (insn))
11486     return "jmp\t%P0";
11487   else
11488     return "call\t%P0";
11489 }
11490   [(set_attr "type" "call")])
11491
11492 (define_insn "*call_1"
11493   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11494          (match_operand 1 "" ""))]
11495   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11496 {
11497   if (constant_call_address_operand (operands[0], Pmode))
11498     return "call\t%P0";
11499   return "call\t%A0";
11500 }
11501   [(set_attr "type" "call")])
11502
11503 (define_insn "*sibcall_1"
11504   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11505          (match_operand 1 "" ""))]
11506   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11507   "@
11508    jmp\t%P0
11509    jmp\t%A0"
11510   [(set_attr "type" "call")])
11511
11512 (define_insn "*call_1_rex64"
11513   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11514          (match_operand 1 "" ""))]
11515   "TARGET_64BIT && !SIBLING_CALL_P (insn)
11516    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
11517 {
11518   if (constant_call_address_operand (operands[0], Pmode))
11519     return "call\t%P0";
11520   return "call\t%A0";
11521 }
11522   [(set_attr "type" "call")])
11523
11524 (define_insn "*call_1_rex64_ms_sysv"
11525   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11526          (match_operand 1 "" ""))
11527    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11528    (clobber (reg:TI XMM6_REG))
11529    (clobber (reg:TI XMM7_REG))
11530    (clobber (reg:TI XMM8_REG))
11531    (clobber (reg:TI XMM9_REG))
11532    (clobber (reg:TI XMM10_REG))
11533    (clobber (reg:TI XMM11_REG))
11534    (clobber (reg:TI XMM12_REG))
11535    (clobber (reg:TI XMM13_REG))
11536    (clobber (reg:TI XMM14_REG))
11537    (clobber (reg:TI XMM15_REG))
11538    (clobber (reg:DI SI_REG))
11539    (clobber (reg:DI DI_REG))]
11540   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11541 {
11542   if (constant_call_address_operand (operands[0], Pmode))
11543     return "call\t%P0";
11544   return "call\t%A0";
11545 }
11546   [(set_attr "type" "call")])
11547
11548 (define_insn "*call_1_rex64_large"
11549   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
11550          (match_operand 1 "" ""))]
11551   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11552   "call\t%A0"
11553   [(set_attr "type" "call")])
11554
11555 (define_insn "*sibcall_1_rex64"
11556   [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
11557          (match_operand 1 "" ""))]
11558   "TARGET_64BIT && SIBLING_CALL_P (insn)"
11559   "@
11560    jmp\t%P0
11561    jmp\t%A0"
11562   [(set_attr "type" "call")])
11563
11564 ;; Call subroutine, returning value in operand 0
11565 (define_expand "call_value_pop"
11566   [(parallel [(set (match_operand 0 "" "")
11567                    (call (match_operand:QI 1 "" "")
11568                          (match_operand:SI 2 "" "")))
11569               (set (reg:SI SP_REG)
11570                    (plus:SI (reg:SI SP_REG)
11571                             (match_operand:SI 4 "" "")))])]
11572   "!TARGET_64BIT"
11573 {
11574   ix86_expand_call (operands[0], operands[1], operands[2],
11575                     operands[3], operands[4], 0);
11576   DONE;
11577 })
11578
11579 (define_expand "call_value"
11580   [(set (match_operand 0 "" "")
11581         (call (match_operand:QI 1 "" "")
11582               (match_operand:SI 2 "" "")))
11583    (use (match_operand:SI 3 "" ""))]
11584   ;; Operand 3 is not used on the i386.
11585   ""
11586 {
11587   ix86_expand_call (operands[0], operands[1], operands[2],
11588                     operands[3], NULL, 0);
11589   DONE;
11590 })
11591
11592 (define_expand "sibcall_value"
11593   [(set (match_operand 0 "" "")
11594         (call (match_operand:QI 1 "" "")
11595               (match_operand:SI 2 "" "")))
11596    (use (match_operand:SI 3 "" ""))]
11597   ;; Operand 3 is not used on the i386.
11598   ""
11599 {
11600   ix86_expand_call (operands[0], operands[1], operands[2],
11601                     operands[3], NULL, 1);
11602   DONE;
11603 })
11604
11605 ;; Call subroutine returning any type.
11606
11607 (define_expand "untyped_call"
11608   [(parallel [(call (match_operand 0 "" "")
11609                     (const_int 0))
11610               (match_operand 1 "" "")
11611               (match_operand 2 "" "")])]
11612   ""
11613 {
11614   int i;
11615
11616   /* In order to give reg-stack an easier job in validating two
11617      coprocessor registers as containing a possible return value,
11618      simply pretend the untyped call returns a complex long double
11619      value. 
11620
11621      We can't use SSE_REGPARM_MAX here since callee is unprototyped
11622      and should have the default ABI.  */
11623
11624   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11625                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11626                     operands[0], const0_rtx,
11627                     GEN_INT ((TARGET_64BIT
11628                               ? (ix86_abi == SYSV_ABI
11629                                  ? X86_64_SSE_REGPARM_MAX
11630                                  : X86_64_MS_SSE_REGPARM_MAX)
11631                               : X86_32_SSE_REGPARM_MAX)
11632                              - 1),
11633                     NULL, 0);
11634
11635   for (i = 0; i < XVECLEN (operands[2], 0); i++)
11636     {
11637       rtx set = XVECEXP (operands[2], 0, i);
11638       emit_move_insn (SET_DEST (set), SET_SRC (set));
11639     }
11640
11641   /* The optimizer does not know that the call sets the function value
11642      registers we stored in the result block.  We avoid problems by
11643      claiming that all hard registers are used and clobbered at this
11644      point.  */
11645   emit_insn (gen_blockage ());
11646
11647   DONE;
11648 })
11649 \f
11650 ;; Prologue and epilogue instructions
11651
11652 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11653 ;; all of memory.  This blocks insns from being moved across this point.
11654
11655 (define_insn "blockage"
11656   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11657   ""
11658   ""
11659   [(set_attr "length" "0")])
11660
11661 ;; Do not schedule instructions accessing memory across this point.
11662
11663 (define_expand "memory_blockage"
11664   [(set (match_dup 0)
11665         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11666   ""
11667 {
11668   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11669   MEM_VOLATILE_P (operands[0]) = 1;
11670 })
11671
11672 (define_insn "*memory_blockage"
11673   [(set (match_operand:BLK 0 "" "")
11674         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11675   ""
11676   ""
11677   [(set_attr "length" "0")])
11678
11679 ;; As USE insns aren't meaningful after reload, this is used instead
11680 ;; to prevent deleting instructions setting registers for PIC code
11681 (define_insn "prologue_use"
11682   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11683   ""
11684   ""
11685   [(set_attr "length" "0")])
11686
11687 ;; Insn emitted into the body of a function to return from a function.
11688 ;; This is only done if the function's epilogue is known to be simple.
11689 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11690
11691 (define_expand "return"
11692   [(return)]
11693   "ix86_can_use_return_insn_p ()"
11694 {
11695   if (crtl->args.pops_args)
11696     {
11697       rtx popc = GEN_INT (crtl->args.pops_args);
11698       emit_jump_insn (gen_return_pop_internal (popc));
11699       DONE;
11700     }
11701 })
11702
11703 (define_insn "return_internal"
11704   [(return)]
11705   "reload_completed"
11706   "ret"
11707   [(set_attr "length" "1")
11708    (set_attr "atom_unit" "jeu")
11709    (set_attr "length_immediate" "0")
11710    (set_attr "modrm" "0")])
11711
11712 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11713 ;; instruction Athlon and K8 have.
11714
11715 (define_insn "return_internal_long"
11716   [(return)
11717    (unspec [(const_int 0)] UNSPEC_REP)]
11718   "reload_completed"
11719   "rep\;ret"
11720   [(set_attr "length" "2")
11721    (set_attr "atom_unit" "jeu")
11722    (set_attr "length_immediate" "0")
11723    (set_attr "prefix_rep" "1")
11724    (set_attr "modrm" "0")])
11725
11726 (define_insn "return_pop_internal"
11727   [(return)
11728    (use (match_operand:SI 0 "const_int_operand" ""))]
11729   "reload_completed"
11730   "ret\t%0"
11731   [(set_attr "length" "3")
11732    (set_attr "atom_unit" "jeu")
11733    (set_attr "length_immediate" "2")
11734    (set_attr "modrm" "0")])
11735
11736 (define_insn "return_indirect_internal"
11737   [(return)
11738    (use (match_operand:SI 0 "register_operand" "r"))]
11739   "reload_completed"
11740   "jmp\t%A0"
11741   [(set_attr "type" "ibr")
11742    (set_attr "length_immediate" "0")])
11743
11744 (define_insn "nop"
11745   [(const_int 0)]
11746   ""
11747   "nop"
11748   [(set_attr "length" "1")
11749    (set_attr "length_immediate" "0")
11750    (set_attr "modrm" "0")])
11751
11752 (define_insn "vswapmov"
11753   [(set (match_operand:SI 0 "register_operand" "=r")
11754         (match_operand:SI 1 "register_operand" "r"))
11755    (unspec_volatile [(const_int 0)] UNSPECV_VSWAPMOV)]
11756   ""
11757   "movl.s\t{%1, %0|%0, %1}"
11758   [(set_attr "length" "2")
11759    (set_attr "length_immediate" "0")
11760    (set_attr "modrm" "0")])
11761
11762 ;; Pad to 16-byte boundary, max skip in op0.  Used to avoid
11763 ;; branch prediction penalty for the third jump in a 16-byte
11764 ;; block on K8.
11765
11766 (define_insn "pad"
11767   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
11768   ""
11769 {
11770 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11771   ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11772 #else
11773   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11774      The align insn is used to avoid 3 jump instructions in the row to improve
11775      branch prediction and the benefits hardly outweigh the cost of extra 8
11776      nops on the average inserted by full alignment pseudo operation.  */
11777 #endif
11778   return "";
11779 }
11780   [(set_attr "length" "16")])
11781
11782 (define_expand "prologue"
11783   [(const_int 0)]
11784   ""
11785   "ix86_expand_prologue (); DONE;")
11786
11787 (define_insn "set_got"
11788   [(set (match_operand:SI 0 "register_operand" "=r")
11789         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11790    (clobber (reg:CC FLAGS_REG))]
11791   "!TARGET_64BIT"
11792   { return output_set_got (operands[0], NULL_RTX); }
11793   [(set_attr "type" "multi")
11794    (set_attr "length" "12")])
11795
11796 (define_insn "set_got_labelled"
11797   [(set (match_operand:SI 0 "register_operand" "=r")
11798         (unspec:SI [(label_ref (match_operand 1 "" ""))]
11799          UNSPEC_SET_GOT))
11800    (clobber (reg:CC FLAGS_REG))]
11801   "!TARGET_64BIT"
11802   { return output_set_got (operands[0], operands[1]); }
11803   [(set_attr "type" "multi")
11804    (set_attr "length" "12")])
11805
11806 (define_insn "set_got_rex64"
11807   [(set (match_operand:DI 0 "register_operand" "=r")
11808         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11809   "TARGET_64BIT"
11810   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11811   [(set_attr "type" "lea")
11812    (set_attr "length_address" "4")
11813    (set_attr "mode" "DI")])
11814
11815 (define_insn "set_rip_rex64"
11816   [(set (match_operand:DI 0 "register_operand" "=r")
11817         (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
11818   "TARGET_64BIT"
11819   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11820   [(set_attr "type" "lea")
11821    (set_attr "length_address" "4")
11822    (set_attr "mode" "DI")])
11823
11824 (define_insn "set_got_offset_rex64"
11825   [(set (match_operand:DI 0 "register_operand" "=r")
11826         (unspec:DI
11827           [(label_ref (match_operand 1 "" ""))]
11828           UNSPEC_SET_GOT_OFFSET))]
11829   "TARGET_64BIT"
11830   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11831   [(set_attr "type" "imov")
11832    (set_attr "length_immediate" "0")
11833    (set_attr "length_address" "8")
11834    (set_attr "mode" "DI")])
11835
11836 (define_expand "epilogue"
11837   [(const_int 0)]
11838   ""
11839   "ix86_expand_epilogue (1); DONE;")
11840
11841 (define_expand "sibcall_epilogue"
11842   [(const_int 0)]
11843   ""
11844   "ix86_expand_epilogue (0); DONE;")
11845
11846 (define_expand "eh_return"
11847   [(use (match_operand 0 "register_operand" ""))]
11848   ""
11849 {
11850   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11851
11852   /* Tricky bit: we write the address of the handler to which we will
11853      be returning into someone else's stack frame, one word below the
11854      stack address we wish to restore.  */
11855   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11856   tmp = plus_constant (tmp, -UNITS_PER_WORD);
11857   tmp = gen_rtx_MEM (Pmode, tmp);
11858   emit_move_insn (tmp, ra);
11859
11860   emit_jump_insn (gen_eh_return_internal ());
11861   emit_barrier ();
11862   DONE;
11863 })
11864
11865 (define_insn_and_split "eh_return_internal"
11866   [(eh_return)]
11867   ""
11868   "#"
11869   "epilogue_completed"
11870   [(const_int 0)]
11871   "ix86_expand_epilogue (2); DONE;")
11872
11873 (define_insn "leave"
11874   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11875    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11876    (clobber (mem:BLK (scratch)))]
11877   "!TARGET_64BIT"
11878   "leave"
11879   [(set_attr "type" "leave")])
11880
11881 (define_insn "leave_rex64"
11882   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11883    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11884    (clobber (mem:BLK (scratch)))]
11885   "TARGET_64BIT"
11886   "leave"
11887   [(set_attr "type" "leave")])
11888 \f
11889 ;; Bit manipulation instructions.
11890
11891 (define_expand "ffs<mode>2"
11892   [(set (match_dup 2) (const_int -1))
11893    (parallel [(set (reg:CCZ FLAGS_REG)
11894                    (compare:CCZ
11895                      (match_operand:SWI48 1 "nonimmediate_operand" "")
11896                      (const_int 0)))
11897               (set (match_operand:SWI48 0 "register_operand" "")
11898                    (ctz:SWI48 (match_dup 1)))])
11899    (set (match_dup 0) (if_then_else:SWI48
11900                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
11901                         (match_dup 2)
11902                         (match_dup 0)))
11903    (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11904               (clobber (reg:CC FLAGS_REG))])]
11905   ""
11906 {
11907   if (<MODE>mode == SImode && !TARGET_CMOVE)
11908     {
11909       emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
11910       DONE;
11911     }
11912   operands[2] = gen_reg_rtx (<MODE>mode);
11913 })
11914
11915 (define_insn_and_split "ffssi2_no_cmove"
11916   [(set (match_operand:SI 0 "register_operand" "=r")
11917         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
11918    (clobber (match_scratch:SI 2 "=&q"))
11919    (clobber (reg:CC FLAGS_REG))]
11920   "!TARGET_CMOVE"
11921   "#"
11922   "&& reload_completed"
11923   [(parallel [(set (reg:CCZ FLAGS_REG)
11924                    (compare:CCZ (match_dup 1) (const_int 0)))
11925               (set (match_dup 0) (ctz:SI (match_dup 1)))])
11926    (set (strict_low_part (match_dup 3))
11927         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
11928    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
11929               (clobber (reg:CC FLAGS_REG))])
11930    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
11931               (clobber (reg:CC FLAGS_REG))])
11932    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
11933               (clobber (reg:CC FLAGS_REG))])]
11934 {
11935   operands[3] = gen_lowpart (QImode, operands[2]);
11936   ix86_expand_clear (operands[2]);
11937 })
11938
11939 (define_insn "*ffs<mode>_1"
11940   [(set (reg:CCZ FLAGS_REG)
11941         (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11942                      (const_int 0)))
11943    (set (match_operand:SWI48 0 "register_operand" "=r")
11944         (ctz:SWI48 (match_dup 1)))]
11945   ""
11946   "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
11947   [(set_attr "type" "alu1")
11948    (set_attr "prefix_0f" "1")
11949    (set_attr "mode" "<MODE>")])
11950
11951 (define_insn "ctz<mode>2"
11952   [(set (match_operand:SWI48 0 "register_operand" "=r")
11953         (ctz:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
11954    (clobber (reg:CC FLAGS_REG))]
11955   ""
11956   "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
11957   [(set_attr "type" "alu1")
11958    (set_attr "prefix_0f" "1")
11959    (set_attr "mode" "<MODE>")])
11960
11961 (define_expand "clz<mode>2"
11962   [(parallel
11963      [(set (match_operand:SWI248 0 "register_operand" "")
11964            (minus:SWI248
11965              (match_dup 2)
11966              (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
11967       (clobber (reg:CC FLAGS_REG))])
11968    (parallel
11969      [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
11970       (clobber (reg:CC FLAGS_REG))])]
11971   ""
11972 {
11973   if (TARGET_ABM)
11974     {
11975       emit_insn (gen_clz<mode>2_abm (operands[0], operands[1]));
11976       DONE;
11977     }
11978   operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
11979 })
11980
11981 (define_insn "clz<mode>2_abm"
11982   [(set (match_operand:SWI248 0 "register_operand" "=r")
11983         (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11984    (clobber (reg:CC FLAGS_REG))]
11985   "TARGET_ABM"
11986   "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
11987   [(set_attr "prefix_rep" "1")
11988    (set_attr "type" "bitmanip")
11989    (set_attr "mode" "<MODE>")])
11990
11991 (define_insn "bsr_rex64"
11992   [(set (match_operand:DI 0 "register_operand" "=r")
11993         (minus:DI (const_int 63)
11994                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
11995    (clobber (reg:CC FLAGS_REG))]
11996   "TARGET_64BIT"
11997   "bsr{q}\t{%1, %0|%0, %1}"
11998   [(set_attr "type" "alu1")
11999    (set_attr "prefix_0f" "1")
12000    (set_attr "mode" "DI")])
12001
12002 (define_insn "bsr"
12003   [(set (match_operand:SI 0 "register_operand" "=r")
12004         (minus:SI (const_int 31)
12005                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12006    (clobber (reg:CC FLAGS_REG))]
12007   ""
12008   "bsr{l}\t{%1, %0|%0, %1}"
12009   [(set_attr "type" "alu1")
12010    (set_attr "prefix_0f" "1")
12011    (set_attr "mode" "SI")])
12012
12013 (define_insn "*bsrhi"
12014   [(set (match_operand:HI 0 "register_operand" "=r")
12015         (minus:HI (const_int 15)
12016                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12017    (clobber (reg:CC FLAGS_REG))]
12018   ""
12019   "bsr{w}\t{%1, %0|%0, %1}"
12020   [(set_attr "type" "alu1")
12021    (set_attr "prefix_0f" "1")
12022    (set_attr "mode" "HI")])
12023
12024 (define_insn "popcount<mode>2"
12025   [(set (match_operand:SWI248 0 "register_operand" "=r")
12026         (popcount:SWI248
12027           (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12028    (clobber (reg:CC FLAGS_REG))]
12029   "TARGET_POPCNT"
12030 {
12031 #if TARGET_MACHO
12032   return "popcnt\t{%1, %0|%0, %1}";
12033 #else
12034   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12035 #endif
12036 }
12037   [(set_attr "prefix_rep" "1")
12038    (set_attr "type" "bitmanip")
12039    (set_attr "mode" "<MODE>")])
12040
12041 (define_insn "*popcount<mode>2_cmp"
12042   [(set (reg FLAGS_REG)
12043         (compare
12044           (popcount:SWI248
12045             (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12046           (const_int 0)))
12047    (set (match_operand:SWI248 0 "register_operand" "=r")
12048         (popcount:SWI248 (match_dup 1)))]
12049   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12050 {
12051 #if TARGET_MACHO
12052   return "popcnt\t{%1, %0|%0, %1}";
12053 #else
12054   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12055 #endif
12056 }
12057   [(set_attr "prefix_rep" "1")
12058    (set_attr "type" "bitmanip")
12059    (set_attr "mode" "<MODE>")])
12060
12061 (define_insn "*popcountsi2_cmp_zext"
12062   [(set (reg FLAGS_REG)
12063         (compare
12064           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12065           (const_int 0)))
12066    (set (match_operand:DI 0 "register_operand" "=r")
12067         (zero_extend:DI(popcount:SI (match_dup 1))))]
12068   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12069 {
12070 #if TARGET_MACHO
12071   return "popcnt\t{%1, %0|%0, %1}";
12072 #else
12073   return "popcnt{l}\t{%1, %0|%0, %1}";
12074 #endif
12075 }
12076   [(set_attr "prefix_rep" "1")
12077    (set_attr "type" "bitmanip")
12078    (set_attr "mode" "SI")])
12079
12080 (define_expand "bswap<mode>2"
12081   [(set (match_operand:SWI48 0 "register_operand" "")
12082         (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
12083   ""
12084 {
12085   if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
12086     {
12087       rtx x = operands[0];
12088
12089       emit_move_insn (x, operands[1]);
12090       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12091       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12092       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12093       DONE;
12094     }
12095 })
12096
12097 (define_insn "*bswap<mode>2_movbe"
12098   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12099         (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12100   "TARGET_MOVBE
12101    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12102   "@
12103     bswap\t%0
12104     movbe\t{%1, %0|%0, %1}
12105     movbe\t{%1, %0|%0, %1}"
12106   [(set_attr "type" "bitmanip,imov,imov")
12107    (set_attr "modrm" "0,1,1")
12108    (set_attr "prefix_0f" "*,1,1")
12109    (set_attr "prefix_extra" "*,1,1")
12110    (set_attr "mode" "<MODE>")])
12111
12112 (define_insn "*bswap<mode>2_1"
12113   [(set (match_operand:SWI48 0 "register_operand" "=r")
12114         (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12115   "TARGET_BSWAP"
12116   "bswap\t%0"
12117   [(set_attr "type" "bitmanip")
12118    (set_attr "modrm" "0")
12119    (set_attr "mode" "<MODE>")])
12120
12121 (define_insn "*bswaphi_lowpart_1"
12122   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12123         (bswap:HI (match_dup 0)))
12124    (clobber (reg:CC FLAGS_REG))]
12125   "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12126   "@
12127     xchg{b}\t{%h0, %b0|%b0, %h0}
12128     rol{w}\t{$8, %0|%0, 8}"
12129   [(set_attr "length" "2,4")
12130    (set_attr "mode" "QI,HI")])
12131
12132 (define_insn "bswaphi_lowpart"
12133   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12134         (bswap:HI (match_dup 0)))
12135    (clobber (reg:CC FLAGS_REG))]
12136   ""
12137   "rol{w}\t{$8, %0|%0, 8}"
12138   [(set_attr "length" "4")
12139    (set_attr "mode" "HI")])
12140
12141 (define_expand "paritydi2"
12142   [(set (match_operand:DI 0 "register_operand" "")
12143         (parity:DI (match_operand:DI 1 "register_operand" "")))]
12144   "! TARGET_POPCNT"
12145 {
12146   rtx scratch = gen_reg_rtx (QImode);
12147   rtx cond;
12148
12149   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12150                                 NULL_RTX, operands[1]));
12151
12152   cond = gen_rtx_fmt_ee (ORDERED, QImode,
12153                          gen_rtx_REG (CCmode, FLAGS_REG),
12154                          const0_rtx);
12155   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12156
12157   if (TARGET_64BIT)
12158     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12159   else
12160     {
12161       rtx tmp = gen_reg_rtx (SImode);
12162
12163       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12164       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12165     }
12166   DONE;
12167 })
12168
12169 (define_expand "paritysi2"
12170   [(set (match_operand:SI 0 "register_operand" "")
12171         (parity:SI (match_operand:SI 1 "register_operand" "")))]
12172   "! TARGET_POPCNT"
12173 {
12174   rtx scratch = gen_reg_rtx (QImode);
12175   rtx cond;
12176
12177   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12178
12179   cond = gen_rtx_fmt_ee (ORDERED, QImode,
12180                          gen_rtx_REG (CCmode, FLAGS_REG),
12181                          const0_rtx);
12182   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12183
12184   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12185   DONE;
12186 })
12187
12188 (define_insn_and_split "paritydi2_cmp"
12189   [(set (reg:CC FLAGS_REG)
12190         (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12191                    UNSPEC_PARITY))
12192    (clobber (match_scratch:DI 0 "=r"))
12193    (clobber (match_scratch:SI 1 "=&r"))
12194    (clobber (match_scratch:HI 2 "=Q"))]
12195   "! TARGET_POPCNT"
12196   "#"
12197   "&& reload_completed"
12198   [(parallel
12199      [(set (match_dup 1)
12200            (xor:SI (match_dup 1) (match_dup 4)))
12201       (clobber (reg:CC FLAGS_REG))])
12202    (parallel
12203      [(set (reg:CC FLAGS_REG)
12204            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12205       (clobber (match_dup 1))
12206       (clobber (match_dup 2))])]
12207 {
12208   operands[4] = gen_lowpart (SImode, operands[3]);
12209
12210   if (TARGET_64BIT)
12211     {
12212       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12213       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12214     }
12215   else
12216     operands[1] = gen_highpart (SImode, operands[3]);
12217 })
12218
12219 (define_insn_and_split "paritysi2_cmp"
12220   [(set (reg:CC FLAGS_REG)
12221         (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12222                    UNSPEC_PARITY))
12223    (clobber (match_scratch:SI 0 "=r"))
12224    (clobber (match_scratch:HI 1 "=&Q"))]
12225   "! TARGET_POPCNT"
12226   "#"
12227   "&& reload_completed"
12228   [(parallel
12229      [(set (match_dup 1)
12230            (xor:HI (match_dup 1) (match_dup 3)))
12231       (clobber (reg:CC FLAGS_REG))])
12232    (parallel
12233      [(set (reg:CC FLAGS_REG)
12234            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12235       (clobber (match_dup 1))])]
12236 {
12237   operands[3] = gen_lowpart (HImode, operands[2]);
12238
12239   emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12240   emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12241 })
12242
12243 (define_insn "*parityhi2_cmp"
12244   [(set (reg:CC FLAGS_REG)
12245         (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12246                    UNSPEC_PARITY))
12247    (clobber (match_scratch:HI 0 "=Q"))]
12248   "! TARGET_POPCNT"
12249   "xor{b}\t{%h0, %b0|%b0, %h0}"
12250   [(set_attr "length" "2")
12251    (set_attr "mode" "HI")])
12252 \f
12253 ;; Thread-local storage patterns for ELF.
12254 ;;
12255 ;; Note that these code sequences must appear exactly as shown
12256 ;; in order to allow linker relaxation.
12257
12258 (define_insn "*tls_global_dynamic_32_gnu"
12259   [(set (match_operand:SI 0 "register_operand" "=a")
12260         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12261                     (match_operand:SI 2 "tls_symbolic_operand" "")
12262                     (match_operand:SI 3 "call_insn_operand" "")]
12263                     UNSPEC_TLS_GD))
12264    (clobber (match_scratch:SI 4 "=d"))
12265    (clobber (match_scratch:SI 5 "=c"))
12266    (clobber (reg:CC FLAGS_REG))]
12267   "!TARGET_64BIT && TARGET_GNU_TLS"
12268   "lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}\;call\t%P3"
12269   [(set_attr "type" "multi")
12270    (set_attr "length" "12")])
12271
12272 (define_expand "tls_global_dynamic_32"
12273   [(parallel [(set (match_operand:SI 0 "register_operand" "")
12274                    (unspec:SI
12275                     [(match_dup 2)
12276                      (match_operand:SI 1 "tls_symbolic_operand" "")
12277                      (match_dup 3)]
12278                     UNSPEC_TLS_GD))
12279               (clobber (match_scratch:SI 4 ""))
12280               (clobber (match_scratch:SI 5 ""))
12281               (clobber (reg:CC FLAGS_REG))])]
12282   ""
12283 {
12284   if (flag_pic)
12285     operands[2] = pic_offset_table_rtx;
12286   else
12287     {
12288       operands[2] = gen_reg_rtx (Pmode);
12289       emit_insn (gen_set_got (operands[2]));
12290     }
12291   if (TARGET_GNU2_TLS)
12292     {
12293        emit_insn (gen_tls_dynamic_gnu2_32
12294                   (operands[0], operands[1], operands[2]));
12295        DONE;
12296     }
12297   operands[3] = ix86_tls_get_addr ();
12298 })
12299
12300 (define_insn "*tls_global_dynamic_64"
12301   [(set (match_operand:DI 0 "register_operand" "=a")
12302         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
12303                  (match_operand:DI 3 "" "")))
12304    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12305               UNSPEC_TLS_GD)]
12306   "TARGET_64BIT"
12307   { 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"; }
12308   [(set_attr "type" "multi")
12309    (set_attr "length" "16")])
12310
12311 (define_expand "tls_global_dynamic_64"
12312   [(parallel [(set (match_operand:DI 0 "register_operand" "")
12313                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
12314               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12315                          UNSPEC_TLS_GD)])]
12316   ""
12317 {
12318   if (TARGET_GNU2_TLS)
12319     {
12320        emit_insn (gen_tls_dynamic_gnu2_64
12321                   (operands[0], operands[1]));
12322        DONE;
12323     }
12324   operands[2] = ix86_tls_get_addr ();
12325 })
12326
12327 (define_insn "*tls_local_dynamic_base_32_gnu"
12328   [(set (match_operand:SI 0 "register_operand" "=a")
12329         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12330                     (match_operand:SI 2 "call_insn_operand" "")]
12331                    UNSPEC_TLS_LD_BASE))
12332    (clobber (match_scratch:SI 3 "=d"))
12333    (clobber (match_scratch:SI 4 "=c"))
12334    (clobber (reg:CC FLAGS_REG))]
12335   "!TARGET_64BIT && TARGET_GNU_TLS"
12336   "lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}\;call\t%P2"
12337   [(set_attr "type" "multi")
12338    (set_attr "length" "11")])
12339
12340 (define_expand "tls_local_dynamic_base_32"
12341   [(parallel [(set (match_operand:SI 0 "register_operand" "")
12342                    (unspec:SI [(match_dup 1) (match_dup 2)]
12343                               UNSPEC_TLS_LD_BASE))
12344               (clobber (match_scratch:SI 3 ""))
12345               (clobber (match_scratch:SI 4 ""))
12346               (clobber (reg:CC FLAGS_REG))])]
12347   ""
12348 {
12349   if (flag_pic)
12350     operands[1] = pic_offset_table_rtx;
12351   else
12352     {
12353       operands[1] = gen_reg_rtx (Pmode);
12354       emit_insn (gen_set_got (operands[1]));
12355     }
12356   if (TARGET_GNU2_TLS)
12357     {
12358        emit_insn (gen_tls_dynamic_gnu2_32
12359                   (operands[0], ix86_tls_module_base (), operands[1]));
12360        DONE;
12361     }
12362   operands[2] = ix86_tls_get_addr ();
12363 })
12364
12365 (define_insn "*tls_local_dynamic_base_64"
12366   [(set (match_operand:DI 0 "register_operand" "=a")
12367         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
12368                  (match_operand:DI 2 "" "")))
12369    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12370   "TARGET_64BIT"
12371   "lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}\;call\t%P1"
12372   [(set_attr "type" "multi")
12373    (set_attr "length" "12")])
12374
12375 (define_expand "tls_local_dynamic_base_64"
12376   [(parallel [(set (match_operand:DI 0 "register_operand" "")
12377                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
12378               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
12379   ""
12380 {
12381   if (TARGET_GNU2_TLS)
12382     {
12383        emit_insn (gen_tls_dynamic_gnu2_64
12384                   (operands[0], ix86_tls_module_base ()));
12385        DONE;
12386     }
12387   operands[1] = ix86_tls_get_addr ();
12388 })
12389
12390 ;; Local dynamic of a single variable is a lose.  Show combine how
12391 ;; to convert that back to global dynamic.
12392
12393 (define_insn_and_split "*tls_local_dynamic_32_once"
12394   [(set (match_operand:SI 0 "register_operand" "=a")
12395         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12396                              (match_operand:SI 2 "call_insn_operand" "")]
12397                             UNSPEC_TLS_LD_BASE)
12398                  (const:SI (unspec:SI
12399                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
12400                             UNSPEC_DTPOFF))))
12401    (clobber (match_scratch:SI 4 "=d"))
12402    (clobber (match_scratch:SI 5 "=c"))
12403    (clobber (reg:CC FLAGS_REG))]
12404   ""
12405   "#"
12406   ""
12407   [(parallel [(set (match_dup 0)
12408                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12409                               UNSPEC_TLS_GD))
12410               (clobber (match_dup 4))
12411               (clobber (match_dup 5))
12412               (clobber (reg:CC FLAGS_REG))])]
12413   "")
12414
12415 ;; Load and add the thread base pointer from %gs:0.
12416
12417 (define_insn "*load_tp_si"
12418   [(set (match_operand:SI 0 "register_operand" "=r")
12419         (unspec:SI [(const_int 0)] UNSPEC_TP))]
12420   "!TARGET_64BIT"
12421   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
12422   [(set_attr "type" "imov")
12423    (set_attr "modrm" "0")
12424    (set_attr "length" "7")
12425    (set_attr "memory" "load")
12426    (set_attr "imm_disp" "false")])
12427
12428 (define_insn "*add_tp_si"
12429   [(set (match_operand:SI 0 "register_operand" "=r")
12430         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12431                  (match_operand:SI 1 "register_operand" "0")))
12432    (clobber (reg:CC FLAGS_REG))]
12433   "!TARGET_64BIT"
12434   "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
12435   [(set_attr "type" "alu")
12436    (set_attr "modrm" "0")
12437    (set_attr "length" "7")
12438    (set_attr "memory" "load")
12439    (set_attr "imm_disp" "false")])
12440
12441 (define_insn "*load_tp_di"
12442   [(set (match_operand:DI 0 "register_operand" "=r")
12443         (unspec:DI [(const_int 0)] UNSPEC_TP))]
12444   "TARGET_64BIT"
12445   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
12446   [(set_attr "type" "imov")
12447    (set_attr "modrm" "0")
12448    (set_attr "length" "7")
12449    (set_attr "memory" "load")
12450    (set_attr "imm_disp" "false")])
12451
12452 (define_insn "*add_tp_di"
12453   [(set (match_operand:DI 0 "register_operand" "=r")
12454         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
12455                  (match_operand:DI 1 "register_operand" "0")))
12456    (clobber (reg:CC FLAGS_REG))]
12457   "TARGET_64BIT"
12458   "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
12459   [(set_attr "type" "alu")
12460    (set_attr "modrm" "0")
12461    (set_attr "length" "7")
12462    (set_attr "memory" "load")
12463    (set_attr "imm_disp" "false")])
12464
12465 ;; GNU2 TLS patterns can be split.
12466
12467 (define_expand "tls_dynamic_gnu2_32"
12468   [(set (match_dup 3)
12469         (plus:SI (match_operand:SI 2 "register_operand" "")
12470                  (const:SI
12471                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12472                              UNSPEC_TLSDESC))))
12473    (parallel
12474     [(set (match_operand:SI 0 "register_operand" "")
12475           (unspec:SI [(match_dup 1) (match_dup 3)
12476                       (match_dup 2) (reg:SI SP_REG)]
12477                       UNSPEC_TLSDESC))
12478      (clobber (reg:CC FLAGS_REG))])]
12479   "!TARGET_64BIT && TARGET_GNU2_TLS"
12480 {
12481   operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12482   ix86_tls_descriptor_calls_expanded_in_cfun = true;
12483 })
12484
12485 (define_insn "*tls_dynamic_lea_32"
12486   [(set (match_operand:SI 0 "register_operand" "=r")
12487         (plus:SI (match_operand:SI 1 "register_operand" "b")
12488                  (const:SI
12489                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12490                               UNSPEC_TLSDESC))))]
12491   "!TARGET_64BIT && TARGET_GNU2_TLS"
12492   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
12493   [(set_attr "type" "lea")
12494    (set_attr "mode" "SI")
12495    (set_attr "length" "6")
12496    (set_attr "length_address" "4")])
12497
12498 (define_insn "*tls_dynamic_call_32"
12499   [(set (match_operand:SI 0 "register_operand" "=a")
12500         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12501                     (match_operand:SI 2 "register_operand" "0")
12502                     ;; we have to make sure %ebx still points to the GOT
12503                     (match_operand:SI 3 "register_operand" "b")
12504                     (reg:SI SP_REG)]
12505                    UNSPEC_TLSDESC))
12506    (clobber (reg:CC FLAGS_REG))]
12507   "!TARGET_64BIT && TARGET_GNU2_TLS"
12508   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12509   [(set_attr "type" "call")
12510    (set_attr "length" "2")
12511    (set_attr "length_address" "0")])
12512
12513 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12514   [(set (match_operand:SI 0 "register_operand" "=&a")
12515         (plus:SI
12516          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12517                      (match_operand:SI 4 "" "")
12518                      (match_operand:SI 2 "register_operand" "b")
12519                      (reg:SI SP_REG)]
12520                     UNSPEC_TLSDESC)
12521          (const:SI (unspec:SI
12522                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
12523                     UNSPEC_DTPOFF))))
12524    (clobber (reg:CC FLAGS_REG))]
12525   "!TARGET_64BIT && TARGET_GNU2_TLS"
12526   "#"
12527   ""
12528   [(set (match_dup 0) (match_dup 5))]
12529 {
12530   operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12531   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12532 })
12533
12534 (define_expand "tls_dynamic_gnu2_64"
12535   [(set (match_dup 2)
12536         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12537                    UNSPEC_TLSDESC))
12538    (parallel
12539     [(set (match_operand:DI 0 "register_operand" "")
12540           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12541                      UNSPEC_TLSDESC))
12542      (clobber (reg:CC FLAGS_REG))])]
12543   "TARGET_64BIT && TARGET_GNU2_TLS"
12544 {
12545   operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12546   ix86_tls_descriptor_calls_expanded_in_cfun = true;
12547 })
12548
12549 (define_insn "*tls_dynamic_lea_64"
12550   [(set (match_operand:DI 0 "register_operand" "=r")
12551         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12552                    UNSPEC_TLSDESC))]
12553   "TARGET_64BIT && TARGET_GNU2_TLS"
12554   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
12555   [(set_attr "type" "lea")
12556    (set_attr "mode" "DI")
12557    (set_attr "length" "7")
12558    (set_attr "length_address" "4")])
12559
12560 (define_insn "*tls_dynamic_call_64"
12561   [(set (match_operand:DI 0 "register_operand" "=a")
12562         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
12563                     (match_operand:DI 2 "register_operand" "0")
12564                     (reg:DI SP_REG)]
12565                    UNSPEC_TLSDESC))
12566    (clobber (reg:CC FLAGS_REG))]
12567   "TARGET_64BIT && TARGET_GNU2_TLS"
12568   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12569   [(set_attr "type" "call")
12570    (set_attr "length" "2")
12571    (set_attr "length_address" "0")])
12572
12573 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12574   [(set (match_operand:DI 0 "register_operand" "=&a")
12575         (plus:DI
12576          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12577                      (match_operand:DI 3 "" "")
12578                      (reg:DI SP_REG)]
12579                     UNSPEC_TLSDESC)
12580          (const:DI (unspec:DI
12581                     [(match_operand:DI 1 "tls_symbolic_operand" "")]
12582                     UNSPEC_DTPOFF))))
12583    (clobber (reg:CC FLAGS_REG))]
12584   "TARGET_64BIT && TARGET_GNU2_TLS"
12585   "#"
12586   ""
12587   [(set (match_dup 0) (match_dup 4))]
12588 {
12589   operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12590   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12591 })
12592
12593 ;;
12594 \f
12595 ;; These patterns match the binary 387 instructions for addM3, subM3,
12596 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
12597 ;; SFmode.  The first is the normal insn, the second the same insn but
12598 ;; with one operand a conversion, and the third the same insn but with
12599 ;; the other operand a conversion.  The conversion may be SFmode or
12600 ;; SImode if the target mode DFmode, but only SImode if the target mode
12601 ;; is SFmode.
12602
12603 ;; Gcc is slightly more smart about handling normal two address instructions
12604 ;; so use special patterns for add and mull.
12605
12606 (define_insn "*fop_<mode>_comm_mixed_avx"
12607   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
12608         (match_operator:MODEF 3 "binary_fp_operator"
12609           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
12610            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
12611   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12612    && COMMUTATIVE_ARITH_P (operands[3])
12613    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12614   "* return output_387_binary_op (insn, operands);"
12615   [(set (attr "type")
12616         (if_then_else (eq_attr "alternative" "1")
12617            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12618               (const_string "ssemul")
12619               (const_string "sseadd"))
12620            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12621               (const_string "fmul")
12622               (const_string "fop"))))
12623    (set_attr "prefix" "orig,maybe_vex")
12624    (set_attr "mode" "<MODE>")])
12625
12626 (define_insn "*fop_<mode>_comm_mixed"
12627   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
12628         (match_operator:MODEF 3 "binary_fp_operator"
12629           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
12630            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
12631   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12632    && COMMUTATIVE_ARITH_P (operands[3])
12633    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12634   "* return output_387_binary_op (insn, operands);"
12635   [(set (attr "type")
12636         (if_then_else (eq_attr "alternative" "1")
12637            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12638               (const_string "ssemul")
12639               (const_string "sseadd"))
12640            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12641               (const_string "fmul")
12642               (const_string "fop"))))
12643    (set_attr "mode" "<MODE>")])
12644
12645 (define_insn "*fop_<mode>_comm_avx"
12646   [(set (match_operand:MODEF 0 "register_operand" "=x")
12647         (match_operator:MODEF 3 "binary_fp_operator"
12648           [(match_operand:MODEF 1 "nonimmediate_operand" "%x")
12649            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12650   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12651    && COMMUTATIVE_ARITH_P (operands[3])
12652    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12653   "* return output_387_binary_op (insn, operands);"
12654   [(set (attr "type")
12655         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12656            (const_string "ssemul")
12657            (const_string "sseadd")))
12658    (set_attr "prefix" "vex")
12659    (set_attr "mode" "<MODE>")])
12660
12661 (define_insn "*fop_<mode>_comm_sse"
12662   [(set (match_operand:MODEF 0 "register_operand" "=x")
12663         (match_operator:MODEF 3 "binary_fp_operator"
12664           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12665            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12666   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12667    && COMMUTATIVE_ARITH_P (operands[3])
12668    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12669   "* return output_387_binary_op (insn, operands);"
12670   [(set (attr "type")
12671         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12672            (const_string "ssemul")
12673            (const_string "sseadd")))
12674    (set_attr "mode" "<MODE>")])
12675
12676 (define_insn "*fop_<mode>_comm_i387"
12677   [(set (match_operand:MODEF 0 "register_operand" "=f")
12678         (match_operator:MODEF 3 "binary_fp_operator"
12679           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12680            (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
12681   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12682    && COMMUTATIVE_ARITH_P (operands[3])
12683    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12684   "* return output_387_binary_op (insn, operands);"
12685   [(set (attr "type")
12686         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12687            (const_string "fmul")
12688            (const_string "fop")))
12689    (set_attr "mode" "<MODE>")])
12690
12691 (define_insn "*fop_<mode>_1_mixed_avx"
12692   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
12693         (match_operator:MODEF 3 "binary_fp_operator"
12694           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,x")
12695            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
12696   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12697    && !COMMUTATIVE_ARITH_P (operands[3])
12698    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12699   "* return output_387_binary_op (insn, operands);"
12700   [(set (attr "type")
12701         (cond [(and (eq_attr "alternative" "2")
12702                     (match_operand:MODEF 3 "mult_operator" ""))
12703                  (const_string "ssemul")
12704                (and (eq_attr "alternative" "2")
12705                     (match_operand:MODEF 3 "div_operator" ""))
12706                  (const_string "ssediv")
12707                (eq_attr "alternative" "2")
12708                  (const_string "sseadd")
12709                (match_operand:MODEF 3 "mult_operator" "")
12710                  (const_string "fmul")
12711                (match_operand:MODEF 3 "div_operator" "")
12712                  (const_string "fdiv")
12713               ]
12714               (const_string "fop")))
12715    (set_attr "prefix" "orig,orig,maybe_vex")
12716    (set_attr "mode" "<MODE>")])
12717
12718 (define_insn "*fop_<mode>_1_mixed"
12719   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
12720         (match_operator:MODEF 3 "binary_fp_operator"
12721           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
12722            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
12723   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12724    && !COMMUTATIVE_ARITH_P (operands[3])
12725    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12726   "* return output_387_binary_op (insn, operands);"
12727   [(set (attr "type")
12728         (cond [(and (eq_attr "alternative" "2")
12729                     (match_operand:MODEF 3 "mult_operator" ""))
12730                  (const_string "ssemul")
12731                (and (eq_attr "alternative" "2")
12732                     (match_operand:MODEF 3 "div_operator" ""))
12733                  (const_string "ssediv")
12734                (eq_attr "alternative" "2")
12735                  (const_string "sseadd")
12736                (match_operand:MODEF 3 "mult_operator" "")
12737                  (const_string "fmul")
12738                (match_operand:MODEF 3 "div_operator" "")
12739                  (const_string "fdiv")
12740               ]
12741               (const_string "fop")))
12742    (set_attr "mode" "<MODE>")])
12743
12744 (define_insn "*rcpsf2_sse"
12745   [(set (match_operand:SF 0 "register_operand" "=x")
12746         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
12747                    UNSPEC_RCP))]
12748   "TARGET_SSE_MATH"
12749   "%vrcpss\t{%1, %d0|%d0, %1}"
12750   [(set_attr "type" "sse")
12751    (set_attr "atom_sse_attr" "rcp")
12752    (set_attr "prefix" "maybe_vex")
12753    (set_attr "mode" "SF")])
12754
12755 (define_insn "*fop_<mode>_1_avx"
12756   [(set (match_operand:MODEF 0 "register_operand" "=x")
12757         (match_operator:MODEF 3 "binary_fp_operator"
12758           [(match_operand:MODEF 1 "register_operand" "x")
12759            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12760   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12761    && !COMMUTATIVE_ARITH_P (operands[3])"
12762   "* return output_387_binary_op (insn, operands);"
12763   [(set (attr "type")
12764         (cond [(match_operand:MODEF 3 "mult_operator" "")
12765                  (const_string "ssemul")
12766                (match_operand:MODEF 3 "div_operator" "")
12767                  (const_string "ssediv")
12768               ]
12769               (const_string "sseadd")))
12770    (set_attr "prefix" "vex")
12771    (set_attr "mode" "<MODE>")])
12772
12773 (define_insn "*fop_<mode>_1_sse"
12774   [(set (match_operand:MODEF 0 "register_operand" "=x")
12775         (match_operator:MODEF 3 "binary_fp_operator"
12776           [(match_operand:MODEF 1 "register_operand" "0")
12777            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12778   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12779    && !COMMUTATIVE_ARITH_P (operands[3])"
12780   "* return output_387_binary_op (insn, operands);"
12781   [(set (attr "type")
12782         (cond [(match_operand:MODEF 3 "mult_operator" "")
12783                  (const_string "ssemul")
12784                (match_operand:MODEF 3 "div_operator" "")
12785                  (const_string "ssediv")
12786               ]
12787               (const_string "sseadd")))
12788    (set_attr "mode" "<MODE>")])
12789
12790 ;; This pattern is not fully shadowed by the pattern above.
12791 (define_insn "*fop_<mode>_1_i387"
12792   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12793         (match_operator:MODEF 3 "binary_fp_operator"
12794           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
12795            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
12796   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12797    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
12798    && !COMMUTATIVE_ARITH_P (operands[3])
12799    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12800   "* return output_387_binary_op (insn, operands);"
12801   [(set (attr "type")
12802         (cond [(match_operand:MODEF 3 "mult_operator" "")
12803                  (const_string "fmul")
12804                (match_operand:MODEF 3 "div_operator" "")
12805                  (const_string "fdiv")
12806               ]
12807               (const_string "fop")))
12808    (set_attr "mode" "<MODE>")])
12809
12810 ;; ??? Add SSE splitters for these!
12811 (define_insn "*fop_<MODEF:mode>_2_i387"
12812   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12813         (match_operator:MODEF 3 "binary_fp_operator"
12814           [(float:MODEF
12815              (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
12816            (match_operand:MODEF 2 "register_operand" "0,0")]))]
12817   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
12818    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12819    && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12820   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12821   [(set (attr "type")
12822         (cond [(match_operand:MODEF 3 "mult_operator" "")
12823                  (const_string "fmul")
12824                (match_operand:MODEF 3 "div_operator" "")
12825                  (const_string "fdiv")
12826               ]
12827               (const_string "fop")))
12828    (set_attr "fp_int_src" "true")
12829    (set_attr "mode" "<X87MODEI12:MODE>")])
12830
12831 (define_insn "*fop_<MODEF:mode>_3_i387"
12832   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12833         (match_operator:MODEF 3 "binary_fp_operator"
12834           [(match_operand:MODEF 1 "register_operand" "0,0")
12835            (float:MODEF
12836              (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
12837   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
12838    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12839    && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12840   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12841   [(set (attr "type")
12842         (cond [(match_operand:MODEF 3 "mult_operator" "")
12843                  (const_string "fmul")
12844                (match_operand:MODEF 3 "div_operator" "")
12845                  (const_string "fdiv")
12846               ]
12847               (const_string "fop")))
12848    (set_attr "fp_int_src" "true")
12849    (set_attr "mode" "<MODE>")])
12850
12851 (define_insn "*fop_df_4_i387"
12852   [(set (match_operand:DF 0 "register_operand" "=f,f")
12853         (match_operator:DF 3 "binary_fp_operator"
12854            [(float_extend:DF
12855              (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
12856             (match_operand:DF 2 "register_operand" "0,f")]))]
12857   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12858    && !(TARGET_SSE2 && TARGET_SSE_MATH)
12859    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12860   "* return output_387_binary_op (insn, operands);"
12861   [(set (attr "type")
12862         (cond [(match_operand:DF 3 "mult_operator" "")
12863                  (const_string "fmul")
12864                (match_operand:DF 3 "div_operator" "")
12865                  (const_string "fdiv")
12866               ]
12867               (const_string "fop")))
12868    (set_attr "mode" "SF")])
12869
12870 (define_insn "*fop_df_5_i387"
12871   [(set (match_operand:DF 0 "register_operand" "=f,f")
12872         (match_operator:DF 3 "binary_fp_operator"
12873           [(match_operand:DF 1 "register_operand" "0,f")
12874            (float_extend:DF
12875             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12876   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12877    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12878   "* return output_387_binary_op (insn, operands);"
12879   [(set (attr "type")
12880         (cond [(match_operand:DF 3 "mult_operator" "")
12881                  (const_string "fmul")
12882                (match_operand:DF 3 "div_operator" "")
12883                  (const_string "fdiv")
12884               ]
12885               (const_string "fop")))
12886    (set_attr "mode" "SF")])
12887
12888 (define_insn "*fop_df_6_i387"
12889   [(set (match_operand:DF 0 "register_operand" "=f,f")
12890         (match_operator:DF 3 "binary_fp_operator"
12891           [(float_extend:DF
12892             (match_operand:SF 1 "register_operand" "0,f"))
12893            (float_extend:DF
12894             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12895   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12896    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12897   "* return output_387_binary_op (insn, operands);"
12898   [(set (attr "type")
12899         (cond [(match_operand:DF 3 "mult_operator" "")
12900                  (const_string "fmul")
12901                (match_operand:DF 3 "div_operator" "")
12902                  (const_string "fdiv")
12903               ]
12904               (const_string "fop")))
12905    (set_attr "mode" "SF")])
12906
12907 (define_insn "*fop_xf_comm_i387"
12908   [(set (match_operand:XF 0 "register_operand" "=f")
12909         (match_operator:XF 3 "binary_fp_operator"
12910                         [(match_operand:XF 1 "register_operand" "%0")
12911                          (match_operand:XF 2 "register_operand" "f")]))]
12912   "TARGET_80387
12913    && COMMUTATIVE_ARITH_P (operands[3])"
12914   "* return output_387_binary_op (insn, operands);"
12915   [(set (attr "type")
12916         (if_then_else (match_operand:XF 3 "mult_operator" "")
12917            (const_string "fmul")
12918            (const_string "fop")))
12919    (set_attr "mode" "XF")])
12920
12921 (define_insn "*fop_xf_1_i387"
12922   [(set (match_operand:XF 0 "register_operand" "=f,f")
12923         (match_operator:XF 3 "binary_fp_operator"
12924                         [(match_operand:XF 1 "register_operand" "0,f")
12925                          (match_operand:XF 2 "register_operand" "f,0")]))]
12926   "TARGET_80387
12927    && !COMMUTATIVE_ARITH_P (operands[3])"
12928   "* return output_387_binary_op (insn, operands);"
12929   [(set (attr "type")
12930         (cond [(match_operand:XF 3 "mult_operator" "")
12931                  (const_string "fmul")
12932                (match_operand:XF 3 "div_operator" "")
12933                  (const_string "fdiv")
12934               ]
12935               (const_string "fop")))
12936    (set_attr "mode" "XF")])
12937
12938 (define_insn "*fop_xf_2_i387"
12939   [(set (match_operand:XF 0 "register_operand" "=f,f")
12940         (match_operator:XF 3 "binary_fp_operator"
12941           [(float:XF
12942              (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
12943            (match_operand:XF 2 "register_operand" "0,0")]))]
12944   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12945   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12946   [(set (attr "type")
12947         (cond [(match_operand:XF 3 "mult_operator" "")
12948                  (const_string "fmul")
12949                (match_operand:XF 3 "div_operator" "")
12950                  (const_string "fdiv")
12951               ]
12952               (const_string "fop")))
12953    (set_attr "fp_int_src" "true")
12954    (set_attr "mode" "<MODE>")])
12955
12956 (define_insn "*fop_xf_3_i387"
12957   [(set (match_operand:XF 0 "register_operand" "=f,f")
12958         (match_operator:XF 3 "binary_fp_operator"
12959           [(match_operand:XF 1 "register_operand" "0,0")
12960            (float:XF
12961              (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
12962   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12963   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12964   [(set (attr "type")
12965         (cond [(match_operand:XF 3 "mult_operator" "")
12966                  (const_string "fmul")
12967                (match_operand:XF 3 "div_operator" "")
12968                  (const_string "fdiv")
12969               ]
12970               (const_string "fop")))
12971    (set_attr "fp_int_src" "true")
12972    (set_attr "mode" "<MODE>")])
12973
12974 (define_insn "*fop_xf_4_i387"
12975   [(set (match_operand:XF 0 "register_operand" "=f,f")
12976         (match_operator:XF 3 "binary_fp_operator"
12977            [(float_extend:XF
12978               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
12979             (match_operand:XF 2 "register_operand" "0,f")]))]
12980   "TARGET_80387"
12981   "* return output_387_binary_op (insn, operands);"
12982   [(set (attr "type")
12983         (cond [(match_operand:XF 3 "mult_operator" "")
12984                  (const_string "fmul")
12985                (match_operand:XF 3 "div_operator" "")
12986                  (const_string "fdiv")
12987               ]
12988               (const_string "fop")))
12989    (set_attr "mode" "<MODE>")])
12990
12991 (define_insn "*fop_xf_5_i387"
12992   [(set (match_operand:XF 0 "register_operand" "=f,f")
12993         (match_operator:XF 3 "binary_fp_operator"
12994           [(match_operand:XF 1 "register_operand" "0,f")
12995            (float_extend:XF
12996              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
12997   "TARGET_80387"
12998   "* return output_387_binary_op (insn, operands);"
12999   [(set (attr "type")
13000         (cond [(match_operand:XF 3 "mult_operator" "")
13001                  (const_string "fmul")
13002                (match_operand:XF 3 "div_operator" "")
13003                  (const_string "fdiv")
13004               ]
13005               (const_string "fop")))
13006    (set_attr "mode" "<MODE>")])
13007
13008 (define_insn "*fop_xf_6_i387"
13009   [(set (match_operand:XF 0 "register_operand" "=f,f")
13010         (match_operator:XF 3 "binary_fp_operator"
13011           [(float_extend:XF
13012              (match_operand:MODEF 1 "register_operand" "0,f"))
13013            (float_extend:XF
13014              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13015   "TARGET_80387"
13016   "* return output_387_binary_op (insn, operands);"
13017   [(set (attr "type")
13018         (cond [(match_operand:XF 3 "mult_operator" "")
13019                  (const_string "fmul")
13020                (match_operand:XF 3 "div_operator" "")
13021                  (const_string "fdiv")
13022               ]
13023               (const_string "fop")))
13024    (set_attr "mode" "<MODE>")])
13025
13026 (define_split
13027   [(set (match_operand 0 "register_operand" "")
13028         (match_operator 3 "binary_fp_operator"
13029            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
13030             (match_operand 2 "register_operand" "")]))]
13031   "reload_completed
13032    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13033    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13034   [(const_int 0)]
13035 {
13036   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13037   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13038   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13039                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
13040                                           GET_MODE (operands[3]),
13041                                           operands[4],
13042                                           operands[2])));
13043   ix86_free_from_memory (GET_MODE (operands[1]));
13044   DONE;
13045 })
13046
13047 (define_split
13048   [(set (match_operand 0 "register_operand" "")
13049         (match_operator 3 "binary_fp_operator"
13050            [(match_operand 1 "register_operand" "")
13051             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
13052   "reload_completed
13053    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13054    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13055   [(const_int 0)]
13056 {
13057   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13058   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13059   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13060                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
13061                                           GET_MODE (operands[3]),
13062                                           operands[1],
13063                                           operands[4])));
13064   ix86_free_from_memory (GET_MODE (operands[2]));
13065   DONE;
13066 })
13067 \f
13068 ;; FPU special functions.
13069
13070 ;; This pattern implements a no-op XFmode truncation for
13071 ;; all fancy i386 XFmode math functions.
13072
13073 (define_insn "truncxf<mode>2_i387_noop_unspec"
13074   [(set (match_operand:MODEF 0 "register_operand" "=f")
13075         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13076         UNSPEC_TRUNC_NOOP))]
13077   "TARGET_USE_FANCY_MATH_387"
13078   "* return output_387_reg_move (insn, operands);"
13079   [(set_attr "type" "fmov")
13080    (set_attr "mode" "<MODE>")])
13081
13082 (define_insn "sqrtxf2"
13083   [(set (match_operand:XF 0 "register_operand" "=f")
13084         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13085   "TARGET_USE_FANCY_MATH_387"
13086   "fsqrt"
13087   [(set_attr "type" "fpspc")
13088    (set_attr "mode" "XF")
13089    (set_attr "athlon_decode" "direct")
13090    (set_attr "amdfam10_decode" "direct")])
13091
13092 (define_insn "sqrt_extend<mode>xf2_i387"
13093   [(set (match_operand:XF 0 "register_operand" "=f")
13094         (sqrt:XF
13095           (float_extend:XF
13096             (match_operand:MODEF 1 "register_operand" "0"))))]
13097   "TARGET_USE_FANCY_MATH_387"
13098   "fsqrt"
13099   [(set_attr "type" "fpspc")
13100    (set_attr "mode" "XF")
13101    (set_attr "athlon_decode" "direct")
13102    (set_attr "amdfam10_decode" "direct")])
13103
13104 (define_insn "*rsqrtsf2_sse"
13105   [(set (match_operand:SF 0 "register_operand" "=x")
13106         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13107                    UNSPEC_RSQRT))]
13108   "TARGET_SSE_MATH"
13109   "%vrsqrtss\t{%1, %d0|%d0, %1}"
13110   [(set_attr "type" "sse")
13111    (set_attr "atom_sse_attr" "rcp")
13112    (set_attr "prefix" "maybe_vex")
13113    (set_attr "mode" "SF")])
13114
13115 (define_expand "rsqrtsf2"
13116   [(set (match_operand:SF 0 "register_operand" "")
13117         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
13118                    UNSPEC_RSQRT))]
13119   "TARGET_SSE_MATH"
13120 {
13121   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13122   DONE;
13123 })
13124
13125 (define_insn "*sqrt<mode>2_sse"
13126   [(set (match_operand:MODEF 0 "register_operand" "=x")
13127         (sqrt:MODEF
13128           (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13129   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13130   "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}"
13131   [(set_attr "type" "sse")
13132    (set_attr "atom_sse_attr" "sqrt")
13133    (set_attr "prefix" "maybe_vex")
13134    (set_attr "mode" "<MODE>")
13135    (set_attr "athlon_decode" "*")
13136    (set_attr "amdfam10_decode" "*")])
13137
13138 (define_expand "sqrt<mode>2"
13139   [(set (match_operand:MODEF 0 "register_operand" "")
13140         (sqrt:MODEF
13141           (match_operand:MODEF 1 "nonimmediate_operand" "")))]
13142   "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13143    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13144 {
13145   if (<MODE>mode == SFmode
13146       && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
13147       && flag_finite_math_only && !flag_trapping_math
13148       && flag_unsafe_math_optimizations)
13149     {
13150       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13151       DONE;
13152     }
13153
13154   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13155     {
13156       rtx op0 = gen_reg_rtx (XFmode);
13157       rtx op1 = force_reg (<MODE>mode, operands[1]);
13158
13159       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13160       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13161       DONE;
13162    }
13163 })
13164
13165 (define_insn "fpremxf4_i387"
13166   [(set (match_operand:XF 0 "register_operand" "=f")
13167         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13168                     (match_operand:XF 3 "register_operand" "1")]
13169                    UNSPEC_FPREM_F))
13170    (set (match_operand:XF 1 "register_operand" "=u")
13171         (unspec:XF [(match_dup 2) (match_dup 3)]
13172                    UNSPEC_FPREM_U))
13173    (set (reg:CCFP FPSR_REG)
13174         (unspec:CCFP [(match_dup 2) (match_dup 3)]
13175                      UNSPEC_C2_FLAG))]
13176   "TARGET_USE_FANCY_MATH_387"
13177   "fprem"
13178   [(set_attr "type" "fpspc")
13179    (set_attr "mode" "XF")])
13180
13181 (define_expand "fmodxf3"
13182   [(use (match_operand:XF 0 "register_operand" ""))
13183    (use (match_operand:XF 1 "general_operand" ""))
13184    (use (match_operand:XF 2 "general_operand" ""))]
13185   "TARGET_USE_FANCY_MATH_387"
13186 {
13187   rtx label = gen_label_rtx ();
13188
13189   rtx op1 = gen_reg_rtx (XFmode);
13190   rtx op2 = gen_reg_rtx (XFmode);
13191
13192   emit_move_insn (op2, operands[2]);
13193   emit_move_insn (op1, operands[1]);
13194
13195   emit_label (label);
13196   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13197   ix86_emit_fp_unordered_jump (label);
13198   LABEL_NUSES (label) = 1;
13199
13200   emit_move_insn (operands[0], op1);
13201   DONE;
13202 })
13203
13204 (define_expand "fmod<mode>3"
13205   [(use (match_operand:MODEF 0 "register_operand" ""))
13206    (use (match_operand:MODEF 1 "general_operand" ""))
13207    (use (match_operand:MODEF 2 "general_operand" ""))]
13208   "TARGET_USE_FANCY_MATH_387"
13209 {
13210   rtx label = gen_label_rtx ();
13211
13212   rtx op1 = gen_reg_rtx (XFmode);
13213   rtx op2 = gen_reg_rtx (XFmode);
13214
13215   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13216   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13217
13218   emit_label (label);
13219   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13220   ix86_emit_fp_unordered_jump (label);
13221   LABEL_NUSES (label) = 1;
13222
13223   /* Truncate the result properly for strict SSE math.  */
13224   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13225       && !TARGET_MIX_SSE_I387)
13226     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
13227   else
13228     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
13229
13230   DONE;
13231 })
13232
13233 (define_insn "fprem1xf4_i387"
13234   [(set (match_operand:XF 0 "register_operand" "=f")
13235         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13236                     (match_operand:XF 3 "register_operand" "1")]
13237                    UNSPEC_FPREM1_F))
13238    (set (match_operand:XF 1 "register_operand" "=u")
13239         (unspec:XF [(match_dup 2) (match_dup 3)]
13240                    UNSPEC_FPREM1_U))
13241    (set (reg:CCFP FPSR_REG)
13242         (unspec:CCFP [(match_dup 2) (match_dup 3)]
13243                      UNSPEC_C2_FLAG))]
13244   "TARGET_USE_FANCY_MATH_387"
13245   "fprem1"
13246   [(set_attr "type" "fpspc")
13247    (set_attr "mode" "XF")])
13248
13249 (define_expand "remainderxf3"
13250   [(use (match_operand:XF 0 "register_operand" ""))
13251    (use (match_operand:XF 1 "general_operand" ""))
13252    (use (match_operand:XF 2 "general_operand" ""))]
13253   "TARGET_USE_FANCY_MATH_387"
13254 {
13255   rtx label = gen_label_rtx ();
13256
13257   rtx op1 = gen_reg_rtx (XFmode);
13258   rtx op2 = gen_reg_rtx (XFmode);
13259
13260   emit_move_insn (op2, operands[2]);
13261   emit_move_insn (op1, operands[1]);
13262
13263   emit_label (label);
13264   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13265   ix86_emit_fp_unordered_jump (label);
13266   LABEL_NUSES (label) = 1;
13267
13268   emit_move_insn (operands[0], op1);
13269   DONE;
13270 })
13271
13272 (define_expand "remainder<mode>3"
13273   [(use (match_operand:MODEF 0 "register_operand" ""))
13274    (use (match_operand:MODEF 1 "general_operand" ""))
13275    (use (match_operand:MODEF 2 "general_operand" ""))]
13276   "TARGET_USE_FANCY_MATH_387"
13277 {
13278   rtx label = gen_label_rtx ();
13279
13280   rtx op1 = gen_reg_rtx (XFmode);
13281   rtx op2 = gen_reg_rtx (XFmode);
13282
13283   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13284   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13285
13286   emit_label (label);
13287
13288   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13289   ix86_emit_fp_unordered_jump (label);
13290   LABEL_NUSES (label) = 1;
13291
13292   /* Truncate the result properly for strict SSE math.  */
13293   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13294       && !TARGET_MIX_SSE_I387)
13295     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
13296   else
13297     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
13298
13299   DONE;
13300 })
13301
13302 (define_insn "*sinxf2_i387"
13303   [(set (match_operand:XF 0 "register_operand" "=f")
13304         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13305   "TARGET_USE_FANCY_MATH_387
13306    && flag_unsafe_math_optimizations"
13307   "fsin"
13308   [(set_attr "type" "fpspc")
13309    (set_attr "mode" "XF")])
13310
13311 (define_insn "*sin_extend<mode>xf2_i387"
13312   [(set (match_operand:XF 0 "register_operand" "=f")
13313         (unspec:XF [(float_extend:XF
13314                       (match_operand:MODEF 1 "register_operand" "0"))]
13315                    UNSPEC_SIN))]
13316   "TARGET_USE_FANCY_MATH_387
13317    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13318        || TARGET_MIX_SSE_I387)
13319    && flag_unsafe_math_optimizations"
13320   "fsin"
13321   [(set_attr "type" "fpspc")
13322    (set_attr "mode" "XF")])
13323
13324 (define_insn "*cosxf2_i387"
13325   [(set (match_operand:XF 0 "register_operand" "=f")
13326         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13327   "TARGET_USE_FANCY_MATH_387
13328    && flag_unsafe_math_optimizations"
13329   "fcos"
13330   [(set_attr "type" "fpspc")
13331    (set_attr "mode" "XF")])
13332
13333 (define_insn "*cos_extend<mode>xf2_i387"
13334   [(set (match_operand:XF 0 "register_operand" "=f")
13335         (unspec:XF [(float_extend:XF
13336                       (match_operand:MODEF 1 "register_operand" "0"))]
13337                    UNSPEC_COS))]
13338   "TARGET_USE_FANCY_MATH_387
13339    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13340        || TARGET_MIX_SSE_I387)
13341    && flag_unsafe_math_optimizations"
13342   "fcos"
13343   [(set_attr "type" "fpspc")
13344    (set_attr "mode" "XF")])
13345
13346 ;; When sincos pattern is defined, sin and cos builtin functions will be
13347 ;; expanded to sincos pattern with one of its outputs left unused.
13348 ;; CSE pass will figure out if two sincos patterns can be combined,
13349 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13350 ;; depending on the unused output.
13351
13352 (define_insn "sincosxf3"
13353   [(set (match_operand:XF 0 "register_operand" "=f")
13354         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13355                    UNSPEC_SINCOS_COS))
13356    (set (match_operand:XF 1 "register_operand" "=u")
13357         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13358   "TARGET_USE_FANCY_MATH_387
13359    && flag_unsafe_math_optimizations"
13360   "fsincos"
13361   [(set_attr "type" "fpspc")
13362    (set_attr "mode" "XF")])
13363
13364 (define_split
13365   [(set (match_operand:XF 0 "register_operand" "")
13366         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13367                    UNSPEC_SINCOS_COS))
13368    (set (match_operand:XF 1 "register_operand" "")
13369         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13370   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13371    && !(reload_completed || reload_in_progress)"
13372   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
13373   "")
13374
13375 (define_split
13376   [(set (match_operand:XF 0 "register_operand" "")
13377         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13378                    UNSPEC_SINCOS_COS))
13379    (set (match_operand:XF 1 "register_operand" "")
13380         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13381   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13382    && !(reload_completed || reload_in_progress)"
13383   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
13384   "")
13385
13386 (define_insn "sincos_extend<mode>xf3_i387"
13387   [(set (match_operand:XF 0 "register_operand" "=f")
13388         (unspec:XF [(float_extend:XF
13389                       (match_operand:MODEF 2 "register_operand" "0"))]
13390                    UNSPEC_SINCOS_COS))
13391    (set (match_operand:XF 1 "register_operand" "=u")
13392         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13393   "TARGET_USE_FANCY_MATH_387
13394    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13395        || TARGET_MIX_SSE_I387)
13396    && flag_unsafe_math_optimizations"
13397   "fsincos"
13398   [(set_attr "type" "fpspc")
13399    (set_attr "mode" "XF")])
13400
13401 (define_split
13402   [(set (match_operand:XF 0 "register_operand" "")
13403         (unspec:XF [(float_extend:XF
13404                       (match_operand:MODEF 2 "register_operand" ""))]
13405                    UNSPEC_SINCOS_COS))
13406    (set (match_operand:XF 1 "register_operand" "")
13407         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13408   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13409    && !(reload_completed || reload_in_progress)"
13410   [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
13411   "")
13412
13413 (define_split
13414   [(set (match_operand:XF 0 "register_operand" "")
13415         (unspec:XF [(float_extend:XF
13416                       (match_operand:MODEF 2 "register_operand" ""))]
13417                    UNSPEC_SINCOS_COS))
13418    (set (match_operand:XF 1 "register_operand" "")
13419         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13420   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13421    && !(reload_completed || reload_in_progress)"
13422   [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
13423   "")
13424
13425 (define_expand "sincos<mode>3"
13426   [(use (match_operand:MODEF 0 "register_operand" ""))
13427    (use (match_operand:MODEF 1 "register_operand" ""))
13428    (use (match_operand:MODEF 2 "register_operand" ""))]
13429   "TARGET_USE_FANCY_MATH_387
13430    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13431        || TARGET_MIX_SSE_I387)
13432    && flag_unsafe_math_optimizations"
13433 {
13434   rtx op0 = gen_reg_rtx (XFmode);
13435   rtx op1 = gen_reg_rtx (XFmode);
13436
13437   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13438   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13439   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13440   DONE;
13441 })
13442
13443 (define_insn "fptanxf4_i387"
13444   [(set (match_operand:XF 0 "register_operand" "=f")
13445         (match_operand:XF 3 "const_double_operand" "F"))
13446    (set (match_operand:XF 1 "register_operand" "=u")
13447         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13448                    UNSPEC_TAN))]
13449   "TARGET_USE_FANCY_MATH_387
13450    && flag_unsafe_math_optimizations
13451    && standard_80387_constant_p (operands[3]) == 2"
13452   "fptan"
13453   [(set_attr "type" "fpspc")
13454    (set_attr "mode" "XF")])
13455
13456 (define_insn "fptan_extend<mode>xf4_i387"
13457   [(set (match_operand:MODEF 0 "register_operand" "=f")
13458         (match_operand:MODEF 3 "const_double_operand" "F"))
13459    (set (match_operand:XF 1 "register_operand" "=u")
13460         (unspec:XF [(float_extend:XF
13461                       (match_operand:MODEF 2 "register_operand" "0"))]
13462                    UNSPEC_TAN))]
13463   "TARGET_USE_FANCY_MATH_387
13464    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13465        || TARGET_MIX_SSE_I387)
13466    && flag_unsafe_math_optimizations
13467    && standard_80387_constant_p (operands[3]) == 2"
13468   "fptan"
13469   [(set_attr "type" "fpspc")
13470    (set_attr "mode" "XF")])
13471
13472 (define_expand "tanxf2"
13473   [(use (match_operand:XF 0 "register_operand" ""))
13474    (use (match_operand:XF 1 "register_operand" ""))]
13475   "TARGET_USE_FANCY_MATH_387
13476    && flag_unsafe_math_optimizations"
13477 {
13478   rtx one = gen_reg_rtx (XFmode);
13479   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13480
13481   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13482   DONE;
13483 })
13484
13485 (define_expand "tan<mode>2"
13486   [(use (match_operand:MODEF 0 "register_operand" ""))
13487    (use (match_operand:MODEF 1 "register_operand" ""))]
13488   "TARGET_USE_FANCY_MATH_387
13489    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13490        || TARGET_MIX_SSE_I387)
13491    && flag_unsafe_math_optimizations"
13492 {
13493   rtx op0 = gen_reg_rtx (XFmode);
13494
13495   rtx one = gen_reg_rtx (<MODE>mode);
13496   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13497
13498   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13499                                              operands[1], op2));
13500   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13501   DONE;
13502 })
13503
13504 (define_insn "*fpatanxf3_i387"
13505   [(set (match_operand:XF 0 "register_operand" "=f")
13506         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13507                     (match_operand:XF 2 "register_operand" "u")]
13508                    UNSPEC_FPATAN))
13509    (clobber (match_scratch:XF 3 "=2"))]
13510   "TARGET_USE_FANCY_MATH_387
13511    && flag_unsafe_math_optimizations"
13512   "fpatan"
13513   [(set_attr "type" "fpspc")
13514    (set_attr "mode" "XF")])
13515
13516 (define_insn "fpatan_extend<mode>xf3_i387"
13517   [(set (match_operand:XF 0 "register_operand" "=f")
13518         (unspec:XF [(float_extend:XF
13519                       (match_operand:MODEF 1 "register_operand" "0"))
13520                     (float_extend:XF
13521                       (match_operand:MODEF 2 "register_operand" "u"))]
13522                    UNSPEC_FPATAN))
13523    (clobber (match_scratch:XF 3 "=2"))]
13524   "TARGET_USE_FANCY_MATH_387
13525    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13526        || TARGET_MIX_SSE_I387)
13527    && flag_unsafe_math_optimizations"
13528   "fpatan"
13529   [(set_attr "type" "fpspc")
13530    (set_attr "mode" "XF")])
13531
13532 (define_expand "atan2xf3"
13533   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13534                    (unspec:XF [(match_operand:XF 2 "register_operand" "")
13535                                (match_operand:XF 1 "register_operand" "")]
13536                               UNSPEC_FPATAN))
13537               (clobber (match_scratch:XF 3 ""))])]
13538   "TARGET_USE_FANCY_MATH_387
13539    && flag_unsafe_math_optimizations"
13540   "")
13541
13542 (define_expand "atan2<mode>3"
13543   [(use (match_operand:MODEF 0 "register_operand" ""))
13544    (use (match_operand:MODEF 1 "register_operand" ""))
13545    (use (match_operand:MODEF 2 "register_operand" ""))]
13546   "TARGET_USE_FANCY_MATH_387
13547    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13548        || TARGET_MIX_SSE_I387)
13549    && flag_unsafe_math_optimizations"
13550 {
13551   rtx op0 = gen_reg_rtx (XFmode);
13552
13553   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13554   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13555   DONE;
13556 })
13557
13558 (define_expand "atanxf2"
13559   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13560                    (unspec:XF [(match_dup 2)
13561                                (match_operand:XF 1 "register_operand" "")]
13562                               UNSPEC_FPATAN))
13563               (clobber (match_scratch:XF 3 ""))])]
13564   "TARGET_USE_FANCY_MATH_387
13565    && flag_unsafe_math_optimizations"
13566 {
13567   operands[2] = gen_reg_rtx (XFmode);
13568   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
13569 })
13570
13571 (define_expand "atan<mode>2"
13572   [(use (match_operand:MODEF 0 "register_operand" ""))
13573    (use (match_operand:MODEF 1 "register_operand" ""))]
13574   "TARGET_USE_FANCY_MATH_387
13575    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13576        || TARGET_MIX_SSE_I387)
13577    && flag_unsafe_math_optimizations"
13578 {
13579   rtx op0 = gen_reg_rtx (XFmode);
13580
13581   rtx op2 = gen_reg_rtx (<MODE>mode);
13582   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
13583
13584   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13585   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13586   DONE;
13587 })
13588
13589 (define_expand "asinxf2"
13590   [(set (match_dup 2)
13591         (mult:XF (match_operand:XF 1 "register_operand" "")
13592                  (match_dup 1)))
13593    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13594    (set (match_dup 5) (sqrt:XF (match_dup 4)))
13595    (parallel [(set (match_operand:XF 0 "register_operand" "")
13596                    (unspec:XF [(match_dup 5) (match_dup 1)]
13597                               UNSPEC_FPATAN))
13598               (clobber (match_scratch:XF 6 ""))])]
13599   "TARGET_USE_FANCY_MATH_387
13600    && flag_unsafe_math_optimizations"
13601 {
13602   int i;
13603
13604   if (optimize_insn_for_size_p ())
13605     FAIL;
13606
13607   for (i = 2; i < 6; i++)
13608     operands[i] = gen_reg_rtx (XFmode);
13609
13610   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
13611 })
13612
13613 (define_expand "asin<mode>2"
13614   [(use (match_operand:MODEF 0 "register_operand" ""))
13615    (use (match_operand:MODEF 1 "general_operand" ""))]
13616  "TARGET_USE_FANCY_MATH_387
13617    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13618        || TARGET_MIX_SSE_I387)
13619    && flag_unsafe_math_optimizations"
13620 {
13621   rtx op0 = gen_reg_rtx (XFmode);
13622   rtx op1 = gen_reg_rtx (XFmode);
13623
13624   if (optimize_insn_for_size_p ())
13625     FAIL;
13626
13627   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13628   emit_insn (gen_asinxf2 (op0, op1));
13629   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13630   DONE;
13631 })
13632
13633 (define_expand "acosxf2"
13634   [(set (match_dup 2)
13635         (mult:XF (match_operand:XF 1 "register_operand" "")
13636                  (match_dup 1)))
13637    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13638    (set (match_dup 5) (sqrt:XF (match_dup 4)))
13639    (parallel [(set (match_operand:XF 0 "register_operand" "")
13640                    (unspec:XF [(match_dup 1) (match_dup 5)]
13641                               UNSPEC_FPATAN))
13642               (clobber (match_scratch:XF 6 ""))])]
13643   "TARGET_USE_FANCY_MATH_387
13644    && flag_unsafe_math_optimizations"
13645 {
13646   int i;
13647
13648   if (optimize_insn_for_size_p ())
13649     FAIL;
13650
13651   for (i = 2; i < 6; i++)
13652     operands[i] = gen_reg_rtx (XFmode);
13653
13654   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
13655 })
13656
13657 (define_expand "acos<mode>2"
13658   [(use (match_operand:MODEF 0 "register_operand" ""))
13659    (use (match_operand:MODEF 1 "general_operand" ""))]
13660  "TARGET_USE_FANCY_MATH_387
13661    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13662        || TARGET_MIX_SSE_I387)
13663    && flag_unsafe_math_optimizations"
13664 {
13665   rtx op0 = gen_reg_rtx (XFmode);
13666   rtx op1 = gen_reg_rtx (XFmode);
13667
13668   if (optimize_insn_for_size_p ())
13669     FAIL;
13670
13671   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13672   emit_insn (gen_acosxf2 (op0, op1));
13673   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13674   DONE;
13675 })
13676
13677 (define_insn "fyl2xxf3_i387"
13678   [(set (match_operand:XF 0 "register_operand" "=f")
13679         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13680                     (match_operand:XF 2 "register_operand" "u")]
13681                    UNSPEC_FYL2X))
13682    (clobber (match_scratch:XF 3 "=2"))]
13683   "TARGET_USE_FANCY_MATH_387
13684    && flag_unsafe_math_optimizations"
13685   "fyl2x"
13686   [(set_attr "type" "fpspc")
13687    (set_attr "mode" "XF")])
13688
13689 (define_insn "fyl2x_extend<mode>xf3_i387"
13690   [(set (match_operand:XF 0 "register_operand" "=f")
13691         (unspec:XF [(float_extend:XF
13692                       (match_operand:MODEF 1 "register_operand" "0"))
13693                     (match_operand:XF 2 "register_operand" "u")]
13694                    UNSPEC_FYL2X))
13695    (clobber (match_scratch:XF 3 "=2"))]
13696   "TARGET_USE_FANCY_MATH_387
13697    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13698        || TARGET_MIX_SSE_I387)
13699    && flag_unsafe_math_optimizations"
13700   "fyl2x"
13701   [(set_attr "type" "fpspc")
13702    (set_attr "mode" "XF")])
13703
13704 (define_expand "logxf2"
13705   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13706                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
13707                                (match_dup 2)] UNSPEC_FYL2X))
13708               (clobber (match_scratch:XF 3 ""))])]
13709   "TARGET_USE_FANCY_MATH_387
13710    && flag_unsafe_math_optimizations"
13711 {
13712   operands[2] = gen_reg_rtx (XFmode);
13713   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
13714 })
13715
13716 (define_expand "log<mode>2"
13717   [(use (match_operand:MODEF 0 "register_operand" ""))
13718    (use (match_operand:MODEF 1 "register_operand" ""))]
13719   "TARGET_USE_FANCY_MATH_387
13720    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13721        || TARGET_MIX_SSE_I387)
13722    && flag_unsafe_math_optimizations"
13723 {
13724   rtx op0 = gen_reg_rtx (XFmode);
13725
13726   rtx op2 = gen_reg_rtx (XFmode);
13727   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
13728
13729   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13730   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13731   DONE;
13732 })
13733
13734 (define_expand "log10xf2"
13735   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13736                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
13737                                (match_dup 2)] UNSPEC_FYL2X))
13738               (clobber (match_scratch:XF 3 ""))])]
13739   "TARGET_USE_FANCY_MATH_387
13740    && flag_unsafe_math_optimizations"
13741 {
13742   operands[2] = gen_reg_rtx (XFmode);
13743   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
13744 })
13745
13746 (define_expand "log10<mode>2"
13747   [(use (match_operand:MODEF 0 "register_operand" ""))
13748    (use (match_operand:MODEF 1 "register_operand" ""))]
13749   "TARGET_USE_FANCY_MATH_387
13750    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13751        || TARGET_MIX_SSE_I387)
13752    && flag_unsafe_math_optimizations"
13753 {
13754   rtx op0 = gen_reg_rtx (XFmode);
13755
13756   rtx op2 = gen_reg_rtx (XFmode);
13757   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
13758
13759   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13760   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13761   DONE;
13762 })
13763
13764 (define_expand "log2xf2"
13765   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13766                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
13767                                (match_dup 2)] UNSPEC_FYL2X))
13768               (clobber (match_scratch:XF 3 ""))])]
13769   "TARGET_USE_FANCY_MATH_387
13770    && flag_unsafe_math_optimizations"
13771 {
13772   operands[2] = gen_reg_rtx (XFmode);
13773   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13774 })
13775
13776 (define_expand "log2<mode>2"
13777   [(use (match_operand:MODEF 0 "register_operand" ""))
13778    (use (match_operand:MODEF 1 "register_operand" ""))]
13779   "TARGET_USE_FANCY_MATH_387
13780    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13781        || TARGET_MIX_SSE_I387)
13782    && flag_unsafe_math_optimizations"
13783 {
13784   rtx op0 = gen_reg_rtx (XFmode);
13785
13786   rtx op2 = gen_reg_rtx (XFmode);
13787   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
13788
13789   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13790   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13791   DONE;
13792 })
13793
13794 (define_insn "fyl2xp1xf3_i387"
13795   [(set (match_operand:XF 0 "register_operand" "=f")
13796         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13797                     (match_operand:XF 2 "register_operand" "u")]
13798                    UNSPEC_FYL2XP1))
13799    (clobber (match_scratch:XF 3 "=2"))]
13800   "TARGET_USE_FANCY_MATH_387
13801    && flag_unsafe_math_optimizations"
13802   "fyl2xp1"
13803   [(set_attr "type" "fpspc")
13804    (set_attr "mode" "XF")])
13805
13806 (define_insn "fyl2xp1_extend<mode>xf3_i387"
13807   [(set (match_operand:XF 0 "register_operand" "=f")
13808         (unspec:XF [(float_extend:XF
13809                       (match_operand:MODEF 1 "register_operand" "0"))
13810                     (match_operand:XF 2 "register_operand" "u")]
13811                    UNSPEC_FYL2XP1))
13812    (clobber (match_scratch:XF 3 "=2"))]
13813   "TARGET_USE_FANCY_MATH_387
13814    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13815        || TARGET_MIX_SSE_I387)
13816    && flag_unsafe_math_optimizations"
13817   "fyl2xp1"
13818   [(set_attr "type" "fpspc")
13819    (set_attr "mode" "XF")])
13820
13821 (define_expand "log1pxf2"
13822   [(use (match_operand:XF 0 "register_operand" ""))
13823    (use (match_operand:XF 1 "register_operand" ""))]
13824   "TARGET_USE_FANCY_MATH_387
13825    && flag_unsafe_math_optimizations"
13826 {
13827   if (optimize_insn_for_size_p ())
13828     FAIL;
13829
13830   ix86_emit_i387_log1p (operands[0], operands[1]);
13831   DONE;
13832 })
13833
13834 (define_expand "log1p<mode>2"
13835   [(use (match_operand:MODEF 0 "register_operand" ""))
13836    (use (match_operand:MODEF 1 "register_operand" ""))]
13837   "TARGET_USE_FANCY_MATH_387
13838    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13839        || TARGET_MIX_SSE_I387)
13840    && flag_unsafe_math_optimizations"
13841 {
13842   rtx op0;
13843
13844   if (optimize_insn_for_size_p ())
13845     FAIL;
13846
13847   op0 = gen_reg_rtx (XFmode);
13848
13849   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
13850
13851   ix86_emit_i387_log1p (op0, operands[1]);
13852   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13853   DONE;
13854 })
13855
13856 (define_insn "fxtractxf3_i387"
13857   [(set (match_operand:XF 0 "register_operand" "=f")
13858         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13859                    UNSPEC_XTRACT_FRACT))
13860    (set (match_operand:XF 1 "register_operand" "=u")
13861         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
13862   "TARGET_USE_FANCY_MATH_387
13863    && flag_unsafe_math_optimizations"
13864   "fxtract"
13865   [(set_attr "type" "fpspc")
13866    (set_attr "mode" "XF")])
13867
13868 (define_insn "fxtract_extend<mode>xf3_i387"
13869   [(set (match_operand:XF 0 "register_operand" "=f")
13870         (unspec:XF [(float_extend:XF
13871                       (match_operand:MODEF 2 "register_operand" "0"))]
13872                    UNSPEC_XTRACT_FRACT))
13873    (set (match_operand:XF 1 "register_operand" "=u")
13874         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
13875   "TARGET_USE_FANCY_MATH_387
13876    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13877        || TARGET_MIX_SSE_I387)
13878    && flag_unsafe_math_optimizations"
13879   "fxtract"
13880   [(set_attr "type" "fpspc")
13881    (set_attr "mode" "XF")])
13882
13883 (define_expand "logbxf2"
13884   [(parallel [(set (match_dup 2)
13885                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
13886                               UNSPEC_XTRACT_FRACT))
13887               (set (match_operand:XF 0 "register_operand" "")
13888                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
13889   "TARGET_USE_FANCY_MATH_387
13890    && flag_unsafe_math_optimizations"
13891 {
13892   operands[2] = gen_reg_rtx (XFmode);
13893 })
13894
13895 (define_expand "logb<mode>2"
13896   [(use (match_operand:MODEF 0 "register_operand" ""))
13897    (use (match_operand:MODEF 1 "register_operand" ""))]
13898   "TARGET_USE_FANCY_MATH_387
13899    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13900        || TARGET_MIX_SSE_I387)
13901    && flag_unsafe_math_optimizations"
13902 {
13903   rtx op0 = gen_reg_rtx (XFmode);
13904   rtx op1 = gen_reg_rtx (XFmode);
13905
13906   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13907   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
13908   DONE;
13909 })
13910
13911 (define_expand "ilogbxf2"
13912   [(use (match_operand:SI 0 "register_operand" ""))
13913    (use (match_operand:XF 1 "register_operand" ""))]
13914   "TARGET_USE_FANCY_MATH_387
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_fxtractxf3_i387 (op0, op1, operands[1]));
13926   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13927   DONE;
13928 })
13929
13930 (define_expand "ilogb<mode>2"
13931   [(use (match_operand:SI 0 "register_operand" ""))
13932    (use (match_operand:MODEF 1 "register_operand" ""))]
13933   "TARGET_USE_FANCY_MATH_387
13934    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13935        || TARGET_MIX_SSE_I387)
13936    && flag_unsafe_math_optimizations"
13937 {
13938   rtx op0, op1;
13939
13940   if (optimize_insn_for_size_p ())
13941     FAIL;
13942
13943   op0 = gen_reg_rtx (XFmode);
13944   op1 = gen_reg_rtx (XFmode);
13945
13946   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13947   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13948   DONE;
13949 })
13950
13951 (define_insn "*f2xm1xf2_i387"
13952   [(set (match_operand:XF 0 "register_operand" "=f")
13953         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13954                    UNSPEC_F2XM1))]
13955   "TARGET_USE_FANCY_MATH_387
13956    && flag_unsafe_math_optimizations"
13957   "f2xm1"
13958   [(set_attr "type" "fpspc")
13959    (set_attr "mode" "XF")])
13960
13961 (define_insn "*fscalexf4_i387"
13962   [(set (match_operand:XF 0 "register_operand" "=f")
13963         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13964                     (match_operand:XF 3 "register_operand" "1")]
13965                    UNSPEC_FSCALE_FRACT))
13966    (set (match_operand:XF 1 "register_operand" "=u")
13967         (unspec:XF [(match_dup 2) (match_dup 3)]
13968                    UNSPEC_FSCALE_EXP))]
13969   "TARGET_USE_FANCY_MATH_387
13970    && flag_unsafe_math_optimizations"
13971   "fscale"
13972   [(set_attr "type" "fpspc")
13973    (set_attr "mode" "XF")])
13974
13975 (define_expand "expNcorexf3"
13976   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
13977                                (match_operand:XF 2 "register_operand" "")))
13978    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
13979    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
13980    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
13981    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
13982    (parallel [(set (match_operand:XF 0 "register_operand" "")
13983                    (unspec:XF [(match_dup 8) (match_dup 4)]
13984                               UNSPEC_FSCALE_FRACT))
13985               (set (match_dup 9)
13986                    (unspec:XF [(match_dup 8) (match_dup 4)]
13987                               UNSPEC_FSCALE_EXP))])]
13988   "TARGET_USE_FANCY_MATH_387
13989    && flag_unsafe_math_optimizations"
13990 {
13991   int i;
13992
13993   if (optimize_insn_for_size_p ())
13994     FAIL;
13995
13996   for (i = 3; i < 10; i++)
13997     operands[i] = gen_reg_rtx (XFmode);
13998
13999   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
14000 })
14001
14002 (define_expand "expxf2"
14003   [(use (match_operand:XF 0 "register_operand" ""))
14004    (use (match_operand:XF 1 "register_operand" ""))]
14005   "TARGET_USE_FANCY_MATH_387
14006    && flag_unsafe_math_optimizations"
14007 {
14008   rtx op2;
14009
14010   if (optimize_insn_for_size_p ())
14011     FAIL;
14012
14013   op2 = gen_reg_rtx (XFmode);
14014   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14015
14016   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14017   DONE;
14018 })
14019
14020 (define_expand "exp<mode>2"
14021   [(use (match_operand:MODEF 0 "register_operand" ""))
14022    (use (match_operand:MODEF 1 "general_operand" ""))]
14023  "TARGET_USE_FANCY_MATH_387
14024    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14025        || TARGET_MIX_SSE_I387)
14026    && flag_unsafe_math_optimizations"
14027 {
14028   rtx op0, op1;
14029
14030   if (optimize_insn_for_size_p ())
14031     FAIL;
14032
14033   op0 = gen_reg_rtx (XFmode);
14034   op1 = gen_reg_rtx (XFmode);
14035
14036   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14037   emit_insn (gen_expxf2 (op0, op1));
14038   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14039   DONE;
14040 })
14041
14042 (define_expand "exp10xf2"
14043   [(use (match_operand:XF 0 "register_operand" ""))
14044    (use (match_operand:XF 1 "register_operand" ""))]
14045   "TARGET_USE_FANCY_MATH_387
14046    && flag_unsafe_math_optimizations"
14047 {
14048   rtx op2;
14049
14050   if (optimize_insn_for_size_p ())
14051     FAIL;
14052
14053   op2 = gen_reg_rtx (XFmode);
14054   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14055
14056   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14057   DONE;
14058 })
14059
14060 (define_expand "exp10<mode>2"
14061   [(use (match_operand:MODEF 0 "register_operand" ""))
14062    (use (match_operand:MODEF 1 "general_operand" ""))]
14063  "TARGET_USE_FANCY_MATH_387
14064    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14065        || TARGET_MIX_SSE_I387)
14066    && flag_unsafe_math_optimizations"
14067 {
14068   rtx op0, op1;
14069
14070   if (optimize_insn_for_size_p ())
14071     FAIL;
14072
14073   op0 = gen_reg_rtx (XFmode);
14074   op1 = gen_reg_rtx (XFmode);
14075
14076   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14077   emit_insn (gen_exp10xf2 (op0, op1));
14078   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14079   DONE;
14080 })
14081
14082 (define_expand "exp2xf2"
14083   [(use (match_operand:XF 0 "register_operand" ""))
14084    (use (match_operand:XF 1 "register_operand" ""))]
14085   "TARGET_USE_FANCY_MATH_387
14086    && flag_unsafe_math_optimizations"
14087 {
14088   rtx op2;
14089
14090   if (optimize_insn_for_size_p ())
14091     FAIL;
14092
14093   op2 = gen_reg_rtx (XFmode);
14094   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
14095
14096   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14097   DONE;
14098 })
14099
14100 (define_expand "exp2<mode>2"
14101   [(use (match_operand:MODEF 0 "register_operand" ""))
14102    (use (match_operand:MODEF 1 "general_operand" ""))]
14103  "TARGET_USE_FANCY_MATH_387
14104    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14105        || TARGET_MIX_SSE_I387)
14106    && flag_unsafe_math_optimizations"
14107 {
14108   rtx op0, op1;
14109
14110   if (optimize_insn_for_size_p ())
14111     FAIL;
14112
14113   op0 = gen_reg_rtx (XFmode);
14114   op1 = gen_reg_rtx (XFmode);
14115
14116   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14117   emit_insn (gen_exp2xf2 (op0, op1));
14118   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14119   DONE;
14120 })
14121
14122 (define_expand "expm1xf2"
14123   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14124                                (match_dup 2)))
14125    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14126    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14127    (set (match_dup 9) (float_extend:XF (match_dup 13)))
14128    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14129    (parallel [(set (match_dup 7)
14130                    (unspec:XF [(match_dup 6) (match_dup 4)]
14131                               UNSPEC_FSCALE_FRACT))
14132               (set (match_dup 8)
14133                    (unspec:XF [(match_dup 6) (match_dup 4)]
14134                               UNSPEC_FSCALE_EXP))])
14135    (parallel [(set (match_dup 10)
14136                    (unspec:XF [(match_dup 9) (match_dup 8)]
14137                               UNSPEC_FSCALE_FRACT))
14138               (set (match_dup 11)
14139                    (unspec:XF [(match_dup 9) (match_dup 8)]
14140                               UNSPEC_FSCALE_EXP))])
14141    (set (match_dup 12) (minus:XF (match_dup 10)
14142                                  (float_extend:XF (match_dup 13))))
14143    (set (match_operand:XF 0 "register_operand" "")
14144         (plus:XF (match_dup 12) (match_dup 7)))]
14145   "TARGET_USE_FANCY_MATH_387
14146    && flag_unsafe_math_optimizations"
14147 {
14148   int i;
14149
14150   if (optimize_insn_for_size_p ())
14151     FAIL;
14152
14153   for (i = 2; i < 13; i++)
14154     operands[i] = gen_reg_rtx (XFmode);
14155
14156   operands[13]
14157     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14158
14159   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14160 })
14161
14162 (define_expand "expm1<mode>2"
14163   [(use (match_operand:MODEF 0 "register_operand" ""))
14164    (use (match_operand:MODEF 1 "general_operand" ""))]
14165  "TARGET_USE_FANCY_MATH_387
14166    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14167        || TARGET_MIX_SSE_I387)
14168    && flag_unsafe_math_optimizations"
14169 {
14170   rtx op0, op1;
14171
14172   if (optimize_insn_for_size_p ())
14173     FAIL;
14174
14175   op0 = gen_reg_rtx (XFmode);
14176   op1 = gen_reg_rtx (XFmode);
14177
14178   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14179   emit_insn (gen_expm1xf2 (op0, op1));
14180   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14181   DONE;
14182 })
14183
14184 (define_expand "ldexpxf3"
14185   [(set (match_dup 3)
14186         (float:XF (match_operand:SI 2 "register_operand" "")))
14187    (parallel [(set (match_operand:XF 0 " register_operand" "")
14188                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
14189                                (match_dup 3)]
14190                               UNSPEC_FSCALE_FRACT))
14191               (set (match_dup 4)
14192                    (unspec:XF [(match_dup 1) (match_dup 3)]
14193                               UNSPEC_FSCALE_EXP))])]
14194   "TARGET_USE_FANCY_MATH_387
14195    && flag_unsafe_math_optimizations"
14196 {
14197   if (optimize_insn_for_size_p ())
14198     FAIL;
14199
14200   operands[3] = gen_reg_rtx (XFmode);
14201   operands[4] = gen_reg_rtx (XFmode);
14202 })
14203
14204 (define_expand "ldexp<mode>3"
14205   [(use (match_operand:MODEF 0 "register_operand" ""))
14206    (use (match_operand:MODEF 1 "general_operand" ""))
14207    (use (match_operand:SI 2 "register_operand" ""))]
14208  "TARGET_USE_FANCY_MATH_387
14209    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14210        || TARGET_MIX_SSE_I387)
14211    && flag_unsafe_math_optimizations"
14212 {
14213   rtx op0, op1;
14214
14215   if (optimize_insn_for_size_p ())
14216     FAIL;
14217
14218   op0 = gen_reg_rtx (XFmode);
14219   op1 = gen_reg_rtx (XFmode);
14220
14221   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14222   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14223   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14224   DONE;
14225 })
14226
14227 (define_expand "scalbxf3"
14228   [(parallel [(set (match_operand:XF 0 " register_operand" "")
14229                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
14230                                (match_operand:XF 2 "register_operand" "")]
14231                               UNSPEC_FSCALE_FRACT))
14232               (set (match_dup 3)
14233                    (unspec:XF [(match_dup 1) (match_dup 2)]
14234                               UNSPEC_FSCALE_EXP))])]
14235   "TARGET_USE_FANCY_MATH_387
14236    && flag_unsafe_math_optimizations"
14237 {
14238   if (optimize_insn_for_size_p ())
14239     FAIL;
14240
14241   operands[3] = gen_reg_rtx (XFmode);
14242 })
14243
14244 (define_expand "scalb<mode>3"
14245   [(use (match_operand:MODEF 0 "register_operand" ""))
14246    (use (match_operand:MODEF 1 "general_operand" ""))
14247    (use (match_operand:MODEF 2 "general_operand" ""))]
14248  "TARGET_USE_FANCY_MATH_387
14249    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14250        || TARGET_MIX_SSE_I387)
14251    && flag_unsafe_math_optimizations"
14252 {
14253   rtx op0, op1, op2;
14254
14255   if (optimize_insn_for_size_p ())
14256     FAIL;
14257
14258   op0 = gen_reg_rtx (XFmode);
14259   op1 = gen_reg_rtx (XFmode);
14260   op2 = gen_reg_rtx (XFmode);
14261
14262   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14263   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14264   emit_insn (gen_scalbxf3 (op0, op1, op2));
14265   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14266   DONE;
14267 })
14268
14269 (define_expand "significandxf2"
14270   [(parallel [(set (match_operand:XF 0 "register_operand" "")
14271                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14272                               UNSPEC_XTRACT_FRACT))
14273               (set (match_dup 2)
14274                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14275   "TARGET_USE_FANCY_MATH_387
14276    && flag_unsafe_math_optimizations"
14277 {
14278   operands[2] = gen_reg_rtx (XFmode);
14279 })
14280
14281 (define_expand "significand<mode>2"
14282   [(use (match_operand:MODEF 0 "register_operand" ""))
14283    (use (match_operand:MODEF 1 "register_operand" ""))]
14284   "TARGET_USE_FANCY_MATH_387
14285    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14286        || TARGET_MIX_SSE_I387)
14287    && flag_unsafe_math_optimizations"
14288 {
14289   rtx op0 = gen_reg_rtx (XFmode);
14290   rtx op1 = gen_reg_rtx (XFmode);
14291
14292   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14293   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14294   DONE;
14295 })
14296 \f
14297
14298 (define_insn "sse4_1_round<mode>2"
14299   [(set (match_operand:MODEF 0 "register_operand" "=x")
14300         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14301                        (match_operand:SI 2 "const_0_to_15_operand" "n")]
14302                       UNSPEC_ROUND))]
14303   "TARGET_ROUND"
14304   "%vrounds<ssemodefsuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14305   [(set_attr "type" "ssecvt")
14306    (set_attr "prefix_extra" "1")
14307    (set_attr "prefix" "maybe_vex")
14308    (set_attr "mode" "<MODE>")])
14309
14310 (define_insn "rintxf2"
14311   [(set (match_operand:XF 0 "register_operand" "=f")
14312         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14313                    UNSPEC_FRNDINT))]
14314   "TARGET_USE_FANCY_MATH_387
14315    && flag_unsafe_math_optimizations"
14316   "frndint"
14317   [(set_attr "type" "fpspc")
14318    (set_attr "mode" "XF")])
14319
14320 (define_expand "rint<mode>2"
14321   [(use (match_operand:MODEF 0 "register_operand" ""))
14322    (use (match_operand:MODEF 1 "register_operand" ""))]
14323   "(TARGET_USE_FANCY_MATH_387
14324     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14325         || TARGET_MIX_SSE_I387)
14326     && flag_unsafe_math_optimizations)
14327    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14328        && !flag_trapping_math)"
14329 {
14330   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14331       && !flag_trapping_math)
14332     {
14333       if (!TARGET_ROUND && optimize_insn_for_size_p ())
14334         FAIL;
14335       if (TARGET_ROUND)
14336         emit_insn (gen_sse4_1_round<mode>2
14337                    (operands[0], operands[1], GEN_INT (0x04)));
14338       else
14339         ix86_expand_rint (operand0, operand1);
14340     }
14341   else
14342     {
14343       rtx op0 = gen_reg_rtx (XFmode);
14344       rtx op1 = gen_reg_rtx (XFmode);
14345
14346       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14347       emit_insn (gen_rintxf2 (op0, op1));
14348
14349       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14350     }
14351   DONE;
14352 })
14353
14354 (define_expand "round<mode>2"
14355   [(match_operand:MODEF 0 "register_operand" "")
14356    (match_operand:MODEF 1 "nonimmediate_operand" "")]
14357   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14358    && !flag_trapping_math && !flag_rounding_math"
14359 {
14360   if (optimize_insn_for_size_p ())
14361     FAIL;
14362   if (TARGET_64BIT || (<MODE>mode != DFmode))
14363     ix86_expand_round (operand0, operand1);
14364   else
14365     ix86_expand_rounddf_32 (operand0, operand1);
14366   DONE;
14367 })
14368
14369 (define_insn_and_split "*fistdi2_1"
14370   [(set (match_operand:DI 0 "nonimmediate_operand" "")
14371         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14372                    UNSPEC_FIST))]
14373   "TARGET_USE_FANCY_MATH_387
14374    && can_create_pseudo_p ()"
14375   "#"
14376   "&& 1"
14377   [(const_int 0)]
14378 {
14379   if (memory_operand (operands[0], VOIDmode))
14380     emit_insn (gen_fistdi2 (operands[0], operands[1]));
14381   else
14382     {
14383       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14384       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14385                                          operands[2]));
14386     }
14387   DONE;
14388 }
14389   [(set_attr "type" "fpspc")
14390    (set_attr "mode" "DI")])
14391
14392 (define_insn "fistdi2"
14393   [(set (match_operand:DI 0 "memory_operand" "=m")
14394         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14395                    UNSPEC_FIST))
14396    (clobber (match_scratch:XF 2 "=&1f"))]
14397   "TARGET_USE_FANCY_MATH_387"
14398   "* return output_fix_trunc (insn, operands, 0);"
14399   [(set_attr "type" "fpspc")
14400    (set_attr "mode" "DI")])
14401
14402 (define_insn "fistdi2_with_temp"
14403   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14404         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14405                    UNSPEC_FIST))
14406    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14407    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14408   "TARGET_USE_FANCY_MATH_387"
14409   "#"
14410   [(set_attr "type" "fpspc")
14411    (set_attr "mode" "DI")])
14412
14413 (define_split
14414   [(set (match_operand:DI 0 "register_operand" "")
14415         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14416                    UNSPEC_FIST))
14417    (clobber (match_operand:DI 2 "memory_operand" ""))
14418    (clobber (match_scratch 3 ""))]
14419   "reload_completed"
14420   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14421               (clobber (match_dup 3))])
14422    (set (match_dup 0) (match_dup 2))]
14423   "")
14424
14425 (define_split
14426   [(set (match_operand:DI 0 "memory_operand" "")
14427         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14428                    UNSPEC_FIST))
14429    (clobber (match_operand:DI 2 "memory_operand" ""))
14430    (clobber (match_scratch 3 ""))]
14431   "reload_completed"
14432   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14433               (clobber (match_dup 3))])]
14434   "")
14435
14436 (define_insn_and_split "*fist<mode>2_1"
14437   [(set (match_operand:X87MODEI12 0 "register_operand" "")
14438         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14439                            UNSPEC_FIST))]
14440   "TARGET_USE_FANCY_MATH_387
14441    && can_create_pseudo_p ()"
14442   "#"
14443   "&& 1"
14444   [(const_int 0)]
14445 {
14446   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14447   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14448                                         operands[2]));
14449   DONE;
14450 }
14451   [(set_attr "type" "fpspc")
14452    (set_attr "mode" "<MODE>")])
14453
14454 (define_insn "fist<mode>2"
14455   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14456         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14457                            UNSPEC_FIST))]
14458   "TARGET_USE_FANCY_MATH_387"
14459   "* return output_fix_trunc (insn, operands, 0);"
14460   [(set_attr "type" "fpspc")
14461    (set_attr "mode" "<MODE>")])
14462
14463 (define_insn "fist<mode>2_with_temp"
14464   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
14465         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14466                            UNSPEC_FIST))
14467    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
14468   "TARGET_USE_FANCY_MATH_387"
14469   "#"
14470   [(set_attr "type" "fpspc")
14471    (set_attr "mode" "<MODE>")])
14472
14473 (define_split
14474   [(set (match_operand:X87MODEI12 0 "register_operand" "")
14475         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14476                            UNSPEC_FIST))
14477    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14478   "reload_completed"
14479   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
14480    (set (match_dup 0) (match_dup 2))]
14481   "")
14482
14483 (define_split
14484   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14485         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14486                            UNSPEC_FIST))
14487    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14488   "reload_completed"
14489   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
14490   "")
14491
14492 (define_expand "lrintxf<mode>2"
14493   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14494      (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14495                       UNSPEC_FIST))]
14496   "TARGET_USE_FANCY_MATH_387"
14497   "")
14498
14499 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
14500   [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14501      (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
14502                         UNSPEC_FIX_NOTRUNC))]
14503   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14504    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
14505   "")
14506
14507 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
14508   [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14509    (match_operand:MODEF 1 "register_operand" "")]
14510   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14511    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
14512    && !flag_trapping_math && !flag_rounding_math"
14513 {
14514   if (optimize_insn_for_size_p ())
14515     FAIL;
14516   ix86_expand_lround (operand0, operand1);
14517   DONE;
14518 })
14519
14520 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14521 (define_insn_and_split "frndintxf2_floor"
14522   [(set (match_operand:XF 0 "register_operand" "")
14523         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14524          UNSPEC_FRNDINT_FLOOR))
14525    (clobber (reg:CC FLAGS_REG))]
14526   "TARGET_USE_FANCY_MATH_387
14527    && flag_unsafe_math_optimizations
14528    && can_create_pseudo_p ()"
14529   "#"
14530   "&& 1"
14531   [(const_int 0)]
14532 {
14533   ix86_optimize_mode_switching[I387_FLOOR] = 1;
14534
14535   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14536   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14537
14538   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14539                                         operands[2], operands[3]));
14540   DONE;
14541 }
14542   [(set_attr "type" "frndint")
14543    (set_attr "i387_cw" "floor")
14544    (set_attr "mode" "XF")])
14545
14546 (define_insn "frndintxf2_floor_i387"
14547   [(set (match_operand:XF 0 "register_operand" "=f")
14548         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14549          UNSPEC_FRNDINT_FLOOR))
14550    (use (match_operand:HI 2 "memory_operand" "m"))
14551    (use (match_operand:HI 3 "memory_operand" "m"))]
14552   "TARGET_USE_FANCY_MATH_387
14553    && flag_unsafe_math_optimizations"
14554   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14555   [(set_attr "type" "frndint")
14556    (set_attr "i387_cw" "floor")
14557    (set_attr "mode" "XF")])
14558
14559 (define_expand "floorxf2"
14560   [(use (match_operand:XF 0 "register_operand" ""))
14561    (use (match_operand:XF 1 "register_operand" ""))]
14562   "TARGET_USE_FANCY_MATH_387
14563    && flag_unsafe_math_optimizations"
14564 {
14565   if (optimize_insn_for_size_p ())
14566     FAIL;
14567   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14568   DONE;
14569 })
14570
14571 (define_expand "floor<mode>2"
14572   [(use (match_operand:MODEF 0 "register_operand" ""))
14573    (use (match_operand:MODEF 1 "register_operand" ""))]
14574   "(TARGET_USE_FANCY_MATH_387
14575     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14576         || TARGET_MIX_SSE_I387)
14577     && flag_unsafe_math_optimizations)
14578    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14579        && !flag_trapping_math)"
14580 {
14581   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14582       && !flag_trapping_math
14583       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14584     {
14585       if (!TARGET_ROUND && optimize_insn_for_size_p ())
14586         FAIL;
14587       if (TARGET_ROUND)
14588         emit_insn (gen_sse4_1_round<mode>2
14589                    (operands[0], operands[1], GEN_INT (0x01)));
14590       else if (TARGET_64BIT || (<MODE>mode != DFmode))
14591         ix86_expand_floorceil (operand0, operand1, true);
14592       else
14593         ix86_expand_floorceildf_32 (operand0, operand1, true);
14594     }
14595   else
14596     {
14597       rtx op0, op1;
14598
14599       if (optimize_insn_for_size_p ())
14600         FAIL;
14601
14602       op0 = gen_reg_rtx (XFmode);
14603       op1 = gen_reg_rtx (XFmode);
14604       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14605       emit_insn (gen_frndintxf2_floor (op0, op1));
14606
14607       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14608     }
14609   DONE;
14610 })
14611
14612 (define_insn_and_split "*fist<mode>2_floor_1"
14613   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14614         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14615          UNSPEC_FIST_FLOOR))
14616    (clobber (reg:CC FLAGS_REG))]
14617   "TARGET_USE_FANCY_MATH_387
14618    && flag_unsafe_math_optimizations
14619    && can_create_pseudo_p ()"
14620   "#"
14621   "&& 1"
14622   [(const_int 0)]
14623 {
14624   ix86_optimize_mode_switching[I387_FLOOR] = 1;
14625
14626   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14627   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14628   if (memory_operand (operands[0], VOIDmode))
14629     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14630                                       operands[2], operands[3]));
14631   else
14632     {
14633       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14634       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14635                                                   operands[2], operands[3],
14636                                                   operands[4]));
14637     }
14638   DONE;
14639 }
14640   [(set_attr "type" "fistp")
14641    (set_attr "i387_cw" "floor")
14642    (set_attr "mode" "<MODE>")])
14643
14644 (define_insn "fistdi2_floor"
14645   [(set (match_operand:DI 0 "memory_operand" "=m")
14646         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14647          UNSPEC_FIST_FLOOR))
14648    (use (match_operand:HI 2 "memory_operand" "m"))
14649    (use (match_operand:HI 3 "memory_operand" "m"))
14650    (clobber (match_scratch:XF 4 "=&1f"))]
14651   "TARGET_USE_FANCY_MATH_387
14652    && flag_unsafe_math_optimizations"
14653   "* return output_fix_trunc (insn, operands, 0);"
14654   [(set_attr "type" "fistp")
14655    (set_attr "i387_cw" "floor")
14656    (set_attr "mode" "DI")])
14657
14658 (define_insn "fistdi2_floor_with_temp"
14659   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14660         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14661          UNSPEC_FIST_FLOOR))
14662    (use (match_operand:HI 2 "memory_operand" "m,m"))
14663    (use (match_operand:HI 3 "memory_operand" "m,m"))
14664    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14665    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14666   "TARGET_USE_FANCY_MATH_387
14667    && flag_unsafe_math_optimizations"
14668   "#"
14669   [(set_attr "type" "fistp")
14670    (set_attr "i387_cw" "floor")
14671    (set_attr "mode" "DI")])
14672
14673 (define_split
14674   [(set (match_operand:DI 0 "register_operand" "")
14675         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14676          UNSPEC_FIST_FLOOR))
14677    (use (match_operand:HI 2 "memory_operand" ""))
14678    (use (match_operand:HI 3 "memory_operand" ""))
14679    (clobber (match_operand:DI 4 "memory_operand" ""))
14680    (clobber (match_scratch 5 ""))]
14681   "reload_completed"
14682   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14683               (use (match_dup 2))
14684               (use (match_dup 3))
14685               (clobber (match_dup 5))])
14686    (set (match_dup 0) (match_dup 4))]
14687   "")
14688
14689 (define_split
14690   [(set (match_operand:DI 0 "memory_operand" "")
14691         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14692          UNSPEC_FIST_FLOOR))
14693    (use (match_operand:HI 2 "memory_operand" ""))
14694    (use (match_operand:HI 3 "memory_operand" ""))
14695    (clobber (match_operand:DI 4 "memory_operand" ""))
14696    (clobber (match_scratch 5 ""))]
14697   "reload_completed"
14698   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14699               (use (match_dup 2))
14700               (use (match_dup 3))
14701               (clobber (match_dup 5))])]
14702   "")
14703
14704 (define_insn "fist<mode>2_floor"
14705   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14706         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14707          UNSPEC_FIST_FLOOR))
14708    (use (match_operand:HI 2 "memory_operand" "m"))
14709    (use (match_operand:HI 3 "memory_operand" "m"))]
14710   "TARGET_USE_FANCY_MATH_387
14711    && flag_unsafe_math_optimizations"
14712   "* return output_fix_trunc (insn, operands, 0);"
14713   [(set_attr "type" "fistp")
14714    (set_attr "i387_cw" "floor")
14715    (set_attr "mode" "<MODE>")])
14716
14717 (define_insn "fist<mode>2_floor_with_temp"
14718   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
14719         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
14720          UNSPEC_FIST_FLOOR))
14721    (use (match_operand:HI 2 "memory_operand" "m,m"))
14722    (use (match_operand:HI 3 "memory_operand" "m,m"))
14723    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
14724   "TARGET_USE_FANCY_MATH_387
14725    && flag_unsafe_math_optimizations"
14726   "#"
14727   [(set_attr "type" "fistp")
14728    (set_attr "i387_cw" "floor")
14729    (set_attr "mode" "<MODE>")])
14730
14731 (define_split
14732   [(set (match_operand:X87MODEI12 0 "register_operand" "")
14733         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14734          UNSPEC_FIST_FLOOR))
14735    (use (match_operand:HI 2 "memory_operand" ""))
14736    (use (match_operand:HI 3 "memory_operand" ""))
14737    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14738   "reload_completed"
14739   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
14740                                   UNSPEC_FIST_FLOOR))
14741               (use (match_dup 2))
14742               (use (match_dup 3))])
14743    (set (match_dup 0) (match_dup 4))]
14744   "")
14745
14746 (define_split
14747   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14748         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14749          UNSPEC_FIST_FLOOR))
14750    (use (match_operand:HI 2 "memory_operand" ""))
14751    (use (match_operand:HI 3 "memory_operand" ""))
14752    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14753   "reload_completed"
14754   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
14755                                   UNSPEC_FIST_FLOOR))
14756               (use (match_dup 2))
14757               (use (match_dup 3))])]
14758   "")
14759
14760 (define_expand "lfloorxf<mode>2"
14761   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14762                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14763                     UNSPEC_FIST_FLOOR))
14764               (clobber (reg:CC FLAGS_REG))])]
14765   "TARGET_USE_FANCY_MATH_387
14766    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14767    && flag_unsafe_math_optimizations"
14768   "")
14769
14770 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
14771   [(match_operand:SWI48 0 "nonimmediate_operand" "")
14772    (match_operand:MODEF 1 "register_operand" "")]
14773   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14774    && !flag_trapping_math"
14775 {
14776   if (TARGET_64BIT && optimize_insn_for_size_p ())
14777     FAIL;
14778   ix86_expand_lfloorceil (operand0, operand1, true);
14779   DONE;
14780 })
14781
14782 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14783 (define_insn_and_split "frndintxf2_ceil"
14784   [(set (match_operand:XF 0 "register_operand" "")
14785         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14786          UNSPEC_FRNDINT_CEIL))
14787    (clobber (reg:CC FLAGS_REG))]
14788   "TARGET_USE_FANCY_MATH_387
14789    && flag_unsafe_math_optimizations
14790    && can_create_pseudo_p ()"
14791   "#"
14792   "&& 1"
14793   [(const_int 0)]
14794 {
14795   ix86_optimize_mode_switching[I387_CEIL] = 1;
14796
14797   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14798   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14799
14800   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
14801                                        operands[2], operands[3]));
14802   DONE;
14803 }
14804   [(set_attr "type" "frndint")
14805    (set_attr "i387_cw" "ceil")
14806    (set_attr "mode" "XF")])
14807
14808 (define_insn "frndintxf2_ceil_i387"
14809   [(set (match_operand:XF 0 "register_operand" "=f")
14810         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14811          UNSPEC_FRNDINT_CEIL))
14812    (use (match_operand:HI 2 "memory_operand" "m"))
14813    (use (match_operand:HI 3 "memory_operand" "m"))]
14814   "TARGET_USE_FANCY_MATH_387
14815    && flag_unsafe_math_optimizations"
14816   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14817   [(set_attr "type" "frndint")
14818    (set_attr "i387_cw" "ceil")
14819    (set_attr "mode" "XF")])
14820
14821 (define_expand "ceilxf2"
14822   [(use (match_operand:XF 0 "register_operand" ""))
14823    (use (match_operand:XF 1 "register_operand" ""))]
14824   "TARGET_USE_FANCY_MATH_387
14825    && flag_unsafe_math_optimizations"
14826 {
14827   if (optimize_insn_for_size_p ())
14828     FAIL;
14829   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
14830   DONE;
14831 })
14832
14833 (define_expand "ceil<mode>2"
14834   [(use (match_operand:MODEF 0 "register_operand" ""))
14835    (use (match_operand:MODEF 1 "register_operand" ""))]
14836   "(TARGET_USE_FANCY_MATH_387
14837     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14838         || TARGET_MIX_SSE_I387)
14839     && flag_unsafe_math_optimizations)
14840    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14841        && !flag_trapping_math)"
14842 {
14843   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14844       && !flag_trapping_math
14845       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14846     {
14847       if (TARGET_ROUND)
14848         emit_insn (gen_sse4_1_round<mode>2
14849                    (operands[0], operands[1], GEN_INT (0x02)));
14850       else if (optimize_insn_for_size_p ())
14851         FAIL;
14852       else if (TARGET_64BIT || (<MODE>mode != DFmode))
14853         ix86_expand_floorceil (operand0, operand1, false);
14854       else
14855         ix86_expand_floorceildf_32 (operand0, operand1, false);
14856     }
14857   else
14858     {
14859       rtx op0, op1;
14860
14861       if (optimize_insn_for_size_p ())
14862         FAIL;
14863
14864       op0 = gen_reg_rtx (XFmode);
14865       op1 = gen_reg_rtx (XFmode);
14866       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14867       emit_insn (gen_frndintxf2_ceil (op0, op1));
14868
14869       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14870     }
14871   DONE;
14872 })
14873
14874 (define_insn_and_split "*fist<mode>2_ceil_1"
14875   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14876         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14877          UNSPEC_FIST_CEIL))
14878    (clobber (reg:CC FLAGS_REG))]
14879   "TARGET_USE_FANCY_MATH_387
14880    && flag_unsafe_math_optimizations
14881    && can_create_pseudo_p ()"
14882   "#"
14883   "&& 1"
14884   [(const_int 0)]
14885 {
14886   ix86_optimize_mode_switching[I387_CEIL] = 1;
14887
14888   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14889   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14890   if (memory_operand (operands[0], VOIDmode))
14891     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
14892                                      operands[2], operands[3]));
14893   else
14894     {
14895       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14896       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
14897                                                  operands[2], operands[3],
14898                                                  operands[4]));
14899     }
14900   DONE;
14901 }
14902   [(set_attr "type" "fistp")
14903    (set_attr "i387_cw" "ceil")
14904    (set_attr "mode" "<MODE>")])
14905
14906 (define_insn "fistdi2_ceil"
14907   [(set (match_operand:DI 0 "memory_operand" "=m")
14908         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14909          UNSPEC_FIST_CEIL))
14910    (use (match_operand:HI 2 "memory_operand" "m"))
14911    (use (match_operand:HI 3 "memory_operand" "m"))
14912    (clobber (match_scratch:XF 4 "=&1f"))]
14913   "TARGET_USE_FANCY_MATH_387
14914    && flag_unsafe_math_optimizations"
14915   "* return output_fix_trunc (insn, operands, 0);"
14916   [(set_attr "type" "fistp")
14917    (set_attr "i387_cw" "ceil")
14918    (set_attr "mode" "DI")])
14919
14920 (define_insn "fistdi2_ceil_with_temp"
14921   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14922         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14923          UNSPEC_FIST_CEIL))
14924    (use (match_operand:HI 2 "memory_operand" "m,m"))
14925    (use (match_operand:HI 3 "memory_operand" "m,m"))
14926    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14927    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14928   "TARGET_USE_FANCY_MATH_387
14929    && flag_unsafe_math_optimizations"
14930   "#"
14931   [(set_attr "type" "fistp")
14932    (set_attr "i387_cw" "ceil")
14933    (set_attr "mode" "DI")])
14934
14935 (define_split
14936   [(set (match_operand:DI 0 "register_operand" "")
14937         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14938          UNSPEC_FIST_CEIL))
14939    (use (match_operand:HI 2 "memory_operand" ""))
14940    (use (match_operand:HI 3 "memory_operand" ""))
14941    (clobber (match_operand:DI 4 "memory_operand" ""))
14942    (clobber (match_scratch 5 ""))]
14943   "reload_completed"
14944   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
14945               (use (match_dup 2))
14946               (use (match_dup 3))
14947               (clobber (match_dup 5))])
14948    (set (match_dup 0) (match_dup 4))]
14949   "")
14950
14951 (define_split
14952   [(set (match_operand:DI 0 "memory_operand" "")
14953         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14954          UNSPEC_FIST_CEIL))
14955    (use (match_operand:HI 2 "memory_operand" ""))
14956    (use (match_operand:HI 3 "memory_operand" ""))
14957    (clobber (match_operand:DI 4 "memory_operand" ""))
14958    (clobber (match_scratch 5 ""))]
14959   "reload_completed"
14960   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
14961               (use (match_dup 2))
14962               (use (match_dup 3))
14963               (clobber (match_dup 5))])]
14964   "")
14965
14966 (define_insn "fist<mode>2_ceil"
14967   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14968         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14969          UNSPEC_FIST_CEIL))
14970    (use (match_operand:HI 2 "memory_operand" "m"))
14971    (use (match_operand:HI 3 "memory_operand" "m"))]
14972   "TARGET_USE_FANCY_MATH_387
14973    && flag_unsafe_math_optimizations"
14974   "* return output_fix_trunc (insn, operands, 0);"
14975   [(set_attr "type" "fistp")
14976    (set_attr "i387_cw" "ceil")
14977    (set_attr "mode" "<MODE>")])
14978
14979 (define_insn "fist<mode>2_ceil_with_temp"
14980   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
14981         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
14982          UNSPEC_FIST_CEIL))
14983    (use (match_operand:HI 2 "memory_operand" "m,m"))
14984    (use (match_operand:HI 3 "memory_operand" "m,m"))
14985    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
14986   "TARGET_USE_FANCY_MATH_387
14987    && flag_unsafe_math_optimizations"
14988   "#"
14989   [(set_attr "type" "fistp")
14990    (set_attr "i387_cw" "ceil")
14991    (set_attr "mode" "<MODE>")])
14992
14993 (define_split
14994   [(set (match_operand:X87MODEI12 0 "register_operand" "")
14995         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14996          UNSPEC_FIST_CEIL))
14997    (use (match_operand:HI 2 "memory_operand" ""))
14998    (use (match_operand:HI 3 "memory_operand" ""))
14999    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
15000   "reload_completed"
15001   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
15002                                   UNSPEC_FIST_CEIL))
15003               (use (match_dup 2))
15004               (use (match_dup 3))])
15005    (set (match_dup 0) (match_dup 4))]
15006   "")
15007
15008 (define_split
15009   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
15010         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
15011          UNSPEC_FIST_CEIL))
15012    (use (match_operand:HI 2 "memory_operand" ""))
15013    (use (match_operand:HI 3 "memory_operand" ""))
15014    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
15015   "reload_completed"
15016   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
15017                                   UNSPEC_FIST_CEIL))
15018               (use (match_dup 2))
15019               (use (match_dup 3))])]
15020   "")
15021
15022 (define_expand "lceilxf<mode>2"
15023   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
15024                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
15025                     UNSPEC_FIST_CEIL))
15026               (clobber (reg:CC FLAGS_REG))])]
15027   "TARGET_USE_FANCY_MATH_387
15028    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15029    && flag_unsafe_math_optimizations"
15030   "")
15031
15032 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
15033   [(match_operand:SWI48 0 "nonimmediate_operand" "")
15034    (match_operand:MODEF 1 "register_operand" "")]
15035   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15036    && !flag_trapping_math"
15037 {
15038   ix86_expand_lfloorceil (operand0, operand1, false);
15039   DONE;
15040 })
15041
15042 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15043 (define_insn_and_split "frndintxf2_trunc"
15044   [(set (match_operand:XF 0 "register_operand" "")
15045         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15046          UNSPEC_FRNDINT_TRUNC))
15047    (clobber (reg:CC FLAGS_REG))]
15048   "TARGET_USE_FANCY_MATH_387
15049    && flag_unsafe_math_optimizations
15050    && can_create_pseudo_p ()"
15051   "#"
15052   "&& 1"
15053   [(const_int 0)]
15054 {
15055   ix86_optimize_mode_switching[I387_TRUNC] = 1;
15056
15057   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15058   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
15059
15060   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
15061                                         operands[2], operands[3]));
15062   DONE;
15063 }
15064   [(set_attr "type" "frndint")
15065    (set_attr "i387_cw" "trunc")
15066    (set_attr "mode" "XF")])
15067
15068 (define_insn "frndintxf2_trunc_i387"
15069   [(set (match_operand:XF 0 "register_operand" "=f")
15070         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15071          UNSPEC_FRNDINT_TRUNC))
15072    (use (match_operand:HI 2 "memory_operand" "m"))
15073    (use (match_operand:HI 3 "memory_operand" "m"))]
15074   "TARGET_USE_FANCY_MATH_387
15075    && flag_unsafe_math_optimizations"
15076   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15077   [(set_attr "type" "frndint")
15078    (set_attr "i387_cw" "trunc")
15079    (set_attr "mode" "XF")])
15080
15081 (define_expand "btruncxf2"
15082   [(use (match_operand:XF 0 "register_operand" ""))
15083    (use (match_operand:XF 1 "register_operand" ""))]
15084   "TARGET_USE_FANCY_MATH_387
15085    && flag_unsafe_math_optimizations"
15086 {
15087   if (optimize_insn_for_size_p ())
15088     FAIL;
15089   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
15090   DONE;
15091 })
15092
15093 (define_expand "btrunc<mode>2"
15094   [(use (match_operand:MODEF 0 "register_operand" ""))
15095    (use (match_operand:MODEF 1 "register_operand" ""))]
15096   "(TARGET_USE_FANCY_MATH_387
15097     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15098         || TARGET_MIX_SSE_I387)
15099     && flag_unsafe_math_optimizations)
15100    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15101        && !flag_trapping_math)"
15102 {
15103   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15104       && !flag_trapping_math
15105       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
15106     {
15107       if (TARGET_ROUND)
15108         emit_insn (gen_sse4_1_round<mode>2
15109                    (operands[0], operands[1], GEN_INT (0x03)));
15110       else if (optimize_insn_for_size_p ())
15111         FAIL;
15112       else if (TARGET_64BIT || (<MODE>mode != DFmode))
15113         ix86_expand_trunc (operand0, operand1);
15114       else
15115         ix86_expand_truncdf_32 (operand0, operand1);
15116     }
15117   else
15118     {
15119       rtx op0, op1;
15120
15121       if (optimize_insn_for_size_p ())
15122         FAIL;
15123
15124       op0 = gen_reg_rtx (XFmode);
15125       op1 = gen_reg_rtx (XFmode);
15126       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15127       emit_insn (gen_frndintxf2_trunc (op0, op1));
15128
15129       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15130     }
15131   DONE;
15132 })
15133
15134 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15135 (define_insn_and_split "frndintxf2_mask_pm"
15136   [(set (match_operand:XF 0 "register_operand" "")
15137         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15138          UNSPEC_FRNDINT_MASK_PM))
15139    (clobber (reg:CC FLAGS_REG))]
15140   "TARGET_USE_FANCY_MATH_387
15141    && flag_unsafe_math_optimizations
15142    && can_create_pseudo_p ()"
15143   "#"
15144   "&& 1"
15145   [(const_int 0)]
15146 {
15147   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15148
15149   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15150   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15151
15152   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15153                                           operands[2], operands[3]));
15154   DONE;
15155 }
15156   [(set_attr "type" "frndint")
15157    (set_attr "i387_cw" "mask_pm")
15158    (set_attr "mode" "XF")])
15159
15160 (define_insn "frndintxf2_mask_pm_i387"
15161   [(set (match_operand:XF 0 "register_operand" "=f")
15162         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15163          UNSPEC_FRNDINT_MASK_PM))
15164    (use (match_operand:HI 2 "memory_operand" "m"))
15165    (use (match_operand:HI 3 "memory_operand" "m"))]
15166   "TARGET_USE_FANCY_MATH_387
15167    && flag_unsafe_math_optimizations"
15168   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15169   [(set_attr "type" "frndint")
15170    (set_attr "i387_cw" "mask_pm")
15171    (set_attr "mode" "XF")])
15172
15173 (define_expand "nearbyintxf2"
15174   [(use (match_operand:XF 0 "register_operand" ""))
15175    (use (match_operand:XF 1 "register_operand" ""))]
15176   "TARGET_USE_FANCY_MATH_387
15177    && flag_unsafe_math_optimizations"
15178 {
15179   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15180
15181   DONE;
15182 })
15183
15184 (define_expand "nearbyint<mode>2"
15185   [(use (match_operand:MODEF 0 "register_operand" ""))
15186    (use (match_operand:MODEF 1 "register_operand" ""))]
15187   "TARGET_USE_FANCY_MATH_387
15188    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15189        || TARGET_MIX_SSE_I387)
15190    && flag_unsafe_math_optimizations"
15191 {
15192   rtx op0 = gen_reg_rtx (XFmode);
15193   rtx op1 = gen_reg_rtx (XFmode);
15194
15195   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15196   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15197
15198   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15199   DONE;
15200 })
15201
15202 (define_insn "fxam<mode>2_i387"
15203   [(set (match_operand:HI 0 "register_operand" "=a")
15204         (unspec:HI
15205           [(match_operand:X87MODEF 1 "register_operand" "f")]
15206           UNSPEC_FXAM))]
15207   "TARGET_USE_FANCY_MATH_387"
15208   "fxam\n\tfnstsw\t%0"
15209   [(set_attr "type" "multi")
15210    (set_attr "length" "4")
15211    (set_attr "unit" "i387")
15212    (set_attr "mode" "<MODE>")])
15213
15214 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15215   [(set (match_operand:HI 0 "register_operand" "")
15216         (unspec:HI
15217           [(match_operand:MODEF 1 "memory_operand" "")]
15218           UNSPEC_FXAM_MEM))]
15219   "TARGET_USE_FANCY_MATH_387
15220    && can_create_pseudo_p ()"
15221   "#"
15222   "&& 1"
15223   [(set (match_dup 2)(match_dup 1))
15224    (set (match_dup 0)
15225         (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15226 {
15227   operands[2] = gen_reg_rtx (<MODE>mode);
15228
15229   MEM_VOLATILE_P (operands[1]) = 1;
15230 }
15231   [(set_attr "type" "multi")
15232    (set_attr "unit" "i387")
15233    (set_attr "mode" "<MODE>")])
15234
15235 (define_expand "isinfxf2"
15236   [(use (match_operand:SI 0 "register_operand" ""))
15237    (use (match_operand:XF 1 "register_operand" ""))]
15238   "TARGET_USE_FANCY_MATH_387
15239    && TARGET_C99_FUNCTIONS"
15240 {
15241   rtx mask = GEN_INT (0x45);
15242   rtx val = GEN_INT (0x05);
15243
15244   rtx cond;
15245
15246   rtx scratch = gen_reg_rtx (HImode);
15247   rtx res = gen_reg_rtx (QImode);
15248
15249   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15250
15251   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15252   emit_insn (gen_cmpqi_ext_3 (scratch, val));
15253   cond = gen_rtx_fmt_ee (EQ, QImode,
15254                          gen_rtx_REG (CCmode, FLAGS_REG),
15255                          const0_rtx);
15256   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15257   emit_insn (gen_zero_extendqisi2 (operands[0], res));
15258   DONE;
15259 })
15260
15261 (define_expand "isinf<mode>2"
15262   [(use (match_operand:SI 0 "register_operand" ""))
15263    (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15264   "TARGET_USE_FANCY_MATH_387
15265    && TARGET_C99_FUNCTIONS
15266    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15267 {
15268   rtx mask = GEN_INT (0x45);
15269   rtx val = GEN_INT (0x05);
15270
15271   rtx cond;
15272
15273   rtx scratch = gen_reg_rtx (HImode);
15274   rtx res = gen_reg_rtx (QImode);
15275
15276   /* Remove excess precision by forcing value through memory. */
15277   if (memory_operand (operands[1], VOIDmode))
15278     emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15279   else
15280     {
15281       enum ix86_stack_slot slot = (virtuals_instantiated
15282                                    ? SLOT_TEMP
15283                                    : SLOT_VIRTUAL);
15284       rtx temp = assign_386_stack_local (<MODE>mode, slot);
15285
15286       emit_move_insn (temp, operands[1]);
15287       emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15288     }
15289
15290   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15291   emit_insn (gen_cmpqi_ext_3 (scratch, val));
15292   cond = gen_rtx_fmt_ee (EQ, QImode,
15293                          gen_rtx_REG (CCmode, FLAGS_REG),
15294                          const0_rtx);
15295   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15296   emit_insn (gen_zero_extendqisi2 (operands[0], res));
15297   DONE;
15298 })
15299
15300 (define_expand "signbit<mode>2"
15301   [(use (match_operand:SI 0 "register_operand" ""))
15302    (use (match_operand:X87MODEF 1 "register_operand" ""))]
15303   "TARGET_USE_FANCY_MATH_387
15304    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15305 {
15306   rtx mask = GEN_INT (0x0200);
15307
15308   rtx scratch = gen_reg_rtx (HImode);
15309
15310   emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
15311   emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
15312   DONE;
15313 })
15314 \f
15315 ;; Block operation instructions
15316
15317 (define_insn "cld"
15318   [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15319   ""
15320   "cld"
15321   [(set_attr "length" "1")
15322    (set_attr "length_immediate" "0")
15323    (set_attr "modrm" "0")])
15324
15325 (define_expand "movmemsi"
15326   [(use (match_operand:BLK 0 "memory_operand" ""))
15327    (use (match_operand:BLK 1 "memory_operand" ""))
15328    (use (match_operand:SI 2 "nonmemory_operand" ""))
15329    (use (match_operand:SI 3 "const_int_operand" ""))
15330    (use (match_operand:SI 4 "const_int_operand" ""))
15331    (use (match_operand:SI 5 "const_int_operand" ""))]
15332   ""
15333 {
15334  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15335                          operands[4], operands[5]))
15336    DONE;
15337  else
15338    FAIL;
15339 })
15340
15341 (define_expand "movmemdi"
15342   [(use (match_operand:BLK 0 "memory_operand" ""))
15343    (use (match_operand:BLK 1 "memory_operand" ""))
15344    (use (match_operand:DI 2 "nonmemory_operand" ""))
15345    (use (match_operand:DI 3 "const_int_operand" ""))
15346    (use (match_operand:SI 4 "const_int_operand" ""))
15347    (use (match_operand:SI 5 "const_int_operand" ""))]
15348   "TARGET_64BIT"
15349 {
15350  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15351                          operands[4], operands[5]))
15352    DONE;
15353  else
15354    FAIL;
15355 })
15356
15357 ;; Most CPUs don't like single string operations
15358 ;; Handle this case here to simplify previous expander.
15359
15360 (define_expand "strmov"
15361   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15362    (set (match_operand 1 "memory_operand" "") (match_dup 4))
15363    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15364               (clobber (reg:CC FLAGS_REG))])
15365    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15366               (clobber (reg:CC FLAGS_REG))])]
15367   ""
15368 {
15369   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15370
15371   /* If .md ever supports :P for Pmode, these can be directly
15372      in the pattern above.  */
15373   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15374   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15375
15376   /* Can't use this if the user has appropriated esi or edi.  */
15377   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15378       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15379     {
15380       emit_insn (gen_strmov_singleop (operands[0], operands[1],
15381                                       operands[2], operands[3],
15382                                       operands[5], operands[6]));
15383       DONE;
15384     }
15385
15386   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15387 })
15388
15389 (define_expand "strmov_singleop"
15390   [(parallel [(set (match_operand 1 "memory_operand" "")
15391                    (match_operand 3 "memory_operand" ""))
15392               (set (match_operand 0 "register_operand" "")
15393                    (match_operand 4 "" ""))
15394               (set (match_operand 2 "register_operand" "")
15395                    (match_operand 5 "" ""))])]
15396   ""
15397   "ix86_current_function_needs_cld = 1;")
15398
15399 (define_insn "*strmovdi_rex_1"
15400   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15401         (mem:DI (match_operand:DI 3 "register_operand" "1")))
15402    (set (match_operand:DI 0 "register_operand" "=D")
15403         (plus:DI (match_dup 2)
15404                  (const_int 8)))
15405    (set (match_operand:DI 1 "register_operand" "=S")
15406         (plus:DI (match_dup 3)
15407                  (const_int 8)))]
15408   "TARGET_64BIT"
15409   "movsq"
15410   [(set_attr "type" "str")
15411    (set_attr "mode" "DI")
15412    (set_attr "memory" "both")])
15413
15414 (define_insn "*strmovsi_1"
15415   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
15416         (mem:SI (match_operand:SI 3 "register_operand" "1")))
15417    (set (match_operand:SI 0 "register_operand" "=D")
15418         (plus:SI (match_dup 2)
15419                  (const_int 4)))
15420    (set (match_operand:SI 1 "register_operand" "=S")
15421         (plus:SI (match_dup 3)
15422                  (const_int 4)))]
15423   "!TARGET_64BIT"
15424   "movs{l|d}"
15425   [(set_attr "type" "str")
15426    (set_attr "mode" "SI")
15427    (set_attr "memory" "both")])
15428
15429 (define_insn "*strmovsi_rex_1"
15430   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
15431         (mem:SI (match_operand:DI 3 "register_operand" "1")))
15432    (set (match_operand:DI 0 "register_operand" "=D")
15433         (plus:DI (match_dup 2)
15434                  (const_int 4)))
15435    (set (match_operand:DI 1 "register_operand" "=S")
15436         (plus:DI (match_dup 3)
15437                  (const_int 4)))]
15438   "TARGET_64BIT"
15439   "movs{l|d}"
15440   [(set_attr "type" "str")
15441    (set_attr "mode" "SI")
15442    (set_attr "memory" "both")])
15443
15444 (define_insn "*strmovhi_1"
15445   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
15446         (mem:HI (match_operand:SI 3 "register_operand" "1")))
15447    (set (match_operand:SI 0 "register_operand" "=D")
15448         (plus:SI (match_dup 2)
15449                  (const_int 2)))
15450    (set (match_operand:SI 1 "register_operand" "=S")
15451         (plus:SI (match_dup 3)
15452                  (const_int 2)))]
15453   "!TARGET_64BIT"
15454   "movsw"
15455   [(set_attr "type" "str")
15456    (set_attr "memory" "both")
15457    (set_attr "mode" "HI")])
15458
15459 (define_insn "*strmovhi_rex_1"
15460   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
15461         (mem:HI (match_operand:DI 3 "register_operand" "1")))
15462    (set (match_operand:DI 0 "register_operand" "=D")
15463         (plus:DI (match_dup 2)
15464                  (const_int 2)))
15465    (set (match_operand:DI 1 "register_operand" "=S")
15466         (plus:DI (match_dup 3)
15467                  (const_int 2)))]
15468   "TARGET_64BIT"
15469   "movsw"
15470   [(set_attr "type" "str")
15471    (set_attr "memory" "both")
15472    (set_attr "mode" "HI")])
15473
15474 (define_insn "*strmovqi_1"
15475   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
15476         (mem:QI (match_operand:SI 3 "register_operand" "1")))
15477    (set (match_operand:SI 0 "register_operand" "=D")
15478         (plus:SI (match_dup 2)
15479                  (const_int 1)))
15480    (set (match_operand:SI 1 "register_operand" "=S")
15481         (plus:SI (match_dup 3)
15482                  (const_int 1)))]
15483   "!TARGET_64BIT"
15484   "movsb"
15485   [(set_attr "type" "str")
15486    (set_attr "memory" "both")
15487    (set_attr "mode" "QI")])
15488
15489 (define_insn "*strmovqi_rex_1"
15490   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
15491         (mem:QI (match_operand:DI 3 "register_operand" "1")))
15492    (set (match_operand:DI 0 "register_operand" "=D")
15493         (plus:DI (match_dup 2)
15494                  (const_int 1)))
15495    (set (match_operand:DI 1 "register_operand" "=S")
15496         (plus:DI (match_dup 3)
15497                  (const_int 1)))]
15498   "TARGET_64BIT"
15499   "movsb"
15500   [(set_attr "type" "str")
15501    (set_attr "memory" "both")
15502    (set_attr "prefix_rex" "0")
15503    (set_attr "mode" "QI")])
15504
15505 (define_expand "rep_mov"
15506   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15507               (set (match_operand 0 "register_operand" "")
15508                    (match_operand 5 "" ""))
15509               (set (match_operand 2 "register_operand" "")
15510                    (match_operand 6 "" ""))
15511               (set (match_operand 1 "memory_operand" "")
15512                    (match_operand 3 "memory_operand" ""))
15513               (use (match_dup 4))])]
15514   ""
15515   "ix86_current_function_needs_cld = 1;")
15516
15517 (define_insn "*rep_movdi_rex64"
15518   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15519    (set (match_operand:DI 0 "register_operand" "=D")
15520         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15521                             (const_int 3))
15522                  (match_operand:DI 3 "register_operand" "0")))
15523    (set (match_operand:DI 1 "register_operand" "=S")
15524         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15525                  (match_operand:DI 4 "register_operand" "1")))
15526    (set (mem:BLK (match_dup 3))
15527         (mem:BLK (match_dup 4)))
15528    (use (match_dup 5))]
15529   "TARGET_64BIT"
15530   "rep{%;} movsq"
15531   [(set_attr "type" "str")
15532    (set_attr "prefix_rep" "1")
15533    (set_attr "memory" "both")
15534    (set_attr "mode" "DI")])
15535
15536 (define_insn "*rep_movsi"
15537   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
15538    (set (match_operand:SI 0 "register_operand" "=D")
15539         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
15540                             (const_int 2))
15541                  (match_operand:SI 3 "register_operand" "0")))
15542    (set (match_operand:SI 1 "register_operand" "=S")
15543         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
15544                  (match_operand:SI 4 "register_operand" "1")))
15545    (set (mem:BLK (match_dup 3))
15546         (mem:BLK (match_dup 4)))
15547    (use (match_dup 5))]
15548   "!TARGET_64BIT"
15549   "rep{%;} movs{l|d}"
15550   [(set_attr "type" "str")
15551    (set_attr "prefix_rep" "1")
15552    (set_attr "memory" "both")
15553    (set_attr "mode" "SI")])
15554
15555 (define_insn "*rep_movsi_rex64"
15556   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15557    (set (match_operand:DI 0 "register_operand" "=D")
15558         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15559                             (const_int 2))
15560                  (match_operand:DI 3 "register_operand" "0")))
15561    (set (match_operand:DI 1 "register_operand" "=S")
15562         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
15563                  (match_operand:DI 4 "register_operand" "1")))
15564    (set (mem:BLK (match_dup 3))
15565         (mem:BLK (match_dup 4)))
15566    (use (match_dup 5))]
15567   "TARGET_64BIT"
15568   "rep{%;} movs{l|d}"
15569   [(set_attr "type" "str")
15570    (set_attr "prefix_rep" "1")
15571    (set_attr "memory" "both")
15572    (set_attr "mode" "SI")])
15573
15574 (define_insn "*rep_movqi"
15575   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
15576    (set (match_operand:SI 0 "register_operand" "=D")
15577         (plus:SI (match_operand:SI 3 "register_operand" "0")
15578                  (match_operand:SI 5 "register_operand" "2")))
15579    (set (match_operand:SI 1 "register_operand" "=S")
15580         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
15581    (set (mem:BLK (match_dup 3))
15582         (mem:BLK (match_dup 4)))
15583    (use (match_dup 5))]
15584   "!TARGET_64BIT"
15585   "rep{%;} movsb"
15586   [(set_attr "type" "str")
15587    (set_attr "prefix_rep" "1")
15588    (set_attr "memory" "both")
15589    (set_attr "mode" "SI")])
15590
15591 (define_insn "*rep_movqi_rex64"
15592   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15593    (set (match_operand:DI 0 "register_operand" "=D")
15594         (plus:DI (match_operand:DI 3 "register_operand" "0")
15595                  (match_operand:DI 5 "register_operand" "2")))
15596    (set (match_operand:DI 1 "register_operand" "=S")
15597         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
15598    (set (mem:BLK (match_dup 3))
15599         (mem:BLK (match_dup 4)))
15600    (use (match_dup 5))]
15601   "TARGET_64BIT"
15602   "rep{%;} movsb"
15603   [(set_attr "type" "str")
15604    (set_attr "prefix_rep" "1")
15605    (set_attr "memory" "both")
15606    (set_attr "mode" "SI")])
15607
15608 (define_expand "setmemsi"
15609    [(use (match_operand:BLK 0 "memory_operand" ""))
15610     (use (match_operand:SI 1 "nonmemory_operand" ""))
15611     (use (match_operand 2 "const_int_operand" ""))
15612     (use (match_operand 3 "const_int_operand" ""))
15613     (use (match_operand:SI 4 "const_int_operand" ""))
15614     (use (match_operand:SI 5 "const_int_operand" ""))]
15615   ""
15616 {
15617  if (ix86_expand_setmem (operands[0], operands[1],
15618                          operands[2], operands[3],
15619                          operands[4], operands[5]))
15620    DONE;
15621  else
15622    FAIL;
15623 })
15624
15625 (define_expand "setmemdi"
15626    [(use (match_operand:BLK 0 "memory_operand" ""))
15627     (use (match_operand:DI 1 "nonmemory_operand" ""))
15628     (use (match_operand 2 "const_int_operand" ""))
15629     (use (match_operand 3 "const_int_operand" ""))
15630     (use (match_operand 4 "const_int_operand" ""))
15631     (use (match_operand 5 "const_int_operand" ""))]
15632   "TARGET_64BIT"
15633 {
15634  if (ix86_expand_setmem (operands[0], operands[1],
15635                          operands[2], operands[3],
15636                          operands[4], operands[5]))
15637    DONE;
15638  else
15639    FAIL;
15640 })
15641
15642 ;; Most CPUs don't like single string operations
15643 ;; Handle this case here to simplify previous expander.
15644
15645 (define_expand "strset"
15646   [(set (match_operand 1 "memory_operand" "")
15647         (match_operand 2 "register_operand" ""))
15648    (parallel [(set (match_operand 0 "register_operand" "")
15649                    (match_dup 3))
15650               (clobber (reg:CC FLAGS_REG))])]
15651   ""
15652 {
15653   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15654     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15655
15656   /* If .md ever supports :P for Pmode, this can be directly
15657      in the pattern above.  */
15658   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15659                               GEN_INT (GET_MODE_SIZE (GET_MODE
15660                                                       (operands[2]))));
15661   if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15662     {
15663       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15664                                       operands[3]));
15665       DONE;
15666     }
15667 })
15668
15669 (define_expand "strset_singleop"
15670   [(parallel [(set (match_operand 1 "memory_operand" "")
15671                    (match_operand 2 "register_operand" ""))
15672               (set (match_operand 0 "register_operand" "")
15673                    (match_operand 3 "" ""))])]
15674   ""
15675   "ix86_current_function_needs_cld = 1;")
15676
15677 (define_insn "*strsetdi_rex_1"
15678   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
15679         (match_operand:DI 2 "register_operand" "a"))
15680    (set (match_operand:DI 0 "register_operand" "=D")
15681         (plus:DI (match_dup 1)
15682                  (const_int 8)))]
15683   "TARGET_64BIT"
15684   "stosq"
15685   [(set_attr "type" "str")
15686    (set_attr "memory" "store")
15687    (set_attr "mode" "DI")])
15688
15689 (define_insn "*strsetsi_1"
15690   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
15691         (match_operand:SI 2 "register_operand" "a"))
15692    (set (match_operand:SI 0 "register_operand" "=D")
15693         (plus:SI (match_dup 1)
15694                  (const_int 4)))]
15695   "!TARGET_64BIT"
15696   "stos{l|d}"
15697   [(set_attr "type" "str")
15698    (set_attr "memory" "store")
15699    (set_attr "mode" "SI")])
15700
15701 (define_insn "*strsetsi_rex_1"
15702   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
15703         (match_operand:SI 2 "register_operand" "a"))
15704    (set (match_operand:DI 0 "register_operand" "=D")
15705         (plus:DI (match_dup 1)
15706                  (const_int 4)))]
15707   "TARGET_64BIT"
15708   "stos{l|d}"
15709   [(set_attr "type" "str")
15710    (set_attr "memory" "store")
15711    (set_attr "mode" "SI")])
15712
15713 (define_insn "*strsethi_1"
15714   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
15715         (match_operand:HI 2 "register_operand" "a"))
15716    (set (match_operand:SI 0 "register_operand" "=D")
15717         (plus:SI (match_dup 1)
15718                  (const_int 2)))]
15719   "!TARGET_64BIT"
15720   "stosw"
15721   [(set_attr "type" "str")
15722    (set_attr "memory" "store")
15723    (set_attr "mode" "HI")])
15724
15725 (define_insn "*strsethi_rex_1"
15726   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
15727         (match_operand:HI 2 "register_operand" "a"))
15728    (set (match_operand:DI 0 "register_operand" "=D")
15729         (plus:DI (match_dup 1)
15730                  (const_int 2)))]
15731   "TARGET_64BIT"
15732   "stosw"
15733   [(set_attr "type" "str")
15734    (set_attr "memory" "store")
15735    (set_attr "mode" "HI")])
15736
15737 (define_insn "*strsetqi_1"
15738   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
15739         (match_operand:QI 2 "register_operand" "a"))
15740    (set (match_operand:SI 0 "register_operand" "=D")
15741         (plus:SI (match_dup 1)
15742                  (const_int 1)))]
15743   "!TARGET_64BIT"
15744   "stosb"
15745   [(set_attr "type" "str")
15746    (set_attr "memory" "store")
15747    (set_attr "mode" "QI")])
15748
15749 (define_insn "*strsetqi_rex_1"
15750   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
15751         (match_operand:QI 2 "register_operand" "a"))
15752    (set (match_operand:DI 0 "register_operand" "=D")
15753         (plus:DI (match_dup 1)
15754                  (const_int 1)))]
15755   "TARGET_64BIT"
15756   "stosb"
15757   [(set_attr "type" "str")
15758    (set_attr "memory" "store")
15759    (set_attr "prefix_rex" "0")
15760    (set_attr "mode" "QI")])
15761
15762 (define_expand "rep_stos"
15763   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15764               (set (match_operand 0 "register_operand" "")
15765                    (match_operand 4 "" ""))
15766               (set (match_operand 2 "memory_operand" "") (const_int 0))
15767               (use (match_operand 3 "register_operand" ""))
15768               (use (match_dup 1))])]
15769   ""
15770   "ix86_current_function_needs_cld = 1;")
15771
15772 (define_insn "*rep_stosdi_rex64"
15773   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15774    (set (match_operand:DI 0 "register_operand" "=D")
15775         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15776                             (const_int 3))
15777                  (match_operand:DI 3 "register_operand" "0")))
15778    (set (mem:BLK (match_dup 3))
15779         (const_int 0))
15780    (use (match_operand:DI 2 "register_operand" "a"))
15781    (use (match_dup 4))]
15782   "TARGET_64BIT"
15783   "rep{%;} stosq"
15784   [(set_attr "type" "str")
15785    (set_attr "prefix_rep" "1")
15786    (set_attr "memory" "store")
15787    (set_attr "mode" "DI")])
15788
15789 (define_insn "*rep_stossi"
15790   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
15791    (set (match_operand:SI 0 "register_operand" "=D")
15792         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
15793                             (const_int 2))
15794                  (match_operand:SI 3 "register_operand" "0")))
15795    (set (mem:BLK (match_dup 3))
15796         (const_int 0))
15797    (use (match_operand:SI 2 "register_operand" "a"))
15798    (use (match_dup 4))]
15799   "!TARGET_64BIT"
15800   "rep{%;} stos{l|d}"
15801   [(set_attr "type" "str")
15802    (set_attr "prefix_rep" "1")
15803    (set_attr "memory" "store")
15804    (set_attr "mode" "SI")])
15805
15806 (define_insn "*rep_stossi_rex64"
15807   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15808    (set (match_operand:DI 0 "register_operand" "=D")
15809         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15810                             (const_int 2))
15811                  (match_operand:DI 3 "register_operand" "0")))
15812    (set (mem:BLK (match_dup 3))
15813         (const_int 0))
15814    (use (match_operand:SI 2 "register_operand" "a"))
15815    (use (match_dup 4))]
15816   "TARGET_64BIT"
15817   "rep{%;} stos{l|d}"
15818   [(set_attr "type" "str")
15819    (set_attr "prefix_rep" "1")
15820    (set_attr "memory" "store")
15821    (set_attr "mode" "SI")])
15822
15823 (define_insn "*rep_stosqi"
15824   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
15825    (set (match_operand:SI 0 "register_operand" "=D")
15826         (plus:SI (match_operand:SI 3 "register_operand" "0")
15827                  (match_operand:SI 4 "register_operand" "1")))
15828    (set (mem:BLK (match_dup 3))
15829         (const_int 0))
15830    (use (match_operand:QI 2 "register_operand" "a"))
15831    (use (match_dup 4))]
15832   "!TARGET_64BIT"
15833   "rep{%;} stosb"
15834   [(set_attr "type" "str")
15835    (set_attr "prefix_rep" "1")
15836    (set_attr "memory" "store")
15837    (set_attr "mode" "QI")])
15838
15839 (define_insn "*rep_stosqi_rex64"
15840   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15841    (set (match_operand:DI 0 "register_operand" "=D")
15842         (plus:DI (match_operand:DI 3 "register_operand" "0")
15843                  (match_operand:DI 4 "register_operand" "1")))
15844    (set (mem:BLK (match_dup 3))
15845         (const_int 0))
15846    (use (match_operand:QI 2 "register_operand" "a"))
15847    (use (match_dup 4))]
15848   "TARGET_64BIT"
15849   "rep{%;} stosb"
15850   [(set_attr "type" "str")
15851    (set_attr "prefix_rep" "1")
15852    (set_attr "memory" "store")
15853    (set_attr "prefix_rex" "0")
15854    (set_attr "mode" "QI")])
15855
15856 (define_expand "cmpstrnsi"
15857   [(set (match_operand:SI 0 "register_operand" "")
15858         (compare:SI (match_operand:BLK 1 "general_operand" "")
15859                     (match_operand:BLK 2 "general_operand" "")))
15860    (use (match_operand 3 "general_operand" ""))
15861    (use (match_operand 4 "immediate_operand" ""))]
15862   ""
15863 {
15864   rtx addr1, addr2, out, outlow, count, countreg, align;
15865
15866   if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
15867     FAIL;
15868
15869   /* Can't use this if the user has appropriated esi or edi.  */
15870   if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
15871     FAIL;
15872
15873   out = operands[0];
15874   if (!REG_P (out))
15875     out = gen_reg_rtx (SImode);
15876
15877   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
15878   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
15879   if (addr1 != XEXP (operands[1], 0))
15880     operands[1] = replace_equiv_address_nv (operands[1], addr1);
15881   if (addr2 != XEXP (operands[2], 0))
15882     operands[2] = replace_equiv_address_nv (operands[2], addr2);
15883
15884   count = operands[3];
15885   countreg = ix86_zero_extend_to_Pmode (count);
15886
15887   /* %%% Iff we are testing strict equality, we can use known alignment
15888      to good advantage.  This may be possible with combine, particularly
15889      once cc0 is dead.  */
15890   align = operands[4];
15891
15892   if (CONST_INT_P (count))
15893     {
15894       if (INTVAL (count) == 0)
15895         {
15896           emit_move_insn (operands[0], const0_rtx);
15897           DONE;
15898         }
15899       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
15900                                      operands[1], operands[2]));
15901     }
15902   else
15903     {
15904       rtx (*cmp_insn)(rtx, rtx);
15905
15906       if (TARGET_64BIT)
15907         cmp_insn = gen_cmpdi_1;
15908       else
15909         cmp_insn = gen_cmpsi_1;
15910       emit_insn (cmp_insn (countreg, countreg));
15911       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
15912                                   operands[1], operands[2]));
15913     }
15914
15915   outlow = gen_lowpart (QImode, out);
15916   emit_insn (gen_cmpintqi (outlow));
15917   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
15918
15919   if (operands[0] != out)
15920     emit_move_insn (operands[0], out);
15921
15922   DONE;
15923 })
15924
15925 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
15926
15927 (define_expand "cmpintqi"
15928   [(set (match_dup 1)
15929         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15930    (set (match_dup 2)
15931         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15932    (parallel [(set (match_operand:QI 0 "register_operand" "")
15933                    (minus:QI (match_dup 1)
15934                              (match_dup 2)))
15935               (clobber (reg:CC FLAGS_REG))])]
15936   ""
15937   "operands[1] = gen_reg_rtx (QImode);
15938    operands[2] = gen_reg_rtx (QImode);")
15939
15940 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
15941 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
15942
15943 (define_expand "cmpstrnqi_nz_1"
15944   [(parallel [(set (reg:CC FLAGS_REG)
15945                    (compare:CC (match_operand 4 "memory_operand" "")
15946                                (match_operand 5 "memory_operand" "")))
15947               (use (match_operand 2 "register_operand" ""))
15948               (use (match_operand:SI 3 "immediate_operand" ""))
15949               (clobber (match_operand 0 "register_operand" ""))
15950               (clobber (match_operand 1 "register_operand" ""))
15951               (clobber (match_dup 2))])]
15952   ""
15953   "ix86_current_function_needs_cld = 1;")
15954
15955 (define_insn "*cmpstrnqi_nz_1"
15956   [(set (reg:CC FLAGS_REG)
15957         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
15958                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
15959    (use (match_operand:SI 6 "register_operand" "2"))
15960    (use (match_operand:SI 3 "immediate_operand" "i"))
15961    (clobber (match_operand:SI 0 "register_operand" "=S"))
15962    (clobber (match_operand:SI 1 "register_operand" "=D"))
15963    (clobber (match_operand:SI 2 "register_operand" "=c"))]
15964   "!TARGET_64BIT"
15965   "repz{%;} cmpsb"
15966   [(set_attr "type" "str")
15967    (set_attr "mode" "QI")
15968    (set_attr "prefix_rep" "1")])
15969
15970 (define_insn "*cmpstrnqi_nz_rex_1"
15971   [(set (reg:CC FLAGS_REG)
15972         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
15973                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
15974    (use (match_operand:DI 6 "register_operand" "2"))
15975    (use (match_operand:SI 3 "immediate_operand" "i"))
15976    (clobber (match_operand:DI 0 "register_operand" "=S"))
15977    (clobber (match_operand:DI 1 "register_operand" "=D"))
15978    (clobber (match_operand:DI 2 "register_operand" "=c"))]
15979   "TARGET_64BIT"
15980   "repz{%;} cmpsb"
15981   [(set_attr "type" "str")
15982    (set_attr "mode" "QI")
15983    (set_attr "prefix_rex" "0")
15984    (set_attr "prefix_rep" "1")])
15985
15986 ;; The same, but the count is not known to not be zero.
15987
15988 (define_expand "cmpstrnqi_1"
15989   [(parallel [(set (reg:CC FLAGS_REG)
15990                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
15991                                      (const_int 0))
15992                   (compare:CC (match_operand 4 "memory_operand" "")
15993                               (match_operand 5 "memory_operand" ""))
15994                   (const_int 0)))
15995               (use (match_operand:SI 3 "immediate_operand" ""))
15996               (use (reg:CC FLAGS_REG))
15997               (clobber (match_operand 0 "register_operand" ""))
15998               (clobber (match_operand 1 "register_operand" ""))
15999               (clobber (match_dup 2))])]
16000   ""
16001   "ix86_current_function_needs_cld = 1;")
16002
16003 (define_insn "*cmpstrnqi_1"
16004   [(set (reg:CC FLAGS_REG)
16005         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
16006                              (const_int 0))
16007           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
16008                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
16009           (const_int 0)))
16010    (use (match_operand:SI 3 "immediate_operand" "i"))
16011    (use (reg:CC FLAGS_REG))
16012    (clobber (match_operand:SI 0 "register_operand" "=S"))
16013    (clobber (match_operand:SI 1 "register_operand" "=D"))
16014    (clobber (match_operand:SI 2 "register_operand" "=c"))]
16015   "!TARGET_64BIT"
16016   "repz{%;} cmpsb"
16017   [(set_attr "type" "str")
16018    (set_attr "mode" "QI")
16019    (set_attr "prefix_rep" "1")])
16020
16021 (define_insn "*cmpstrnqi_rex_1"
16022   [(set (reg:CC FLAGS_REG)
16023         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
16024                              (const_int 0))
16025           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
16026                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
16027           (const_int 0)))
16028    (use (match_operand:SI 3 "immediate_operand" "i"))
16029    (use (reg:CC FLAGS_REG))
16030    (clobber (match_operand:DI 0 "register_operand" "=S"))
16031    (clobber (match_operand:DI 1 "register_operand" "=D"))
16032    (clobber (match_operand:DI 2 "register_operand" "=c"))]
16033   "TARGET_64BIT"
16034   "repz{%;} cmpsb"
16035   [(set_attr "type" "str")
16036    (set_attr "mode" "QI")
16037    (set_attr "prefix_rex" "0")
16038    (set_attr "prefix_rep" "1")])
16039
16040 (define_expand "strlensi"
16041   [(set (match_operand:SI 0 "register_operand" "")
16042         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
16043                     (match_operand:QI 2 "immediate_operand" "")
16044                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
16045   ""
16046 {
16047  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16048    DONE;
16049  else
16050    FAIL;
16051 })
16052
16053 (define_expand "strlendi"
16054   [(set (match_operand:DI 0 "register_operand" "")
16055         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
16056                     (match_operand:QI 2 "immediate_operand" "")
16057                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
16058   ""
16059 {
16060  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16061    DONE;
16062  else
16063    FAIL;
16064 })
16065
16066 (define_expand "strlenqi_1"
16067   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
16068               (clobber (match_operand 1 "register_operand" ""))
16069               (clobber (reg:CC FLAGS_REG))])]
16070   ""
16071   "ix86_current_function_needs_cld = 1;")
16072
16073 (define_insn "*strlenqi_1"
16074   [(set (match_operand:SI 0 "register_operand" "=&c")
16075         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
16076                     (match_operand:QI 2 "register_operand" "a")
16077                     (match_operand:SI 3 "immediate_operand" "i")
16078                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
16079    (clobber (match_operand:SI 1 "register_operand" "=D"))
16080    (clobber (reg:CC FLAGS_REG))]
16081   "!TARGET_64BIT"
16082   "repnz{%;} scasb"
16083   [(set_attr "type" "str")
16084    (set_attr "mode" "QI")
16085    (set_attr "prefix_rep" "1")])
16086
16087 (define_insn "*strlenqi_rex_1"
16088   [(set (match_operand:DI 0 "register_operand" "=&c")
16089         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
16090                     (match_operand:QI 2 "register_operand" "a")
16091                     (match_operand:DI 3 "immediate_operand" "i")
16092                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
16093    (clobber (match_operand:DI 1 "register_operand" "=D"))
16094    (clobber (reg:CC FLAGS_REG))]
16095   "TARGET_64BIT"
16096   "repnz{%;} scasb"
16097   [(set_attr "type" "str")
16098    (set_attr "mode" "QI")
16099    (set_attr "prefix_rex" "0")
16100    (set_attr "prefix_rep" "1")])
16101
16102 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
16103 ;; handled in combine, but it is not currently up to the task.
16104 ;; When used for their truth value, the cmpstrn* expanders generate
16105 ;; code like this:
16106 ;;
16107 ;;   repz cmpsb
16108 ;;   seta       %al
16109 ;;   setb       %dl
16110 ;;   cmpb       %al, %dl
16111 ;;   jcc        label
16112 ;;
16113 ;; The intermediate three instructions are unnecessary.
16114
16115 ;; This one handles cmpstrn*_nz_1...
16116 (define_peephole2
16117   [(parallel[
16118      (set (reg:CC FLAGS_REG)
16119           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16120                       (mem:BLK (match_operand 5 "register_operand" ""))))
16121      (use (match_operand 6 "register_operand" ""))
16122      (use (match_operand:SI 3 "immediate_operand" ""))
16123      (clobber (match_operand 0 "register_operand" ""))
16124      (clobber (match_operand 1 "register_operand" ""))
16125      (clobber (match_operand 2 "register_operand" ""))])
16126    (set (match_operand:QI 7 "register_operand" "")
16127         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16128    (set (match_operand:QI 8 "register_operand" "")
16129         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16130    (set (reg FLAGS_REG)
16131         (compare (match_dup 7) (match_dup 8)))
16132   ]
16133   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16134   [(parallel[
16135      (set (reg:CC FLAGS_REG)
16136           (compare:CC (mem:BLK (match_dup 4))
16137                       (mem:BLK (match_dup 5))))
16138      (use (match_dup 6))
16139      (use (match_dup 3))
16140      (clobber (match_dup 0))
16141      (clobber (match_dup 1))
16142      (clobber (match_dup 2))])]
16143   "")
16144
16145 ;; ...and this one handles cmpstrn*_1.
16146 (define_peephole2
16147   [(parallel[
16148      (set (reg:CC FLAGS_REG)
16149           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
16150                                (const_int 0))
16151             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16152                         (mem:BLK (match_operand 5 "register_operand" "")))
16153             (const_int 0)))
16154      (use (match_operand:SI 3 "immediate_operand" ""))
16155      (use (reg:CC FLAGS_REG))
16156      (clobber (match_operand 0 "register_operand" ""))
16157      (clobber (match_operand 1 "register_operand" ""))
16158      (clobber (match_operand 2 "register_operand" ""))])
16159    (set (match_operand:QI 7 "register_operand" "")
16160         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16161    (set (match_operand:QI 8 "register_operand" "")
16162         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16163    (set (reg FLAGS_REG)
16164         (compare (match_dup 7) (match_dup 8)))
16165   ]
16166   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16167   [(parallel[
16168      (set (reg:CC FLAGS_REG)
16169           (if_then_else:CC (ne (match_dup 6)
16170                                (const_int 0))
16171             (compare:CC (mem:BLK (match_dup 4))
16172                         (mem:BLK (match_dup 5)))
16173             (const_int 0)))
16174      (use (match_dup 3))
16175      (use (reg:CC FLAGS_REG))
16176      (clobber (match_dup 0))
16177      (clobber (match_dup 1))
16178      (clobber (match_dup 2))])]
16179   "")
16180
16181
16182 \f
16183 ;; Conditional move instructions.
16184
16185 (define_expand "mov<mode>cc"
16186   [(set (match_operand:SWIM 0 "register_operand" "")
16187         (if_then_else:SWIM (match_operand 1 "comparison_operator" "")
16188                            (match_operand:SWIM 2 "general_operand" "")
16189                            (match_operand:SWIM 3 "general_operand" "")))]
16190   ""
16191   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16192
16193 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16194 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16195 ;; So just document what we're doing explicitly.
16196
16197 (define_expand "x86_mov<mode>cc_0_m1"
16198   [(parallel
16199     [(set (match_operand:SWI48 0 "register_operand" "")
16200           (if_then_else:SWI48
16201             (match_operator:SWI48 2 "ix86_carry_flag_operator"
16202              [(match_operand 1 "flags_reg_operand" "")
16203               (const_int 0)])
16204             (const_int -1)
16205             (const_int 0)))
16206      (clobber (reg:CC FLAGS_REG))])]
16207   ""
16208   "")
16209
16210 (define_insn "*x86_mov<mode>cc_0_m1"
16211   [(set (match_operand:SWI48 0 "register_operand" "=r")
16212         (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16213                              [(reg FLAGS_REG) (const_int 0)])
16214           (const_int -1)
16215           (const_int 0)))
16216    (clobber (reg:CC FLAGS_REG))]
16217   ""
16218   "sbb{<imodesuffix>}\t%0, %0"
16219   ; Since we don't have the proper number of operands for an alu insn,
16220   ; fill in all the blanks.
16221   [(set_attr "type" "alu")
16222    (set_attr "use_carry" "1")
16223    (set_attr "pent_pair" "pu")
16224    (set_attr "memory" "none")
16225    (set_attr "imm_disp" "false")
16226    (set_attr "mode" "<MODE>")
16227    (set_attr "length_immediate" "0")])
16228
16229 (define_insn "*x86_mov<mode>cc_0_m1_se"
16230   [(set (match_operand:SWI48 0 "register_operand" "=r")
16231         (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16232                              [(reg FLAGS_REG) (const_int 0)])
16233                             (const_int 1)
16234                             (const_int 0)))
16235    (clobber (reg:CC FLAGS_REG))]
16236   ""
16237   "sbb{<imodesuffix>}\t%0, %0"
16238   [(set_attr "type" "alu")
16239    (set_attr "use_carry" "1")
16240    (set_attr "pent_pair" "pu")
16241    (set_attr "memory" "none")
16242    (set_attr "imm_disp" "false")
16243    (set_attr "mode" "<MODE>")
16244    (set_attr "length_immediate" "0")])
16245
16246 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16247   [(set (match_operand:SWI48 0 "register_operand" "=r")
16248         (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16249                     [(reg FLAGS_REG) (const_int 0)])))]
16250   ""
16251   "sbb{<imodesuffix>}\t%0, %0"
16252   [(set_attr "type" "alu")
16253    (set_attr "use_carry" "1")
16254    (set_attr "pent_pair" "pu")
16255    (set_attr "memory" "none")
16256    (set_attr "imm_disp" "false")
16257    (set_attr "mode" "<MODE>")
16258    (set_attr "length_immediate" "0")])
16259
16260 (define_insn "*mov<mode>cc_noc"
16261   [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16262         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16263                                [(reg FLAGS_REG) (const_int 0)])
16264           (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16265           (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16266   "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16267   "@
16268    cmov%O2%C1\t{%2, %0|%0, %2}
16269    cmov%O2%c1\t{%3, %0|%0, %3}"
16270   [(set_attr "type" "icmov")
16271    (set_attr "mode" "<MODE>")])
16272
16273 (define_insn_and_split "*movqicc_noc"
16274   [(set (match_operand:QI 0 "register_operand" "=r,r")
16275         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16276                            [(match_operand 4 "flags_reg_operand" "")
16277                             (const_int 0)])
16278                       (match_operand:QI 2 "register_operand" "r,0")
16279                       (match_operand:QI 3 "register_operand" "0,r")))]
16280   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16281   "#"
16282   "&& reload_completed"
16283   [(set (match_dup 0)
16284         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16285                       (match_dup 2)
16286                       (match_dup 3)))]
16287   "operands[0] = gen_lowpart (SImode, operands[0]);
16288    operands[2] = gen_lowpart (SImode, operands[2]);
16289    operands[3] = gen_lowpart (SImode, operands[3]);"
16290   [(set_attr "type" "icmov")
16291    (set_attr "mode" "SI")])
16292
16293 (define_expand "mov<mode>cc"
16294   [(set (match_operand:X87MODEF 0 "register_operand" "")
16295         (if_then_else:X87MODEF
16296           (match_operand 1 "ix86_fp_comparison_operator" "")
16297           (match_operand:X87MODEF 2 "register_operand" "")
16298           (match_operand:X87MODEF 3 "register_operand" "")))]
16299   "(TARGET_80387 && TARGET_CMOVE)
16300    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16301   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16302
16303 (define_insn "*movsfcc_1_387"
16304   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16305         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16306                                 [(reg FLAGS_REG) (const_int 0)])
16307                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16308                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16309   "TARGET_80387 && TARGET_CMOVE
16310    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16311   "@
16312    fcmov%F1\t{%2, %0|%0, %2}
16313    fcmov%f1\t{%3, %0|%0, %3}
16314    cmov%O2%C1\t{%2, %0|%0, %2}
16315    cmov%O2%c1\t{%3, %0|%0, %3}"
16316   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16317    (set_attr "mode" "SF,SF,SI,SI")])
16318
16319 (define_insn "*movdfcc_1"
16320   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16321         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16322                                 [(reg FLAGS_REG) (const_int 0)])
16323                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16324                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16325   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16326    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16327   "@
16328    fcmov%F1\t{%2, %0|%0, %2}
16329    fcmov%f1\t{%3, %0|%0, %3}
16330    #
16331    #"
16332   [(set_attr "type" "fcmov,fcmov,multi,multi")
16333    (set_attr "mode" "DF")])
16334
16335 (define_insn "*movdfcc_1_rex64"
16336   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16337         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16338                                 [(reg FLAGS_REG) (const_int 0)])
16339                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16340                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16341   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16342    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16343   "@
16344    fcmov%F1\t{%2, %0|%0, %2}
16345    fcmov%f1\t{%3, %0|%0, %3}
16346    cmov%O2%C1\t{%2, %0|%0, %2}
16347    cmov%O2%c1\t{%3, %0|%0, %3}"
16348   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16349    (set_attr "mode" "DF")])
16350
16351 (define_split
16352   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16353         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16354                                 [(match_operand 4 "flags_reg_operand" "")
16355                                  (const_int 0)])
16356                       (match_operand:DF 2 "nonimmediate_operand" "")
16357                       (match_operand:DF 3 "nonimmediate_operand" "")))]
16358   "!TARGET_64BIT && reload_completed"
16359   [(set (match_dup 2)
16360         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16361                       (match_dup 5)
16362                       (match_dup 6)))
16363    (set (match_dup 3)
16364         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16365                       (match_dup 7)
16366                       (match_dup 8)))]
16367 {
16368   split_di (&operands[2], 2, &operands[5], &operands[7]);
16369   split_di (&operands[0], 1, &operands[2], &operands[3]);
16370 })
16371
16372 (define_insn "*movxfcc_1"
16373   [(set (match_operand:XF 0 "register_operand" "=f,f")
16374         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16375                                 [(reg FLAGS_REG) (const_int 0)])
16376                       (match_operand:XF 2 "register_operand" "f,0")
16377                       (match_operand:XF 3 "register_operand" "0,f")))]
16378   "TARGET_80387 && TARGET_CMOVE"
16379   "@
16380    fcmov%F1\t{%2, %0|%0, %2}
16381    fcmov%f1\t{%3, %0|%0, %3}"
16382   [(set_attr "type" "fcmov")
16383    (set_attr "mode" "XF")])
16384
16385 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16386 ;; the scalar versions to have only XMM registers as operands.
16387
16388 ;; XOP conditional move
16389 (define_insn "*xop_pcmov_<mode>"
16390   [(set (match_operand:MODEF 0 "register_operand" "=x")
16391         (if_then_else:MODEF
16392           (match_operand:MODEF 1 "register_operand" "x")
16393           (match_operand:MODEF 2 "register_operand" "x")
16394           (match_operand:MODEF 3 "register_operand" "x")))]
16395   "TARGET_XOP"
16396   "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16397   [(set_attr "type" "sse4arg")])
16398
16399 ;; These versions of the min/max patterns are intentionally ignorant of
16400 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16401 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16402 ;; are undefined in this condition, we're certain this is correct.
16403
16404 (define_insn "*avx_<code><mode>3"
16405   [(set (match_operand:MODEF 0 "register_operand" "=x")
16406         (smaxmin:MODEF
16407           (match_operand:MODEF 1 "nonimmediate_operand" "%x")
16408           (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
16409   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16410   "v<maxmin_float>s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16411   [(set_attr "type" "sseadd")
16412    (set_attr "prefix" "vex")
16413    (set_attr "mode" "<MODE>")])
16414
16415 (define_insn "<code><mode>3"
16416   [(set (match_operand:MODEF 0 "register_operand" "=x")
16417         (smaxmin:MODEF
16418           (match_operand:MODEF 1 "nonimmediate_operand" "%0")
16419           (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
16420   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16421   "<maxmin_float>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
16422   [(set_attr "type" "sseadd")
16423    (set_attr "mode" "<MODE>")])
16424
16425 ;; These versions of the min/max patterns implement exactly the operations
16426 ;;   min = (op1 < op2 ? op1 : op2)
16427 ;;   max = (!(op1 < op2) ? op1 : op2)
16428 ;; Their operands are not commutative, and thus they may be used in the
16429 ;; presence of -0.0 and NaN.
16430
16431 (define_insn "*avx_ieee_smin<mode>3"
16432   [(set (match_operand:MODEF 0 "register_operand" "=x")
16433         (unspec:MODEF
16434           [(match_operand:MODEF 1 "register_operand" "x")
16435            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16436          UNSPEC_IEEE_MIN))]
16437   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16438   "vmins<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16439   [(set_attr "type" "sseadd")
16440    (set_attr "prefix" "vex")
16441    (set_attr "mode" "<MODE>")])
16442
16443 (define_insn "*ieee_smin<mode>3"
16444   [(set (match_operand:MODEF 0 "register_operand" "=x")
16445         (unspec:MODEF
16446           [(match_operand:MODEF 1 "register_operand" "0")
16447            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16448          UNSPEC_IEEE_MIN))]
16449   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16450   "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
16451   [(set_attr "type" "sseadd")
16452    (set_attr "mode" "<MODE>")])
16453
16454 (define_insn "*avx_ieee_smax<mode>3"
16455   [(set (match_operand:MODEF 0 "register_operand" "=x")
16456         (unspec:MODEF
16457           [(match_operand:MODEF 1 "register_operand" "0")
16458            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16459          UNSPEC_IEEE_MAX))]
16460   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16461   "vmaxs<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16462   [(set_attr "type" "sseadd")
16463    (set_attr "prefix" "vex")
16464    (set_attr "mode" "<MODE>")])
16465
16466 (define_insn "*ieee_smax<mode>3"
16467   [(set (match_operand:MODEF 0 "register_operand" "=x")
16468         (unspec:MODEF
16469           [(match_operand:MODEF 1 "register_operand" "0")
16470            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16471          UNSPEC_IEEE_MAX))]
16472   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16473   "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
16474   [(set_attr "type" "sseadd")
16475    (set_attr "mode" "<MODE>")])
16476
16477 ;; Make two stack loads independent:
16478 ;;   fld aa              fld aa
16479 ;;   fld %st(0)     ->   fld bb
16480 ;;   fmul bb             fmul %st(1), %st
16481 ;;
16482 ;; Actually we only match the last two instructions for simplicity.
16483 (define_peephole2
16484   [(set (match_operand 0 "fp_register_operand" "")
16485         (match_operand 1 "fp_register_operand" ""))
16486    (set (match_dup 0)
16487         (match_operator 2 "binary_fp_operator"
16488            [(match_dup 0)
16489             (match_operand 3 "memory_operand" "")]))]
16490   "REGNO (operands[0]) != REGNO (operands[1])"
16491   [(set (match_dup 0) (match_dup 3))
16492    (set (match_dup 0) (match_dup 4))]
16493
16494   ;; The % modifier is not operational anymore in peephole2's, so we have to
16495   ;; swap the operands manually in the case of addition and multiplication.
16496   "if (COMMUTATIVE_ARITH_P (operands[2]))
16497      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
16498                                  operands[0], operands[1]);
16499    else
16500      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
16501                                  operands[1], operands[0]);")
16502
16503 ;; Conditional addition patterns
16504 (define_expand "add<mode>cc"
16505   [(match_operand:SWI 0 "register_operand" "")
16506    (match_operand 1 "comparison_operator" "")
16507    (match_operand:SWI 2 "register_operand" "")
16508    (match_operand:SWI 3 "const_int_operand" "")]
16509   ""
16510   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16511
16512 \f
16513 ;; Misc patterns (?)
16514
16515 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16516 ;; Otherwise there will be nothing to keep
16517 ;;
16518 ;; [(set (reg ebp) (reg esp))]
16519 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16520 ;;  (clobber (eflags)]
16521 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16522 ;;
16523 ;; in proper program order.
16524 (define_insn "pro_epilogue_adjust_stack_1"
16525   [(set (match_operand:SI 0 "register_operand" "=r,r")
16526         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
16527                  (match_operand:SI 2 "immediate_operand" "i,i")))
16528    (clobber (reg:CC FLAGS_REG))
16529    (clobber (mem:BLK (scratch)))]
16530   "!TARGET_64BIT"
16531 {
16532   switch (get_attr_type (insn))
16533     {
16534     case TYPE_IMOV:
16535       return "mov{l}\t{%1, %0|%0, %1}";
16536
16537     case TYPE_ALU:
16538       gcc_assert (rtx_equal_p (operands[0], operands[1]));
16539       if (x86_maybe_negate_const_int (&operands[2], SImode))
16540         return "sub{l}\t{%2, %0|%0, %2}";
16541
16542       return "add{l}\t{%2, %0|%0, %2}";
16543
16544     default:
16545       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16546       return "lea{l}\t{%a2, %0|%0, %a2}";
16547     }
16548 }
16549   [(set (attr "type")
16550         (cond [(and (eq_attr "alternative" "0") 
16551                     (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
16552                  (const_string "alu")
16553                (match_operand:SI 2 "const0_operand" "")
16554                  (const_string "imov")
16555               ]
16556               (const_string "lea")))
16557    (set (attr "length_immediate")
16558         (cond [(eq_attr "type" "imov")
16559                  (const_string "0")
16560                (and (eq_attr "type" "alu")
16561                     (match_operand 2 "const128_operand" ""))
16562                  (const_string "1")
16563               ]
16564               (const_string "*")))
16565    (set_attr "mode" "SI")])
16566
16567 (define_insn "pro_epilogue_adjust_stack_rex64"
16568   [(set (match_operand:DI 0 "register_operand" "=r,r")
16569         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
16570                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
16571    (clobber (reg:CC FLAGS_REG))
16572    (clobber (mem:BLK (scratch)))]
16573   "TARGET_64BIT"
16574 {
16575   switch (get_attr_type (insn))
16576     {
16577     case TYPE_IMOV:
16578       return "mov{q}\t{%1, %0|%0, %1}";
16579
16580     case TYPE_ALU:
16581       gcc_assert (rtx_equal_p (operands[0], operands[1]));
16582       if (x86_maybe_negate_const_int (&operands[2], DImode))
16583         return "sub{q}\t{%2, %0|%0, %2}";
16584
16585       return "add{q}\t{%2, %0|%0, %2}";
16586
16587     default:
16588       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16589       return "lea{q}\t{%a2, %0|%0, %a2}";
16590     }
16591 }
16592   [(set (attr "type")
16593         (cond [(and (eq_attr "alternative" "0")
16594                     (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
16595                  (const_string "alu")
16596                (match_operand:DI 2 "const0_operand" "")
16597                  (const_string "imov")
16598               ]
16599               (const_string "lea")))
16600    (set (attr "length_immediate")
16601         (cond [(eq_attr "type" "imov")
16602                  (const_string "0")
16603                (and (eq_attr "type" "alu")
16604                     (match_operand 2 "const128_operand" ""))
16605                  (const_string "1")
16606               ]
16607               (const_string "*")))
16608    (set_attr "mode" "DI")])
16609
16610 (define_insn "pro_epilogue_adjust_stack_rex64_2"
16611   [(set (match_operand:DI 0 "register_operand" "=r,r")
16612         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
16613                  (match_operand:DI 3 "immediate_operand" "i,i")))
16614    (use (match_operand:DI 2 "register_operand" "r,r"))
16615    (clobber (reg:CC FLAGS_REG))
16616    (clobber (mem:BLK (scratch)))]
16617   "TARGET_64BIT"
16618 {
16619   switch (get_attr_type (insn))
16620     {
16621     case TYPE_ALU:
16622       return "add{q}\t{%2, %0|%0, %2}";
16623
16624     case TYPE_LEA:
16625       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
16626       return "lea{q}\t{%a2, %0|%0, %a2}";
16627
16628     default:
16629       gcc_unreachable ();
16630     }
16631 }
16632   [(set_attr "type" "alu,lea")
16633    (set_attr "mode" "DI")])
16634
16635 (define_insn "allocate_stack_worker_32"
16636   [(set (match_operand:SI 0 "register_operand" "=a")
16637         (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")]
16638                             UNSPECV_STACK_PROBE))
16639    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 1)))
16640    (clobber (reg:CC FLAGS_REG))]
16641   "!TARGET_64BIT && TARGET_STACK_PROBE"
16642   "call\t___chkstk"
16643   [(set_attr "type" "multi")
16644    (set_attr "length" "5")])
16645
16646 (define_insn "allocate_stack_worker_64"
16647   [(set (match_operand:DI 0 "register_operand" "=a")
16648         (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "0")]
16649                             UNSPECV_STACK_PROBE))
16650    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 1)))
16651    (clobber (reg:DI R10_REG))
16652    (clobber (reg:DI R11_REG))
16653    (clobber (reg:CC FLAGS_REG))]
16654   "TARGET_64BIT && TARGET_STACK_PROBE"
16655   "call\t___chkstk"
16656   [(set_attr "type" "multi")
16657    (set_attr "length" "5")])
16658
16659 (define_expand "allocate_stack"
16660   [(match_operand 0 "register_operand" "")
16661    (match_operand 1 "general_operand" "")]
16662   "TARGET_STACK_PROBE"
16663 {
16664   rtx x;
16665
16666 #ifndef CHECK_STACK_LIMIT
16667 #define CHECK_STACK_LIMIT 0
16668 #endif
16669
16670   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16671       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16672     {
16673       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16674                                stack_pointer_rtx, 0, OPTAB_DIRECT);
16675       if (x != stack_pointer_rtx)
16676         emit_move_insn (stack_pointer_rtx, x);
16677     }
16678   else
16679     {
16680       x = copy_to_mode_reg (Pmode, operands[1]);
16681       if (TARGET_64BIT)
16682         x = gen_allocate_stack_worker_64 (x, x);
16683       else
16684         x = gen_allocate_stack_worker_32 (x, x);
16685       emit_insn (x);
16686     }
16687
16688   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16689   DONE;
16690 })
16691
16692 ;; Use IOR for stack probes, this is shorter.
16693 (define_expand "probe_stack"
16694   [(match_operand 0 "memory_operand" "")]
16695   ""
16696 {
16697   if (GET_MODE (operands[0]) == DImode)
16698     emit_insn (gen_iordi3 (operands[0], operands[0], const0_rtx));
16699   else
16700     emit_insn (gen_iorsi3 (operands[0], operands[0], const0_rtx));
16701   DONE;
16702 })
16703
16704 (define_expand "builtin_setjmp_receiver"
16705   [(label_ref (match_operand 0 "" ""))]
16706   "!TARGET_64BIT && flag_pic"
16707 {
16708 #if TARGET_MACHO
16709   if (TARGET_MACHO)
16710     {
16711       rtx xops[3];
16712       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16713       rtx label_rtx = gen_label_rtx ();
16714       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16715       xops[0] = xops[1] = picreg;
16716       xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16717       ix86_expand_binary_operator (MINUS, SImode, xops);
16718     }
16719   else
16720 #endif
16721     emit_insn (gen_set_got (pic_offset_table_rtx));
16722   DONE;
16723 })
16724 \f
16725 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16726
16727 (define_split
16728   [(set (match_operand 0 "register_operand" "")
16729         (match_operator 3 "promotable_binary_operator"
16730            [(match_operand 1 "register_operand" "")
16731             (match_operand 2 "aligned_operand" "")]))
16732    (clobber (reg:CC FLAGS_REG))]
16733   "! TARGET_PARTIAL_REG_STALL && reload_completed
16734    && ((GET_MODE (operands[0]) == HImode
16735         && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16736             /* ??? next two lines just !satisfies_constraint_K (...) */
16737             || !CONST_INT_P (operands[2])
16738             || satisfies_constraint_K (operands[2])))
16739        || (GET_MODE (operands[0]) == QImode
16740            && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16741   [(parallel [(set (match_dup 0)
16742                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16743               (clobber (reg:CC FLAGS_REG))])]
16744   "operands[0] = gen_lowpart (SImode, operands[0]);
16745    operands[1] = gen_lowpart (SImode, operands[1]);
16746    if (GET_CODE (operands[3]) != ASHIFT)
16747      operands[2] = gen_lowpart (SImode, operands[2]);
16748    PUT_MODE (operands[3], SImode);")
16749
16750 ; Promote the QImode tests, as i386 has encoding of the AND
16751 ; instruction with 32-bit sign-extended immediate and thus the
16752 ; instruction size is unchanged, except in the %eax case for
16753 ; which it is increased by one byte, hence the ! optimize_size.
16754 (define_split
16755   [(set (match_operand 0 "flags_reg_operand" "")
16756         (match_operator 2 "compare_operator"
16757           [(and (match_operand 3 "aligned_operand" "")
16758                 (match_operand 4 "const_int_operand" ""))
16759            (const_int 0)]))
16760    (set (match_operand 1 "register_operand" "")
16761         (and (match_dup 3) (match_dup 4)))]
16762   "! TARGET_PARTIAL_REG_STALL && reload_completed
16763    && optimize_insn_for_speed_p ()
16764    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16765        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16766    /* Ensure that the operand will remain sign-extended immediate.  */
16767    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16768   [(parallel [(set (match_dup 0)
16769                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16770                                     (const_int 0)]))
16771               (set (match_dup 1)
16772                    (and:SI (match_dup 3) (match_dup 4)))])]
16773 {
16774   operands[4]
16775     = gen_int_mode (INTVAL (operands[4])
16776                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16777   operands[1] = gen_lowpart (SImode, operands[1]);
16778   operands[3] = gen_lowpart (SImode, operands[3]);
16779 })
16780
16781 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16782 ; the TEST instruction with 32-bit sign-extended immediate and thus
16783 ; the instruction size would at least double, which is not what we
16784 ; want even with ! optimize_size.
16785 (define_split
16786   [(set (match_operand 0 "flags_reg_operand" "")
16787         (match_operator 1 "compare_operator"
16788           [(and (match_operand:HI 2 "aligned_operand" "")
16789                 (match_operand:HI 3 "const_int_operand" ""))
16790            (const_int 0)]))]
16791   "! TARGET_PARTIAL_REG_STALL && reload_completed
16792    && ! TARGET_FAST_PREFIX
16793    && optimize_insn_for_speed_p ()
16794    /* Ensure that the operand will remain sign-extended immediate.  */
16795    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16796   [(set (match_dup 0)
16797         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16798                          (const_int 0)]))]
16799 {
16800   operands[3]
16801     = gen_int_mode (INTVAL (operands[3])
16802                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16803   operands[2] = gen_lowpart (SImode, operands[2]);
16804 })
16805
16806 (define_split
16807   [(set (match_operand 0 "register_operand" "")
16808         (neg (match_operand 1 "register_operand" "")))
16809    (clobber (reg:CC FLAGS_REG))]
16810   "! TARGET_PARTIAL_REG_STALL && reload_completed
16811    && (GET_MODE (operands[0]) == HImode
16812        || (GET_MODE (operands[0]) == QImode
16813            && (TARGET_PROMOTE_QImode
16814                || optimize_insn_for_size_p ())))"
16815   [(parallel [(set (match_dup 0)
16816                    (neg:SI (match_dup 1)))
16817               (clobber (reg:CC FLAGS_REG))])]
16818   "operands[0] = gen_lowpart (SImode, operands[0]);
16819    operands[1] = gen_lowpart (SImode, operands[1]);")
16820
16821 (define_split
16822   [(set (match_operand 0 "register_operand" "")
16823         (not (match_operand 1 "register_operand" "")))]
16824   "! TARGET_PARTIAL_REG_STALL && reload_completed
16825    && (GET_MODE (operands[0]) == HImode
16826        || (GET_MODE (operands[0]) == QImode
16827            && (TARGET_PROMOTE_QImode
16828                || optimize_insn_for_size_p ())))"
16829   [(set (match_dup 0)
16830         (not:SI (match_dup 1)))]
16831   "operands[0] = gen_lowpart (SImode, operands[0]);
16832    operands[1] = gen_lowpart (SImode, operands[1]);")
16833
16834 (define_split
16835   [(set (match_operand 0 "register_operand" "")
16836         (if_then_else (match_operator 1 "comparison_operator"
16837                                 [(reg FLAGS_REG) (const_int 0)])
16838                       (match_operand 2 "register_operand" "")
16839                       (match_operand 3 "register_operand" "")))]
16840   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
16841    && (GET_MODE (operands[0]) == HImode
16842        || (GET_MODE (operands[0]) == QImode
16843            && (TARGET_PROMOTE_QImode
16844                || optimize_insn_for_size_p ())))"
16845   [(set (match_dup 0)
16846         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16847   "operands[0] = gen_lowpart (SImode, operands[0]);
16848    operands[2] = gen_lowpart (SImode, operands[2]);
16849    operands[3] = gen_lowpart (SImode, operands[3]);")
16850
16851 \f
16852 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
16853 ;; transform a complex memory operation into two memory to register operations.
16854
16855 ;; Don't push memory operands
16856 (define_peephole2
16857   [(set (match_operand:SI 0 "push_operand" "")
16858         (match_operand:SI 1 "memory_operand" ""))
16859    (match_scratch:SI 2 "r")]
16860   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16861    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16862   [(set (match_dup 2) (match_dup 1))
16863    (set (match_dup 0) (match_dup 2))]
16864   "")
16865
16866 (define_peephole2
16867   [(set (match_operand:DI 0 "push_operand" "")
16868         (match_operand:DI 1 "memory_operand" ""))
16869    (match_scratch:DI 2 "r")]
16870   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16871    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16872   [(set (match_dup 2) (match_dup 1))
16873    (set (match_dup 0) (match_dup 2))]
16874   "")
16875
16876 ;; We need to handle SFmode only, because DFmode and XFmode is split to
16877 ;; SImode pushes.
16878 (define_peephole2
16879   [(set (match_operand:SF 0 "push_operand" "")
16880         (match_operand:SF 1 "memory_operand" ""))
16881    (match_scratch:SF 2 "r")]
16882   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16883    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16884   [(set (match_dup 2) (match_dup 1))
16885    (set (match_dup 0) (match_dup 2))]
16886   "")
16887
16888 (define_peephole2
16889   [(set (match_operand:HI 0 "push_operand" "")
16890         (match_operand:HI 1 "memory_operand" ""))
16891    (match_scratch:HI 2 "r")]
16892   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16893    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16894   [(set (match_dup 2) (match_dup 1))
16895    (set (match_dup 0) (match_dup 2))]
16896   "")
16897
16898 (define_peephole2
16899   [(set (match_operand:QI 0 "push_operand" "")
16900         (match_operand:QI 1 "memory_operand" ""))
16901    (match_scratch:QI 2 "q")]
16902   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16903    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16904   [(set (match_dup 2) (match_dup 1))
16905    (set (match_dup 0) (match_dup 2))]
16906   "")
16907
16908 ;; Don't move an immediate directly to memory when the instruction
16909 ;; gets too big.
16910 (define_peephole2
16911   [(match_scratch:SI 1 "r")
16912    (set (match_operand:SI 0 "memory_operand" "")
16913         (const_int 0))]
16914   "optimize_insn_for_speed_p ()
16915    && ! TARGET_USE_MOV0
16916    && TARGET_SPLIT_LONG_MOVES
16917    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16918    && peep2_regno_dead_p (0, FLAGS_REG)"
16919   [(parallel [(set (match_dup 1) (const_int 0))
16920               (clobber (reg:CC FLAGS_REG))])
16921    (set (match_dup 0) (match_dup 1))]
16922   "")
16923
16924 (define_peephole2
16925   [(match_scratch:HI 1 "r")
16926    (set (match_operand:HI 0 "memory_operand" "")
16927         (const_int 0))]
16928   "optimize_insn_for_speed_p ()
16929    && ! TARGET_USE_MOV0
16930    && TARGET_SPLIT_LONG_MOVES
16931    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16932    && peep2_regno_dead_p (0, FLAGS_REG)"
16933   [(parallel [(set (match_dup 2) (const_int 0))
16934               (clobber (reg:CC FLAGS_REG))])
16935    (set (match_dup 0) (match_dup 1))]
16936   "operands[2] = gen_lowpart (SImode, operands[1]);")
16937
16938 (define_peephole2
16939   [(match_scratch:QI 1 "q")
16940    (set (match_operand:QI 0 "memory_operand" "")
16941         (const_int 0))]
16942   "optimize_insn_for_speed_p ()
16943    && ! TARGET_USE_MOV0
16944    && TARGET_SPLIT_LONG_MOVES
16945    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16946    && peep2_regno_dead_p (0, FLAGS_REG)"
16947   [(parallel [(set (match_dup 2) (const_int 0))
16948               (clobber (reg:CC FLAGS_REG))])
16949    (set (match_dup 0) (match_dup 1))]
16950   "operands[2] = gen_lowpart (SImode, operands[1]);")
16951
16952 (define_peephole2
16953   [(match_scratch:SI 2 "r")
16954    (set (match_operand:SI 0 "memory_operand" "")
16955         (match_operand:SI 1 "immediate_operand" ""))]
16956   "optimize_insn_for_speed_p ()
16957    && TARGET_SPLIT_LONG_MOVES
16958    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16959   [(set (match_dup 2) (match_dup 1))
16960    (set (match_dup 0) (match_dup 2))]
16961   "")
16962
16963 (define_peephole2
16964   [(match_scratch:HI 2 "r")
16965    (set (match_operand:HI 0 "memory_operand" "")
16966         (match_operand:HI 1 "immediate_operand" ""))]
16967   "optimize_insn_for_speed_p ()
16968    && TARGET_SPLIT_LONG_MOVES
16969    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16970   [(set (match_dup 2) (match_dup 1))
16971    (set (match_dup 0) (match_dup 2))]
16972   "")
16973
16974 (define_peephole2
16975   [(match_scratch:QI 2 "q")
16976    (set (match_operand:QI 0 "memory_operand" "")
16977         (match_operand:QI 1 "immediate_operand" ""))]
16978   "optimize_insn_for_speed_p ()
16979    && TARGET_SPLIT_LONG_MOVES
16980    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16981   [(set (match_dup 2) (match_dup 1))
16982    (set (match_dup 0) (match_dup 2))]
16983   "")
16984
16985 ;; Don't compare memory with zero, load and use a test instead.
16986 (define_peephole2
16987   [(set (match_operand 0 "flags_reg_operand" "")
16988         (match_operator 1 "compare_operator"
16989           [(match_operand:SI 2 "memory_operand" "")
16990            (const_int 0)]))
16991    (match_scratch:SI 3 "r")]
16992   "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16993   [(set (match_dup 3) (match_dup 2))
16994    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
16995   "")
16996
16997 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16998 ;; Don't split NOTs with a displacement operand, because resulting XOR
16999 ;; will not be pairable anyway.
17000 ;;
17001 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
17002 ;; represented using a modRM byte.  The XOR replacement is long decoded,
17003 ;; so this split helps here as well.
17004 ;;
17005 ;; Note: Can't do this as a regular split because we can't get proper
17006 ;; lifetime information then.
17007
17008 (define_peephole2
17009   [(set (match_operand:SI 0 "nonimmediate_operand" "")
17010         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
17011   "optimize_insn_for_speed_p ()
17012    && ((TARGET_NOT_UNPAIRABLE
17013         && (!MEM_P (operands[0])
17014             || !memory_displacement_operand (operands[0], SImode)))
17015        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
17016    && peep2_regno_dead_p (0, FLAGS_REG)"
17017   [(parallel [(set (match_dup 0)
17018                    (xor:SI (match_dup 1) (const_int -1)))
17019               (clobber (reg:CC FLAGS_REG))])]
17020   "")
17021
17022 (define_peephole2
17023   [(set (match_operand:HI 0 "nonimmediate_operand" "")
17024         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
17025   "optimize_insn_for_speed_p ()
17026    && ((TARGET_NOT_UNPAIRABLE
17027         && (!MEM_P (operands[0])
17028             || !memory_displacement_operand (operands[0], HImode)))
17029        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
17030    && peep2_regno_dead_p (0, FLAGS_REG)"
17031   [(parallel [(set (match_dup 0)
17032                    (xor:HI (match_dup 1) (const_int -1)))
17033               (clobber (reg:CC FLAGS_REG))])]
17034   "")
17035
17036 (define_peephole2
17037   [(set (match_operand:QI 0 "nonimmediate_operand" "")
17038         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
17039   "optimize_insn_for_speed_p ()
17040    && ((TARGET_NOT_UNPAIRABLE
17041         && (!MEM_P (operands[0])
17042             || !memory_displacement_operand (operands[0], QImode)))
17043        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
17044    && peep2_regno_dead_p (0, FLAGS_REG)"
17045   [(parallel [(set (match_dup 0)
17046                    (xor:QI (match_dup 1) (const_int -1)))
17047               (clobber (reg:CC FLAGS_REG))])]
17048   "")
17049
17050 ;; Non pairable "test imm, reg" instructions can be translated to
17051 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
17052 ;; byte opcode instead of two, have a short form for byte operands),
17053 ;; so do it for other CPUs as well.  Given that the value was dead,
17054 ;; this should not create any new dependencies.  Pass on the sub-word
17055 ;; versions if we're concerned about partial register stalls.
17056
17057 (define_peephole2
17058   [(set (match_operand 0 "flags_reg_operand" "")
17059         (match_operator 1 "compare_operator"
17060           [(and:SI (match_operand:SI 2 "register_operand" "")
17061                    (match_operand:SI 3 "immediate_operand" ""))
17062            (const_int 0)]))]
17063   "ix86_match_ccmode (insn, CCNOmode)
17064    && (true_regnum (operands[2]) != AX_REG
17065        || satisfies_constraint_K (operands[3]))
17066    && peep2_reg_dead_p (1, operands[2])"
17067   [(parallel
17068      [(set (match_dup 0)
17069            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17070                             (const_int 0)]))
17071       (set (match_dup 2)
17072            (and:SI (match_dup 2) (match_dup 3)))])]
17073   "")
17074
17075 ;; We don't need to handle HImode case, because it will be promoted to SImode
17076 ;; on ! TARGET_PARTIAL_REG_STALL
17077
17078 (define_peephole2
17079   [(set (match_operand 0 "flags_reg_operand" "")
17080         (match_operator 1 "compare_operator"
17081           [(and:QI (match_operand:QI 2 "register_operand" "")
17082                    (match_operand:QI 3 "immediate_operand" ""))
17083            (const_int 0)]))]
17084   "! TARGET_PARTIAL_REG_STALL
17085    && ix86_match_ccmode (insn, CCNOmode)
17086    && true_regnum (operands[2]) != AX_REG
17087    && peep2_reg_dead_p (1, operands[2])"
17088   [(parallel
17089      [(set (match_dup 0)
17090            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17091                             (const_int 0)]))
17092       (set (match_dup 2)
17093            (and:QI (match_dup 2) (match_dup 3)))])]
17094   "")
17095
17096 (define_peephole2
17097   [(set (match_operand 0 "flags_reg_operand" "")
17098         (match_operator 1 "compare_operator"
17099           [(and:SI
17100              (zero_extract:SI
17101                (match_operand 2 "ext_register_operand" "")
17102                (const_int 8)
17103                (const_int 8))
17104              (match_operand 3 "const_int_operand" ""))
17105            (const_int 0)]))]
17106   "! TARGET_PARTIAL_REG_STALL
17107    && ix86_match_ccmode (insn, CCNOmode)
17108    && true_regnum (operands[2]) != AX_REG
17109    && peep2_reg_dead_p (1, operands[2])"
17110   [(parallel [(set (match_dup 0)
17111                    (match_op_dup 1
17112                      [(and:SI
17113                         (zero_extract:SI
17114                           (match_dup 2)
17115                           (const_int 8)
17116                           (const_int 8))
17117                         (match_dup 3))
17118                       (const_int 0)]))
17119               (set (zero_extract:SI (match_dup 2)
17120                                     (const_int 8)
17121                                     (const_int 8))
17122                    (and:SI
17123                      (zero_extract:SI
17124                        (match_dup 2)
17125                        (const_int 8)
17126                        (const_int 8))
17127                      (match_dup 3)))])]
17128   "")
17129
17130 ;; Don't do logical operations with memory inputs.
17131 (define_peephole2
17132   [(match_scratch:SI 2 "r")
17133    (parallel [(set (match_operand:SI 0 "register_operand" "")
17134                    (match_operator:SI 3 "arith_or_logical_operator"
17135                      [(match_dup 0)
17136                       (match_operand:SI 1 "memory_operand" "")]))
17137               (clobber (reg:CC FLAGS_REG))])]
17138   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
17139   [(set (match_dup 2) (match_dup 1))
17140    (parallel [(set (match_dup 0)
17141                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17142               (clobber (reg:CC FLAGS_REG))])]
17143   "")
17144
17145 (define_peephole2
17146   [(match_scratch:SI 2 "r")
17147    (parallel [(set (match_operand:SI 0 "register_operand" "")
17148                    (match_operator:SI 3 "arith_or_logical_operator"
17149                      [(match_operand:SI 1 "memory_operand" "")
17150                       (match_dup 0)]))
17151               (clobber (reg:CC FLAGS_REG))])]
17152   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
17153   [(set (match_dup 2) (match_dup 1))
17154    (parallel [(set (match_dup 0)
17155                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17156               (clobber (reg:CC FLAGS_REG))])]
17157   "")
17158
17159 ;; Prefer Load+RegOp to Mov+MemOp.  Watch out for cases when the memory address
17160 ;; refers to the destination of the load!
17161
17162 (define_peephole2
17163   [(set (match_operand:SI 0 "register_operand" "")
17164         (match_operand:SI 1 "register_operand" ""))
17165    (parallel [(set (match_dup 0)
17166                    (match_operator:SI 3 "commutative_operator"
17167                      [(match_dup 0)
17168                       (match_operand:SI 2 "memory_operand" "")]))
17169               (clobber (reg:CC FLAGS_REG))])]
17170   "REGNO (operands[0]) != REGNO (operands[1])
17171    && GENERAL_REGNO_P (REGNO (operands[0]))
17172    && GENERAL_REGNO_P (REGNO (operands[1]))"
17173   [(set (match_dup 0) (match_dup 4))
17174    (parallel [(set (match_dup 0)
17175                    (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17176               (clobber (reg:CC FLAGS_REG))])]
17177   "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17178
17179 (define_peephole2
17180   [(set (match_operand 0 "register_operand" "")
17181         (match_operand 1 "register_operand" ""))
17182    (set (match_dup 0)
17183                    (match_operator 3 "commutative_operator"
17184                      [(match_dup 0)
17185                       (match_operand 2 "memory_operand" "")]))]
17186   "REGNO (operands[0]) != REGNO (operands[1])
17187    && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1])) 
17188        || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17189   [(set (match_dup 0) (match_dup 2))
17190    (set (match_dup 0)
17191         (match_op_dup 3 [(match_dup 0) (match_dup 1)]))]
17192   "")
17193
17194 ; Don't do logical operations with memory outputs
17195 ;
17196 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17197 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
17198 ; the same decoder scheduling characteristics as the original.
17199
17200 (define_peephole2
17201   [(match_scratch:SI 2 "r")
17202    (parallel [(set (match_operand:SI 0 "memory_operand" "")
17203                    (match_operator:SI 3 "arith_or_logical_operator"
17204                      [(match_dup 0)
17205                       (match_operand:SI 1 "nonmemory_operand" "")]))
17206               (clobber (reg:CC FLAGS_REG))])]
17207   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
17208    /* Do not split stack checking probes.  */
17209    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17210   [(set (match_dup 2) (match_dup 0))
17211    (parallel [(set (match_dup 2)
17212                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17213               (clobber (reg:CC FLAGS_REG))])
17214    (set (match_dup 0) (match_dup 2))]
17215   "")
17216
17217 (define_peephole2
17218   [(match_scratch:SI 2 "r")
17219    (parallel [(set (match_operand:SI 0 "memory_operand" "")
17220                    (match_operator:SI 3 "arith_or_logical_operator"
17221                      [(match_operand:SI 1 "nonmemory_operand" "")
17222                       (match_dup 0)]))
17223               (clobber (reg:CC FLAGS_REG))])]
17224   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
17225    /* Do not split stack checking probes.  */
17226    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17227   [(set (match_dup 2) (match_dup 0))
17228    (parallel [(set (match_dup 2)
17229                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17230               (clobber (reg:CC FLAGS_REG))])
17231    (set (match_dup 0) (match_dup 2))]
17232   "")
17233
17234 ;; Attempt to always use XOR for zeroing registers.
17235 (define_peephole2
17236   [(set (match_operand 0 "register_operand" "")
17237         (match_operand 1 "const0_operand" ""))]
17238   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17239    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17240    && GENERAL_REG_P (operands[0])
17241    && peep2_regno_dead_p (0, FLAGS_REG)"
17242   [(parallel [(set (match_dup 0) (const_int 0))
17243               (clobber (reg:CC FLAGS_REG))])]
17244 {
17245   operands[0] = gen_lowpart (word_mode, operands[0]);
17246 })
17247
17248 (define_peephole2
17249   [(set (strict_low_part (match_operand 0 "register_operand" ""))
17250         (const_int 0))]
17251   "(GET_MODE (operands[0]) == QImode
17252     || GET_MODE (operands[0]) == HImode)
17253    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17254    && peep2_regno_dead_p (0, FLAGS_REG)"
17255   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17256               (clobber (reg:CC FLAGS_REG))])])
17257
17258 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
17259 (define_peephole2
17260   [(set (match_operand 0 "register_operand" "")
17261         (const_int -1))]
17262   "(GET_MODE (operands[0]) == HImode
17263     || GET_MODE (operands[0]) == SImode
17264     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
17265    && (optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17266    && peep2_regno_dead_p (0, FLAGS_REG)"
17267   [(parallel [(set (match_dup 0) (const_int -1))
17268               (clobber (reg:CC FLAGS_REG))])]
17269   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
17270                               operands[0]);")
17271
17272 ;; Attempt to convert simple leas to adds. These can be created by
17273 ;; move expanders.
17274 (define_peephole2
17275   [(set (match_operand:SI 0 "register_operand" "")
17276         (plus:SI (match_dup 0)
17277                  (match_operand:SI 1 "nonmemory_operand" "")))]
17278   "peep2_regno_dead_p (0, FLAGS_REG)"
17279   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
17280               (clobber (reg:CC FLAGS_REG))])]
17281   "")
17282
17283 (define_peephole2
17284   [(set (match_operand:SI 0 "register_operand" "")
17285         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
17286                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
17287   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
17288   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17289               (clobber (reg:CC FLAGS_REG))])]
17290   "operands[2] = gen_lowpart (SImode, operands[2]);")
17291
17292 (define_peephole2
17293   [(set (match_operand:DI 0 "register_operand" "")
17294         (plus:DI (match_dup 0)
17295                  (match_operand:DI 1 "x86_64_general_operand" "")))]
17296   "peep2_regno_dead_p (0, FLAGS_REG)"
17297   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
17298               (clobber (reg:CC FLAGS_REG))])]
17299   "")
17300
17301 (define_peephole2
17302   [(set (match_operand:SI 0 "register_operand" "")
17303         (mult:SI (match_dup 0)
17304                  (match_operand:SI 1 "const_int_operand" "")))]
17305   "exact_log2 (INTVAL (operands[1])) >= 0
17306    && peep2_regno_dead_p (0, FLAGS_REG)"
17307   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17308               (clobber (reg:CC FLAGS_REG))])]
17309   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17310
17311 (define_peephole2
17312   [(set (match_operand:DI 0 "register_operand" "")
17313         (mult:DI (match_dup 0)
17314                  (match_operand:DI 1 "const_int_operand" "")))]
17315   "exact_log2 (INTVAL (operands[1])) >= 0
17316    && peep2_regno_dead_p (0, FLAGS_REG)"
17317   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
17318               (clobber (reg:CC FLAGS_REG))])]
17319   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17320
17321 (define_peephole2
17322   [(set (match_operand:SI 0 "register_operand" "")
17323         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
17324                    (match_operand:DI 2 "const_int_operand" "")) 0))]
17325   "exact_log2 (INTVAL (operands[2])) >= 0
17326    && REGNO (operands[0]) == REGNO (operands[1])
17327    && peep2_regno_dead_p (0, FLAGS_REG)"
17328   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17329               (clobber (reg:CC FLAGS_REG))])]
17330   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17331
17332 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
17333 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
17334 ;; many CPUs it is also faster, since special hardware to avoid esp
17335 ;; dependencies is present.
17336
17337 ;; While some of these conversions may be done using splitters, we use peepholes
17338 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
17339
17340 ;; Convert prologue esp subtractions to push.
17341 ;; We need register to push.  In order to keep verify_flow_info happy we have
17342 ;; two choices
17343 ;; - use scratch and clobber it in order to avoid dependencies
17344 ;; - use already live register
17345 ;; We can't use the second way right now, since there is no reliable way how to
17346 ;; verify that given register is live.  First choice will also most likely in
17347 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
17348 ;; call clobbered registers are dead.  We may want to use base pointer as an
17349 ;; alternative when no register is available later.
17350
17351 (define_peephole2
17352   [(match_scratch:SI 0 "r")
17353    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
17354               (clobber (reg:CC FLAGS_REG))
17355               (clobber (mem:BLK (scratch)))])]
17356   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
17357   [(clobber (match_dup 0))
17358    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
17359               (clobber (mem:BLK (scratch)))])])
17360
17361 (define_peephole2
17362   [(match_scratch:SI 0 "r")
17363    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
17364               (clobber (reg:CC FLAGS_REG))
17365               (clobber (mem:BLK (scratch)))])]
17366   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
17367   [(clobber (match_dup 0))
17368    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
17369    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
17370               (clobber (mem:BLK (scratch)))])])
17371
17372 ;; Convert esp subtractions to push.
17373 (define_peephole2
17374   [(match_scratch:SI 0 "r")
17375    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
17376               (clobber (reg:CC FLAGS_REG))])]
17377   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
17378   [(clobber (match_dup 0))
17379    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
17380
17381 (define_peephole2
17382   [(match_scratch:SI 0 "r")
17383    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
17384               (clobber (reg:CC FLAGS_REG))])]
17385   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
17386   [(clobber (match_dup 0))
17387    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
17388    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
17389
17390 ;; Convert epilogue deallocator to pop.
17391 (define_peephole2
17392   [(match_scratch:SI 0 "r")
17393    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
17394               (clobber (reg:CC FLAGS_REG))
17395               (clobber (mem:BLK (scratch)))])]
17396   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
17397   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17398               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
17399               (clobber (mem:BLK (scratch)))])]
17400   "")
17401
17402 ;; Two pops case is tricky, since pop causes dependency on destination register.
17403 ;; We use two registers if available.
17404 (define_peephole2
17405   [(match_scratch:SI 0 "r")
17406    (match_scratch:SI 1 "r")
17407    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
17408               (clobber (reg:CC FLAGS_REG))
17409               (clobber (mem:BLK (scratch)))])]
17410   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
17411   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17412               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
17413               (clobber (mem:BLK (scratch)))])
17414    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
17415               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
17416   "")
17417
17418 (define_peephole2
17419   [(match_scratch:SI 0 "r")
17420    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
17421               (clobber (reg:CC FLAGS_REG))
17422               (clobber (mem:BLK (scratch)))])]
17423   "optimize_insn_for_size_p ()"
17424   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17425               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
17426               (clobber (mem:BLK (scratch)))])
17427    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17428               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
17429   "")
17430
17431 ;; Convert esp additions to pop.
17432 (define_peephole2
17433   [(match_scratch:SI 0 "r")
17434    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
17435               (clobber (reg:CC FLAGS_REG))])]
17436   ""
17437   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17438               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
17439   "")
17440
17441 ;; Two pops case is tricky, since pop causes dependency on destination register.
17442 ;; We use two registers if available.
17443 (define_peephole2
17444   [(match_scratch:SI 0 "r")
17445    (match_scratch:SI 1 "r")
17446    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
17447               (clobber (reg:CC FLAGS_REG))])]
17448   ""
17449   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17450               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
17451    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
17452               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
17453   "")
17454
17455 (define_peephole2
17456   [(match_scratch:SI 0 "r")
17457    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
17458               (clobber (reg:CC FLAGS_REG))])]
17459   "optimize_insn_for_size_p ()"
17460   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17461               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
17462    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17463               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
17464   "")
17465 \f
17466 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17467 ;; required and register dies.  Similarly for 128 to -128.
17468 (define_peephole2
17469   [(set (match_operand 0 "flags_reg_operand" "")
17470         (match_operator 1 "compare_operator"
17471           [(match_operand 2 "register_operand" "")
17472            (match_operand 3 "const_int_operand" "")]))]
17473   "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17474      && incdec_operand (operands[3], GET_MODE (operands[3])))
17475     || (!TARGET_FUSE_CMP_AND_BRANCH
17476         && INTVAL (operands[3]) == 128))
17477    && ix86_match_ccmode (insn, CCGCmode)
17478    && peep2_reg_dead_p (1, operands[2])"
17479   [(parallel [(set (match_dup 0)
17480                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17481               (clobber (match_dup 2))])]
17482   "")
17483 \f
17484 (define_peephole2
17485   [(match_scratch:DI 0 "r")
17486    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
17487               (clobber (reg:CC FLAGS_REG))
17488               (clobber (mem:BLK (scratch)))])]
17489   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
17490   [(clobber (match_dup 0))
17491    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
17492               (clobber (mem:BLK (scratch)))])])
17493
17494 (define_peephole2
17495   [(match_scratch:DI 0 "r")
17496    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
17497               (clobber (reg:CC FLAGS_REG))
17498               (clobber (mem:BLK (scratch)))])]
17499   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
17500   [(clobber (match_dup 0))
17501    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
17502    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
17503               (clobber (mem:BLK (scratch)))])])
17504
17505 ;; Convert esp subtractions to push.
17506 (define_peephole2
17507   [(match_scratch:DI 0 "r")
17508    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
17509               (clobber (reg:CC FLAGS_REG))])]
17510   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
17511   [(clobber (match_dup 0))
17512    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
17513
17514 (define_peephole2
17515   [(match_scratch:DI 0 "r")
17516    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
17517               (clobber (reg:CC FLAGS_REG))])]
17518   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
17519   [(clobber (match_dup 0))
17520    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
17521    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
17522
17523 ;; Convert epilogue deallocator to pop.
17524 (define_peephole2
17525   [(match_scratch:DI 0 "r")
17526    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
17527               (clobber (reg:CC FLAGS_REG))
17528               (clobber (mem:BLK (scratch)))])]
17529   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
17530   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17531               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
17532               (clobber (mem:BLK (scratch)))])]
17533   "")
17534
17535 ;; Two pops case is tricky, since pop causes dependency on destination register.
17536 ;; We use two registers if available.
17537 (define_peephole2
17538   [(match_scratch:DI 0 "r")
17539    (match_scratch:DI 1 "r")
17540    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
17541               (clobber (reg:CC FLAGS_REG))
17542               (clobber (mem:BLK (scratch)))])]
17543   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
17544   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17545               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
17546               (clobber (mem:BLK (scratch)))])
17547    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
17548               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
17549   "")
17550
17551 (define_peephole2
17552   [(match_scratch:DI 0 "r")
17553    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
17554               (clobber (reg:CC FLAGS_REG))
17555               (clobber (mem:BLK (scratch)))])]
17556   "optimize_insn_for_size_p ()"
17557   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17558               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
17559               (clobber (mem:BLK (scratch)))])
17560    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17561               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
17562   "")
17563
17564 ;; Convert esp additions to pop.
17565 (define_peephole2
17566   [(match_scratch:DI 0 "r")
17567    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
17568               (clobber (reg:CC FLAGS_REG))])]
17569   ""
17570   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17571               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
17572   "")
17573
17574 ;; Two pops case is tricky, since pop causes dependency on destination register.
17575 ;; We use two registers if available.
17576 (define_peephole2
17577   [(match_scratch:DI 0 "r")
17578    (match_scratch:DI 1 "r")
17579    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
17580               (clobber (reg:CC FLAGS_REG))])]
17581   ""
17582   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17583               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
17584    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
17585               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
17586   "")
17587
17588 (define_peephole2
17589   [(match_scratch:DI 0 "r")
17590    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
17591               (clobber (reg:CC FLAGS_REG))])]
17592   "optimize_insn_for_size_p ()"
17593   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17594               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
17595    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17596               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
17597   "")
17598 \f
17599 ;; Convert imul by three, five and nine into lea
17600 (define_peephole2
17601   [(parallel
17602     [(set (match_operand:SI 0 "register_operand" "")
17603           (mult:SI (match_operand:SI 1 "register_operand" "")
17604                    (match_operand:SI 2 "const_int_operand" "")))
17605      (clobber (reg:CC FLAGS_REG))])]
17606   "INTVAL (operands[2]) == 3
17607    || INTVAL (operands[2]) == 5
17608    || INTVAL (operands[2]) == 9"
17609   [(set (match_dup 0)
17610         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
17611                  (match_dup 1)))]
17612   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
17613
17614 (define_peephole2
17615   [(parallel
17616     [(set (match_operand:SI 0 "register_operand" "")
17617           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
17618                    (match_operand:SI 2 "const_int_operand" "")))
17619      (clobber (reg:CC FLAGS_REG))])]
17620   "optimize_insn_for_speed_p ()
17621    && (INTVAL (operands[2]) == 3
17622        || INTVAL (operands[2]) == 5
17623        || INTVAL (operands[2]) == 9)"
17624   [(set (match_dup 0) (match_dup 1))
17625    (set (match_dup 0)
17626         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
17627                  (match_dup 0)))]
17628   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
17629
17630 (define_peephole2
17631   [(parallel
17632     [(set (match_operand:DI 0 "register_operand" "")
17633           (mult:DI (match_operand:DI 1 "register_operand" "")
17634                    (match_operand:DI 2 "const_int_operand" "")))
17635      (clobber (reg:CC FLAGS_REG))])]
17636   "TARGET_64BIT
17637    && (INTVAL (operands[2]) == 3
17638        || INTVAL (operands[2]) == 5
17639        || INTVAL (operands[2]) == 9)"
17640   [(set (match_dup 0)
17641         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
17642                  (match_dup 1)))]
17643   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
17644
17645 (define_peephole2
17646   [(parallel
17647     [(set (match_operand:DI 0 "register_operand" "")
17648           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
17649                    (match_operand:DI 2 "const_int_operand" "")))
17650      (clobber (reg:CC FLAGS_REG))])]
17651   "TARGET_64BIT
17652    && optimize_insn_for_speed_p ()
17653    && (INTVAL (operands[2]) == 3
17654        || INTVAL (operands[2]) == 5
17655        || INTVAL (operands[2]) == 9)"
17656   [(set (match_dup 0) (match_dup 1))
17657    (set (match_dup 0)
17658         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
17659                  (match_dup 0)))]
17660   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
17661
17662 ;; Imul $32bit_imm, mem, reg is vector decoded, while
17663 ;; imul $32bit_imm, reg, reg is direct decoded.
17664 (define_peephole2
17665   [(match_scratch:DI 3 "r")
17666    (parallel [(set (match_operand:DI 0 "register_operand" "")
17667                    (mult:DI (match_operand:DI 1 "memory_operand" "")
17668                             (match_operand:DI 2 "immediate_operand" "")))
17669               (clobber (reg:CC FLAGS_REG))])]
17670   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17671    && !satisfies_constraint_K (operands[2])"
17672   [(set (match_dup 3) (match_dup 1))
17673    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
17674               (clobber (reg:CC FLAGS_REG))])]
17675 "")
17676
17677 (define_peephole2
17678   [(match_scratch:SI 3 "r")
17679    (parallel [(set (match_operand:SI 0 "register_operand" "")
17680                    (mult:SI (match_operand:SI 1 "memory_operand" "")
17681                             (match_operand:SI 2 "immediate_operand" "")))
17682               (clobber (reg:CC FLAGS_REG))])]
17683   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17684    && !satisfies_constraint_K (operands[2])"
17685   [(set (match_dup 3) (match_dup 1))
17686    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
17687               (clobber (reg:CC FLAGS_REG))])]
17688 "")
17689
17690 (define_peephole2
17691   [(match_scratch:SI 3 "r")
17692    (parallel [(set (match_operand:DI 0 "register_operand" "")
17693                    (zero_extend:DI
17694                      (mult:SI (match_operand:SI 1 "memory_operand" "")
17695                               (match_operand:SI 2 "immediate_operand" ""))))
17696               (clobber (reg:CC FLAGS_REG))])]
17697   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17698    && !satisfies_constraint_K (operands[2])"
17699   [(set (match_dup 3) (match_dup 1))
17700    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17701               (clobber (reg:CC FLAGS_REG))])]
17702 "")
17703
17704 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17705 ;; Convert it into imul reg, reg
17706 ;; It would be better to force assembler to encode instruction using long
17707 ;; immediate, but there is apparently no way to do so.
17708 (define_peephole2
17709   [(parallel [(set (match_operand:DI 0 "register_operand" "")
17710                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
17711                             (match_operand:DI 2 "const_int_operand" "")))
17712               (clobber (reg:CC FLAGS_REG))])
17713    (match_scratch:DI 3 "r")]
17714   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17715    && satisfies_constraint_K (operands[2])"
17716   [(set (match_dup 3) (match_dup 2))
17717    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
17718               (clobber (reg:CC FLAGS_REG))])]
17719 {
17720   if (!rtx_equal_p (operands[0], operands[1]))
17721     emit_move_insn (operands[0], operands[1]);
17722 })
17723
17724 (define_peephole2
17725   [(parallel [(set (match_operand:SI 0 "register_operand" "")
17726                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
17727                             (match_operand:SI 2 "const_int_operand" "")))
17728               (clobber (reg:CC FLAGS_REG))])
17729    (match_scratch:SI 3 "r")]
17730   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17731    && satisfies_constraint_K (operands[2])"
17732   [(set (match_dup 3) (match_dup 2))
17733    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
17734               (clobber (reg:CC FLAGS_REG))])]
17735 {
17736   if (!rtx_equal_p (operands[0], operands[1]))
17737     emit_move_insn (operands[0], operands[1]);
17738 })
17739
17740 (define_peephole2
17741   [(parallel [(set (match_operand:HI 0 "register_operand" "")
17742                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
17743                             (match_operand:HI 2 "immediate_operand" "")))
17744               (clobber (reg:CC FLAGS_REG))])
17745    (match_scratch:HI 3 "r")]
17746   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()"
17747   [(set (match_dup 3) (match_dup 2))
17748    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
17749               (clobber (reg:CC FLAGS_REG))])]
17750 {
17751   if (!rtx_equal_p (operands[0], operands[1]))
17752     emit_move_insn (operands[0], operands[1]);
17753 })
17754
17755 ;; After splitting up read-modify operations, array accesses with memory
17756 ;; operands might end up in form:
17757 ;;  sall    $2, %eax
17758 ;;  movl    4(%esp), %edx
17759 ;;  addl    %edx, %eax
17760 ;; instead of pre-splitting:
17761 ;;  sall    $2, %eax
17762 ;;  addl    4(%esp), %eax
17763 ;; Turn it into:
17764 ;;  movl    4(%esp), %edx
17765 ;;  leal    (%edx,%eax,4), %eax
17766
17767 (define_peephole2
17768   [(parallel [(set (match_operand 0 "register_operand" "")
17769                    (ashift (match_operand 1 "register_operand" "")
17770                            (match_operand 2 "const_int_operand" "")))
17771                (clobber (reg:CC FLAGS_REG))])
17772    (set (match_operand 3 "register_operand")
17773         (match_operand 4 "x86_64_general_operand" ""))
17774    (parallel [(set (match_operand 5 "register_operand" "")
17775                    (plus (match_operand 6 "register_operand" "")
17776                          (match_operand 7 "register_operand" "")))
17777                    (clobber (reg:CC FLAGS_REG))])]
17778   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
17779    /* Validate MODE for lea.  */
17780    && ((!TARGET_PARTIAL_REG_STALL
17781         && (GET_MODE (operands[0]) == QImode
17782             || GET_MODE (operands[0]) == HImode))
17783        || GET_MODE (operands[0]) == SImode
17784        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17785    /* We reorder load and the shift.  */
17786    && !rtx_equal_p (operands[1], operands[3])
17787    && !reg_overlap_mentioned_p (operands[0], operands[4])
17788    /* Last PLUS must consist of operand 0 and 3.  */
17789    && !rtx_equal_p (operands[0], operands[3])
17790    && (rtx_equal_p (operands[3], operands[6])
17791        || rtx_equal_p (operands[3], operands[7]))
17792    && (rtx_equal_p (operands[0], operands[6])
17793        || rtx_equal_p (operands[0], operands[7]))
17794    /* The intermediate operand 0 must die or be same as output.  */
17795    && (rtx_equal_p (operands[0], operands[5])
17796        || peep2_reg_dead_p (3, operands[0]))"
17797   [(set (match_dup 3) (match_dup 4))
17798    (set (match_dup 0) (match_dup 1))]
17799 {
17800   enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
17801   int scale = 1 << INTVAL (operands[2]);
17802   rtx index = gen_lowpart (Pmode, operands[1]);
17803   rtx base = gen_lowpart (Pmode, operands[3]);
17804   rtx dest = gen_lowpart (mode, operands[5]);
17805
17806   operands[1] = gen_rtx_PLUS (Pmode, base,
17807                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
17808   if (mode != Pmode)
17809     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17810   operands[0] = dest;
17811 })
17812 \f
17813 ;; Call-value patterns last so that the wildcard operand does not
17814 ;; disrupt insn-recog's switch tables.
17815
17816 (define_insn "*call_value_pop_0"
17817   [(set (match_operand 0 "" "")
17818         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17819               (match_operand:SI 2 "" "")))
17820    (set (reg:SI SP_REG)
17821         (plus:SI (reg:SI SP_REG)
17822                  (match_operand:SI 3 "immediate_operand" "")))]
17823   "!TARGET_64BIT"
17824 {
17825   if (SIBLING_CALL_P (insn))
17826     return "jmp\t%P1";
17827   else
17828     return "call\t%P1";
17829 }
17830   [(set_attr "type" "callv")])
17831
17832 (define_insn "*call_value_pop_1"
17833   [(set (match_operand 0 "" "")
17834         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17835               (match_operand:SI 2 "" "")))
17836    (set (reg:SI SP_REG)
17837         (plus:SI (reg:SI SP_REG)
17838                  (match_operand:SI 3 "immediate_operand" "i")))]
17839   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17840 {
17841   if (constant_call_address_operand (operands[1], Pmode))
17842     return "call\t%P1";
17843   return "call\t%A1";
17844 }
17845   [(set_attr "type" "callv")])
17846
17847 (define_insn "*sibcall_value_pop_1"
17848   [(set (match_operand 0 "" "")
17849         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17850               (match_operand:SI 2 "" "")))
17851    (set (reg:SI SP_REG)
17852         (plus:SI (reg:SI SP_REG)
17853                  (match_operand:SI 3 "immediate_operand" "i,i")))]
17854   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17855   "@
17856    jmp\t%P1
17857    jmp\t%A1"
17858   [(set_attr "type" "callv")])
17859
17860 (define_insn "*call_value_0"
17861   [(set (match_operand 0 "" "")
17862         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17863               (match_operand:SI 2 "" "")))]
17864   "!TARGET_64BIT"
17865 {
17866   if (SIBLING_CALL_P (insn))
17867     return "jmp\t%P1";
17868   else
17869     return "call\t%P1";
17870 }
17871   [(set_attr "type" "callv")])
17872
17873 (define_insn "*call_value_0_rex64"
17874   [(set (match_operand 0 "" "")
17875         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17876               (match_operand:DI 2 "const_int_operand" "")))]
17877   "TARGET_64BIT"
17878 {
17879   if (SIBLING_CALL_P (insn))
17880     return "jmp\t%P1";
17881   else
17882     return "call\t%P1";
17883 }
17884   [(set_attr "type" "callv")])
17885
17886 (define_insn "*call_value_0_rex64_ms_sysv"
17887   [(set (match_operand 0 "" "")
17888         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17889               (match_operand:DI 2 "const_int_operand" "")))
17890    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17891    (clobber (reg:TI XMM6_REG))
17892    (clobber (reg:TI XMM7_REG))
17893    (clobber (reg:TI XMM8_REG))
17894    (clobber (reg:TI XMM9_REG))
17895    (clobber (reg:TI XMM10_REG))
17896    (clobber (reg:TI XMM11_REG))
17897    (clobber (reg:TI XMM12_REG))
17898    (clobber (reg:TI XMM13_REG))
17899    (clobber (reg:TI XMM14_REG))
17900    (clobber (reg:TI XMM15_REG))
17901    (clobber (reg:DI SI_REG))
17902    (clobber (reg:DI DI_REG))]
17903   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17904 {
17905   if (SIBLING_CALL_P (insn))
17906     return "jmp\t%P1";
17907   else
17908     return "call\t%P1";
17909 }
17910   [(set_attr "type" "callv")])
17911
17912 (define_insn "*call_value_1"
17913   [(set (match_operand 0 "" "")
17914         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17915               (match_operand:SI 2 "" "")))]
17916   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17917 {
17918   if (constant_call_address_operand (operands[1], Pmode))
17919     return "call\t%P1";
17920   return "call\t%A1";
17921 }
17922   [(set_attr "type" "callv")])
17923
17924 (define_insn "*sibcall_value_1"
17925   [(set (match_operand 0 "" "")
17926         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17927               (match_operand:SI 2 "" "")))]
17928   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17929   "@
17930    jmp\t%P1
17931    jmp\t%A1"
17932   [(set_attr "type" "callv")])
17933
17934 (define_insn "*call_value_1_rex64"
17935   [(set (match_operand 0 "" "")
17936         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17937               (match_operand:DI 2 "" "")))]
17938   "TARGET_64BIT && !SIBLING_CALL_P (insn)
17939    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
17940 {
17941   if (constant_call_address_operand (operands[1], Pmode))
17942     return "call\t%P1";
17943   return "call\t%A1";
17944 }
17945   [(set_attr "type" "callv")])
17946
17947 (define_insn "*call_value_1_rex64_ms_sysv"
17948   [(set (match_operand 0 "" "")
17949         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17950               (match_operand:DI 2 "" "")))
17951    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17952    (clobber (reg:TI XMM6_REG))
17953    (clobber (reg:TI XMM7_REG))
17954    (clobber (reg:TI XMM8_REG))
17955    (clobber (reg:TI XMM9_REG))
17956    (clobber (reg:TI XMM10_REG))
17957    (clobber (reg:TI XMM11_REG))
17958    (clobber (reg:TI XMM12_REG))
17959    (clobber (reg:TI XMM13_REG))
17960    (clobber (reg:TI XMM14_REG))
17961    (clobber (reg:TI XMM15_REG))
17962    (clobber (reg:DI SI_REG))
17963    (clobber (reg:DI DI_REG))]
17964   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17965 {
17966   if (constant_call_address_operand (operands[1], Pmode))
17967     return "call\t%P1";
17968   return "call\t%A1";
17969 }
17970   [(set_attr "type" "callv")])
17971
17972 (define_insn "*call_value_1_rex64_large"
17973   [(set (match_operand 0 "" "")
17974         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
17975               (match_operand:DI 2 "" "")))]
17976   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17977   "call\t%A1"
17978   [(set_attr "type" "callv")])
17979
17980 (define_insn "*sibcall_value_1_rex64"
17981   [(set (match_operand 0 "" "")
17982         (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
17983               (match_operand:DI 2 "" "")))]
17984   "TARGET_64BIT && SIBLING_CALL_P (insn)"
17985   "@
17986    jmp\t%P1
17987    jmp\t%A1"
17988   [(set_attr "type" "callv")])
17989 \f
17990 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17991 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17992 ;; caught for use by garbage collectors and the like.  Using an insn that
17993 ;; maps to SIGILL makes it more likely the program will rightfully die.
17994 ;; Keeping with tradition, "6" is in honor of #UD.
17995 (define_insn "trap"
17996   [(trap_if (const_int 1) (const_int 6))]
17997   ""
17998   { return ASM_SHORT "0x0b0f"; }
17999   [(set_attr "length" "2")])
18000
18001 (define_expand "sse_prologue_save"
18002   [(parallel [(set (match_operand:BLK 0 "" "")
18003                    (unspec:BLK [(reg:DI XMM0_REG)
18004                                 (reg:DI XMM1_REG)
18005                                 (reg:DI XMM2_REG)
18006                                 (reg:DI XMM3_REG)
18007                                 (reg:DI XMM4_REG)
18008                                 (reg:DI XMM5_REG)
18009                                 (reg:DI XMM6_REG)
18010                                 (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE))
18011               (clobber (reg:CC FLAGS_REG))
18012               (clobber (match_operand:DI 1 "register_operand" ""))
18013               (use (match_operand:DI 2 "immediate_operand" ""))
18014               (use (label_ref:DI (match_operand 3 "" "")))
18015               (clobber (match_operand:DI 4 "register_operand" ""))
18016               (use (match_dup 1))])]
18017   "TARGET_64BIT"
18018   "")
18019
18020 ;; Pre-reload version of prologue save.  Until after prologue generation we don't know
18021 ;; what the size of save instruction will be.
18022 ;; Operand 0+operand 6 is the memory save area
18023 ;; Operand 1 is number of registers to save (will get overwritten to operand 5)
18024 ;; Operand 2 is number of non-vaargs SSE arguments
18025 ;; Operand 3 is label starting the save block
18026 ;; Operand 4 is used for temporary computation of jump address
18027 (define_insn "*sse_prologue_save_insn1"
18028   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
18029                           (match_operand:DI 6 "const_int_operand" "n")))
18030         (unspec:BLK [(reg:DI XMM0_REG)
18031                      (reg:DI XMM1_REG)
18032                      (reg:DI XMM2_REG)
18033                      (reg:DI XMM3_REG)
18034                      (reg:DI XMM4_REG)
18035                      (reg:DI XMM5_REG)
18036                      (reg:DI XMM6_REG)
18037                      (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE))
18038    (clobber (reg:CC FLAGS_REG))
18039    (clobber (match_operand:DI 1 "register_operand" "=r"))
18040    (use (match_operand:DI 2 "const_int_operand" "i"))
18041    (use (label_ref:DI (match_operand 3 "" "X")))
18042    (clobber (match_operand:DI 4 "register_operand" "=&r"))
18043    (use (match_operand:DI 5 "register_operand" "1"))]
18044   "TARGET_64BIT
18045    && INTVAL (operands[6]) + X86_64_SSE_REGPARM_MAX * 16 - 16 < 128
18046    && INTVAL (operands[6]) + INTVAL (operands[2]) * 16 >= -128"
18047   "#"
18048   [(set_attr "type" "other")
18049    (set_attr "memory" "store")
18050    (set_attr "mode" "DI")])
18051
18052 ;; We know size of save instruction; expand the computation of jump address
18053 ;; in the jumptable.
18054 (define_split
18055   [(parallel [(set (match_operand:BLK 0 "" "")
18056                     (unspec:BLK [(reg:DI XMM0_REG)
18057                                  (reg:DI XMM1_REG)
18058                                  (reg:DI XMM2_REG)
18059                                  (reg:DI XMM3_REG)
18060                                  (reg:DI XMM4_REG)
18061                                  (reg:DI XMM5_REG)
18062                                  (reg:DI XMM6_REG)
18063                                  (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE))
18064                (clobber (reg:CC FLAGS_REG))
18065                (clobber (match_operand:DI 1 "register_operand" ""))
18066                (use (match_operand:DI 2 "const_int_operand" ""))
18067                (use (match_operand 3 "" ""))
18068                (clobber (match_operand:DI 4 "register_operand" ""))
18069                (use (match_operand:DI 5 "register_operand" ""))])]
18070   "reload_completed"
18071   [(parallel [(set (match_dup 0)
18072                    (unspec:BLK [(reg:DI XMM0_REG)
18073                                 (reg:DI XMM1_REG)
18074                                 (reg:DI XMM2_REG)
18075                                 (reg:DI XMM3_REG)
18076                                 (reg:DI XMM4_REG)
18077                                 (reg:DI XMM5_REG)
18078                                 (reg:DI XMM6_REG)
18079                                 (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE_LOW))
18080               (use (match_dup 1))
18081               (use (match_dup 2))
18082               (use (match_dup 3))
18083               (use (match_dup 5))])]
18084 {
18085   /* Movaps is 4 bytes, AVX and movsd is 5 bytes.  */
18086   int size = 4 + (TARGET_AVX || crtl->stack_alignment_needed < 128);
18087
18088   /* Compute address to jump to:
18089      label - eax*size + nnamed_sse_arguments*size. */
18090   if (size == 5)
18091     emit_insn (gen_rtx_SET (VOIDmode, operands[4],
18092                             gen_rtx_PLUS
18093                               (Pmode,
18094                                gen_rtx_MULT (Pmode, operands[1],
18095                                              GEN_INT (4)),
18096                                operands[1])));
18097   else  if (size == 4)
18098     emit_insn (gen_rtx_SET (VOIDmode, operands[4],
18099                             gen_rtx_MULT (Pmode, operands[1],
18100                                           GEN_INT (4))));
18101   else
18102     gcc_unreachable ();
18103   if (INTVAL (operands[2]))
18104     emit_move_insn
18105       (operands[1],
18106        gen_rtx_CONST (DImode,
18107                       gen_rtx_PLUS (DImode,
18108                                     operands[3],
18109                                     GEN_INT (INTVAL (operands[2])
18110                                              * size))));
18111   else
18112     emit_move_insn (operands[1], operands[3]);
18113   emit_insn (gen_subdi3 (operands[1], operands[1], operands[4]));
18114   operands[5] = GEN_INT (size);
18115 })
18116
18117 (define_insn "sse_prologue_save_insn"
18118   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
18119                           (match_operand:DI 4 "const_int_operand" "n")))
18120         (unspec:BLK [(reg:DI XMM0_REG)
18121                      (reg:DI XMM1_REG)
18122                      (reg:DI XMM2_REG)
18123                      (reg:DI XMM3_REG)
18124                      (reg:DI XMM4_REG)
18125                      (reg:DI XMM5_REG)
18126                      (reg:DI XMM6_REG)
18127                      (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE_LOW))
18128    (use (match_operand:DI 1 "register_operand" "r"))
18129    (use (match_operand:DI 2 "const_int_operand" "i"))
18130    (use (label_ref:DI (match_operand 3 "" "X")))
18131    (use (match_operand:DI 5 "const_int_operand" "i"))]
18132   "TARGET_64BIT
18133    && INTVAL (operands[4]) + X86_64_SSE_REGPARM_MAX * 16 - 16 < 128
18134    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
18135 {
18136   int i;
18137   operands[0] = gen_rtx_MEM (Pmode,
18138                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
18139   /* VEX instruction with a REX prefix will #UD.  */
18140   if (TARGET_AVX && GET_CODE (XEXP (operands[0], 0)) != PLUS)
18141     gcc_unreachable ();
18142
18143   output_asm_insn ("jmp\t%A1", operands);
18144   for (i = X86_64_SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
18145     {
18146       operands[4] = adjust_address (operands[0], DImode, i*16);
18147       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
18148       PUT_MODE (operands[4], TImode);
18149       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
18150         output_asm_insn ("rex", operands);
18151       if (crtl->stack_alignment_needed < 128)
18152         output_asm_insn ("%vmovsd\t{%5, %4|%4, %5}", operands);
18153       else
18154         output_asm_insn ("%vmovaps\t{%5, %4|%4, %5}", operands);
18155     }
18156   (*targetm.asm_out.internal_label) (asm_out_file, "L",
18157                                      CODE_LABEL_NUMBER (operands[3]));
18158   return "";
18159 }
18160   [(set_attr "type" "other")
18161    (set_attr "length_immediate" "0")
18162    (set_attr "length_address" "0")
18163    ;; 2 bytes for jump and opernds[4] bytes for each save.
18164    (set (attr "length")
18165      (plus (const_int 2)
18166            (mult (symbol_ref ("INTVAL (operands[5])"))
18167                  (symbol_ref ("X86_64_SSE_REGPARM_MAX - INTVAL (operands[2])")))))
18168    (set_attr "memory" "store")
18169    (set_attr "modrm" "0")
18170    (set_attr "prefix" "maybe_vex")
18171    (set_attr "mode" "DI")])
18172
18173 (define_expand "prefetch"
18174   [(prefetch (match_operand 0 "address_operand" "")
18175              (match_operand:SI 1 "const_int_operand" "")
18176              (match_operand:SI 2 "const_int_operand" ""))]
18177   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
18178 {
18179   int rw = INTVAL (operands[1]);
18180   int locality = INTVAL (operands[2]);
18181
18182   gcc_assert (rw == 0 || rw == 1);
18183   gcc_assert (locality >= 0 && locality <= 3);
18184   gcc_assert (GET_MODE (operands[0]) == Pmode
18185               || GET_MODE (operands[0]) == VOIDmode);
18186
18187   /* Use 3dNOW prefetch in case we are asking for write prefetch not
18188      supported by SSE counterpart or the SSE prefetch is not available
18189      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
18190      of locality.  */
18191   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
18192     operands[2] = GEN_INT (3);
18193   else
18194     operands[1] = const0_rtx;
18195 })
18196
18197 (define_insn "*prefetch_sse_<mode>"
18198   [(prefetch (match_operand:P 0 "address_operand" "p")
18199              (const_int 0)
18200              (match_operand:SI 1 "const_int_operand" ""))]
18201   "TARGET_PREFETCH_SSE"
18202 {
18203   static const char * const patterns[4] = {
18204    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
18205   };
18206
18207   int locality = INTVAL (operands[1]);
18208   gcc_assert (locality >= 0 && locality <= 3);
18209
18210   return patterns[locality];
18211 }
18212   [(set_attr "type" "sse")
18213    (set_attr "atom_sse_attr" "prefetch")
18214    (set (attr "length_address")
18215         (symbol_ref "memory_address_length (operands[0])"))
18216    (set_attr "memory" "none")])
18217
18218 (define_insn "*prefetch_3dnow_<mode>"
18219   [(prefetch (match_operand:P 0 "address_operand" "p")
18220              (match_operand:SI 1 "const_int_operand" "n")
18221              (const_int 3))]
18222   "TARGET_3DNOW"
18223 {
18224   if (INTVAL (operands[1]) == 0)
18225     return "prefetch\t%a0";
18226   else
18227     return "prefetchw\t%a0";
18228 }
18229   [(set_attr "type" "mmx")
18230    (set (attr "length_address")
18231         (symbol_ref "memory_address_length (operands[0])"))
18232    (set_attr "memory" "none")])
18233
18234 (define_expand "stack_protect_set"
18235   [(match_operand 0 "memory_operand" "")
18236    (match_operand 1 "memory_operand" "")]
18237   ""
18238 {
18239 #ifdef TARGET_THREAD_SSP_OFFSET
18240   if (TARGET_64BIT)
18241     emit_insn (gen_stack_tls_protect_set_di (operands[0],
18242                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
18243   else
18244     emit_insn (gen_stack_tls_protect_set_si (operands[0],
18245                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
18246 #else
18247   if (TARGET_64BIT)
18248     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
18249   else
18250     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
18251 #endif
18252   DONE;
18253 })
18254
18255 (define_insn "stack_protect_set_si"
18256   [(set (match_operand:SI 0 "memory_operand" "=m")
18257         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
18258    (set (match_scratch:SI 2 "=&r") (const_int 0))
18259    (clobber (reg:CC FLAGS_REG))]
18260   ""
18261   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
18262   [(set_attr "type" "multi")])
18263
18264 (define_insn "stack_protect_set_di"
18265   [(set (match_operand:DI 0 "memory_operand" "=m")
18266         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
18267    (set (match_scratch:DI 2 "=&r") (const_int 0))
18268    (clobber (reg:CC FLAGS_REG))]
18269   "TARGET_64BIT"
18270   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
18271   [(set_attr "type" "multi")])
18272
18273 (define_insn "stack_tls_protect_set_si"
18274   [(set (match_operand:SI 0 "memory_operand" "=m")
18275         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")]
18276                    UNSPEC_SP_TLS_SET))
18277    (set (match_scratch:SI 2 "=&r") (const_int 0))
18278    (clobber (reg:CC FLAGS_REG))]
18279   ""
18280   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
18281   [(set_attr "type" "multi")])
18282
18283 (define_insn "stack_tls_protect_set_di"
18284   [(set (match_operand:DI 0 "memory_operand" "=m")
18285         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")]
18286                    UNSPEC_SP_TLS_SET))
18287    (set (match_scratch:DI 2 "=&r") (const_int 0))
18288    (clobber (reg:CC FLAGS_REG))]
18289   "TARGET_64BIT"
18290   {
18291      /* The kernel uses a different segment register for performance reasons; a
18292         system call would not have to trash the userspace segment register,
18293         which would be expensive */
18294      if (ix86_cmodel != CM_KERNEL)
18295         return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
18296      else
18297         return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
18298   }
18299   [(set_attr "type" "multi")])
18300
18301 (define_expand "stack_protect_test"
18302   [(match_operand 0 "memory_operand" "")
18303    (match_operand 1 "memory_operand" "")
18304    (match_operand 2 "" "")]
18305   ""
18306 {
18307   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
18308
18309 #ifdef TARGET_THREAD_SSP_OFFSET
18310   if (TARGET_64BIT)
18311     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
18312                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
18313   else
18314     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
18315                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
18316 #else
18317   if (TARGET_64BIT)
18318     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
18319   else
18320     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
18321 #endif
18322
18323   emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
18324                                   flags, const0_rtx, operands[2]));
18325   DONE;
18326 })
18327
18328 (define_insn "stack_protect_test_si"
18329   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
18330         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
18331                      (match_operand:SI 2 "memory_operand" "m")]
18332                     UNSPEC_SP_TEST))
18333    (clobber (match_scratch:SI 3 "=&r"))]
18334   ""
18335   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
18336   [(set_attr "type" "multi")])
18337
18338 (define_insn "stack_protect_test_di"
18339   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
18340         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
18341                      (match_operand:DI 2 "memory_operand" "m")]
18342                     UNSPEC_SP_TEST))
18343    (clobber (match_scratch:DI 3 "=&r"))]
18344   "TARGET_64BIT"
18345   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
18346   [(set_attr "type" "multi")])
18347
18348 (define_insn "stack_tls_protect_test_si"
18349   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
18350         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
18351                      (match_operand:SI 2 "const_int_operand" "i")]
18352                     UNSPEC_SP_TLS_TEST))
18353    (clobber (match_scratch:SI 3 "=r"))]
18354   ""
18355   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
18356   [(set_attr "type" "multi")])
18357
18358 (define_insn "stack_tls_protect_test_di"
18359   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
18360         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
18361                      (match_operand:DI 2 "const_int_operand" "i")]
18362                     UNSPEC_SP_TLS_TEST))
18363    (clobber (match_scratch:DI 3 "=r"))]
18364   "TARGET_64BIT"
18365   {
18366      /* The kernel uses a different segment register for performance reasons; a
18367         system call would not have to trash the userspace segment register,
18368         which would be expensive */
18369      if (ix86_cmodel != CM_KERNEL)
18370         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
18371      else
18372         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
18373   }
18374   [(set_attr "type" "multi")])
18375
18376 (define_insn "sse4_2_crc32<mode>"
18377   [(set (match_operand:SI 0 "register_operand" "=r")
18378         (unspec:SI
18379           [(match_operand:SI 1 "register_operand" "0")
18380            (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
18381           UNSPEC_CRC32))]
18382   "TARGET_SSE4_2 || TARGET_CRC32"
18383   "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
18384   [(set_attr "type" "sselog1")
18385    (set_attr "prefix_rep" "1")
18386    (set_attr "prefix_extra" "1")
18387    (set (attr "prefix_data16")
18388      (if_then_else (match_operand:HI 2 "" "")
18389        (const_string "1")
18390        (const_string "*")))
18391    (set (attr "prefix_rex")
18392      (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
18393        (const_string "1")
18394        (const_string "*")))
18395    (set_attr "mode" "SI")])
18396
18397 (define_insn "sse4_2_crc32di"
18398   [(set (match_operand:DI 0 "register_operand" "=r")
18399         (unspec:DI
18400           [(match_operand:DI 1 "register_operand" "0")
18401            (match_operand:DI 2 "nonimmediate_operand" "rm")]
18402           UNSPEC_CRC32))]
18403   "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
18404   "crc32{q}\t{%2, %0|%0, %2}"
18405   [(set_attr "type" "sselog1")
18406    (set_attr "prefix_rep" "1")
18407    (set_attr "prefix_extra" "1")
18408    (set_attr "mode" "DI")])
18409
18410 (define_expand "rdpmc"
18411   [(match_operand:DI 0 "register_operand" "")
18412    (match_operand:SI 1 "register_operand" "")]
18413   ""
18414 {
18415   rtx reg = gen_reg_rtx (DImode);
18416   rtx si;
18417
18418   /* Force operand 1 into ECX.  */
18419   rtx ecx = gen_rtx_REG (SImode, CX_REG);
18420   emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
18421   si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
18422                                 UNSPECV_RDPMC);
18423
18424   if (TARGET_64BIT)
18425     {
18426       rtvec vec = rtvec_alloc (2);
18427       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18428       rtx upper = gen_reg_rtx (DImode);
18429       rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
18430                                         gen_rtvec (1, const0_rtx),
18431                                         UNSPECV_RDPMC);
18432       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
18433       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
18434       emit_insn (load);
18435       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18436                                    NULL, 1, OPTAB_DIRECT);
18437       reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
18438                                  OPTAB_DIRECT);
18439     }
18440   else
18441     emit_insn (gen_rtx_SET (VOIDmode, reg, si));
18442   emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
18443   DONE;
18444 })
18445
18446 (define_insn "*rdpmc"
18447   [(set (match_operand:DI 0 "register_operand" "=A")
18448         (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
18449                             UNSPECV_RDPMC))]
18450   "!TARGET_64BIT"
18451   "rdpmc"
18452   [(set_attr "type" "other")
18453    (set_attr "length" "2")])
18454
18455 (define_insn "*rdpmc_rex64"
18456   [(set (match_operand:DI 0 "register_operand" "=a")
18457         (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
18458                             UNSPECV_RDPMC))
18459   (set (match_operand:DI 1 "register_operand" "=d")
18460        (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
18461   "TARGET_64BIT"
18462   "rdpmc"
18463   [(set_attr "type" "other")
18464    (set_attr "length" "2")])
18465
18466 (define_expand "rdtsc"
18467   [(set (match_operand:DI 0 "register_operand" "")
18468         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18469   ""
18470 {
18471   if (TARGET_64BIT)
18472     {
18473       rtvec vec = rtvec_alloc (2);
18474       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18475       rtx upper = gen_reg_rtx (DImode);
18476       rtx lower = gen_reg_rtx (DImode);
18477       rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
18478                                          gen_rtvec (1, const0_rtx),
18479                                          UNSPECV_RDTSC);
18480       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
18481       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
18482       emit_insn (load);
18483       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18484                                    NULL, 1, OPTAB_DIRECT);
18485       lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
18486                                    OPTAB_DIRECT);
18487       emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
18488       DONE;
18489     }
18490 })
18491
18492 (define_insn "*rdtsc"
18493   [(set (match_operand:DI 0 "register_operand" "=A")
18494         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18495   "!TARGET_64BIT"
18496   "rdtsc"
18497   [(set_attr "type" "other")
18498    (set_attr "length" "2")])
18499
18500 (define_insn "*rdtsc_rex64"
18501   [(set (match_operand:DI 0 "register_operand" "=a")
18502         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
18503    (set (match_operand:DI 1 "register_operand" "=d")
18504         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18505   "TARGET_64BIT"
18506   "rdtsc"
18507   [(set_attr "type" "other")
18508    (set_attr "length" "2")])
18509
18510 (define_expand "rdtscp"
18511   [(match_operand:DI 0 "register_operand" "")
18512    (match_operand:SI 1 "memory_operand" "")]
18513   ""
18514 {
18515   rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
18516                                     gen_rtvec (1, const0_rtx),
18517                                     UNSPECV_RDTSCP);
18518   rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
18519                                     gen_rtvec (1, const0_rtx),
18520                                     UNSPECV_RDTSCP);
18521   rtx reg = gen_reg_rtx (DImode);
18522   rtx tmp = gen_reg_rtx (SImode);
18523
18524   if (TARGET_64BIT)
18525     {
18526       rtvec vec = rtvec_alloc (3);
18527       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18528       rtx upper = gen_reg_rtx (DImode);
18529       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
18530       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
18531       RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
18532       emit_insn (load);
18533       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18534                                    NULL, 1, OPTAB_DIRECT);
18535       reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
18536                                  OPTAB_DIRECT);
18537     }
18538   else
18539     {
18540       rtvec vec = rtvec_alloc (2);
18541       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18542       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
18543       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
18544       emit_insn (load);
18545     }
18546   emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
18547   emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
18548   DONE;
18549 })
18550
18551 (define_insn "*rdtscp"
18552   [(set (match_operand:DI 0 "register_operand" "=A")
18553         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18554    (set (match_operand:SI 1 "register_operand" "=c")
18555         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18556   "!TARGET_64BIT"
18557   "rdtscp"
18558   [(set_attr "type" "other")
18559    (set_attr "length" "3")])
18560
18561 (define_insn "*rdtscp_rex64"
18562   [(set (match_operand:DI 0 "register_operand" "=a")
18563         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18564    (set (match_operand:DI 1 "register_operand" "=d")
18565         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18566    (set (match_operand:SI 2 "register_operand" "=c")
18567         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18568   "TARGET_64BIT"
18569   "rdtscp"
18570   [(set_attr "type" "other")
18571    (set_attr "length" "3")])
18572
18573 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18574 ;;
18575 ;; LWP instructions
18576 ;;
18577 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18578
18579 (define_expand "lwp_llwpcb"
18580   [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18581                     UNSPECV_LLWP_INTRINSIC)]
18582   "TARGET_LWP"
18583   "")
18584
18585 (define_insn "*lwp_llwpcb<mode>1"
18586   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18587                     UNSPECV_LLWP_INTRINSIC)]
18588   "TARGET_LWP"
18589   "llwpcb\t%0"
18590   [(set_attr "type" "lwp")
18591    (set_attr "mode" "<MODE>")
18592    (set_attr "length" "5")])
18593
18594 (define_expand "lwp_slwpcb"
18595   [(set (match_operand 0 "register_operand" "=r")
18596         (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18597   "TARGET_LWP"
18598   {
18599     if (TARGET_64BIT)
18600       emit_insn (gen_lwp_slwpcbdi (operands[0]));
18601     else
18602       emit_insn (gen_lwp_slwpcbsi (operands[0]));
18603     DONE;
18604   })
18605
18606 (define_insn "lwp_slwpcb<mode>"
18607   [(set (match_operand:P 0 "register_operand" "=r")
18608         (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18609   "TARGET_LWP"
18610   "slwpcb\t%0"
18611   [(set_attr "type" "lwp")
18612    (set_attr "mode" "<MODE>")
18613    (set_attr "length" "5")])
18614
18615 (define_expand "lwp_lwpval<mode>3"
18616   [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18617                      (match_operand:SI 2 "nonimmediate_operand" "rm")
18618                      (match_operand:SI 3 "const_int_operand" "i")]
18619                     UNSPECV_LWPVAL_INTRINSIC)]
18620   "TARGET_LWP"
18621   "/* Avoid unused variable warning.  */
18622    (void) operand0;")
18623
18624 (define_insn "*lwp_lwpval<mode>3_1"
18625   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18626                      (match_operand:SI 1 "nonimmediate_operand" "rm")
18627                      (match_operand:SI 2 "const_int_operand" "i")]
18628                     UNSPECV_LWPVAL_INTRINSIC)]
18629   "TARGET_LWP"
18630   "lwpval\t{%2, %1, %0|%0, %1, %2}"
18631   [(set_attr "type" "lwp")
18632    (set_attr "mode" "<MODE>")
18633    (set (attr "length")
18634         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18635
18636 (define_expand "lwp_lwpins<mode>3"
18637   [(set (reg:CCC FLAGS_REG)
18638         (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18639                               (match_operand:SI 2 "nonimmediate_operand" "rm")
18640                               (match_operand:SI 3 "const_int_operand" "i")]
18641                              UNSPECV_LWPINS_INTRINSIC))
18642    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18643         (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18644   "TARGET_LWP"
18645   "")
18646
18647 (define_insn "*lwp_lwpins<mode>3_1"
18648   [(set (reg:CCC FLAGS_REG)
18649         (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18650                               (match_operand:SI 1 "nonimmediate_operand" "rm")
18651                               (match_operand:SI 2 "const_int_operand" "i")]
18652                              UNSPECV_LWPINS_INTRINSIC))]
18653   "TARGET_LWP"
18654   "lwpins\t{%2, %1, %0|%0, %1, %2}"
18655   [(set_attr "type" "lwp")
18656    (set_attr "mode" "<MODE>")
18657    (set (attr "length")
18658         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18659
18660 (include "mmx.md")
18661 (include "sse.md")
18662 (include "sync.md")