OSDN Git Service

* config/i386/i386.md (any_shiftrt): New code iterator.
[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_constants
66   [; Relocation specifiers
67    (UNSPEC_GOT                  0)
68    (UNSPEC_GOTOFF               1)
69    (UNSPEC_GOTPCREL             2)
70    (UNSPEC_GOTTPOFF             3)
71    (UNSPEC_TPOFF                4)
72    (UNSPEC_NTPOFF               5)
73    (UNSPEC_DTPOFF               6)
74    (UNSPEC_GOTNTPOFF            7)
75    (UNSPEC_INDNTPOFF            8)
76    (UNSPEC_PLTOFF               9)
77    (UNSPEC_MACHOPIC_OFFSET      10)
78
79    ; Prologue support
80    (UNSPEC_STACK_ALLOC          11)
81    (UNSPEC_SET_GOT              12)
82    (UNSPEC_SSE_PROLOGUE_SAVE    13)
83    (UNSPEC_REG_SAVE             14)
84    (UNSPEC_DEF_CFA              15)
85    (UNSPEC_SET_RIP              16)
86    (UNSPEC_SET_GOT_OFFSET       17)
87    (UNSPEC_MEMORY_BLOCKAGE      18)
88
89    ; TLS support
90    (UNSPEC_TP                   20)
91    (UNSPEC_TLS_GD               21)
92    (UNSPEC_TLS_LD_BASE          22)
93    (UNSPEC_TLSDESC              23)
94
95    ; Other random patterns
96    (UNSPEC_SCAS                 30)
97    (UNSPEC_FNSTSW               31)
98    (UNSPEC_SAHF                 32)
99    (UNSPEC_FSTCW                33)
100    (UNSPEC_ADD_CARRY            34)
101    (UNSPEC_FLDCW                35)
102    (UNSPEC_REP                  36)
103    (UNSPEC_LD_MPIC              38)     ; load_macho_picbase
104    (UNSPEC_TRUNC_NOOP           39)
105
106    ; For SSE/MMX support:
107    (UNSPEC_FIX_NOTRUNC          40)
108    (UNSPEC_MASKMOV              41)
109    (UNSPEC_MOVMSK               42)
110    (UNSPEC_MOVNT                43)
111    (UNSPEC_MOVU                 44)
112    (UNSPEC_RCP                  45)
113    (UNSPEC_RSQRT                46)
114    (UNSPEC_SFENCE               47)
115    (UNSPEC_PFRCP                49)
116    (UNSPEC_PFRCPIT1             40)
117    (UNSPEC_PFRCPIT2             41)
118    (UNSPEC_PFRSQRT              42)
119    (UNSPEC_PFRSQIT1             43)
120    (UNSPEC_MFENCE               44)
121    (UNSPEC_LFENCE               45)
122    (UNSPEC_PSADBW               46)
123    (UNSPEC_LDDQU                47)
124    (UNSPEC_MS_TO_SYSV_CALL      48)
125
126    ; Generic math support
127    (UNSPEC_COPYSIGN             50)
128    (UNSPEC_IEEE_MIN             51)     ; not commutative
129    (UNSPEC_IEEE_MAX             52)     ; not commutative
130
131    ; x87 Floating point
132    (UNSPEC_SIN                  60)
133    (UNSPEC_COS                  61)
134    (UNSPEC_FPATAN               62)
135    (UNSPEC_FYL2X                63)
136    (UNSPEC_FYL2XP1              64)
137    (UNSPEC_FRNDINT              65)
138    (UNSPEC_FIST                 66)
139    (UNSPEC_F2XM1                67)
140    (UNSPEC_TAN                  68)
141    (UNSPEC_FXAM                 69)
142
143    ; x87 Rounding
144    (UNSPEC_FRNDINT_FLOOR        70)
145    (UNSPEC_FRNDINT_CEIL         71)
146    (UNSPEC_FRNDINT_TRUNC        72)
147    (UNSPEC_FRNDINT_MASK_PM      73)
148    (UNSPEC_FIST_FLOOR           74)
149    (UNSPEC_FIST_CEIL            75)
150
151    ; x87 Double output FP
152    (UNSPEC_SINCOS_COS           80)
153    (UNSPEC_SINCOS_SIN           81)
154    (UNSPEC_XTRACT_FRACT         84)
155    (UNSPEC_XTRACT_EXP           85)
156    (UNSPEC_FSCALE_FRACT         86)
157    (UNSPEC_FSCALE_EXP           87)
158    (UNSPEC_FPREM_F              88)
159    (UNSPEC_FPREM_U              89)
160    (UNSPEC_FPREM1_F             90)
161    (UNSPEC_FPREM1_U             91)
162
163    (UNSPEC_C2_FLAG              95)
164    (UNSPEC_FXAM_MEM             96)
165
166    ; SSP patterns
167    (UNSPEC_SP_SET               100)
168    (UNSPEC_SP_TEST              101)
169    (UNSPEC_SP_TLS_SET           102)
170    (UNSPEC_SP_TLS_TEST          103)
171
172    ; SSSE3
173    (UNSPEC_PSHUFB               120)
174    (UNSPEC_PSIGN                121)
175    (UNSPEC_PALIGNR              122)
176
177    ; For SSE4A support
178    (UNSPEC_EXTRQI               130)
179    (UNSPEC_EXTRQ                131)
180    (UNSPEC_INSERTQI             132)
181    (UNSPEC_INSERTQ              133)
182
183    ; For SSE4.1 support
184    (UNSPEC_BLENDV               134)
185    (UNSPEC_INSERTPS             135)
186    (UNSPEC_DP                   136)
187    (UNSPEC_MOVNTDQA             137)
188    (UNSPEC_MPSADBW              138)
189    (UNSPEC_PHMINPOSUW           139)
190    (UNSPEC_PTEST                140)
191    (UNSPEC_ROUND                141)
192
193    ; For SSE4.2 support
194    (UNSPEC_CRC32                143)
195    (UNSPEC_PCMPESTR             144)
196    (UNSPEC_PCMPISTR             145)
197
198    ; For FMA4 support
199    (UNSPEC_FMA4_INTRINSIC       150)
200    (UNSPEC_FMA4_FMADDSUB        151)
201    (UNSPEC_FMA4_FMSUBADD        152)
202    (UNSPEC_XOP_UNSIGNED_CMP     151)
203    (UNSPEC_XOP_TRUEFALSE        152)
204    (UNSPEC_XOP_PERMUTE          153)
205    (UNSPEC_FRCZ                 154)
206
207    ; For AES support
208    (UNSPEC_AESENC               159)
209    (UNSPEC_AESENCLAST           160)
210    (UNSPEC_AESDEC               161)
211    (UNSPEC_AESDECLAST           162)
212    (UNSPEC_AESIMC               163)
213    (UNSPEC_AESKEYGENASSIST      164)
214
215    ; For PCLMUL support
216    (UNSPEC_PCLMUL               165)
217
218    ; For AVX support
219    (UNSPEC_PCMP                 166)
220    (UNSPEC_VPERMIL              167)
221    (UNSPEC_VPERMIL2             168)
222    (UNSPEC_VPERMIL2F128         169)
223    (UNSPEC_MASKLOAD             170)
224    (UNSPEC_MASKSTORE            171)
225    (UNSPEC_CAST                 172)
226    (UNSPEC_VTESTP               173)
227   ])
228
229 (define_constants
230   [(UNSPECV_BLOCKAGE            0)
231    (UNSPECV_STACK_PROBE         1)
232    (UNSPECV_EMMS                2)
233    (UNSPECV_LDMXCSR             3)
234    (UNSPECV_STMXCSR             4)
235    (UNSPECV_FEMMS               5)
236    (UNSPECV_CLFLUSH             6)
237    (UNSPECV_ALIGN               7)
238    (UNSPECV_MONITOR             8)
239    (UNSPECV_MWAIT               9)
240    (UNSPECV_CMPXCHG             10)
241    (UNSPECV_XCHG                12)
242    (UNSPECV_LOCK                13)
243    (UNSPECV_PROLOGUE_USE        14)
244    (UNSPECV_CLD                 15)
245    (UNSPECV_VZEROALL            16)
246    (UNSPECV_VZEROUPPER          17)
247    (UNSPECV_RDTSC               18)
248    (UNSPECV_RDTSCP              19)
249    (UNSPECV_RDPMC               20)
250    (UNSPECV_VSWAPMOV            21)
251    (UNSPECV_LLWP_INTRINSIC      22)
252    (UNSPECV_SLWP_INTRINSIC      23)
253    (UNSPECV_LWPVAL_INTRINSIC    24)
254    (UNSPECV_LWPINS_INTRINSIC    25)
255   ])
256
257 ;; Constants to represent pcomtrue/pcomfalse variants
258 (define_constants
259   [(PCOM_FALSE                  0)
260    (PCOM_TRUE                   1)
261    (COM_FALSE_S                 2)
262    (COM_FALSE_P                 3)
263    (COM_TRUE_S                  4)
264    (COM_TRUE_P                  5)
265   ])
266
267 ;; Constants used in the XOP pperm instruction
268 (define_constants
269   [(PPERM_SRC                   0x00)   /* copy source */
270    (PPERM_INVERT                0x20)   /* invert source */
271    (PPERM_REVERSE               0x40)   /* bit reverse source */
272    (PPERM_REV_INV               0x60)   /* bit reverse & invert src */
273    (PPERM_ZERO                  0x80)   /* all 0's */
274    (PPERM_ONES                  0xa0)   /* all 1's */
275    (PPERM_SIGN                  0xc0)   /* propagate sign bit */
276    (PPERM_INV_SIGN              0xe0)   /* invert & propagate sign */
277    (PPERM_SRC1                  0x00)   /* use first source byte */
278    (PPERM_SRC2                  0x10)   /* use second source byte */
279    ])
280
281 ;; Registers by name.
282 (define_constants
283   [(AX_REG                       0)
284    (DX_REG                       1)
285    (CX_REG                       2)
286    (BX_REG                       3)
287    (SI_REG                       4)
288    (DI_REG                       5)
289    (BP_REG                       6)
290    (SP_REG                       7)
291    (ST0_REG                      8)
292    (ST1_REG                      9)
293    (ST2_REG                     10)
294    (ST3_REG                     11)
295    (ST4_REG                     12)
296    (ST5_REG                     13)
297    (ST6_REG                     14)
298    (ST7_REG                     15)
299    (FLAGS_REG                   17)
300    (FPSR_REG                    18)
301    (FPCR_REG                    19)
302    (XMM0_REG                    21)
303    (XMM1_REG                    22)
304    (XMM2_REG                    23)
305    (XMM3_REG                    24)
306    (XMM4_REG                    25)
307    (XMM5_REG                    26)
308    (XMM6_REG                    27)
309    (XMM7_REG                    28)
310    (MM0_REG                     29)
311    (MM1_REG                     30)
312    (MM2_REG                     31)
313    (MM3_REG                     32)
314    (MM4_REG                     33)
315    (MM5_REG                     34)
316    (MM6_REG                     35)
317    (MM7_REG                     36)
318    (R8_REG                      37)
319    (R9_REG                      38)
320    (R10_REG                     39)
321    (R11_REG                     40)
322    (R12_REG                     41)
323    (R13_REG                     42)
324    (XMM8_REG                    45)
325    (XMM9_REG                    46)
326    (XMM10_REG                   47)
327    (XMM11_REG                   48)
328    (XMM12_REG                   49)
329    (XMM13_REG                   50)
330    (XMM14_REG                   51)
331    (XMM15_REG                   52)
332   ])
333
334 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
335 ;; from i386.c.
336
337 ;; In C guard expressions, put expressions which may be compile-time
338 ;; constants first.  This allows for better optimization.  For
339 ;; example, write "TARGET_64BIT && reload_completed", not
340 ;; "reload_completed && TARGET_64BIT".
341
342 \f
343 ;; Processor type.
344 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,atom,
345                     generic64,amdfam10"
346   (const (symbol_ref "ix86_schedule")))
347
348 ;; A basic instruction type.  Refinements due to arguments to be
349 ;; provided in other attributes.
350 (define_attr "type"
351   "other,multi,
352    alu,alu1,negnot,imov,imovx,lea,
353    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
354    icmp,test,ibr,setcc,icmov,
355    push,pop,call,callv,leave,
356    str,bitmanip,
357    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
358    sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
359    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
360    ssemuladd,sse4arg,lwp,
361    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
362   (const_string "other"))
363
364 ;; Main data type used by the insn
365 (define_attr "mode"
366   "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
367   (const_string "unknown"))
368
369 ;; The CPU unit operations uses.
370 (define_attr "unit" "integer,i387,sse,mmx,unknown"
371   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
372            (const_string "i387")
373          (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
374                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
375                           ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
376            (const_string "sse")
377          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
378            (const_string "mmx")
379          (eq_attr "type" "other")
380            (const_string "unknown")]
381          (const_string "integer")))
382
383 ;; The (bounding maximum) length of an instruction immediate.
384 (define_attr "length_immediate" ""
385   (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
386                           bitmanip")
387            (const_int 0)
388          (eq_attr "unit" "i387,sse,mmx")
389            (const_int 0)
390          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
391                           imul,icmp,push,pop")
392            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
393          (eq_attr "type" "imov,test")
394            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
395          (eq_attr "type" "call")
396            (if_then_else (match_operand 0 "constant_call_address_operand" "")
397              (const_int 4)
398              (const_int 0))
399          (eq_attr "type" "callv")
400            (if_then_else (match_operand 1 "constant_call_address_operand" "")
401              (const_int 4)
402              (const_int 0))
403          ;; We don't know the size before shorten_branches.  Expect
404          ;; the instruction to fit for better scheduling.
405          (eq_attr "type" "ibr")
406            (const_int 1)
407          ]
408          (symbol_ref "/* Update immediate_length and other attributes! */
409                       gcc_unreachable (),1")))
410
411 ;; The (bounding maximum) length of an instruction address.
412 (define_attr "length_address" ""
413   (cond [(eq_attr "type" "str,other,multi,fxch")
414            (const_int 0)
415          (and (eq_attr "type" "call")
416               (match_operand 0 "constant_call_address_operand" ""))
417              (const_int 0)
418          (and (eq_attr "type" "callv")
419               (match_operand 1 "constant_call_address_operand" ""))
420              (const_int 0)
421          ]
422          (symbol_ref "ix86_attr_length_address_default (insn)")))
423
424 ;; Set when length prefix is used.
425 (define_attr "prefix_data16" ""
426   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
427            (const_int 0)
428          (eq_attr "mode" "HI")
429            (const_int 1)
430          (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
431            (const_int 1)
432         ]
433         (const_int 0)))
434
435 ;; Set when string REP prefix is used.
436 (define_attr "prefix_rep" ""
437   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
438            (const_int 0)
439          (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
440            (const_int 1)
441         ]
442         (const_int 0)))
443
444 ;; Set when 0f opcode prefix is used.
445 (define_attr "prefix_0f" ""
446   (if_then_else
447     (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
448          (eq_attr "unit" "sse,mmx"))
449     (const_int 1)
450     (const_int 0)))
451
452 ;; Set when REX opcode prefix is used.
453 (define_attr "prefix_rex" ""
454   (cond [(ne (symbol_ref "!TARGET_64BIT") (const_int 0))
455            (const_int 0)
456          (and (eq_attr "mode" "DI")
457               (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
458                    (eq_attr "unit" "!mmx")))
459            (const_int 1)
460          (and (eq_attr "mode" "QI")
461               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
462                   (const_int 0)))
463            (const_int 1)
464          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
465              (const_int 0))
466            (const_int 1)
467          (and (eq_attr "type" "imovx")
468               (match_operand:QI 1 "ext_QIreg_operand" ""))
469            (const_int 1)
470         ]
471         (const_int 0)))
472
473 ;; There are also additional prefixes in 3DNOW, SSSE3.
474 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
475 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
476 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
477 (define_attr "prefix_extra" ""
478   (cond [(eq_attr "type" "ssemuladd,sse4arg")
479            (const_int 2)
480          (eq_attr "type" "sseiadd1,ssecvt1")
481            (const_int 1)
482         ]
483         (const_int 0)))
484
485 ;; Prefix used: original, VEX or maybe VEX.
486 (define_attr "prefix" "orig,vex,maybe_vex"
487   (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
488     (const_string "vex")
489     (const_string "orig")))
490
491 ;; VEX W bit is used.
492 (define_attr "prefix_vex_w" "" (const_int 0))
493
494 ;; The length of VEX prefix
495 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
496 ;; 0f38/0f3a prefixes can't.  In i386.md 0f3[8a] is
497 ;; still prefix_0f 1, with prefix_extra 1.
498 (define_attr "length_vex" ""
499   (if_then_else (and (eq_attr "prefix_0f" "1")
500                      (eq_attr "prefix_extra" "0"))
501     (if_then_else (eq_attr "prefix_vex_w" "1")
502       (symbol_ref "ix86_attr_length_vex_default (insn, 1, 1)")
503       (symbol_ref "ix86_attr_length_vex_default (insn, 1, 0)"))
504     (if_then_else (eq_attr "prefix_vex_w" "1")
505       (symbol_ref "ix86_attr_length_vex_default (insn, 0, 1)")
506       (symbol_ref "ix86_attr_length_vex_default (insn, 0, 0)"))))
507
508 ;; Set when modrm byte is used.
509 (define_attr "modrm" ""
510   (cond [(eq_attr "type" "str,leave")
511            (const_int 0)
512          (eq_attr "unit" "i387")
513            (const_int 0)
514          (and (eq_attr "type" "incdec")
515               (and (eq (symbol_ref "TARGET_64BIT") (const_int 0))
516                    (ior (match_operand:SI 1 "register_operand" "")
517                         (match_operand:HI 1 "register_operand" ""))))
518            (const_int 0)
519          (and (eq_attr "type" "push")
520               (not (match_operand 1 "memory_operand" "")))
521            (const_int 0)
522          (and (eq_attr "type" "pop")
523               (not (match_operand 0 "memory_operand" "")))
524            (const_int 0)
525          (and (eq_attr "type" "imov")
526               (and (not (eq_attr "mode" "DI"))
527                    (ior (and (match_operand 0 "register_operand" "")
528                              (match_operand 1 "immediate_operand" ""))
529                         (ior (and (match_operand 0 "ax_reg_operand" "")
530                                   (match_operand 1 "memory_displacement_only_operand" ""))
531                              (and (match_operand 0 "memory_displacement_only_operand" "")
532                                   (match_operand 1 "ax_reg_operand" ""))))))
533            (const_int 0)
534          (and (eq_attr "type" "call")
535               (match_operand 0 "constant_call_address_operand" ""))
536              (const_int 0)
537          (and (eq_attr "type" "callv")
538               (match_operand 1 "constant_call_address_operand" ""))
539              (const_int 0)
540          (and (eq_attr "type" "alu,alu1,icmp,test")
541               (match_operand 0 "ax_reg_operand" ""))
542              (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
543          ]
544          (const_int 1)))
545
546 ;; The (bounding maximum) length of an instruction in bytes.
547 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
548 ;; Later we may want to split them and compute proper length as for
549 ;; other insns.
550 (define_attr "length" ""
551   (cond [(eq_attr "type" "other,multi,fistp,frndint")
552            (const_int 16)
553          (eq_attr "type" "fcmp")
554            (const_int 4)
555          (eq_attr "unit" "i387")
556            (plus (const_int 2)
557                  (plus (attr "prefix_data16")
558                        (attr "length_address")))
559          (ior (eq_attr "prefix" "vex")
560               (and (eq_attr "prefix" "maybe_vex")
561                     (ne (symbol_ref "TARGET_AVX") (const_int 0))))
562            (plus (attr "length_vex")
563                  (plus (attr "length_immediate")
564                        (plus (attr "modrm")
565                              (attr "length_address"))))]
566          (plus (plus (attr "modrm")
567                      (plus (attr "prefix_0f")
568                            (plus (attr "prefix_rex")
569                                  (plus (attr "prefix_extra")
570                                        (const_int 1)))))
571                (plus (attr "prefix_rep")
572                      (plus (attr "prefix_data16")
573                            (plus (attr "length_immediate")
574                                  (attr "length_address")))))))
575
576 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
577 ;; `store' if there is a simple memory reference therein, or `unknown'
578 ;; if the instruction is complex.
579
580 (define_attr "memory" "none,load,store,both,unknown"
581   (cond [(eq_attr "type" "other,multi,str,lwp")
582            (const_string "unknown")
583          (eq_attr "type" "lea,fcmov,fpspc")
584            (const_string "none")
585          (eq_attr "type" "fistp,leave")
586            (const_string "both")
587          (eq_attr "type" "frndint")
588            (const_string "load")
589          (eq_attr "type" "push")
590            (if_then_else (match_operand 1 "memory_operand" "")
591              (const_string "both")
592              (const_string "store"))
593          (eq_attr "type" "pop")
594            (if_then_else (match_operand 0 "memory_operand" "")
595              (const_string "both")
596              (const_string "load"))
597          (eq_attr "type" "setcc")
598            (if_then_else (match_operand 0 "memory_operand" "")
599              (const_string "store")
600              (const_string "none"))
601          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
602            (if_then_else (ior (match_operand 0 "memory_operand" "")
603                               (match_operand 1 "memory_operand" ""))
604              (const_string "load")
605              (const_string "none"))
606          (eq_attr "type" "ibr")
607            (if_then_else (match_operand 0 "memory_operand" "")
608              (const_string "load")
609              (const_string "none"))
610          (eq_attr "type" "call")
611            (if_then_else (match_operand 0 "constant_call_address_operand" "")
612              (const_string "none")
613              (const_string "load"))
614          (eq_attr "type" "callv")
615            (if_then_else (match_operand 1 "constant_call_address_operand" "")
616              (const_string "none")
617              (const_string "load"))
618          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
619               (match_operand 1 "memory_operand" ""))
620            (const_string "both")
621          (and (match_operand 0 "memory_operand" "")
622               (match_operand 1 "memory_operand" ""))
623            (const_string "both")
624          (match_operand 0 "memory_operand" "")
625            (const_string "store")
626          (match_operand 1 "memory_operand" "")
627            (const_string "load")
628          (and (eq_attr "type"
629                  "!alu1,negnot,ishift1,
630                    imov,imovx,icmp,test,bitmanip,
631                    fmov,fcmp,fsgn,
632                    sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
633                    sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
634               (match_operand 2 "memory_operand" ""))
635            (const_string "load")
636          (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
637               (match_operand 3 "memory_operand" ""))
638            (const_string "load")
639         ]
640         (const_string "none")))
641
642 ;; Indicates if an instruction has both an immediate and a displacement.
643
644 (define_attr "imm_disp" "false,true,unknown"
645   (cond [(eq_attr "type" "other,multi")
646            (const_string "unknown")
647          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
648               (and (match_operand 0 "memory_displacement_operand" "")
649                    (match_operand 1 "immediate_operand" "")))
650            (const_string "true")
651          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
652               (and (match_operand 0 "memory_displacement_operand" "")
653                    (match_operand 2 "immediate_operand" "")))
654            (const_string "true")
655         ]
656         (const_string "false")))
657
658 ;; Indicates if an FP operation has an integer source.
659
660 (define_attr "fp_int_src" "false,true"
661   (const_string "false"))
662
663 ;; Defines rounding mode of an FP operation.
664
665 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
666   (const_string "any"))
667
668 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
669 (define_attr "use_carry" "0,1" (const_string "0"))
670
671 ;; Define attribute to indicate unaligned ssemov insns
672 (define_attr "movu" "0,1" (const_string "0"))
673
674 ;; Describe a user's asm statement.
675 (define_asm_attributes
676   [(set_attr "length" "128")
677    (set_attr "type" "multi")])
678
679 ;; All integer comparison codes.
680 (define_code_iterator int_cond [ne eq ge gt le lt geu gtu leu ltu])
681
682 ;; All floating-point comparison codes.
683 (define_code_iterator fp_cond [unordered ordered
684                                uneq unge ungt unle unlt ltgt])
685
686 (define_code_iterator plusminus [plus minus])
687
688 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
689
690 ;; Base name for define_insn
691 (define_code_attr plusminus_insn
692   [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
693    (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
694
695 ;; Base name for insn mnemonic.
696 (define_code_attr plusminus_mnemonic
697   [(plus "add") (ss_plus "adds") (us_plus "addus")
698    (minus "sub") (ss_minus "subs") (us_minus "subus")])
699 (define_code_attr plusminus_carry_mnemonic
700   [(plus "adc") (minus "sbb")])
701
702 ;; Mark commutative operators as such in constraints.
703 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
704                         (minus "") (ss_minus "") (us_minus "")])
705
706 ;; Mapping of signed max and min
707 (define_code_iterator smaxmin [smax smin])
708
709 ;; Mapping of unsigned max and min
710 (define_code_iterator umaxmin [umax umin])
711
712 ;; Mapping of signed/unsigned max and min
713 (define_code_iterator maxmin [smax smin umax umin])
714
715 ;; Base name for integer and FP insn mnemonic
716 (define_code_attr maxminiprefix [(smax "maxs") (smin "mins")
717                                  (umax "maxu") (umin "minu")])
718 (define_code_attr maxminfprefix [(smax "max") (smin "min")])
719
720 ;; Mapping of logic operators
721 (define_code_iterator any_logic [and ior xor])
722 (define_code_iterator any_or [ior xor])
723
724 ;; Base name for insn mnemonic.
725 (define_code_attr logicprefix [(and "and") (ior "or") (xor "xor")])
726
727 ;; Mapping of shift-right operators
728 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
729
730 ;; Base name for define_insn
731 (define_code_attr shiftrt_insn [(lshiftrt "lshr") (ashiftrt "ashr")])
732
733 ;; Base name for insn mnemonic.
734 (define_code_attr shiftrt [(lshiftrt "shr") (ashiftrt "sar")])
735
736 ;; Mapping of abs neg operators
737 (define_code_iterator absneg [abs neg])
738
739 ;; Base name for x87 insn mnemonic.
740 (define_code_attr absnegprefix [(abs "abs") (neg "chs")])
741
742 ;; Used in signed and unsigned widening multiplications.
743 (define_code_iterator any_extend [sign_extend zero_extend])
744
745 ;; Various insn prefixes for signed and unsigned operations.
746 (define_code_attr u [(sign_extend "") (zero_extend "u")
747                      (div "") (udiv "u")])
748 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
749
750 ;; Used in signed and unsigned divisions.
751 (define_code_iterator any_div [div udiv])
752
753 ;; Instruction prefix for signed and unsigned operations.
754 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")
755                              (div "i") (udiv "")])
756
757 ;; All single word integer modes.
758 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
759
760 ;; Single word integer modes without DImode.
761 (define_mode_iterator SWI124 [QI HI SI])
762
763 ;; Single word integer modes without QImode.
764 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
765
766 ;; Single word integer modes without QImode and HImode.
767 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
768
769 ;; All math-dependant single and double word integer modes.
770 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
771                              (HI "TARGET_HIMODE_MATH")
772                              SI DI (TI "TARGET_64BIT")])
773
774 ;; Math-dependant single word integer modes.
775 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
776                             (HI "TARGET_HIMODE_MATH")
777                             SI (DI "TARGET_64BIT")])
778
779 ;; Math-dependant single word integer modes without QImode.
780 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
781                                SI (DI "TARGET_64BIT")])
782
783 ;; Double word integer modes.
784 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
785                            (TI "TARGET_64BIT")])
786
787 ;; Double word integer modes as mode attribute.
788 (define_mode_attr DWI [(SI "DI") (DI "TI")])
789 (define_mode_attr dwi [(SI "di") (DI "ti")])
790
791 ;; Half mode for double word integer modes.
792 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
793                             (DI "TARGET_64BIT")])
794
795 ;; Instruction suffix for integer modes.
796 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
797
798 ;; Register class for integer modes.
799 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
800
801 ;; Immediate operand constraint for integer modes.
802 (define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")])
803
804 ;; General operand constraint for word modes.
805 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "g") (DI "rme")])
806
807 ;; Immediate operand constraint for double integer modes.
808 (define_mode_attr di [(SI "iF") (DI "e")])
809
810 ;; Immediate operand constraint for shifts.
811 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
812
813 ;; General operand predicate for integer modes.
814 (define_mode_attr general_operand
815         [(QI "general_operand")
816          (HI "general_operand")
817          (SI "general_operand")
818          (DI "x86_64_general_operand")
819          (TI "x86_64_general_operand")])
820
821 ;; General sign/zero extend operand predicate for integer modes.
822 (define_mode_attr general_szext_operand
823         [(QI "general_operand")
824          (HI "general_operand")
825          (SI "general_operand")
826          (DI "x86_64_szext_general_operand")])
827
828 ;; Operand predicate for shifts.
829 (define_mode_attr shift_operand
830         [(QI "nonimmediate_operand")
831          (HI "nonimmediate_operand")
832          (SI "nonimmediate_operand")
833          (DI "shiftdi_operand")
834          (TI "register_operand")])
835
836 ;; Operand predicate for shift argument.
837 (define_mode_attr shift_immediate_operand
838         [(QI "const_1_to_31_operand")
839          (HI "const_1_to_31_operand")
840          (SI "const_1_to_31_operand")
841          (DI "const_1_to_63_operand")])
842
843 ;; Input operand predicate for arithmetic left shifts.
844 (define_mode_attr ashl_input_operand
845         [(QI "nonimmediate_operand")
846          (HI "nonimmediate_operand")
847          (SI "nonimmediate_operand")
848          (DI "ashldi_input_operand")
849          (TI "reg_or_pm1_operand")])
850
851 ;; SSE and x87 SFmode and DFmode floating point modes
852 (define_mode_iterator MODEF [SF DF])
853
854 ;; All x87 floating point modes
855 (define_mode_iterator X87MODEF [SF DF XF])
856
857 ;; All integer modes handled by x87 fisttp operator.
858 (define_mode_iterator X87MODEI [HI SI DI])
859
860 ;; All integer modes handled by integer x87 operators.
861 (define_mode_iterator X87MODEI12 [HI SI])
862
863 ;; All integer modes handled by SSE cvtts?2si* operators.
864 (define_mode_iterator SSEMODEI24 [SI DI])
865
866 ;; SSE asm suffix for floating point modes
867 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
868
869 ;; SSE vector mode corresponding to a scalar mode
870 (define_mode_attr ssevecmode
871   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
872
873 ;; Instruction suffix for REX 64bit operators.
874 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
875
876 ;; This mode iterator allows :P to be used for patterns that operate on
877 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
878 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
879 \f
880 ;; Scheduling descriptions
881
882 (include "pentium.md")
883 (include "ppro.md")
884 (include "k6.md")
885 (include "athlon.md")
886 (include "geode.md")
887 (include "atom.md")
888
889 \f
890 ;; Operand and operator predicates and constraints
891
892 (include "predicates.md")
893 (include "constraints.md")
894
895 \f
896 ;; Compare and branch/compare and store instructions.
897
898 (define_expand "cbranch<mode>4"
899   [(set (reg:CC FLAGS_REG)
900         (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
901                     (match_operand:SDWIM 2 "<general_operand>" "")))
902    (set (pc) (if_then_else
903                (match_operator 0 "comparison_operator"
904                 [(reg:CC FLAGS_REG) (const_int 0)])
905                (label_ref (match_operand 3 "" ""))
906                (pc)))]
907   ""
908 {
909   if (MEM_P (operands[1]) && MEM_P (operands[2]))
910     operands[1] = force_reg (<MODE>mode, operands[1]);
911   ix86_compare_op0 = operands[1];
912   ix86_compare_op1 = operands[2];
913   ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
914   DONE;
915 })
916
917 (define_expand "cstore<mode>4"
918   [(set (reg:CC FLAGS_REG)
919         (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
920                     (match_operand:SWIM 3 "<general_operand>" "")))
921    (set (match_operand:QI 0 "register_operand" "")
922         (match_operator 1 "comparison_operator"
923           [(reg:CC FLAGS_REG) (const_int 0)]))]
924   ""
925 {
926   if (MEM_P (operands[2]) && MEM_P (operands[3]))
927     operands[2] = force_reg (<MODE>mode, operands[2]);
928   ix86_compare_op0 = operands[2];
929   ix86_compare_op1 = operands[3];
930   ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
931   DONE;
932 })
933
934 (define_expand "cmp<mode>_1"
935   [(set (reg:CC FLAGS_REG)
936         (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
937                     (match_operand:SWI48 1 "<general_operand>" "")))]
938   ""
939   "")
940
941 (define_insn "*cmp<mode>_ccno_1"
942   [(set (reg FLAGS_REG)
943         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
944                  (match_operand:SWI 1 "const0_operand" "")))]
945   "ix86_match_ccmode (insn, CCNOmode)"
946   "@
947    test{<imodesuffix>}\t%0, %0
948    cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
949   [(set_attr "type" "test,icmp")
950    (set_attr "length_immediate" "0,1")
951    (set_attr "mode" "<MODE>")])
952
953 (define_insn "*cmp<mode>_1"
954   [(set (reg FLAGS_REG)
955         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
956                  (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
957   "ix86_match_ccmode (insn, CCmode)"
958   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
959   [(set_attr "type" "icmp")
960    (set_attr "mode" "<MODE>")])
961
962 (define_insn "*cmp<mode>_minus_1"
963   [(set (reg FLAGS_REG)
964         (compare
965           (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
966                      (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
967           (const_int 0)))]
968   "ix86_match_ccmode (insn, CCGOCmode)"
969   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
970   [(set_attr "type" "icmp")
971    (set_attr "mode" "<MODE>")])
972
973 (define_insn "*cmpqi_ext_1"
974   [(set (reg FLAGS_REG)
975         (compare
976           (match_operand:QI 0 "general_operand" "Qm")
977           (subreg:QI
978             (zero_extract:SI
979               (match_operand 1 "ext_register_operand" "Q")
980               (const_int 8)
981               (const_int 8)) 0)))]
982   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
983   "cmp{b}\t{%h1, %0|%0, %h1}"
984   [(set_attr "type" "icmp")
985    (set_attr "mode" "QI")])
986
987 (define_insn "*cmpqi_ext_1_rex64"
988   [(set (reg FLAGS_REG)
989         (compare
990           (match_operand:QI 0 "register_operand" "Q")
991           (subreg:QI
992             (zero_extract:SI
993               (match_operand 1 "ext_register_operand" "Q")
994               (const_int 8)
995               (const_int 8)) 0)))]
996   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
997   "cmp{b}\t{%h1, %0|%0, %h1}"
998   [(set_attr "type" "icmp")
999    (set_attr "mode" "QI")])
1000
1001 (define_insn "*cmpqi_ext_2"
1002   [(set (reg FLAGS_REG)
1003         (compare
1004           (subreg:QI
1005             (zero_extract:SI
1006               (match_operand 0 "ext_register_operand" "Q")
1007               (const_int 8)
1008               (const_int 8)) 0)
1009           (match_operand:QI 1 "const0_operand" "")))]
1010   "ix86_match_ccmode (insn, CCNOmode)"
1011   "test{b}\t%h0, %h0"
1012   [(set_attr "type" "test")
1013    (set_attr "length_immediate" "0")
1014    (set_attr "mode" "QI")])
1015
1016 (define_expand "cmpqi_ext_3"
1017   [(set (reg:CC FLAGS_REG)
1018         (compare:CC
1019           (subreg:QI
1020             (zero_extract:SI
1021               (match_operand 0 "ext_register_operand" "")
1022               (const_int 8)
1023               (const_int 8)) 0)
1024           (match_operand:QI 1 "immediate_operand" "")))]
1025   ""
1026   "")
1027
1028 (define_insn "*cmpqi_ext_3_insn"
1029   [(set (reg FLAGS_REG)
1030         (compare
1031           (subreg:QI
1032             (zero_extract:SI
1033               (match_operand 0 "ext_register_operand" "Q")
1034               (const_int 8)
1035               (const_int 8)) 0)
1036           (match_operand:QI 1 "general_operand" "Qmn")))]
1037   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1038   "cmp{b}\t{%1, %h0|%h0, %1}"
1039   [(set_attr "type" "icmp")
1040    (set_attr "modrm" "1")
1041    (set_attr "mode" "QI")])
1042
1043 (define_insn "*cmpqi_ext_3_insn_rex64"
1044   [(set (reg FLAGS_REG)
1045         (compare
1046           (subreg:QI
1047             (zero_extract:SI
1048               (match_operand 0 "ext_register_operand" "Q")
1049               (const_int 8)
1050               (const_int 8)) 0)
1051           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1052   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1053   "cmp{b}\t{%1, %h0|%h0, %1}"
1054   [(set_attr "type" "icmp")
1055    (set_attr "modrm" "1")
1056    (set_attr "mode" "QI")])
1057
1058 (define_insn "*cmpqi_ext_4"
1059   [(set (reg FLAGS_REG)
1060         (compare
1061           (subreg:QI
1062             (zero_extract:SI
1063               (match_operand 0 "ext_register_operand" "Q")
1064               (const_int 8)
1065               (const_int 8)) 0)
1066           (subreg:QI
1067             (zero_extract:SI
1068               (match_operand 1 "ext_register_operand" "Q")
1069               (const_int 8)
1070               (const_int 8)) 0)))]
1071   "ix86_match_ccmode (insn, CCmode)"
1072   "cmp{b}\t{%h1, %h0|%h0, %h1}"
1073   [(set_attr "type" "icmp")
1074    (set_attr "mode" "QI")])
1075
1076 ;; These implement float point compares.
1077 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1078 ;; which would allow mix and match FP modes on the compares.  Which is what
1079 ;; the old patterns did, but with many more of them.
1080
1081 (define_expand "cbranchxf4"
1082   [(set (reg:CC FLAGS_REG)
1083         (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1084                     (match_operand:XF 2 "nonmemory_operand" "")))
1085    (set (pc) (if_then_else
1086               (match_operator 0 "ix86_fp_comparison_operator"
1087                [(reg:CC FLAGS_REG)
1088                 (const_int 0)])
1089               (label_ref (match_operand 3 "" ""))
1090               (pc)))]
1091   "TARGET_80387"
1092 {
1093   ix86_compare_op0 = operands[1];
1094   ix86_compare_op1 = operands[2];
1095   ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1096   DONE;
1097 })
1098
1099 (define_expand "cstorexf4"
1100   [(set (reg:CC FLAGS_REG)
1101         (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1102                     (match_operand:XF 3 "nonmemory_operand" "")))
1103    (set (match_operand:QI 0 "register_operand" "")
1104               (match_operator 1 "ix86_fp_comparison_operator"
1105                [(reg:CC FLAGS_REG)
1106                 (const_int 0)]))]
1107   "TARGET_80387"
1108 {
1109   ix86_compare_op0 = operands[2];
1110   ix86_compare_op1 = operands[3];
1111   ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1112   DONE;
1113 })
1114
1115 (define_expand "cbranch<mode>4"
1116   [(set (reg:CC FLAGS_REG)
1117         (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1118                     (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1119    (set (pc) (if_then_else
1120               (match_operator 0 "ix86_fp_comparison_operator"
1121                [(reg:CC FLAGS_REG)
1122                 (const_int 0)])
1123               (label_ref (match_operand 3 "" ""))
1124               (pc)))]
1125   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1126 {
1127   ix86_compare_op0 = operands[1];
1128   ix86_compare_op1 = operands[2];
1129   ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1130   DONE;
1131 })
1132
1133 (define_expand "cstore<mode>4"
1134   [(set (reg:CC FLAGS_REG)
1135         (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1136                     (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1137    (set (match_operand:QI 0 "register_operand" "")
1138               (match_operator 1 "ix86_fp_comparison_operator"
1139                [(reg:CC FLAGS_REG)
1140                 (const_int 0)]))]
1141   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1142 {
1143   ix86_compare_op0 = operands[2];
1144   ix86_compare_op1 = operands[3];
1145   ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1146   DONE;
1147 })
1148
1149 (define_expand "cbranchcc4"
1150   [(set (pc) (if_then_else
1151               (match_operator 0 "comparison_operator"
1152                [(match_operand 1 "flags_reg_operand" "")
1153                 (match_operand 2 "const0_operand" "")])
1154               (label_ref (match_operand 3 "" ""))
1155               (pc)))]
1156   ""
1157 {
1158   ix86_compare_op0 = operands[1];
1159   ix86_compare_op1 = operands[2];
1160   ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1161   DONE;
1162 })
1163
1164 (define_expand "cstorecc4"
1165   [(set (match_operand:QI 0 "register_operand" "")
1166               (match_operator 1 "comparison_operator"
1167                [(match_operand 2 "flags_reg_operand" "")
1168                 (match_operand 3 "const0_operand" "")]))]
1169   ""
1170 {
1171   ix86_compare_op0 = operands[2];
1172   ix86_compare_op1 = operands[3];
1173   ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1174   DONE;
1175 })
1176
1177
1178 ;; FP compares, step 1:
1179 ;; Set the FP condition codes.
1180 ;;
1181 ;; CCFPmode     compare with exceptions
1182 ;; CCFPUmode    compare with no exceptions
1183
1184 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1185 ;; used to manage the reg stack popping would not be preserved.
1186
1187 (define_insn "*cmpfp_0"
1188   [(set (match_operand:HI 0 "register_operand" "=a")
1189         (unspec:HI
1190           [(compare:CCFP
1191              (match_operand 1 "register_operand" "f")
1192              (match_operand 2 "const0_operand" ""))]
1193         UNSPEC_FNSTSW))]
1194   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1195    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1196   "* return output_fp_compare (insn, operands, 0, 0);"
1197   [(set_attr "type" "multi")
1198    (set_attr "unit" "i387")
1199    (set (attr "mode")
1200      (cond [(match_operand:SF 1 "" "")
1201               (const_string "SF")
1202             (match_operand:DF 1 "" "")
1203               (const_string "DF")
1204            ]
1205            (const_string "XF")))])
1206
1207 (define_insn_and_split "*cmpfp_0_cc"
1208   [(set (reg:CCFP FLAGS_REG)
1209         (compare:CCFP
1210           (match_operand 1 "register_operand" "f")
1211           (match_operand 2 "const0_operand" "")))
1212    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1213   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1214    && TARGET_SAHF && !TARGET_CMOVE
1215    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1216   "#"
1217   "&& reload_completed"
1218   [(set (match_dup 0)
1219         (unspec:HI
1220           [(compare:CCFP (match_dup 1)(match_dup 2))]
1221         UNSPEC_FNSTSW))
1222    (set (reg:CC FLAGS_REG)
1223         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1224   ""
1225   [(set_attr "type" "multi")
1226    (set_attr "unit" "i387")
1227    (set (attr "mode")
1228      (cond [(match_operand:SF 1 "" "")
1229               (const_string "SF")
1230             (match_operand:DF 1 "" "")
1231               (const_string "DF")
1232            ]
1233            (const_string "XF")))])
1234
1235 (define_insn "*cmpfp_xf"
1236   [(set (match_operand:HI 0 "register_operand" "=a")
1237         (unspec:HI
1238           [(compare:CCFP
1239              (match_operand:XF 1 "register_operand" "f")
1240              (match_operand:XF 2 "register_operand" "f"))]
1241           UNSPEC_FNSTSW))]
1242   "TARGET_80387"
1243   "* return output_fp_compare (insn, operands, 0, 0);"
1244   [(set_attr "type" "multi")
1245    (set_attr "unit" "i387")
1246    (set_attr "mode" "XF")])
1247
1248 (define_insn_and_split "*cmpfp_xf_cc"
1249   [(set (reg:CCFP FLAGS_REG)
1250         (compare:CCFP
1251           (match_operand:XF 1 "register_operand" "f")
1252           (match_operand:XF 2 "register_operand" "f")))
1253    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1254   "TARGET_80387
1255    && TARGET_SAHF && !TARGET_CMOVE"
1256   "#"
1257   "&& reload_completed"
1258   [(set (match_dup 0)
1259         (unspec:HI
1260           [(compare:CCFP (match_dup 1)(match_dup 2))]
1261         UNSPEC_FNSTSW))
1262    (set (reg:CC FLAGS_REG)
1263         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1264   ""
1265   [(set_attr "type" "multi")
1266    (set_attr "unit" "i387")
1267    (set_attr "mode" "XF")])
1268
1269 (define_insn "*cmpfp_<mode>"
1270   [(set (match_operand:HI 0 "register_operand" "=a")
1271         (unspec:HI
1272           [(compare:CCFP
1273              (match_operand:MODEF 1 "register_operand" "f")
1274              (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1275           UNSPEC_FNSTSW))]
1276   "TARGET_80387"
1277   "* return output_fp_compare (insn, operands, 0, 0);"
1278   [(set_attr "type" "multi")
1279    (set_attr "unit" "i387")
1280    (set_attr "mode" "<MODE>")])
1281
1282 (define_insn_and_split "*cmpfp_<mode>_cc"
1283   [(set (reg:CCFP FLAGS_REG)
1284         (compare:CCFP
1285           (match_operand:MODEF 1 "register_operand" "f")
1286           (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1287    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1288   "TARGET_80387
1289    && TARGET_SAHF && !TARGET_CMOVE"
1290   "#"
1291   "&& reload_completed"
1292   [(set (match_dup 0)
1293         (unspec:HI
1294           [(compare:CCFP (match_dup 1)(match_dup 2))]
1295         UNSPEC_FNSTSW))
1296    (set (reg:CC FLAGS_REG)
1297         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1298   ""
1299   [(set_attr "type" "multi")
1300    (set_attr "unit" "i387")
1301    (set_attr "mode" "<MODE>")])
1302
1303 (define_insn "*cmpfp_u"
1304   [(set (match_operand:HI 0 "register_operand" "=a")
1305         (unspec:HI
1306           [(compare:CCFPU
1307              (match_operand 1 "register_operand" "f")
1308              (match_operand 2 "register_operand" "f"))]
1309           UNSPEC_FNSTSW))]
1310   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1311    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1312   "* return output_fp_compare (insn, operands, 0, 1);"
1313   [(set_attr "type" "multi")
1314    (set_attr "unit" "i387")
1315    (set (attr "mode")
1316      (cond [(match_operand:SF 1 "" "")
1317               (const_string "SF")
1318             (match_operand:DF 1 "" "")
1319               (const_string "DF")
1320            ]
1321            (const_string "XF")))])
1322
1323 (define_insn_and_split "*cmpfp_u_cc"
1324   [(set (reg:CCFPU FLAGS_REG)
1325         (compare:CCFPU
1326           (match_operand 1 "register_operand" "f")
1327           (match_operand 2 "register_operand" "f")))
1328    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1329   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1330    && TARGET_SAHF && !TARGET_CMOVE
1331    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1332   "#"
1333   "&& reload_completed"
1334   [(set (match_dup 0)
1335         (unspec:HI
1336           [(compare:CCFPU (match_dup 1)(match_dup 2))]
1337         UNSPEC_FNSTSW))
1338    (set (reg:CC FLAGS_REG)
1339         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1340   ""
1341   [(set_attr "type" "multi")
1342    (set_attr "unit" "i387")
1343    (set (attr "mode")
1344      (cond [(match_operand:SF 1 "" "")
1345               (const_string "SF")
1346             (match_operand:DF 1 "" "")
1347               (const_string "DF")
1348            ]
1349            (const_string "XF")))])
1350
1351 (define_insn "*cmpfp_<mode>"
1352   [(set (match_operand:HI 0 "register_operand" "=a")
1353         (unspec:HI
1354           [(compare:CCFP
1355              (match_operand 1 "register_operand" "f")
1356              (match_operator 3 "float_operator"
1357                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1358           UNSPEC_FNSTSW))]
1359   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1360    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1361    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1362   "* return output_fp_compare (insn, operands, 0, 0);"
1363   [(set_attr "type" "multi")
1364    (set_attr "unit" "i387")
1365    (set_attr "fp_int_src" "true")
1366    (set_attr "mode" "<MODE>")])
1367
1368 (define_insn_and_split "*cmpfp_<mode>_cc"
1369   [(set (reg:CCFP FLAGS_REG)
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    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1375   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1376    && TARGET_SAHF && !TARGET_CMOVE
1377    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1378    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1379   "#"
1380   "&& reload_completed"
1381   [(set (match_dup 0)
1382         (unspec:HI
1383           [(compare:CCFP
1384              (match_dup 1)
1385              (match_op_dup 3 [(match_dup 2)]))]
1386         UNSPEC_FNSTSW))
1387    (set (reg:CC FLAGS_REG)
1388         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1389   ""
1390   [(set_attr "type" "multi")
1391    (set_attr "unit" "i387")
1392    (set_attr "fp_int_src" "true")
1393    (set_attr "mode" "<MODE>")])
1394
1395 ;; FP compares, step 2
1396 ;; Move the fpsw to ax.
1397
1398 (define_insn "x86_fnstsw_1"
1399   [(set (match_operand:HI 0 "register_operand" "=a")
1400         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1401   "TARGET_80387"
1402   "fnstsw\t%0"
1403   [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1404    (set_attr "mode" "SI")
1405    (set_attr "unit" "i387")])
1406
1407 ;; FP compares, step 3
1408 ;; Get ax into flags, general case.
1409
1410 (define_insn "x86_sahf_1"
1411   [(set (reg:CC FLAGS_REG)
1412         (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1413                    UNSPEC_SAHF))]
1414   "TARGET_SAHF"
1415 {
1416 #ifdef HAVE_AS_IX86_SAHF
1417   return "sahf";
1418 #else
1419   return ASM_BYTE "0x9e";
1420 #endif
1421 }
1422   [(set_attr "length" "1")
1423    (set_attr "athlon_decode" "vector")
1424    (set_attr "amdfam10_decode" "direct")
1425    (set_attr "mode" "SI")])
1426
1427 ;; Pentium Pro can do steps 1 through 3 in one go.
1428 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1429 (define_insn "*cmpfp_i_mixed"
1430   [(set (reg:CCFP FLAGS_REG)
1431         (compare:CCFP (match_operand 0 "register_operand" "f,x")
1432                       (match_operand 1 "nonimmediate_operand" "f,xm")))]
1433   "TARGET_MIX_SSE_I387
1434    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1435    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1436   "* return output_fp_compare (insn, operands, 1, 0);"
1437   [(set_attr "type" "fcmp,ssecomi")
1438    (set_attr "prefix" "orig,maybe_vex")
1439    (set (attr "mode")
1440      (if_then_else (match_operand:SF 1 "" "")
1441         (const_string "SF")
1442         (const_string "DF")))
1443    (set (attr "prefix_rep")
1444         (if_then_else (eq_attr "type" "ssecomi")
1445                       (const_string "0")
1446                       (const_string "*")))
1447    (set (attr "prefix_data16")
1448         (cond [(eq_attr "type" "fcmp")
1449                  (const_string "*")
1450                (eq_attr "mode" "DF")
1451                  (const_string "1")
1452               ]
1453               (const_string "0")))
1454    (set_attr "athlon_decode" "vector")
1455    (set_attr "amdfam10_decode" "direct")])
1456
1457 (define_insn "*cmpfp_i_sse"
1458   [(set (reg:CCFP FLAGS_REG)
1459         (compare:CCFP (match_operand 0 "register_operand" "x")
1460                       (match_operand 1 "nonimmediate_operand" "xm")))]
1461   "TARGET_SSE_MATH
1462    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1463    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1464   "* return output_fp_compare (insn, operands, 1, 0);"
1465   [(set_attr "type" "ssecomi")
1466    (set_attr "prefix" "maybe_vex")
1467    (set (attr "mode")
1468      (if_then_else (match_operand:SF 1 "" "")
1469         (const_string "SF")
1470         (const_string "DF")))
1471    (set_attr "prefix_rep" "0")
1472    (set (attr "prefix_data16")
1473         (if_then_else (eq_attr "mode" "DF")
1474                       (const_string "1")
1475                       (const_string "0")))
1476    (set_attr "athlon_decode" "vector")
1477    (set_attr "amdfam10_decode" "direct")])
1478
1479 (define_insn "*cmpfp_i_i387"
1480   [(set (reg:CCFP FLAGS_REG)
1481         (compare:CCFP (match_operand 0 "register_operand" "f")
1482                       (match_operand 1 "register_operand" "f")))]
1483   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1484    && TARGET_CMOVE
1485    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1486    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1487   "* return output_fp_compare (insn, operands, 1, 0);"
1488   [(set_attr "type" "fcmp")
1489    (set (attr "mode")
1490      (cond [(match_operand:SF 1 "" "")
1491               (const_string "SF")
1492             (match_operand:DF 1 "" "")
1493               (const_string "DF")
1494            ]
1495            (const_string "XF")))
1496    (set_attr "athlon_decode" "vector")
1497    (set_attr "amdfam10_decode" "direct")])
1498
1499 (define_insn "*cmpfp_iu_mixed"
1500   [(set (reg:CCFPU FLAGS_REG)
1501         (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1502                        (match_operand 1 "nonimmediate_operand" "f,xm")))]
1503   "TARGET_MIX_SSE_I387
1504    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1505    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1506   "* return output_fp_compare (insn, operands, 1, 1);"
1507   [(set_attr "type" "fcmp,ssecomi")
1508    (set_attr "prefix" "orig,maybe_vex")
1509    (set (attr "mode")
1510      (if_then_else (match_operand:SF 1 "" "")
1511         (const_string "SF")
1512         (const_string "DF")))
1513    (set (attr "prefix_rep")
1514         (if_then_else (eq_attr "type" "ssecomi")
1515                       (const_string "0")
1516                       (const_string "*")))
1517    (set (attr "prefix_data16")
1518         (cond [(eq_attr "type" "fcmp")
1519                  (const_string "*")
1520                (eq_attr "mode" "DF")
1521                  (const_string "1")
1522               ]
1523               (const_string "0")))
1524    (set_attr "athlon_decode" "vector")
1525    (set_attr "amdfam10_decode" "direct")])
1526
1527 (define_insn "*cmpfp_iu_sse"
1528   [(set (reg:CCFPU FLAGS_REG)
1529         (compare:CCFPU (match_operand 0 "register_operand" "x")
1530                        (match_operand 1 "nonimmediate_operand" "xm")))]
1531   "TARGET_SSE_MATH
1532    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1533    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1534   "* return output_fp_compare (insn, operands, 1, 1);"
1535   [(set_attr "type" "ssecomi")
1536    (set_attr "prefix" "maybe_vex")
1537    (set (attr "mode")
1538      (if_then_else (match_operand:SF 1 "" "")
1539         (const_string "SF")
1540         (const_string "DF")))
1541    (set_attr "prefix_rep" "0")
1542    (set (attr "prefix_data16")
1543         (if_then_else (eq_attr "mode" "DF")
1544                       (const_string "1")
1545                       (const_string "0")))
1546    (set_attr "athlon_decode" "vector")
1547    (set_attr "amdfam10_decode" "direct")])
1548
1549 (define_insn "*cmpfp_iu_387"
1550   [(set (reg:CCFPU FLAGS_REG)
1551         (compare:CCFPU (match_operand 0 "register_operand" "f")
1552                        (match_operand 1 "register_operand" "f")))]
1553   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1554    && TARGET_CMOVE
1555    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1556    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1557   "* return output_fp_compare (insn, operands, 1, 1);"
1558   [(set_attr "type" "fcmp")
1559    (set (attr "mode")
1560      (cond [(match_operand:SF 1 "" "")
1561               (const_string "SF")
1562             (match_operand:DF 1 "" "")
1563               (const_string "DF")
1564            ]
1565            (const_string "XF")))
1566    (set_attr "athlon_decode" "vector")
1567    (set_attr "amdfam10_decode" "direct")])
1568 \f
1569 ;; Move instructions.
1570
1571 ;; General case of fullword move.
1572
1573 (define_expand "movsi"
1574   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1575         (match_operand:SI 1 "general_operand" ""))]
1576   ""
1577   "ix86_expand_move (SImode, operands); DONE;")
1578
1579 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1580 ;; general_operand.
1581 ;;
1582 ;; %%% We don't use a post-inc memory reference because x86 is not a
1583 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1584 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1585 ;; targets without our curiosities, and it is just as easy to represent
1586 ;; this differently.
1587
1588 (define_insn "*pushsi2"
1589   [(set (match_operand:SI 0 "push_operand" "=<")
1590         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1591   "!TARGET_64BIT"
1592   "push{l}\t%1"
1593   [(set_attr "type" "push")
1594    (set_attr "mode" "SI")])
1595
1596 ;; For 64BIT abi we always round up to 8 bytes.
1597 (define_insn "*pushsi2_rex64"
1598   [(set (match_operand:SI 0 "push_operand" "=X")
1599         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1600   "TARGET_64BIT"
1601   "push{q}\t%q1"
1602   [(set_attr "type" "push")
1603    (set_attr "mode" "SI")])
1604
1605 (define_insn "*pushsi2_prologue"
1606   [(set (match_operand:SI 0 "push_operand" "=<")
1607         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1608    (clobber (mem:BLK (scratch)))]
1609   "!TARGET_64BIT"
1610   "push{l}\t%1"
1611   [(set_attr "type" "push")
1612    (set_attr "mode" "SI")])
1613
1614 (define_insn "*popsi1_epilogue"
1615   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1616         (mem:SI (reg:SI SP_REG)))
1617    (set (reg:SI SP_REG)
1618         (plus:SI (reg:SI SP_REG) (const_int 4)))
1619    (clobber (mem:BLK (scratch)))]
1620   "!TARGET_64BIT"
1621   "pop{l}\t%0"
1622   [(set_attr "type" "pop")
1623    (set_attr "mode" "SI")])
1624
1625 (define_insn "popsi1"
1626   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1627         (mem:SI (reg:SI SP_REG)))
1628    (set (reg:SI SP_REG)
1629         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1630   "!TARGET_64BIT"
1631   "pop{l}\t%0"
1632   [(set_attr "type" "pop")
1633    (set_attr "mode" "SI")])
1634
1635 (define_insn "*movsi_xor"
1636   [(set (match_operand:SI 0 "register_operand" "=r")
1637         (match_operand:SI 1 "const0_operand" ""))
1638    (clobber (reg:CC FLAGS_REG))]
1639   "reload_completed"
1640   "xor{l}\t%0, %0"
1641   [(set_attr "type" "alu1")
1642    (set_attr "mode" "SI")
1643    (set_attr "length_immediate" "0")])
1644
1645 (define_insn "*movsi_or"
1646   [(set (match_operand:SI 0 "register_operand" "=r")
1647         (match_operand:SI 1 "immediate_operand" "i"))
1648    (clobber (reg:CC FLAGS_REG))]
1649   "reload_completed
1650    && operands[1] == constm1_rtx"
1651 {
1652   operands[1] = constm1_rtx;
1653   return "or{l}\t{%1, %0|%0, %1}";
1654 }
1655   [(set_attr "type" "alu1")
1656    (set_attr "mode" "SI")
1657    (set_attr "length_immediate" "1")])
1658
1659 (define_insn "*movsi_1"
1660   [(set (match_operand:SI 0 "nonimmediate_operand"
1661                         "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1662         (match_operand:SI 1 "general_operand"
1663                         "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r   ,m "))]
1664   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1665 {
1666   switch (get_attr_type (insn))
1667     {
1668     case TYPE_SSELOG1:
1669       if (get_attr_mode (insn) == MODE_TI)
1670         return "%vpxor\t%0, %d0";
1671       return "%vxorps\t%0, %d0";
1672
1673     case TYPE_SSEMOV:
1674       switch (get_attr_mode (insn))
1675         {
1676         case MODE_TI:
1677           return "%vmovdqa\t{%1, %0|%0, %1}";
1678         case MODE_V4SF:
1679           return "%vmovaps\t{%1, %0|%0, %1}";
1680         case MODE_SI:
1681           return "%vmovd\t{%1, %0|%0, %1}";
1682         case MODE_SF:
1683           return "%vmovss\t{%1, %0|%0, %1}";
1684         default:
1685           gcc_unreachable ();
1686         }
1687
1688     case TYPE_MMX:
1689       return "pxor\t%0, %0";
1690
1691     case TYPE_MMXMOV:
1692       if (get_attr_mode (insn) == MODE_DI)
1693         return "movq\t{%1, %0|%0, %1}";
1694       return "movd\t{%1, %0|%0, %1}";
1695
1696     case TYPE_LEA:
1697       return "lea{l}\t{%1, %0|%0, %1}";
1698
1699     default:
1700       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1701       return "mov{l}\t{%1, %0|%0, %1}";
1702     }
1703 }
1704   [(set (attr "type")
1705      (cond [(eq_attr "alternative" "2")
1706               (const_string "mmx")
1707             (eq_attr "alternative" "3,4,5")
1708               (const_string "mmxmov")
1709             (eq_attr "alternative" "6")
1710               (const_string "sselog1")
1711             (eq_attr "alternative" "7,8,9,10,11")
1712               (const_string "ssemov")
1713             (match_operand:DI 1 "pic_32bit_operand" "")
1714               (const_string "lea")
1715            ]
1716            (const_string "imov")))
1717    (set (attr "prefix")
1718      (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
1719        (const_string "orig")
1720        (const_string "maybe_vex")))
1721    (set (attr "prefix_data16")
1722      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
1723        (const_string "1")
1724        (const_string "*")))
1725    (set (attr "mode")
1726      (cond [(eq_attr "alternative" "2,3")
1727               (const_string "DI")
1728             (eq_attr "alternative" "6,7")
1729               (if_then_else
1730                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1731                 (const_string "V4SF")
1732                 (const_string "TI"))
1733             (and (eq_attr "alternative" "8,9,10,11")
1734                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1735               (const_string "SF")
1736            ]
1737            (const_string "SI")))])
1738
1739 ;; Stores and loads of ax to arbitrary constant address.
1740 ;; We fake an second form of instruction to force reload to load address
1741 ;; into register when rax is not available
1742 (define_insn "*movabssi_1_rex64"
1743   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1744         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1745   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1746   "@
1747    movabs{l}\t{%1, %P0|%P0, %1}
1748    mov{l}\t{%1, %a0|%a0, %1}"
1749   [(set_attr "type" "imov")
1750    (set_attr "modrm" "0,*")
1751    (set_attr "length_address" "8,0")
1752    (set_attr "length_immediate" "0,*")
1753    (set_attr "memory" "store")
1754    (set_attr "mode" "SI")])
1755
1756 (define_insn "*movabssi_2_rex64"
1757   [(set (match_operand:SI 0 "register_operand" "=a,r")
1758         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1759   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1760   "@
1761    movabs{l}\t{%P1, %0|%0, %P1}
1762    mov{l}\t{%a1, %0|%0, %a1}"
1763   [(set_attr "type" "imov")
1764    (set_attr "modrm" "0,*")
1765    (set_attr "length_address" "8,0")
1766    (set_attr "length_immediate" "0")
1767    (set_attr "memory" "load")
1768    (set_attr "mode" "SI")])
1769
1770 (define_insn "*swapsi"
1771   [(set (match_operand:SI 0 "register_operand" "+r")
1772         (match_operand:SI 1 "register_operand" "+r"))
1773    (set (match_dup 1)
1774         (match_dup 0))]
1775   ""
1776   "xchg{l}\t%1, %0"
1777   [(set_attr "type" "imov")
1778    (set_attr "mode" "SI")
1779    (set_attr "pent_pair" "np")
1780    (set_attr "athlon_decode" "vector")
1781    (set_attr "amdfam10_decode" "double")])
1782
1783 (define_expand "movhi"
1784   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1785         (match_operand:HI 1 "general_operand" ""))]
1786   ""
1787   "ix86_expand_move (HImode, operands); DONE;")
1788
1789 (define_insn "*pushhi2"
1790   [(set (match_operand:HI 0 "push_operand" "=X")
1791         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1792   "!TARGET_64BIT"
1793   "push{l}\t%k1"
1794   [(set_attr "type" "push")
1795    (set_attr "mode" "SI")])
1796
1797 ;; For 64BIT abi we always round up to 8 bytes.
1798 (define_insn "*pushhi2_rex64"
1799   [(set (match_operand:HI 0 "push_operand" "=X")
1800         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1801   "TARGET_64BIT"
1802   "push{q}\t%q1"
1803   [(set_attr "type" "push")
1804    (set_attr "mode" "DI")])
1805
1806 (define_insn "*movhi_1"
1807   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1808         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1809   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1810 {
1811   switch (get_attr_type (insn))
1812     {
1813     case TYPE_IMOVX:
1814       /* movzwl is faster than movw on p2 due to partial word stalls,
1815          though not as fast as an aligned movl.  */
1816       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1817     default:
1818       if (get_attr_mode (insn) == MODE_SI)
1819         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1820       else
1821         return "mov{w}\t{%1, %0|%0, %1}";
1822     }
1823 }
1824   [(set (attr "type")
1825      (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
1826               (const_string "imov")
1827             (and (eq_attr "alternative" "0")
1828                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1829                           (const_int 0))
1830                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1831                           (const_int 0))))
1832               (const_string "imov")
1833             (and (eq_attr "alternative" "1,2")
1834                  (match_operand:HI 1 "aligned_operand" ""))
1835               (const_string "imov")
1836             (and (ne (symbol_ref "TARGET_MOVX")
1837                      (const_int 0))
1838                  (eq_attr "alternative" "0,2"))
1839               (const_string "imovx")
1840            ]
1841            (const_string "imov")))
1842     (set (attr "mode")
1843       (cond [(eq_attr "type" "imovx")
1844                (const_string "SI")
1845              (and (eq_attr "alternative" "1,2")
1846                   (match_operand:HI 1 "aligned_operand" ""))
1847                (const_string "SI")
1848              (and (eq_attr "alternative" "0")
1849                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1850                            (const_int 0))
1851                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1852                            (const_int 0))))
1853                (const_string "SI")
1854             ]
1855             (const_string "HI")))])
1856
1857 ;; Stores and loads of ax to arbitrary constant address.
1858 ;; We fake an second form of instruction to force reload to load address
1859 ;; into register when rax is not available
1860 (define_insn "*movabshi_1_rex64"
1861   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1862         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1863   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1864   "@
1865    movabs{w}\t{%1, %P0|%P0, %1}
1866    mov{w}\t{%1, %a0|%a0, %1}"
1867   [(set_attr "type" "imov")
1868    (set_attr "modrm" "0,*")
1869    (set_attr "length_address" "8,0")
1870    (set_attr "length_immediate" "0,*")
1871    (set_attr "memory" "store")
1872    (set_attr "mode" "HI")])
1873
1874 (define_insn "*movabshi_2_rex64"
1875   [(set (match_operand:HI 0 "register_operand" "=a,r")
1876         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1877   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1878   "@
1879    movabs{w}\t{%P1, %0|%0, %P1}
1880    mov{w}\t{%a1, %0|%0, %a1}"
1881   [(set_attr "type" "imov")
1882    (set_attr "modrm" "0,*")
1883    (set_attr "length_address" "8,0")
1884    (set_attr "length_immediate" "0")
1885    (set_attr "memory" "load")
1886    (set_attr "mode" "HI")])
1887
1888 (define_insn "*swaphi_1"
1889   [(set (match_operand:HI 0 "register_operand" "+r")
1890         (match_operand:HI 1 "register_operand" "+r"))
1891    (set (match_dup 1)
1892         (match_dup 0))]
1893   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
1894   "xchg{l}\t%k1, %k0"
1895   [(set_attr "type" "imov")
1896    (set_attr "mode" "SI")
1897    (set_attr "pent_pair" "np")
1898    (set_attr "athlon_decode" "vector")
1899    (set_attr "amdfam10_decode" "double")])
1900
1901 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1902 (define_insn "*swaphi_2"
1903   [(set (match_operand:HI 0 "register_operand" "+r")
1904         (match_operand:HI 1 "register_operand" "+r"))
1905    (set (match_dup 1)
1906         (match_dup 0))]
1907   "TARGET_PARTIAL_REG_STALL"
1908   "xchg{w}\t%1, %0"
1909   [(set_attr "type" "imov")
1910    (set_attr "mode" "HI")
1911    (set_attr "pent_pair" "np")
1912    (set_attr "athlon_decode" "vector")])
1913
1914 (define_expand "movstricthi"
1915   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1916         (match_operand:HI 1 "general_operand" ""))]
1917   ""
1918 {
1919   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
1920     FAIL;
1921   /* Don't generate memory->memory moves, go through a register */
1922   if (MEM_P (operands[0]) && MEM_P (operands[1]))
1923     operands[1] = force_reg (HImode, operands[1]);
1924 })
1925
1926 (define_insn "*movstricthi_1"
1927   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1928         (match_operand:HI 1 "general_operand" "rn,m"))]
1929   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
1930    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1931   "mov{w}\t{%1, %0|%0, %1}"
1932   [(set_attr "type" "imov")
1933    (set_attr "mode" "HI")])
1934
1935 (define_insn "*movstricthi_xor"
1936   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1937         (match_operand:HI 1 "const0_operand" ""))
1938    (clobber (reg:CC FLAGS_REG))]
1939   "reload_completed"
1940   "xor{w}\t%0, %0"
1941   [(set_attr "type" "alu1")
1942    (set_attr "mode" "HI")
1943    (set_attr "length_immediate" "0")])
1944
1945 (define_expand "movqi"
1946   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1947         (match_operand:QI 1 "general_operand" ""))]
1948   ""
1949   "ix86_expand_move (QImode, operands); DONE;")
1950
1951 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1952 ;; "push a byte".  But actually we use pushl, which has the effect
1953 ;; of rounding the amount pushed up to a word.
1954
1955 (define_insn "*pushqi2"
1956   [(set (match_operand:QI 0 "push_operand" "=X")
1957         (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1958   "!TARGET_64BIT"
1959   "push{l}\t%k1"
1960   [(set_attr "type" "push")
1961    (set_attr "mode" "SI")])
1962
1963 ;; For 64BIT abi we always round up to 8 bytes.
1964 (define_insn "*pushqi2_rex64"
1965   [(set (match_operand:QI 0 "push_operand" "=X")
1966         (match_operand:QI 1 "nonmemory_no_elim_operand" "qn"))]
1967   "TARGET_64BIT"
1968   "push{q}\t%q1"
1969   [(set_attr "type" "push")
1970    (set_attr "mode" "DI")])
1971
1972 ;; Situation is quite tricky about when to choose full sized (SImode) move
1973 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1974 ;; partial register dependency machines (such as AMD Athlon), where QImode
1975 ;; moves issue extra dependency and for partial register stalls machines
1976 ;; that don't use QImode patterns (and QImode move cause stall on the next
1977 ;; instruction).
1978 ;;
1979 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1980 ;; register stall machines with, where we use QImode instructions, since
1981 ;; partial register stall can be caused there.  Then we use movzx.
1982 (define_insn "*movqi_1"
1983   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1984         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1985   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1986 {
1987   switch (get_attr_type (insn))
1988     {
1989     case TYPE_IMOVX:
1990       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
1991       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1992     default:
1993       if (get_attr_mode (insn) == MODE_SI)
1994         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1995       else
1996         return "mov{b}\t{%1, %0|%0, %1}";
1997     }
1998 }
1999   [(set (attr "type")
2000      (cond [(and (eq_attr "alternative" "5")
2001                  (not (match_operand:QI 1 "aligned_operand" "")))
2002               (const_string "imovx")
2003             (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
2004               (const_string "imov")
2005             (and (eq_attr "alternative" "3")
2006                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2007                           (const_int 0))
2008                       (eq (symbol_ref "TARGET_QIMODE_MATH")
2009                           (const_int 0))))
2010               (const_string "imov")
2011             (eq_attr "alternative" "3,5")
2012               (const_string "imovx")
2013             (and (ne (symbol_ref "TARGET_MOVX")
2014                      (const_int 0))
2015                  (eq_attr "alternative" "2"))
2016               (const_string "imovx")
2017            ]
2018            (const_string "imov")))
2019    (set (attr "mode")
2020       (cond [(eq_attr "alternative" "3,4,5")
2021                (const_string "SI")
2022              (eq_attr "alternative" "6")
2023                (const_string "QI")
2024              (eq_attr "type" "imovx")
2025                (const_string "SI")
2026              (and (eq_attr "type" "imov")
2027                   (and (eq_attr "alternative" "0,1")
2028                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
2029                                 (const_int 0))
2030                             (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2031                                      (const_int 0))
2032                                  (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2033                                      (const_int 0))))))
2034                (const_string "SI")
2035              ;; Avoid partial register stalls when not using QImode arithmetic
2036              (and (eq_attr "type" "imov")
2037                   (and (eq_attr "alternative" "0,1")
2038                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
2039                                 (const_int 0))
2040                             (eq (symbol_ref "TARGET_QIMODE_MATH")
2041                                 (const_int 0)))))
2042                (const_string "SI")
2043            ]
2044            (const_string "QI")))])
2045
2046 (define_insn "*swapqi_1"
2047   [(set (match_operand:QI 0 "register_operand" "+r")
2048         (match_operand:QI 1 "register_operand" "+r"))
2049    (set (match_dup 1)
2050         (match_dup 0))]
2051   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2052   "xchg{l}\t%k1, %k0"
2053   [(set_attr "type" "imov")
2054    (set_attr "mode" "SI")
2055    (set_attr "pent_pair" "np")
2056    (set_attr "athlon_decode" "vector")
2057    (set_attr "amdfam10_decode" "vector")])
2058
2059 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
2060 (define_insn "*swapqi_2"
2061   [(set (match_operand:QI 0 "register_operand" "+q")
2062         (match_operand:QI 1 "register_operand" "+q"))
2063    (set (match_dup 1)
2064         (match_dup 0))]
2065   "TARGET_PARTIAL_REG_STALL"
2066   "xchg{b}\t%1, %0"
2067   [(set_attr "type" "imov")
2068    (set_attr "mode" "QI")
2069    (set_attr "pent_pair" "np")
2070    (set_attr "athlon_decode" "vector")])
2071
2072 (define_expand "movstrictqi"
2073   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
2074         (match_operand:QI 1 "general_operand" ""))]
2075   ""
2076 {
2077   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2078     FAIL;
2079   /* Don't generate memory->memory moves, go through a register.  */
2080   if (MEM_P (operands[0]) && MEM_P (operands[1]))
2081     operands[1] = force_reg (QImode, operands[1]);
2082 })
2083
2084 (define_insn "*movstrictqi_1"
2085   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
2086         (match_operand:QI 1 "general_operand" "*qn,m"))]
2087   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2088    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2089   "mov{b}\t{%1, %0|%0, %1}"
2090   [(set_attr "type" "imov")
2091    (set_attr "mode" "QI")])
2092
2093 (define_insn "*movstrictqi_xor"
2094   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
2095         (match_operand:QI 1 "const0_operand" ""))
2096    (clobber (reg:CC FLAGS_REG))]
2097   "reload_completed"
2098   "xor{b}\t%0, %0"
2099   [(set_attr "type" "alu1")
2100    (set_attr "mode" "QI")
2101    (set_attr "length_immediate" "0")])
2102
2103 (define_insn "*movsi_extv_1"
2104   [(set (match_operand:SI 0 "register_operand" "=R")
2105         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
2106                          (const_int 8)
2107                          (const_int 8)))]
2108   ""
2109   "movs{bl|x}\t{%h1, %0|%0, %h1}"
2110   [(set_attr "type" "imovx")
2111    (set_attr "mode" "SI")])
2112
2113 (define_insn "*movhi_extv_1"
2114   [(set (match_operand:HI 0 "register_operand" "=R")
2115         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
2116                          (const_int 8)
2117                          (const_int 8)))]
2118   ""
2119   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2120   [(set_attr "type" "imovx")
2121    (set_attr "mode" "SI")])
2122
2123 (define_insn "*movqi_extv_1"
2124   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2125         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2126                          (const_int 8)
2127                          (const_int 8)))]
2128   "!TARGET_64BIT"
2129 {
2130   switch (get_attr_type (insn))
2131     {
2132     case TYPE_IMOVX:
2133       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2134     default:
2135       return "mov{b}\t{%h1, %0|%0, %h1}";
2136     }
2137 }
2138   [(set (attr "type")
2139      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2140                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2141                              (ne (symbol_ref "TARGET_MOVX")
2142                                  (const_int 0))))
2143         (const_string "imovx")
2144         (const_string "imov")))
2145    (set (attr "mode")
2146      (if_then_else (eq_attr "type" "imovx")
2147         (const_string "SI")
2148         (const_string "QI")))])
2149
2150 (define_insn "*movqi_extv_1_rex64"
2151   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2152         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2153                          (const_int 8)
2154                          (const_int 8)))]
2155   "TARGET_64BIT"
2156 {
2157   switch (get_attr_type (insn))
2158     {
2159     case TYPE_IMOVX:
2160       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2161     default:
2162       return "mov{b}\t{%h1, %0|%0, %h1}";
2163     }
2164 }
2165   [(set (attr "type")
2166      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2167                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2168                              (ne (symbol_ref "TARGET_MOVX")
2169                                  (const_int 0))))
2170         (const_string "imovx")
2171         (const_string "imov")))
2172    (set (attr "mode")
2173      (if_then_else (eq_attr "type" "imovx")
2174         (const_string "SI")
2175         (const_string "QI")))])
2176
2177 ;; Stores and loads of ax to arbitrary constant address.
2178 ;; We fake an second form of instruction to force reload to load address
2179 ;; into register when rax is not available
2180 (define_insn "*movabsqi_1_rex64"
2181   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2182         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
2183   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2184   "@
2185    movabs{b}\t{%1, %P0|%P0, %1}
2186    mov{b}\t{%1, %a0|%a0, %1}"
2187   [(set_attr "type" "imov")
2188    (set_attr "modrm" "0,*")
2189    (set_attr "length_address" "8,0")
2190    (set_attr "length_immediate" "0,*")
2191    (set_attr "memory" "store")
2192    (set_attr "mode" "QI")])
2193
2194 (define_insn "*movabsqi_2_rex64"
2195   [(set (match_operand:QI 0 "register_operand" "=a,r")
2196         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2197   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2198   "@
2199    movabs{b}\t{%P1, %0|%0, %P1}
2200    mov{b}\t{%a1, %0|%0, %a1}"
2201   [(set_attr "type" "imov")
2202    (set_attr "modrm" "0,*")
2203    (set_attr "length_address" "8,0")
2204    (set_attr "length_immediate" "0")
2205    (set_attr "memory" "load")
2206    (set_attr "mode" "QI")])
2207
2208 (define_insn "*movdi_extzv_1"
2209   [(set (match_operand:DI 0 "register_operand" "=R")
2210         (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
2211                          (const_int 8)
2212                          (const_int 8)))]
2213   "TARGET_64BIT"
2214   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2215   [(set_attr "type" "imovx")
2216    (set_attr "mode" "SI")])
2217
2218 (define_insn "*movsi_extzv_1"
2219   [(set (match_operand:SI 0 "register_operand" "=R")
2220         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
2221                          (const_int 8)
2222                          (const_int 8)))]
2223   ""
2224   "movz{bl|x}\t{%h1, %0|%0, %h1}"
2225   [(set_attr "type" "imovx")
2226    (set_attr "mode" "SI")])
2227
2228 (define_insn "*movqi_extzv_2"
2229   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2230         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2231                                     (const_int 8)
2232                                     (const_int 8)) 0))]
2233   "!TARGET_64BIT"
2234 {
2235   switch (get_attr_type (insn))
2236     {
2237     case TYPE_IMOVX:
2238       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2239     default:
2240       return "mov{b}\t{%h1, %0|%0, %h1}";
2241     }
2242 }
2243   [(set (attr "type")
2244      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2245                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2246                              (ne (symbol_ref "TARGET_MOVX")
2247                                  (const_int 0))))
2248         (const_string "imovx")
2249         (const_string "imov")))
2250    (set (attr "mode")
2251      (if_then_else (eq_attr "type" "imovx")
2252         (const_string "SI")
2253         (const_string "QI")))])
2254
2255 (define_insn "*movqi_extzv_2_rex64"
2256   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2257         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2258                                     (const_int 8)
2259                                     (const_int 8)) 0))]
2260   "TARGET_64BIT"
2261 {
2262   switch (get_attr_type (insn))
2263     {
2264     case TYPE_IMOVX:
2265       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2266     default:
2267       return "mov{b}\t{%h1, %0|%0, %h1}";
2268     }
2269 }
2270   [(set (attr "type")
2271      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2272                         (ne (symbol_ref "TARGET_MOVX")
2273                             (const_int 0)))
2274         (const_string "imovx")
2275         (const_string "imov")))
2276    (set (attr "mode")
2277      (if_then_else (eq_attr "type" "imovx")
2278         (const_string "SI")
2279         (const_string "QI")))])
2280
2281 (define_insn "movsi_insv_1"
2282   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2283                          (const_int 8)
2284                          (const_int 8))
2285         (match_operand:SI 1 "general_operand" "Qmn"))]
2286   "!TARGET_64BIT"
2287   "mov{b}\t{%b1, %h0|%h0, %b1}"
2288   [(set_attr "type" "imov")
2289    (set_attr "mode" "QI")])
2290
2291 (define_insn "*movsi_insv_1_rex64"
2292   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2293                          (const_int 8)
2294                          (const_int 8))
2295         (match_operand:SI 1 "nonmemory_operand" "Qn"))]
2296   "TARGET_64BIT"
2297   "mov{b}\t{%b1, %h0|%h0, %b1}"
2298   [(set_attr "type" "imov")
2299    (set_attr "mode" "QI")])
2300
2301 (define_insn "movdi_insv_1_rex64"
2302   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
2303                          (const_int 8)
2304                          (const_int 8))
2305         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
2306   "TARGET_64BIT"
2307   "mov{b}\t{%b1, %h0|%h0, %b1}"
2308   [(set_attr "type" "imov")
2309    (set_attr "mode" "QI")])
2310
2311 (define_insn "*movqi_insv_2"
2312   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2313                          (const_int 8)
2314                          (const_int 8))
2315         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2316                      (const_int 8)))]
2317   ""
2318   "mov{b}\t{%h1, %h0|%h0, %h1}"
2319   [(set_attr "type" "imov")
2320    (set_attr "mode" "QI")])
2321
2322 (define_expand "movdi"
2323   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2324         (match_operand:DI 1 "general_operand" ""))]
2325   ""
2326   "ix86_expand_move (DImode, operands); DONE;")
2327
2328 (define_insn "*pushdi"
2329   [(set (match_operand:DI 0 "push_operand" "=<")
2330         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
2331   "!TARGET_64BIT"
2332   "#")
2333
2334 (define_insn "*pushdi2_rex64"
2335   [(set (match_operand:DI 0 "push_operand" "=<,!<")
2336         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
2337   "TARGET_64BIT"
2338   "@
2339    push{q}\t%1
2340    #"
2341   [(set_attr "type" "push,multi")
2342    (set_attr "mode" "DI")])
2343
2344 ;; Convert impossible pushes of immediate to existing instructions.
2345 ;; First try to get scratch register and go through it.  In case this
2346 ;; fails, push sign extended lower part first and then overwrite
2347 ;; upper part by 32bit move.
2348 (define_peephole2
2349   [(match_scratch:DI 2 "r")
2350    (set (match_operand:DI 0 "push_operand" "")
2351         (match_operand:DI 1 "immediate_operand" ""))]
2352   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2353    && !x86_64_immediate_operand (operands[1], DImode)"
2354   [(set (match_dup 2) (match_dup 1))
2355    (set (match_dup 0) (match_dup 2))]
2356   "")
2357
2358 ;; We need to define this as both peepholer and splitter for case
2359 ;; peephole2 pass is not run.
2360 ;; "&& 1" is needed to keep it from matching the previous pattern.
2361 (define_peephole2
2362   [(set (match_operand:DI 0 "push_operand" "")
2363         (match_operand:DI 1 "immediate_operand" ""))]
2364   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2365    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2366   [(set (match_dup 0) (match_dup 1))
2367    (set (match_dup 2) (match_dup 3))]
2368   "split_di (&operands[1], 1, &operands[2], &operands[3]);
2369    operands[1] = gen_lowpart (DImode, operands[2]);
2370    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2371                                                     GEN_INT (4)));
2372   ")
2373
2374 (define_split
2375   [(set (match_operand:DI 0 "push_operand" "")
2376         (match_operand:DI 1 "immediate_operand" ""))]
2377   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2378                     ? epilogue_completed : reload_completed)
2379    && !symbolic_operand (operands[1], DImode)
2380    && !x86_64_immediate_operand (operands[1], DImode)"
2381   [(set (match_dup 0) (match_dup 1))
2382    (set (match_dup 2) (match_dup 3))]
2383   "split_di (&operands[1], 1, &operands[2], &operands[3]);
2384    operands[1] = gen_lowpart (DImode, operands[2]);
2385    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2386                                                     GEN_INT (4)));
2387   ")
2388
2389 (define_insn "*pushdi2_prologue_rex64"
2390   [(set (match_operand:DI 0 "push_operand" "=<")
2391         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
2392    (clobber (mem:BLK (scratch)))]
2393   "TARGET_64BIT"
2394   "push{q}\t%1"
2395   [(set_attr "type" "push")
2396    (set_attr "mode" "DI")])
2397
2398 (define_insn "*popdi1_epilogue_rex64"
2399   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2400         (mem:DI (reg:DI SP_REG)))
2401    (set (reg:DI SP_REG)
2402         (plus:DI (reg:DI SP_REG) (const_int 8)))
2403    (clobber (mem:BLK (scratch)))]
2404   "TARGET_64BIT"
2405   "pop{q}\t%0"
2406   [(set_attr "type" "pop")
2407    (set_attr "mode" "DI")])
2408
2409 (define_insn "popdi1"
2410   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2411         (mem:DI (reg:DI SP_REG)))
2412    (set (reg:DI SP_REG)
2413         (plus:DI (reg:DI SP_REG) (const_int 8)))]
2414   "TARGET_64BIT"
2415   "pop{q}\t%0"
2416   [(set_attr "type" "pop")
2417    (set_attr "mode" "DI")])
2418
2419 (define_insn "*movdi_xor_rex64"
2420   [(set (match_operand:DI 0 "register_operand" "=r")
2421         (match_operand:DI 1 "const0_operand" ""))
2422    (clobber (reg:CC FLAGS_REG))]
2423   "TARGET_64BIT
2424    && reload_completed"
2425   "xor{l}\t%k0, %k0";
2426   [(set_attr "type" "alu1")
2427    (set_attr "mode" "SI")
2428    (set_attr "length_immediate" "0")])
2429
2430 (define_insn "*movdi_or_rex64"
2431   [(set (match_operand:DI 0 "register_operand" "=r")
2432         (match_operand:DI 1 "const_int_operand" "i"))
2433    (clobber (reg:CC FLAGS_REG))]
2434   "TARGET_64BIT
2435    && reload_completed
2436    && operands[1] == constm1_rtx"
2437 {
2438   operands[1] = constm1_rtx;
2439   return "or{q}\t{%1, %0|%0, %1}";
2440 }
2441   [(set_attr "type" "alu1")
2442    (set_attr "mode" "DI")
2443    (set_attr "length_immediate" "1")])
2444
2445 (define_insn "*movdi_2"
2446   [(set (match_operand:DI 0 "nonimmediate_operand"
2447                         "=r  ,o  ,*y,m*y,*y,*Y2,m  ,*Y2,*Y2,*x,m ,*x,*x")
2448         (match_operand:DI 1 "general_operand"
2449                         "riFo,riF,C ,*y ,m ,C  ,*Y2,*Y2,m  ,C ,*x,*x,m "))]
2450   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2451   "@
2452    #
2453    #
2454    pxor\t%0, %0
2455    movq\t{%1, %0|%0, %1}
2456    movq\t{%1, %0|%0, %1}
2457    %vpxor\t%0, %d0
2458    %vmovq\t{%1, %0|%0, %1}
2459    %vmovdqa\t{%1, %0|%0, %1}
2460    %vmovq\t{%1, %0|%0, %1}
2461    xorps\t%0, %0
2462    movlps\t{%1, %0|%0, %1}
2463    movaps\t{%1, %0|%0, %1}
2464    movlps\t{%1, %0|%0, %1}"
2465   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2466    (set (attr "prefix")
2467      (if_then_else (eq_attr "alternative" "5,6,7,8")
2468        (const_string "vex")
2469        (const_string "orig")))
2470    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2471
2472 (define_split
2473   [(set (match_operand:DI 0 "push_operand" "")
2474         (match_operand:DI 1 "general_operand" ""))]
2475   "!TARGET_64BIT && reload_completed
2476    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2477   [(const_int 0)]
2478   "ix86_split_long_move (operands); DONE;")
2479
2480 ;; %%% This multiword shite has got to go.
2481 (define_split
2482   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2483         (match_operand:DI 1 "general_operand" ""))]
2484   "!TARGET_64BIT && reload_completed
2485    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2486    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2487   [(const_int 0)]
2488   "ix86_split_long_move (operands); DONE;")
2489
2490 (define_insn "*movdi_1_rex64"
2491   [(set (match_operand:DI 0 "nonimmediate_operand"
2492           "=r,r  ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2493         (match_operand:DI 1 "general_operand"
2494           "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r   ,m  ,C ,*x,*Yi,*x,r  ,m ,*Ym,*x"))]
2495   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2496 {
2497   switch (get_attr_type (insn))
2498     {
2499     case TYPE_SSECVT:
2500       if (SSE_REG_P (operands[0]))
2501         return "movq2dq\t{%1, %0|%0, %1}";
2502       else
2503         return "movdq2q\t{%1, %0|%0, %1}";
2504
2505     case TYPE_SSEMOV:
2506       if (TARGET_AVX)
2507         {
2508           if (get_attr_mode (insn) == MODE_TI)
2509             return "vmovdqa\t{%1, %0|%0, %1}";
2510           else
2511             return "vmovq\t{%1, %0|%0, %1}";
2512         }
2513
2514       if (get_attr_mode (insn) == MODE_TI)
2515         return "movdqa\t{%1, %0|%0, %1}";
2516       /* FALLTHRU */
2517
2518     case TYPE_MMXMOV:
2519       /* Moves from and into integer register is done using movd
2520          opcode with REX prefix.  */
2521       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2522         return "movd\t{%1, %0|%0, %1}";
2523       return "movq\t{%1, %0|%0, %1}";
2524
2525     case TYPE_SSELOG1:
2526       return "%vpxor\t%0, %d0";
2527
2528     case TYPE_MMX:
2529       return "pxor\t%0, %0";
2530
2531     case TYPE_MULTI:
2532       return "#";
2533
2534     case TYPE_LEA:
2535       return "lea{q}\t{%a1, %0|%0, %a1}";
2536
2537     default:
2538       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2539       if (get_attr_mode (insn) == MODE_SI)
2540         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2541       else if (which_alternative == 2)
2542         return "movabs{q}\t{%1, %0|%0, %1}";
2543       else
2544         return "mov{q}\t{%1, %0|%0, %1}";
2545     }
2546 }
2547   [(set (attr "type")
2548      (cond [(eq_attr "alternative" "5")
2549               (const_string "mmx")
2550             (eq_attr "alternative" "6,7,8,9,10")
2551               (const_string "mmxmov")
2552             (eq_attr "alternative" "11")
2553               (const_string "sselog1")
2554             (eq_attr "alternative" "12,13,14,15,16")
2555               (const_string "ssemov")
2556             (eq_attr "alternative" "17,18")
2557               (const_string "ssecvt")
2558             (eq_attr "alternative" "4")
2559               (const_string "multi")
2560             (match_operand:DI 1 "pic_32bit_operand" "")
2561               (const_string "lea")
2562            ]
2563            (const_string "imov")))
2564    (set (attr "modrm")
2565      (if_then_else
2566        (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2567          (const_string "0")
2568          (const_string "*")))
2569    (set (attr "length_immediate")
2570      (if_then_else
2571        (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2572          (const_string "8")
2573          (const_string "*")))
2574    (set_attr "prefix_rex" "*,*,*,*,*,*,*,1,*,1,*,*,*,*,*,*,*,*,*")
2575    (set_attr "prefix_data16" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,1,*,*,*")
2576    (set (attr "prefix")
2577      (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
2578        (const_string "maybe_vex")
2579        (const_string "orig")))
2580    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2581
2582 ;; Stores and loads of ax to arbitrary constant address.
2583 ;; We fake an second form of instruction to force reload to load address
2584 ;; into register when rax is not available
2585 (define_insn "*movabsdi_1_rex64"
2586   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2587         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2588   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2589   "@
2590    movabs{q}\t{%1, %P0|%P0, %1}
2591    mov{q}\t{%1, %a0|%a0, %1}"
2592   [(set_attr "type" "imov")
2593    (set_attr "modrm" "0,*")
2594    (set_attr "length_address" "8,0")
2595    (set_attr "length_immediate" "0,*")
2596    (set_attr "memory" "store")
2597    (set_attr "mode" "DI")])
2598
2599 (define_insn "*movabsdi_2_rex64"
2600   [(set (match_operand:DI 0 "register_operand" "=a,r")
2601         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2602   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2603   "@
2604    movabs{q}\t{%P1, %0|%0, %P1}
2605    mov{q}\t{%a1, %0|%0, %a1}"
2606   [(set_attr "type" "imov")
2607    (set_attr "modrm" "0,*")
2608    (set_attr "length_address" "8,0")
2609    (set_attr "length_immediate" "0")
2610    (set_attr "memory" "load")
2611    (set_attr "mode" "DI")])
2612
2613 ;; Convert impossible stores of immediate to existing instructions.
2614 ;; First try to get scratch register and go through it.  In case this
2615 ;; fails, move by 32bit parts.
2616 (define_peephole2
2617   [(match_scratch:DI 2 "r")
2618    (set (match_operand:DI 0 "memory_operand" "")
2619         (match_operand:DI 1 "immediate_operand" ""))]
2620   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2621    && !x86_64_immediate_operand (operands[1], DImode)"
2622   [(set (match_dup 2) (match_dup 1))
2623    (set (match_dup 0) (match_dup 2))]
2624   "")
2625
2626 ;; We need to define this as both peepholer and splitter for case
2627 ;; peephole2 pass is not run.
2628 ;; "&& 1" is needed to keep it from matching the previous pattern.
2629 (define_peephole2
2630   [(set (match_operand:DI 0 "memory_operand" "")
2631         (match_operand:DI 1 "immediate_operand" ""))]
2632   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2633    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2634   [(set (match_dup 2) (match_dup 3))
2635    (set (match_dup 4) (match_dup 5))]
2636   "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2637
2638 (define_split
2639   [(set (match_operand:DI 0 "memory_operand" "")
2640         (match_operand:DI 1 "immediate_operand" ""))]
2641   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2642                     ? epilogue_completed : reload_completed)
2643    && !symbolic_operand (operands[1], DImode)
2644    && !x86_64_immediate_operand (operands[1], DImode)"
2645   [(set (match_dup 2) (match_dup 3))
2646    (set (match_dup 4) (match_dup 5))]
2647   "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2648
2649 (define_insn "*swapdi_rex64"
2650   [(set (match_operand:DI 0 "register_operand" "+r")
2651         (match_operand:DI 1 "register_operand" "+r"))
2652    (set (match_dup 1)
2653         (match_dup 0))]
2654   "TARGET_64BIT"
2655   "xchg{q}\t%1, %0"
2656   [(set_attr "type" "imov")
2657    (set_attr "mode" "DI")
2658    (set_attr "pent_pair" "np")
2659    (set_attr "athlon_decode" "vector")
2660    (set_attr "amdfam10_decode" "double")])
2661
2662 (define_expand "movoi"
2663   [(set (match_operand:OI 0 "nonimmediate_operand" "")
2664         (match_operand:OI 1 "general_operand" ""))]
2665   "TARGET_AVX"
2666   "ix86_expand_move (OImode, operands); DONE;")
2667
2668 (define_insn "*movoi_internal"
2669   [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
2670         (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
2671   "TARGET_AVX
2672    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2673 {
2674   switch (which_alternative)
2675     {
2676     case 0:
2677       return "vxorps\t%0, %0, %0";
2678     case 1:
2679     case 2:
2680       if (misaligned_operand (operands[0], OImode)
2681           || misaligned_operand (operands[1], OImode))
2682         return "vmovdqu\t{%1, %0|%0, %1}";
2683       else
2684         return "vmovdqa\t{%1, %0|%0, %1}";
2685     default:
2686       gcc_unreachable ();
2687     }
2688 }
2689   [(set_attr "type" "sselog1,ssemov,ssemov")
2690    (set_attr "prefix" "vex")
2691    (set_attr "mode" "OI")])
2692
2693 (define_expand "movti"
2694   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2695         (match_operand:TI 1 "nonimmediate_operand" ""))]
2696   "TARGET_SSE || TARGET_64BIT"
2697 {
2698   if (TARGET_64BIT)
2699     ix86_expand_move (TImode, operands);
2700   else if (push_operand (operands[0], TImode))
2701     ix86_expand_push (TImode, operands[1]);
2702   else
2703     ix86_expand_vector_move (TImode, operands);
2704   DONE;
2705 })
2706
2707 (define_insn "*movti_internal"
2708   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2709         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2710   "TARGET_SSE && !TARGET_64BIT
2711    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2712 {
2713   switch (which_alternative)
2714     {
2715     case 0:
2716       if (get_attr_mode (insn) == MODE_V4SF)
2717         return "%vxorps\t%0, %d0";
2718       else
2719         return "%vpxor\t%0, %d0";
2720     case 1:
2721     case 2:
2722       /* TDmode values are passed as TImode on the stack.  Moving them
2723          to stack may result in unaligned memory access.  */
2724       if (misaligned_operand (operands[0], TImode)
2725           || misaligned_operand (operands[1], TImode))
2726         {
2727           if (get_attr_mode (insn) == MODE_V4SF)
2728             return "%vmovups\t{%1, %0|%0, %1}";
2729          else
2730            return "%vmovdqu\t{%1, %0|%0, %1}";
2731         }
2732       else
2733         {
2734           if (get_attr_mode (insn) == MODE_V4SF)
2735             return "%vmovaps\t{%1, %0|%0, %1}";
2736          else
2737            return "%vmovdqa\t{%1, %0|%0, %1}";
2738         }
2739     default:
2740       gcc_unreachable ();
2741     }
2742 }
2743   [(set_attr "type" "sselog1,ssemov,ssemov")
2744    (set_attr "prefix" "maybe_vex")
2745    (set (attr "mode")
2746         (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2747                     (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0)))
2748                  (const_string "V4SF")
2749                (and (eq_attr "alternative" "2")
2750                     (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2751                         (const_int 0)))
2752                  (const_string "V4SF")]
2753               (const_string "TI")))])
2754
2755 (define_insn "*movti_rex64"
2756   [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
2757         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2758   "TARGET_64BIT
2759    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2760 {
2761   switch (which_alternative)
2762     {
2763     case 0:
2764     case 1:
2765       return "#";
2766     case 2:
2767       if (get_attr_mode (insn) == MODE_V4SF)
2768         return "%vxorps\t%0, %d0";
2769       else
2770         return "%vpxor\t%0, %d0";
2771     case 3:
2772     case 4:
2773       /* TDmode values are passed as TImode on the stack.  Moving them
2774          to stack may result in unaligned memory access.  */
2775       if (misaligned_operand (operands[0], TImode)
2776           || misaligned_operand (operands[1], TImode))
2777         {
2778           if (get_attr_mode (insn) == MODE_V4SF)
2779             return "%vmovups\t{%1, %0|%0, %1}";
2780          else
2781            return "%vmovdqu\t{%1, %0|%0, %1}";
2782         }
2783       else
2784         {
2785           if (get_attr_mode (insn) == MODE_V4SF)
2786             return "%vmovaps\t{%1, %0|%0, %1}";
2787          else
2788            return "%vmovdqa\t{%1, %0|%0, %1}";
2789         }
2790     default:
2791       gcc_unreachable ();
2792     }
2793 }
2794   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2795    (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
2796    (set (attr "mode")
2797         (cond [(eq_attr "alternative" "2,3")
2798                  (if_then_else
2799                    (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2800                        (const_int 0))
2801                    (const_string "V4SF")
2802                    (const_string "TI"))
2803                (eq_attr "alternative" "4")
2804                  (if_then_else
2805                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2806                             (const_int 0))
2807                         (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2808                             (const_int 0)))
2809                    (const_string "V4SF")
2810                    (const_string "TI"))]
2811                (const_string "DI")))])
2812
2813 (define_split
2814   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2815         (match_operand:TI 1 "general_operand" ""))]
2816   "reload_completed && !SSE_REG_P (operands[0])
2817    && !SSE_REG_P (operands[1])"
2818   [(const_int 0)]
2819   "ix86_split_long_move (operands); DONE;")
2820
2821 ;; This expands to what emit_move_complex would generate if we didn't
2822 ;; have a movti pattern.  Having this avoids problems with reload on
2823 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2824 ;; to have around all the time.
2825 (define_expand "movcdi"
2826   [(set (match_operand:CDI 0 "nonimmediate_operand" "")
2827         (match_operand:CDI 1 "general_operand" ""))]
2828   ""
2829 {
2830   if (push_operand (operands[0], CDImode))
2831     emit_move_complex_push (CDImode, operands[0], operands[1]);
2832   else
2833     emit_move_complex_parts (operands[0], operands[1]);
2834   DONE;
2835 })
2836
2837 (define_expand "movsf"
2838   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2839         (match_operand:SF 1 "general_operand" ""))]
2840   ""
2841   "ix86_expand_move (SFmode, operands); DONE;")
2842
2843 (define_insn "*pushsf"
2844   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2845         (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2846   "!TARGET_64BIT"
2847 {
2848   /* Anything else should be already split before reg-stack.  */
2849   gcc_assert (which_alternative == 1);
2850   return "push{l}\t%1";
2851 }
2852   [(set_attr "type" "multi,push,multi")
2853    (set_attr "unit" "i387,*,*")
2854    (set_attr "mode" "SF,SI,SF")])
2855
2856 (define_insn "*pushsf_rex64"
2857   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2858         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2859   "TARGET_64BIT"
2860 {
2861   /* Anything else should be already split before reg-stack.  */
2862   gcc_assert (which_alternative == 1);
2863   return "push{q}\t%q1";
2864 }
2865   [(set_attr "type" "multi,push,multi")
2866    (set_attr "unit" "i387,*,*")
2867    (set_attr "mode" "SF,DI,SF")])
2868
2869 (define_split
2870   [(set (match_operand:SF 0 "push_operand" "")
2871         (match_operand:SF 1 "memory_operand" ""))]
2872   "reload_completed
2873    && MEM_P (operands[1])
2874    && (operands[2] = find_constant_src (insn))"
2875   [(set (match_dup 0)
2876         (match_dup 2))])
2877
2878 ;; %%% Kill this when call knows how to work this out.
2879 (define_split
2880   [(set (match_operand:SF 0 "push_operand" "")
2881         (match_operand:SF 1 "any_fp_register_operand" ""))]
2882   "!TARGET_64BIT"
2883   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2884    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2885
2886 (define_split
2887   [(set (match_operand:SF 0 "push_operand" "")
2888         (match_operand:SF 1 "any_fp_register_operand" ""))]
2889   "TARGET_64BIT"
2890   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2891    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2892
2893 (define_insn "*movsf_1"
2894   [(set (match_operand:SF 0 "nonimmediate_operand"
2895           "=f,m,f,r  ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
2896         (match_operand:SF 1 "general_operand"
2897           "fm,f,G,rmF,Fr,C,x,xm,x,m  ,*y,*y ,r  ,Yi,r   ,*Ym"))]
2898   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2899    && (reload_in_progress || reload_completed
2900        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2901        || (!TARGET_SSE_MATH && optimize_function_for_size_p (cfun)
2902            && standard_80387_constant_p (operands[1]))
2903        || GET_CODE (operands[1]) != CONST_DOUBLE
2904        || memory_operand (operands[0], SFmode))"
2905 {
2906   switch (which_alternative)
2907     {
2908     case 0:
2909     case 1:
2910       return output_387_reg_move (insn, operands);
2911
2912     case 2:
2913       return standard_80387_constant_opcode (operands[1]);
2914
2915     case 3:
2916     case 4:
2917       return "mov{l}\t{%1, %0|%0, %1}";
2918     case 5:
2919       if (get_attr_mode (insn) == MODE_TI)
2920         return "%vpxor\t%0, %d0";
2921       else
2922         return "%vxorps\t%0, %d0";
2923     case 6:
2924       if (get_attr_mode (insn) == MODE_V4SF)
2925         return "%vmovaps\t{%1, %0|%0, %1}";
2926       else
2927         return "%vmovss\t{%1, %d0|%d0, %1}";
2928     case 7:
2929       if (TARGET_AVX)
2930         return REG_P (operands[1]) ? "vmovss\t{%1, %0, %0|%0, %0, %1}"
2931                                    : "vmovss\t{%1, %0|%0, %1}";
2932       else
2933         return "movss\t{%1, %0|%0, %1}";
2934     case 8:
2935       return "%vmovss\t{%1, %0|%0, %1}";
2936
2937     case 9: case 10: case 14: case 15:
2938       return "movd\t{%1, %0|%0, %1}";
2939     case 12: case 13:
2940       return "%vmovd\t{%1, %0|%0, %1}";
2941
2942     case 11:
2943       return "movq\t{%1, %0|%0, %1}";
2944
2945     default:
2946       gcc_unreachable ();
2947     }
2948 }
2949   [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2950    (set (attr "prefix")
2951      (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
2952        (const_string "maybe_vex")
2953        (const_string "orig")))
2954    (set (attr "mode")
2955         (cond [(eq_attr "alternative" "3,4,9,10")
2956                  (const_string "SI")
2957                (eq_attr "alternative" "5")
2958                  (if_then_else
2959                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2960                                  (const_int 0))
2961                              (ne (symbol_ref "TARGET_SSE2")
2962                                  (const_int 0)))
2963                         (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2964                             (const_int 0)))
2965                    (const_string "TI")
2966                    (const_string "V4SF"))
2967                /* For architectures resolving dependencies on
2968                   whole SSE registers use APS move to break dependency
2969                   chains, otherwise use short move to avoid extra work.
2970
2971                   Do the same for architectures resolving dependencies on
2972                   the parts.  While in DF mode it is better to always handle
2973                   just register parts, the SF mode is different due to lack
2974                   of instructions to load just part of the register.  It is
2975                   better to maintain the whole registers in single format
2976                   to avoid problems on using packed logical operations.  */
2977                (eq_attr "alternative" "6")
2978                  (if_then_else
2979                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2980                             (const_int 0))
2981                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2982                             (const_int 0)))
2983                    (const_string "V4SF")
2984                    (const_string "SF"))
2985                (eq_attr "alternative" "11")
2986                  (const_string "DI")]
2987                (const_string "SF")))])
2988
2989 (define_insn "*swapsf"
2990   [(set (match_operand:SF 0 "fp_register_operand" "+f")
2991         (match_operand:SF 1 "fp_register_operand" "+f"))
2992    (set (match_dup 1)
2993         (match_dup 0))]
2994   "reload_completed || TARGET_80387"
2995 {
2996   if (STACK_TOP_P (operands[0]))
2997     return "fxch\t%1";
2998   else
2999     return "fxch\t%0";
3000 }
3001   [(set_attr "type" "fxch")
3002    (set_attr "mode" "SF")])
3003
3004 (define_expand "movdf"
3005   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3006         (match_operand:DF 1 "general_operand" ""))]
3007   ""
3008   "ix86_expand_move (DFmode, operands); DONE;")
3009
3010 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3011 ;; Size of pushdf using integer instructions is 2+2*memory operand size
3012 ;; On the average, pushdf using integers can be still shorter.  Allow this
3013 ;; pattern for optimize_size too.
3014
3015 (define_insn "*pushdf_nointeger"
3016   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
3017         (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
3018   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
3019 {
3020   /* This insn should be already split before reg-stack.  */
3021   gcc_unreachable ();
3022 }
3023   [(set_attr "type" "multi")
3024    (set_attr "unit" "i387,*,*,*")
3025    (set_attr "mode" "DF,SI,SI,DF")])
3026
3027 (define_insn "*pushdf_integer"
3028   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
3029         (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
3030   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
3031 {
3032   /* This insn should be already split before reg-stack.  */
3033   gcc_unreachable ();
3034 }
3035   [(set_attr "type" "multi")
3036    (set_attr "unit" "i387,*,*")
3037    (set_attr "mode" "DF,SI,DF")])
3038
3039 ;; %%% Kill this when call knows how to work this out.
3040 (define_split
3041   [(set (match_operand:DF 0 "push_operand" "")
3042         (match_operand:DF 1 "any_fp_register_operand" ""))]
3043   "reload_completed"
3044   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3045    (set (mem:DF (reg:P SP_REG)) (match_dup 1))]
3046   "")
3047
3048 (define_split
3049   [(set (match_operand:DF 0 "push_operand" "")
3050         (match_operand:DF 1 "general_operand" ""))]
3051   "reload_completed"
3052   [(const_int 0)]
3053   "ix86_split_long_move (operands); DONE;")
3054
3055 ;; Moving is usually shorter when only FP registers are used. This separate
3056 ;; movdf pattern avoids the use of integer registers for FP operations
3057 ;; when optimizing for size.
3058
3059 (define_insn "*movdf_nointeger"
3060   [(set (match_operand:DF 0 "nonimmediate_operand"
3061                         "=f,m,f,*r  ,o  ,Y2*x,Y2*x,Y2*x ,m  ")
3062         (match_operand:DF 1 "general_operand"
3063                         "fm,f,G,*roF,*Fr,C   ,Y2*x,mY2*x,Y2*x"))]
3064   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3065    && ((optimize_function_for_size_p (cfun)
3066        || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
3067    && (reload_in_progress || reload_completed
3068        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3069        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3070            && optimize_function_for_size_p (cfun)
3071            && !memory_operand (operands[0], DFmode)
3072            && standard_80387_constant_p (operands[1]))
3073        || GET_CODE (operands[1]) != CONST_DOUBLE
3074        || ((optimize_function_for_size_p (cfun)
3075             || !TARGET_MEMORY_MISMATCH_STALL
3076             || reload_in_progress || reload_completed)
3077            && memory_operand (operands[0], DFmode)))"
3078 {
3079   switch (which_alternative)
3080     {
3081     case 0:
3082     case 1:
3083       return output_387_reg_move (insn, operands);
3084
3085     case 2:
3086       return standard_80387_constant_opcode (operands[1]);
3087
3088     case 3:
3089     case 4:
3090       return "#";
3091     case 5:
3092       switch (get_attr_mode (insn))
3093         {
3094         case MODE_V4SF:
3095           return "%vxorps\t%0, %d0";
3096         case MODE_V2DF:
3097           return "%vxorpd\t%0, %d0";
3098         case MODE_TI:
3099           return "%vpxor\t%0, %d0";
3100         default:
3101           gcc_unreachable ();
3102         }
3103     case 6:
3104     case 7:
3105     case 8:
3106       switch (get_attr_mode (insn))
3107         {
3108         case MODE_V4SF:
3109           return "%vmovaps\t{%1, %0|%0, %1}";
3110         case MODE_V2DF:
3111           return "%vmovapd\t{%1, %0|%0, %1}";
3112         case MODE_TI:
3113           return "%vmovdqa\t{%1, %0|%0, %1}";
3114         case MODE_DI:
3115           return "%vmovq\t{%1, %0|%0, %1}";
3116         case MODE_DF:
3117           if (TARGET_AVX)
3118             {
3119               if (REG_P (operands[0]) && REG_P (operands[1]))
3120                 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3121               else
3122                 return "vmovsd\t{%1, %0|%0, %1}";
3123             }
3124           else
3125             return "movsd\t{%1, %0|%0, %1}";
3126         case MODE_V1DF:
3127           if (TARGET_AVX)
3128             {
3129               if (REG_P (operands[0]))
3130                 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
3131               else
3132                 return "vmovlpd\t{%1, %0|%0, %1}";
3133             }
3134           else
3135             return "movlpd\t{%1, %0|%0, %1}";
3136         case MODE_V2SF:
3137           if (TARGET_AVX)
3138             {
3139               if (REG_P (operands[0]))
3140                 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
3141               else
3142                 return "vmovlps\t{%1, %0|%0, %1}";
3143             }
3144           else
3145             return "movlps\t{%1, %0|%0, %1}";
3146         default:
3147           gcc_unreachable ();
3148         }
3149
3150     default:
3151       gcc_unreachable ();
3152     }
3153 }
3154   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3155    (set (attr "prefix")
3156      (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3157        (const_string "orig")
3158        (const_string "maybe_vex")))
3159    (set (attr "prefix_data16")
3160      (if_then_else (eq_attr "mode" "V1DF")
3161        (const_string "1")
3162        (const_string "*")))
3163    (set (attr "mode")
3164         (cond [(eq_attr "alternative" "0,1,2")
3165                  (const_string "DF")
3166                (eq_attr "alternative" "3,4")
3167                  (const_string "SI")
3168
3169                /* For SSE1, we have many fewer alternatives.  */
3170                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3171                  (cond [(eq_attr "alternative" "5,6")
3172                           (const_string "V4SF")
3173                        ]
3174                    (const_string "V2SF"))
3175
3176                /* xorps is one byte shorter.  */
3177                (eq_attr "alternative" "5")
3178                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3179                             (const_int 0))
3180                           (const_string "V4SF")
3181                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3182                             (const_int 0))
3183                           (const_string "TI")
3184                        ]
3185                        (const_string "V2DF"))
3186
3187                /* For architectures resolving dependencies on
3188                   whole SSE registers use APD move to break dependency
3189                   chains, otherwise use short move to avoid extra work.
3190
3191                   movaps encodes one byte shorter.  */
3192                (eq_attr "alternative" "6")
3193                  (cond
3194                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3195                         (const_int 0))
3196                       (const_string "V4SF")
3197                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3198                         (const_int 0))
3199                       (const_string "V2DF")
3200                    ]
3201                    (const_string "DF"))
3202                /* For architectures resolving dependencies on register
3203                   parts we may avoid extra work to zero out upper part
3204                   of register.  */
3205                (eq_attr "alternative" "7")
3206                  (if_then_else
3207                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3208                        (const_int 0))
3209                    (const_string "V1DF")
3210                    (const_string "DF"))
3211               ]
3212               (const_string "DF")))])
3213
3214 (define_insn "*movdf_integer_rex64"
3215   [(set (match_operand:DF 0 "nonimmediate_operand"
3216                 "=f,m,f,r  ,m ,Y2*x,Y2*x,Y2*x,m   ,Yi,r ")
3217         (match_operand:DF 1 "general_operand"
3218                 "fm,f,G,rmF,Fr,C   ,Y2*x,m   ,Y2*x,r ,Yi"))]
3219   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3220    && (reload_in_progress || reload_completed
3221        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3222        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3223            && optimize_function_for_size_p (cfun)
3224            && standard_80387_constant_p (operands[1]))
3225        || GET_CODE (operands[1]) != CONST_DOUBLE
3226        || memory_operand (operands[0], DFmode))"
3227 {
3228   switch (which_alternative)
3229     {
3230     case 0:
3231     case 1:
3232       return output_387_reg_move (insn, operands);
3233
3234     case 2:
3235       return standard_80387_constant_opcode (operands[1]);
3236
3237     case 3:
3238     case 4:
3239       return "#";
3240
3241     case 5:
3242       switch (get_attr_mode (insn))
3243         {
3244         case MODE_V4SF:
3245           return "%vxorps\t%0, %d0";
3246         case MODE_V2DF:
3247           return "%vxorpd\t%0, %d0";
3248         case MODE_TI:
3249           return "%vpxor\t%0, %d0";
3250         default:
3251           gcc_unreachable ();
3252         }
3253     case 6:
3254     case 7:
3255     case 8:
3256       switch (get_attr_mode (insn))
3257         {
3258         case MODE_V4SF:
3259           return "%vmovaps\t{%1, %0|%0, %1}";
3260         case MODE_V2DF:
3261           return "%vmovapd\t{%1, %0|%0, %1}";
3262         case MODE_TI:
3263           return "%vmovdqa\t{%1, %0|%0, %1}";
3264         case MODE_DI:
3265           return "%vmovq\t{%1, %0|%0, %1}";
3266         case MODE_DF:
3267           if (TARGET_AVX)
3268             {
3269               if (REG_P (operands[0]) && REG_P (operands[1]))
3270                 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3271               else
3272                 return "vmovsd\t{%1, %0|%0, %1}";
3273             }
3274           else
3275             return "movsd\t{%1, %0|%0, %1}";
3276         case MODE_V1DF:
3277           return "%vmovlpd\t{%1, %d0|%d0, %1}";
3278         case MODE_V2SF:
3279           return "%vmovlps\t{%1, %d0|%d0, %1}";
3280         default:
3281           gcc_unreachable ();
3282         }
3283
3284     case 9:
3285     case 10:
3286     return "%vmovd\t{%1, %0|%0, %1}";
3287
3288     default:
3289       gcc_unreachable();
3290     }
3291 }
3292   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
3293    (set (attr "prefix")
3294      (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3295        (const_string "orig")
3296        (const_string "maybe_vex")))
3297    (set (attr "prefix_data16")
3298      (if_then_else (eq_attr "mode" "V1DF")
3299        (const_string "1")
3300        (const_string "*")))
3301    (set (attr "mode")
3302         (cond [(eq_attr "alternative" "0,1,2")
3303                  (const_string "DF")
3304                (eq_attr "alternative" "3,4,9,10")
3305                  (const_string "DI")
3306
3307                /* For SSE1, we have many fewer alternatives.  */
3308                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3309                  (cond [(eq_attr "alternative" "5,6")
3310                           (const_string "V4SF")
3311                        ]
3312                    (const_string "V2SF"))
3313
3314                /* xorps is one byte shorter.  */
3315                (eq_attr "alternative" "5")
3316                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3317                             (const_int 0))
3318                           (const_string "V4SF")
3319                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3320                             (const_int 0))
3321                           (const_string "TI")
3322                        ]
3323                        (const_string "V2DF"))
3324
3325                /* For architectures resolving dependencies on
3326                   whole SSE registers use APD move to break dependency
3327                   chains, otherwise use short move to avoid extra work.
3328
3329                   movaps encodes one byte shorter.  */
3330                (eq_attr "alternative" "6")
3331                  (cond
3332                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3333                         (const_int 0))
3334                       (const_string "V4SF")
3335                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3336                         (const_int 0))
3337                       (const_string "V2DF")
3338                    ]
3339                    (const_string "DF"))
3340                /* For architectures resolving dependencies on register
3341                   parts we may avoid extra work to zero out upper part
3342                   of register.  */
3343                (eq_attr "alternative" "7")
3344                  (if_then_else
3345                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3346                        (const_int 0))
3347                    (const_string "V1DF")
3348                    (const_string "DF"))
3349               ]
3350               (const_string "DF")))])
3351
3352 (define_insn "*movdf_integer"
3353   [(set (match_operand:DF 0 "nonimmediate_operand"
3354                 "=f,m,f,r  ,o ,Y2*x,Y2*x,Y2*x,m   ")
3355         (match_operand:DF 1 "general_operand"
3356                 "fm,f,G,roF,Fr,C   ,Y2*x,m   ,Y2*x"))]
3357   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3358    && optimize_function_for_speed_p (cfun)
3359    && TARGET_INTEGER_DFMODE_MOVES
3360    && (reload_in_progress || reload_completed
3361        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3362        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3363            && optimize_function_for_size_p (cfun)
3364            && standard_80387_constant_p (operands[1]))
3365        || GET_CODE (operands[1]) != CONST_DOUBLE
3366        || memory_operand (operands[0], DFmode))"
3367 {
3368   switch (which_alternative)
3369     {
3370     case 0:
3371     case 1:
3372       return output_387_reg_move (insn, operands);
3373
3374     case 2:
3375       return standard_80387_constant_opcode (operands[1]);
3376
3377     case 3:
3378     case 4:
3379       return "#";
3380
3381     case 5:
3382       switch (get_attr_mode (insn))
3383         {
3384         case MODE_V4SF:
3385           return "xorps\t%0, %0";
3386         case MODE_V2DF:
3387           return "xorpd\t%0, %0";
3388         case MODE_TI:
3389           return "pxor\t%0, %0";
3390         default:
3391           gcc_unreachable ();
3392         }
3393     case 6:
3394     case 7:
3395     case 8:
3396       switch (get_attr_mode (insn))
3397         {
3398         case MODE_V4SF:
3399           return "movaps\t{%1, %0|%0, %1}";
3400         case MODE_V2DF:
3401           return "movapd\t{%1, %0|%0, %1}";
3402         case MODE_TI:
3403           return "movdqa\t{%1, %0|%0, %1}";
3404         case MODE_DI:
3405           return "movq\t{%1, %0|%0, %1}";
3406         case MODE_DF:
3407           return "movsd\t{%1, %0|%0, %1}";
3408         case MODE_V1DF:
3409           return "movlpd\t{%1, %0|%0, %1}";
3410         case MODE_V2SF:
3411           return "movlps\t{%1, %0|%0, %1}";
3412         default:
3413           gcc_unreachable ();
3414         }
3415
3416     default:
3417       gcc_unreachable();
3418     }
3419 }
3420   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3421    (set (attr "prefix_data16")
3422      (if_then_else (eq_attr "mode" "V1DF")
3423        (const_string "1")
3424        (const_string "*")))
3425    (set (attr "mode")
3426         (cond [(eq_attr "alternative" "0,1,2")
3427                  (const_string "DF")
3428                (eq_attr "alternative" "3,4")
3429                  (const_string "SI")
3430
3431                /* For SSE1, we have many fewer alternatives.  */
3432                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3433                  (cond [(eq_attr "alternative" "5,6")
3434                           (const_string "V4SF")
3435                        ]
3436                    (const_string "V2SF"))
3437
3438                /* xorps is one byte shorter.  */
3439                (eq_attr "alternative" "5")
3440                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3441                             (const_int 0))
3442                           (const_string "V4SF")
3443                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3444                             (const_int 0))
3445                           (const_string "TI")
3446                        ]
3447                        (const_string "V2DF"))
3448
3449                /* For architectures resolving dependencies on
3450                   whole SSE registers use APD move to break dependency
3451                   chains, otherwise use short move to avoid extra work.
3452
3453                   movaps encodes one byte shorter.  */
3454                (eq_attr "alternative" "6")
3455                  (cond
3456                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3457                         (const_int 0))
3458                       (const_string "V4SF")
3459                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3460                         (const_int 0))
3461                       (const_string "V2DF")
3462                    ]
3463                    (const_string "DF"))
3464                /* For architectures resolving dependencies on register
3465                   parts we may avoid extra work to zero out upper part
3466                   of register.  */
3467                (eq_attr "alternative" "7")
3468                  (if_then_else
3469                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3470                        (const_int 0))
3471                    (const_string "V1DF")
3472                    (const_string "DF"))
3473               ]
3474               (const_string "DF")))])
3475
3476 (define_split
3477   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3478         (match_operand:DF 1 "general_operand" ""))]
3479   "reload_completed
3480    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3481    && ! (ANY_FP_REG_P (operands[0]) ||
3482          (GET_CODE (operands[0]) == SUBREG
3483           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3484    && ! (ANY_FP_REG_P (operands[1]) ||
3485          (GET_CODE (operands[1]) == SUBREG
3486           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3487   [(const_int 0)]
3488   "ix86_split_long_move (operands); DONE;")
3489
3490 (define_insn "*swapdf"
3491   [(set (match_operand:DF 0 "fp_register_operand" "+f")
3492         (match_operand:DF 1 "fp_register_operand" "+f"))
3493    (set (match_dup 1)
3494         (match_dup 0))]
3495   "reload_completed || TARGET_80387"
3496 {
3497   if (STACK_TOP_P (operands[0]))
3498     return "fxch\t%1";
3499   else
3500     return "fxch\t%0";
3501 }
3502   [(set_attr "type" "fxch")
3503    (set_attr "mode" "DF")])
3504
3505 (define_expand "movxf"
3506   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3507         (match_operand:XF 1 "general_operand" ""))]
3508   ""
3509   "ix86_expand_move (XFmode, operands); DONE;")
3510
3511 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3512 ;; Size of pushdf using integer instructions is 3+3*memory operand size
3513 ;; Pushing using integer instructions is longer except for constants
3514 ;; and direct memory references.
3515 ;; (assuming that any given constant is pushed only once, but this ought to be
3516 ;;  handled elsewhere).
3517
3518 (define_insn "*pushxf_nointeger"
3519   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
3520         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
3521   "optimize_function_for_size_p (cfun)"
3522 {
3523   /* This insn should be already split before reg-stack.  */
3524   gcc_unreachable ();
3525 }
3526   [(set_attr "type" "multi")
3527    (set_attr "unit" "i387,*,*")
3528    (set_attr "mode" "XF,SI,SI")])
3529
3530 (define_insn "*pushxf_integer"
3531   [(set (match_operand:XF 0 "push_operand" "=<,<")
3532         (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
3533   "optimize_function_for_speed_p (cfun)"
3534 {
3535   /* This insn should be already split before reg-stack.  */
3536   gcc_unreachable ();
3537 }
3538   [(set_attr "type" "multi")
3539    (set_attr "unit" "i387,*")
3540    (set_attr "mode" "XF,SI")])
3541
3542 (define_split
3543   [(set (match_operand 0 "push_operand" "")
3544         (match_operand 1 "general_operand" ""))]
3545   "reload_completed
3546    && (GET_MODE (operands[0]) == XFmode
3547        || GET_MODE (operands[0]) == DFmode)
3548    && !ANY_FP_REG_P (operands[1])"
3549   [(const_int 0)]
3550   "ix86_split_long_move (operands); DONE;")
3551
3552 (define_split
3553   [(set (match_operand:XF 0 "push_operand" "")
3554         (match_operand:XF 1 "any_fp_register_operand" ""))]
3555   ""
3556   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3557    (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
3558   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3559
3560 ;; Do not use integer registers when optimizing for size
3561 (define_insn "*movxf_nointeger"
3562   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3563         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3564   "optimize_function_for_size_p (cfun)
3565    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3566    && (reload_in_progress || reload_completed
3567        || standard_80387_constant_p (operands[1])
3568        || GET_CODE (operands[1]) != CONST_DOUBLE
3569        || memory_operand (operands[0], XFmode))"
3570 {
3571   switch (which_alternative)
3572     {
3573     case 0:
3574     case 1:
3575       return output_387_reg_move (insn, operands);
3576
3577     case 2:
3578       return standard_80387_constant_opcode (operands[1]);
3579
3580     case 3: case 4:
3581       return "#";
3582     default:
3583       gcc_unreachable ();
3584     }
3585 }
3586   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3587    (set_attr "mode" "XF,XF,XF,SI,SI")])
3588
3589 (define_insn "*movxf_integer"
3590   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
3591         (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
3592   "optimize_function_for_speed_p (cfun)
3593    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3594    && (reload_in_progress || reload_completed
3595        || GET_CODE (operands[1]) != CONST_DOUBLE
3596        || memory_operand (operands[0], XFmode))"
3597 {
3598   switch (which_alternative)
3599     {
3600     case 0:
3601     case 1:
3602       return output_387_reg_move (insn, operands);
3603
3604     case 2:
3605       return standard_80387_constant_opcode (operands[1]);
3606
3607     case 3: case 4:
3608       return "#";
3609
3610     default:
3611       gcc_unreachable ();
3612     }
3613 }
3614   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3615    (set_attr "mode" "XF,XF,XF,SI,SI")])
3616
3617 (define_expand "movtf"
3618   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3619         (match_operand:TF 1 "nonimmediate_operand" ""))]
3620   "TARGET_SSE2"
3621 {
3622   ix86_expand_move (TFmode, operands);
3623   DONE;
3624 })
3625
3626 (define_insn "*movtf_internal"
3627   [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
3628         (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
3629   "TARGET_SSE2
3630    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3631 {
3632   switch (which_alternative)
3633     {
3634     case 0:
3635     case 1:
3636       if (get_attr_mode (insn) == MODE_V4SF)
3637         return "%vmovaps\t{%1, %0|%0, %1}";
3638       else
3639         return "%vmovdqa\t{%1, %0|%0, %1}";
3640     case 2:
3641       if (get_attr_mode (insn) == MODE_V4SF)
3642         return "%vxorps\t%0, %d0";
3643       else
3644         return "%vpxor\t%0, %d0";
3645     case 3:
3646     case 4:
3647         return "#";
3648     default:
3649       gcc_unreachable ();
3650     }
3651 }
3652   [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
3653    (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
3654    (set (attr "mode")
3655         (cond [(eq_attr "alternative" "0,2")
3656                  (if_then_else
3657                    (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3658                        (const_int 0))
3659                    (const_string "V4SF")
3660                    (const_string "TI"))
3661                (eq_attr "alternative" "1")
3662                  (if_then_else
3663                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3664                             (const_int 0))
3665                         (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3666                             (const_int 0)))
3667                    (const_string "V4SF")
3668                    (const_string "TI"))]
3669                (const_string "DI")))])
3670
3671 (define_insn "*pushtf_sse"
3672   [(set (match_operand:TF 0 "push_operand" "=<,<,<")
3673         (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
3674   "TARGET_SSE2"
3675 {
3676   /* This insn should be already split before reg-stack.  */
3677   gcc_unreachable ();
3678 }
3679   [(set_attr "type" "multi")
3680    (set_attr "unit" "sse,*,*")
3681    (set_attr "mode" "TF,SI,SI")])
3682
3683 (define_split
3684   [(set (match_operand:TF 0 "push_operand" "")
3685         (match_operand:TF 1 "general_operand" ""))]
3686   "TARGET_SSE2 && reload_completed
3687    && !SSE_REG_P (operands[1])"
3688   [(const_int 0)]
3689   "ix86_split_long_move (operands); DONE;")
3690
3691 (define_split
3692   [(set (match_operand:TF 0 "push_operand" "")
3693         (match_operand:TF 1 "any_fp_register_operand" ""))]
3694   "TARGET_SSE2"
3695   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3696    (set (mem:TF (reg:P SP_REG)) (match_dup 1))]
3697   "")
3698
3699 (define_split
3700   [(set (match_operand 0 "nonimmediate_operand" "")
3701         (match_operand 1 "general_operand" ""))]
3702   "reload_completed
3703    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3704    && GET_MODE (operands[0]) == XFmode
3705    && ! (ANY_FP_REG_P (operands[0]) ||
3706          (GET_CODE (operands[0]) == SUBREG
3707           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3708    && ! (ANY_FP_REG_P (operands[1]) ||
3709          (GET_CODE (operands[1]) == SUBREG
3710           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3711   [(const_int 0)]
3712   "ix86_split_long_move (operands); DONE;")
3713
3714 (define_split
3715   [(set (match_operand 0 "register_operand" "")
3716         (match_operand 1 "memory_operand" ""))]
3717   "reload_completed
3718    && MEM_P (operands[1])
3719    && (GET_MODE (operands[0]) == TFmode
3720        || GET_MODE (operands[0]) == XFmode
3721        || GET_MODE (operands[0]) == SFmode
3722        || GET_MODE (operands[0]) == DFmode)
3723    && (operands[2] = find_constant_src (insn))"
3724   [(set (match_dup 0) (match_dup 2))]
3725 {
3726   rtx c = operands[2];
3727   rtx r = operands[0];
3728
3729   if (GET_CODE (r) == SUBREG)
3730     r = SUBREG_REG (r);
3731
3732   if (SSE_REG_P (r))
3733     {
3734       if (!standard_sse_constant_p (c))
3735         FAIL;
3736     }
3737   else if (FP_REG_P (r))
3738     {
3739       if (!standard_80387_constant_p (c))
3740         FAIL;
3741     }
3742   else if (MMX_REG_P (r))
3743     FAIL;
3744 })
3745
3746 (define_split
3747   [(set (match_operand 0 "register_operand" "")
3748         (float_extend (match_operand 1 "memory_operand" "")))]
3749   "reload_completed
3750    && MEM_P (operands[1])
3751    && (GET_MODE (operands[0]) == TFmode
3752        || GET_MODE (operands[0]) == XFmode
3753        || GET_MODE (operands[0]) == SFmode
3754        || GET_MODE (operands[0]) == DFmode)
3755    && (operands[2] = find_constant_src (insn))"
3756   [(set (match_dup 0) (match_dup 2))]
3757 {
3758   rtx c = operands[2];
3759   rtx r = operands[0];
3760
3761   if (GET_CODE (r) == SUBREG)
3762     r = SUBREG_REG (r);
3763
3764   if (SSE_REG_P (r))
3765     {
3766       if (!standard_sse_constant_p (c))
3767         FAIL;
3768     }
3769   else if (FP_REG_P (r))
3770     {
3771       if (!standard_80387_constant_p (c))
3772         FAIL;
3773     }
3774   else if (MMX_REG_P (r))
3775     FAIL;
3776 })
3777
3778 (define_insn "swapxf"
3779   [(set (match_operand:XF 0 "register_operand" "+f")
3780         (match_operand:XF 1 "register_operand" "+f"))
3781    (set (match_dup 1)
3782         (match_dup 0))]
3783   "TARGET_80387"
3784 {
3785   if (STACK_TOP_P (operands[0]))
3786     return "fxch\t%1";
3787   else
3788     return "fxch\t%0";
3789 }
3790   [(set_attr "type" "fxch")
3791    (set_attr "mode" "XF")])
3792
3793 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3794 (define_split
3795   [(set (match_operand:X87MODEF 0 "register_operand" "")
3796         (match_operand:X87MODEF 1 "immediate_operand" ""))]
3797   "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3798    && (standard_80387_constant_p (operands[1]) == 8
3799        || standard_80387_constant_p (operands[1]) == 9)"
3800   [(set (match_dup 0)(match_dup 1))
3801    (set (match_dup 0)
3802         (neg:X87MODEF (match_dup 0)))]
3803 {
3804   REAL_VALUE_TYPE r;
3805
3806   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3807   if (real_isnegzero (&r))
3808     operands[1] = CONST0_RTX (<MODE>mode);
3809   else
3810     operands[1] = CONST1_RTX (<MODE>mode);
3811 })
3812
3813 (define_split
3814   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3815         (match_operand:TF 1 "general_operand" ""))]
3816   "reload_completed
3817    && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
3818   [(const_int 0)]
3819   "ix86_split_long_move (operands); DONE;")
3820 \f
3821 ;; Zero extension instructions
3822
3823 (define_expand "zero_extendhisi2"
3824   [(set (match_operand:SI 0 "register_operand" "")
3825      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3826   ""
3827 {
3828   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3829     {
3830       operands[1] = force_reg (HImode, operands[1]);
3831       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3832       DONE;
3833     }
3834 })
3835
3836 (define_insn "zero_extendhisi2_and"
3837   [(set (match_operand:SI 0 "register_operand" "=r")
3838      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3839    (clobber (reg:CC FLAGS_REG))]
3840   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3841   "#"
3842   [(set_attr "type" "alu1")
3843    (set_attr "mode" "SI")])
3844
3845 (define_split
3846   [(set (match_operand:SI 0 "register_operand" "")
3847         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3848    (clobber (reg:CC FLAGS_REG))]
3849   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND
3850    && optimize_function_for_speed_p (cfun)"
3851   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3852               (clobber (reg:CC FLAGS_REG))])]
3853   "")
3854
3855 (define_insn "*zero_extendhisi2_movzwl"
3856   [(set (match_operand:SI 0 "register_operand" "=r")
3857      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3858   "!TARGET_ZERO_EXTEND_WITH_AND
3859    || optimize_function_for_size_p (cfun)"
3860   "movz{wl|x}\t{%1, %0|%0, %1}"
3861   [(set_attr "type" "imovx")
3862    (set_attr "mode" "SI")])
3863
3864 (define_expand "zero_extendqihi2"
3865   [(parallel
3866     [(set (match_operand:HI 0 "register_operand" "")
3867        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3868      (clobber (reg:CC FLAGS_REG))])]
3869   ""
3870   "")
3871
3872 (define_insn "*zero_extendqihi2_and"
3873   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3874      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3875    (clobber (reg:CC FLAGS_REG))]
3876   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3877   "#"
3878   [(set_attr "type" "alu1")
3879    (set_attr "mode" "HI")])
3880
3881 (define_insn "*zero_extendqihi2_movzbw_and"
3882   [(set (match_operand:HI 0 "register_operand" "=r,r")
3883      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3884    (clobber (reg:CC FLAGS_REG))]
3885   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3886   "#"
3887   [(set_attr "type" "imovx,alu1")
3888    (set_attr "mode" "HI")])
3889
3890 ; zero extend to SImode here to avoid partial register stalls
3891 (define_insn "*zero_extendqihi2_movzbl"
3892   [(set (match_operand:HI 0 "register_operand" "=r")
3893      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3894   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3895    && reload_completed"
3896   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3897   [(set_attr "type" "imovx")
3898    (set_attr "mode" "SI")])
3899
3900 ;; For the movzbw case strip only the clobber
3901 (define_split
3902   [(set (match_operand:HI 0 "register_operand" "")
3903         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3904    (clobber (reg:CC FLAGS_REG))]
3905   "reload_completed
3906    && (!TARGET_ZERO_EXTEND_WITH_AND
3907        || optimize_function_for_size_p (cfun))
3908    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3909   [(set (match_operand:HI 0 "register_operand" "")
3910         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3911
3912 ;; When source and destination does not overlap, clear destination
3913 ;; first and then do the movb
3914 (define_split
3915   [(set (match_operand:HI 0 "register_operand" "")
3916         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3917    (clobber (reg:CC FLAGS_REG))]
3918   "reload_completed
3919    && ANY_QI_REG_P (operands[0])
3920    && (TARGET_ZERO_EXTEND_WITH_AND
3921        && optimize_function_for_speed_p (cfun))
3922    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3923   [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3924 {
3925   operands[2] = gen_lowpart (QImode, operands[0]);
3926   ix86_expand_clear (operands[0]);
3927 })
3928
3929 ;; Rest is handled by single and.
3930 (define_split
3931   [(set (match_operand:HI 0 "register_operand" "")
3932         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3933    (clobber (reg:CC FLAGS_REG))]
3934   "reload_completed
3935    && true_regnum (operands[0]) == true_regnum (operands[1])"
3936   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3937               (clobber (reg:CC FLAGS_REG))])]
3938   "")
3939
3940 (define_expand "zero_extendqisi2"
3941   [(parallel
3942     [(set (match_operand:SI 0 "register_operand" "")
3943        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3944      (clobber (reg:CC FLAGS_REG))])]
3945   ""
3946   "")
3947
3948 (define_insn "*zero_extendqisi2_and"
3949   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3950      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3951    (clobber (reg:CC FLAGS_REG))]
3952   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3953   "#"
3954   [(set_attr "type" "alu1")
3955    (set_attr "mode" "SI")])
3956
3957 (define_insn "*zero_extendqisi2_movzbl_and"
3958   [(set (match_operand:SI 0 "register_operand" "=r,r")
3959      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3960    (clobber (reg:CC FLAGS_REG))]
3961   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3962   "#"
3963   [(set_attr "type" "imovx,alu1")
3964    (set_attr "mode" "SI")])
3965
3966 (define_insn "*zero_extendqisi2_movzbl"
3967   [(set (match_operand:SI 0 "register_operand" "=r")
3968      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3969   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3970    && reload_completed"
3971   "movz{bl|x}\t{%1, %0|%0, %1}"
3972   [(set_attr "type" "imovx")
3973    (set_attr "mode" "SI")])
3974
3975 ;; For the movzbl case strip only the clobber
3976 (define_split
3977   [(set (match_operand:SI 0 "register_operand" "")
3978         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3979    (clobber (reg:CC FLAGS_REG))]
3980   "reload_completed
3981    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3982    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3983   [(set (match_dup 0)
3984         (zero_extend:SI (match_dup 1)))])
3985
3986 ;; When source and destination does not overlap, clear destination
3987 ;; first and then do the movb
3988 (define_split
3989   [(set (match_operand:SI 0 "register_operand" "")
3990         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3991    (clobber (reg:CC FLAGS_REG))]
3992   "reload_completed
3993    && ANY_QI_REG_P (operands[0])
3994    && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3995    && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3996    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3997   [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3998 {
3999   operands[2] = gen_lowpart (QImode, operands[0]);
4000   ix86_expand_clear (operands[0]);
4001 })
4002
4003 ;; Rest is handled by single and.
4004 (define_split
4005   [(set (match_operand:SI 0 "register_operand" "")
4006         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
4007    (clobber (reg:CC FLAGS_REG))]
4008   "reload_completed
4009    && true_regnum (operands[0]) == true_regnum (operands[1])"
4010   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
4011               (clobber (reg:CC FLAGS_REG))])]
4012   "")
4013
4014 ;; %%% Kill me once multi-word ops are sane.
4015 (define_expand "zero_extendsidi2"
4016   [(set (match_operand:DI 0 "register_operand" "")
4017      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
4018   ""
4019 {
4020   if (!TARGET_64BIT)
4021     {
4022       emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
4023       DONE;
4024     }
4025 })
4026
4027 (define_insn "zero_extendsidi2_32"
4028   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
4029         (zero_extend:DI
4030          (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r   ,m  ,r   ,m")))
4031    (clobber (reg:CC FLAGS_REG))]
4032   "!TARGET_64BIT"
4033   "@
4034    #
4035    #
4036    #
4037    movd\t{%1, %0|%0, %1}
4038    movd\t{%1, %0|%0, %1}
4039    %vmovd\t{%1, %0|%0, %1}
4040    %vmovd\t{%1, %0|%0, %1}"
4041   [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
4042    (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
4043    (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
4044
4045 (define_insn "zero_extendsidi2_rex64"
4046   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
4047      (zero_extend:DI
4048        (match_operand:SI 1 "nonimmediate_operand"  "rm,0,r   ,m  ,r   ,m")))]
4049   "TARGET_64BIT"
4050   "@
4051    mov\t{%k1, %k0|%k0, %k1}
4052    #
4053    movd\t{%1, %0|%0, %1}
4054    movd\t{%1, %0|%0, %1}
4055    %vmovd\t{%1, %0|%0, %1}
4056    %vmovd\t{%1, %0|%0, %1}"
4057   [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
4058    (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
4059    (set_attr "prefix_0f" "0,*,*,*,*,*")
4060    (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
4061
4062 (define_split
4063   [(set (match_operand:DI 0 "memory_operand" "")
4064      (zero_extend:DI (match_dup 0)))]
4065   "TARGET_64BIT"
4066   [(set (match_dup 4) (const_int 0))]
4067   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4068
4069 (define_split
4070   [(set (match_operand:DI 0 "register_operand" "")
4071         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
4072    (clobber (reg:CC FLAGS_REG))]
4073   "!TARGET_64BIT && reload_completed
4074    && true_regnum (operands[0]) == true_regnum (operands[1])"
4075   [(set (match_dup 4) (const_int 0))]
4076   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4077
4078 (define_split
4079   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4080         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
4081    (clobber (reg:CC FLAGS_REG))]
4082   "!TARGET_64BIT && reload_completed
4083    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
4084   [(set (match_dup 3) (match_dup 1))
4085    (set (match_dup 4) (const_int 0))]
4086   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4087
4088 (define_insn "zero_extendhidi2"
4089   [(set (match_operand:DI 0 "register_operand" "=r")
4090      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
4091   "TARGET_64BIT"
4092   "movz{wl|x}\t{%1, %k0|%k0, %1}"
4093   [(set_attr "type" "imovx")
4094    (set_attr "mode" "SI")])
4095
4096 (define_insn "zero_extendqidi2"
4097   [(set (match_operand:DI 0 "register_operand" "=r")
4098      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
4099   "TARGET_64BIT"
4100   "movz{bl|x}\t{%1, %k0|%k0, %1}"
4101   [(set_attr "type" "imovx")
4102    (set_attr "mode" "SI")])
4103 \f
4104 ;; Sign extension instructions
4105
4106 (define_expand "extendsidi2"
4107   [(parallel [(set (match_operand:DI 0 "register_operand" "")
4108                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4109               (clobber (reg:CC FLAGS_REG))
4110               (clobber (match_scratch:SI 2 ""))])]
4111   ""
4112 {
4113   if (TARGET_64BIT)
4114     {
4115       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
4116       DONE;
4117     }
4118 })
4119
4120 (define_insn "*extendsidi2_1"
4121   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
4122         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
4123    (clobber (reg:CC FLAGS_REG))
4124    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
4125   "!TARGET_64BIT"
4126   "#")
4127
4128 (define_insn "extendsidi2_rex64"
4129   [(set (match_operand:DI 0 "register_operand" "=*a,r")
4130         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
4131   "TARGET_64BIT"
4132   "@
4133    {cltq|cdqe}
4134    movs{lq|x}\t{%1, %0|%0, %1}"
4135   [(set_attr "type" "imovx")
4136    (set_attr "mode" "DI")
4137    (set_attr "prefix_0f" "0")
4138    (set_attr "modrm" "0,1")])
4139
4140 (define_insn "extendhidi2"
4141   [(set (match_operand:DI 0 "register_operand" "=r")
4142         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
4143   "TARGET_64BIT"
4144   "movs{wq|x}\t{%1, %0|%0, %1}"
4145   [(set_attr "type" "imovx")
4146    (set_attr "mode" "DI")])
4147
4148 (define_insn "extendqidi2"
4149   [(set (match_operand:DI 0 "register_operand" "=r")
4150         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4151   "TARGET_64BIT"
4152   "movs{bq|x}\t{%1, %0|%0, %1}"
4153    [(set_attr "type" "imovx")
4154     (set_attr "mode" "DI")])
4155
4156 ;; Extend to memory case when source register does die.
4157 (define_split
4158   [(set (match_operand:DI 0 "memory_operand" "")
4159         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4160    (clobber (reg:CC FLAGS_REG))
4161    (clobber (match_operand:SI 2 "register_operand" ""))]
4162   "(reload_completed
4163     && dead_or_set_p (insn, operands[1])
4164     && !reg_mentioned_p (operands[1], operands[0]))"
4165   [(set (match_dup 3) (match_dup 1))
4166    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4167               (clobber (reg:CC FLAGS_REG))])
4168    (set (match_dup 4) (match_dup 1))]
4169   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4170
4171 ;; Extend to memory case when source register does not die.
4172 (define_split
4173   [(set (match_operand:DI 0 "memory_operand" "")
4174         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4175    (clobber (reg:CC FLAGS_REG))
4176    (clobber (match_operand:SI 2 "register_operand" ""))]
4177   "reload_completed"
4178   [(const_int 0)]
4179 {
4180   split_di (&operands[0], 1, &operands[3], &operands[4]);
4181
4182   emit_move_insn (operands[3], operands[1]);
4183
4184   /* Generate a cltd if possible and doing so it profitable.  */
4185   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4186       && true_regnum (operands[1]) == AX_REG
4187       && true_regnum (operands[2]) == DX_REG)
4188     {
4189       emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
4190     }
4191   else
4192     {
4193       emit_move_insn (operands[2], operands[1]);
4194       emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
4195     }
4196   emit_move_insn (operands[4], operands[2]);
4197   DONE;
4198 })
4199
4200 ;; Extend to register case.  Optimize case where source and destination
4201 ;; registers match and cases where we can use cltd.
4202 (define_split
4203   [(set (match_operand:DI 0 "register_operand" "")
4204         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4205    (clobber (reg:CC FLAGS_REG))
4206    (clobber (match_scratch:SI 2 ""))]
4207   "reload_completed"
4208   [(const_int 0)]
4209 {
4210   split_di (&operands[0], 1, &operands[3], &operands[4]);
4211
4212   if (true_regnum (operands[3]) != true_regnum (operands[1]))
4213     emit_move_insn (operands[3], operands[1]);
4214
4215   /* Generate a cltd if possible and doing so it profitable.  */
4216   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4217       && true_regnum (operands[3]) == AX_REG)
4218     {
4219       emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
4220       DONE;
4221     }
4222
4223   if (true_regnum (operands[4]) != true_regnum (operands[1]))
4224     emit_move_insn (operands[4], operands[1]);
4225
4226   emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
4227   DONE;
4228 })
4229
4230 (define_insn "extendhisi2"
4231   [(set (match_operand:SI 0 "register_operand" "=*a,r")
4232         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4233   ""
4234 {
4235   switch (get_attr_prefix_0f (insn))
4236     {
4237     case 0:
4238       return "{cwtl|cwde}";
4239     default:
4240       return "movs{wl|x}\t{%1, %0|%0, %1}";
4241     }
4242 }
4243   [(set_attr "type" "imovx")
4244    (set_attr "mode" "SI")
4245    (set (attr "prefix_0f")
4246      ;; movsx is short decodable while cwtl is vector decoded.
4247      (if_then_else (and (eq_attr "cpu" "!k6")
4248                         (eq_attr "alternative" "0"))
4249         (const_string "0")
4250         (const_string "1")))
4251    (set (attr "modrm")
4252      (if_then_else (eq_attr "prefix_0f" "0")
4253         (const_string "0")
4254         (const_string "1")))])
4255
4256 (define_insn "*extendhisi2_zext"
4257   [(set (match_operand:DI 0 "register_operand" "=*a,r")
4258         (zero_extend:DI
4259           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4260   "TARGET_64BIT"
4261 {
4262   switch (get_attr_prefix_0f (insn))
4263     {
4264     case 0:
4265       return "{cwtl|cwde}";
4266     default:
4267       return "movs{wl|x}\t{%1, %k0|%k0, %1}";
4268     }
4269 }
4270   [(set_attr "type" "imovx")
4271    (set_attr "mode" "SI")
4272    (set (attr "prefix_0f")
4273      ;; movsx is short decodable while cwtl is vector decoded.
4274      (if_then_else (and (eq_attr "cpu" "!k6")
4275                         (eq_attr "alternative" "0"))
4276         (const_string "0")
4277         (const_string "1")))
4278    (set (attr "modrm")
4279      (if_then_else (eq_attr "prefix_0f" "0")
4280         (const_string "0")
4281         (const_string "1")))])
4282
4283 (define_insn "extendqihi2"
4284   [(set (match_operand:HI 0 "register_operand" "=*a,r")
4285         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4286   ""
4287 {
4288   switch (get_attr_prefix_0f (insn))
4289     {
4290     case 0:
4291       return "{cbtw|cbw}";
4292     default:
4293       return "movs{bw|x}\t{%1, %0|%0, %1}";
4294     }
4295 }
4296   [(set_attr "type" "imovx")
4297    (set_attr "mode" "HI")
4298    (set (attr "prefix_0f")
4299      ;; movsx is short decodable while cwtl is vector decoded.
4300      (if_then_else (and (eq_attr "cpu" "!k6")
4301                         (eq_attr "alternative" "0"))
4302         (const_string "0")
4303         (const_string "1")))
4304    (set (attr "modrm")
4305      (if_then_else (eq_attr "prefix_0f" "0")
4306         (const_string "0")
4307         (const_string "1")))])
4308
4309 (define_insn "extendqisi2"
4310   [(set (match_operand:SI 0 "register_operand" "=r")
4311         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4312   ""
4313   "movs{bl|x}\t{%1, %0|%0, %1}"
4314    [(set_attr "type" "imovx")
4315     (set_attr "mode" "SI")])
4316
4317 (define_insn "*extendqisi2_zext"
4318   [(set (match_operand:DI 0 "register_operand" "=r")
4319         (zero_extend:DI
4320           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4321   "TARGET_64BIT"
4322   "movs{bl|x}\t{%1, %k0|%k0, %1}"
4323    [(set_attr "type" "imovx")
4324     (set_attr "mode" "SI")])
4325 \f
4326 ;; Conversions between float and double.
4327
4328 ;; These are all no-ops in the model used for the 80387.  So just
4329 ;; emit moves.
4330
4331 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4332 (define_insn "*dummy_extendsfdf2"
4333   [(set (match_operand:DF 0 "push_operand" "=<")
4334         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY2")))]
4335   "0"
4336   "#")
4337
4338 (define_split
4339   [(set (match_operand:DF 0 "push_operand" "")
4340         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
4341   ""
4342   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4343    (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4344
4345 (define_insn "*dummy_extendsfxf2"
4346   [(set (match_operand:XF 0 "push_operand" "=<")
4347         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
4348   "0"
4349   "#")
4350
4351 (define_split
4352   [(set (match_operand:XF 0 "push_operand" "")
4353         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
4354   ""
4355   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4356    (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4357   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4358
4359 (define_split
4360   [(set (match_operand:XF 0 "push_operand" "")
4361         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
4362   ""
4363   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4364    (set (mem:DF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4365   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4366
4367 (define_expand "extendsfdf2"
4368   [(set (match_operand:DF 0 "nonimmediate_operand" "")
4369         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
4370   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4371 {
4372   /* ??? Needed for compress_float_constant since all fp constants
4373      are LEGITIMATE_CONSTANT_P.  */
4374   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4375     {
4376       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4377           && standard_80387_constant_p (operands[1]) > 0)
4378         {
4379           operands[1] = simplify_const_unary_operation
4380             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4381           emit_move_insn_1 (operands[0], operands[1]);
4382           DONE;
4383         }
4384       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4385     }
4386 })
4387
4388 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4389    cvtss2sd:
4390       unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4391       cvtps2pd xmm2,xmm1
4392    We do the conversion post reload to avoid producing of 128bit spills
4393    that might lead to ICE on 32bit target.  The sequence unlikely combine
4394    anyway.  */
4395 (define_split
4396   [(set (match_operand:DF 0 "register_operand" "")
4397         (float_extend:DF
4398           (match_operand:SF 1 "nonimmediate_operand" "")))]
4399   "TARGET_USE_VECTOR_FP_CONVERTS
4400    && optimize_insn_for_speed_p ()
4401    && reload_completed && SSE_REG_P (operands[0])"
4402    [(set (match_dup 2)
4403          (float_extend:V2DF
4404            (vec_select:V2SF
4405              (match_dup 3)
4406              (parallel [(const_int 0) (const_int 1)]))))]
4407 {
4408   operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4409   operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4410   /* Use movss for loading from memory, unpcklps reg, reg for registers.
4411      Try to avoid move when unpacking can be done in source.  */
4412   if (REG_P (operands[1]))
4413     {
4414       /* If it is unsafe to overwrite upper half of source, we need
4415          to move to destination and unpack there.  */
4416       if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4417            || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4418           && true_regnum (operands[0]) != true_regnum (operands[1]))
4419         {
4420           rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4421           emit_move_insn (tmp, operands[1]);
4422         }
4423       else
4424         operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4425       emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4426                                              operands[3]));
4427     }
4428   else
4429     emit_insn (gen_vec_setv4sf_0 (operands[3],
4430                                   CONST0_RTX (V4SFmode), operands[1]));
4431 })
4432
4433 (define_insn "*extendsfdf2_mixed"
4434   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4435         (float_extend:DF
4436           (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4437   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4438 {
4439   switch (which_alternative)
4440     {
4441     case 0:
4442     case 1:
4443       return output_387_reg_move (insn, operands);
4444
4445     case 2:
4446       return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4447
4448     default:
4449       gcc_unreachable ();
4450     }
4451 }
4452   [(set_attr "type" "fmov,fmov,ssecvt")
4453    (set_attr "prefix" "orig,orig,maybe_vex")
4454    (set_attr "mode" "SF,XF,DF")])
4455
4456 (define_insn "*extendsfdf2_sse"
4457   [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4458         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4459   "TARGET_SSE2 && TARGET_SSE_MATH"
4460   "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4461   [(set_attr "type" "ssecvt")
4462    (set_attr "prefix" "maybe_vex")
4463    (set_attr "mode" "DF")])
4464
4465 (define_insn "*extendsfdf2_i387"
4466   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4467         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4468   "TARGET_80387"
4469   "* return output_387_reg_move (insn, operands);"
4470   [(set_attr "type" "fmov")
4471    (set_attr "mode" "SF,XF")])
4472
4473 (define_expand "extend<mode>xf2"
4474   [(set (match_operand:XF 0 "nonimmediate_operand" "")
4475         (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4476   "TARGET_80387"
4477 {
4478   /* ??? Needed for compress_float_constant since all fp constants
4479      are LEGITIMATE_CONSTANT_P.  */
4480   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4481     {
4482       if (standard_80387_constant_p (operands[1]) > 0)
4483         {
4484           operands[1] = simplify_const_unary_operation
4485             (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4486           emit_move_insn_1 (operands[0], operands[1]);
4487           DONE;
4488         }
4489       operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4490     }
4491 })
4492
4493 (define_insn "*extend<mode>xf2_i387"
4494   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4495         (float_extend:XF
4496           (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4497   "TARGET_80387"
4498   "* return output_387_reg_move (insn, operands);"
4499   [(set_attr "type" "fmov")
4500    (set_attr "mode" "<MODE>,XF")])
4501
4502 ;; %%% This seems bad bad news.
4503 ;; This cannot output into an f-reg because there is no way to be sure
4504 ;; of truncating in that case.  Otherwise this is just like a simple move
4505 ;; insn.  So we pretend we can output to a reg in order to get better
4506 ;; register preferencing, but we really use a stack slot.
4507
4508 ;; Conversion from DFmode to SFmode.
4509
4510 (define_expand "truncdfsf2"
4511   [(set (match_operand:SF 0 "nonimmediate_operand" "")
4512         (float_truncate:SF
4513           (match_operand:DF 1 "nonimmediate_operand" "")))]
4514   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4515 {
4516   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4517     ;
4518   else if (flag_unsafe_math_optimizations)
4519     ;
4520   else
4521     {
4522       enum ix86_stack_slot slot = (virtuals_instantiated
4523                                    ? SLOT_TEMP
4524                                    : SLOT_VIRTUAL);
4525       rtx temp = assign_386_stack_local (SFmode, slot);
4526       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4527       DONE;
4528     }
4529 })
4530
4531 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4532    cvtsd2ss:
4533       unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4534       cvtpd2ps xmm2,xmm1
4535    We do the conversion post reload to avoid producing of 128bit spills
4536    that might lead to ICE on 32bit target.  The sequence unlikely combine
4537    anyway.  */
4538 (define_split
4539   [(set (match_operand:SF 0 "register_operand" "")
4540         (float_truncate:SF
4541           (match_operand:DF 1 "nonimmediate_operand" "")))]
4542   "TARGET_USE_VECTOR_FP_CONVERTS
4543    && optimize_insn_for_speed_p ()
4544    && reload_completed && SSE_REG_P (operands[0])"
4545    [(set (match_dup 2)
4546          (vec_concat:V4SF
4547            (float_truncate:V2SF
4548              (match_dup 4))
4549            (match_dup 3)))]
4550 {
4551   operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4552   operands[3] = CONST0_RTX (V2SFmode);
4553   operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4554   /* Use movsd for loading from memory, unpcklpd for registers.
4555      Try to avoid move when unpacking can be done in source, or SSE3
4556      movddup is available.  */
4557   if (REG_P (operands[1]))
4558     {
4559       if (!TARGET_SSE3
4560           && true_regnum (operands[0]) != true_regnum (operands[1])
4561           && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4562               || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4563         {
4564           rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4565           emit_move_insn (tmp, operands[1]);
4566           operands[1] = tmp;
4567         }
4568       else if (!TARGET_SSE3)
4569         operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4570       emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4571     }
4572   else
4573     emit_insn (gen_sse2_loadlpd (operands[4],
4574                                  CONST0_RTX (V2DFmode), operands[1]));
4575 })
4576
4577 (define_expand "truncdfsf2_with_temp"
4578   [(parallel [(set (match_operand:SF 0 "" "")
4579                    (float_truncate:SF (match_operand:DF 1 "" "")))
4580               (clobber (match_operand:SF 2 "" ""))])]
4581   "")
4582
4583 (define_insn "*truncdfsf_fast_mixed"
4584   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm,x")
4585         (float_truncate:SF
4586           (match_operand:DF 1 "nonimmediate_operand" "f  ,xm")))]
4587   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4588 {
4589   switch (which_alternative)
4590     {
4591     case 0:
4592       return output_387_reg_move (insn, operands);
4593     case 1:
4594       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4595     default:
4596       gcc_unreachable ();
4597     }
4598 }
4599   [(set_attr "type" "fmov,ssecvt")
4600    (set_attr "prefix" "orig,maybe_vex")
4601    (set_attr "mode" "SF")])
4602
4603 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4604 ;; because nothing we do here is unsafe.
4605 (define_insn "*truncdfsf_fast_sse"
4606   [(set (match_operand:SF 0 "nonimmediate_operand"   "=x")
4607         (float_truncate:SF
4608           (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4609   "TARGET_SSE2 && TARGET_SSE_MATH"
4610   "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4611   [(set_attr "type" "ssecvt")
4612    (set_attr "prefix" "maybe_vex")
4613    (set_attr "mode" "SF")])
4614
4615 (define_insn "*truncdfsf_fast_i387"
4616   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
4617         (float_truncate:SF
4618           (match_operand:DF 1 "nonimmediate_operand" "f")))]
4619   "TARGET_80387 && flag_unsafe_math_optimizations"
4620   "* return output_387_reg_move (insn, operands);"
4621   [(set_attr "type" "fmov")
4622    (set_attr "mode" "SF")])
4623
4624 (define_insn "*truncdfsf_mixed"
4625   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,Y2 ,?f,?x,?*r")
4626         (float_truncate:SF
4627           (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4628    (clobber (match_operand:SF 2 "memory_operand"     "=X,X  ,m ,m ,m"))]
4629   "TARGET_MIX_SSE_I387"
4630 {
4631   switch (which_alternative)
4632     {
4633     case 0:
4634       return output_387_reg_move (insn, operands);
4635     case 1:
4636       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4637
4638     default:
4639       return "#";
4640     }
4641 }
4642   [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4643    (set_attr "unit" "*,*,i387,i387,i387")
4644    (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4645    (set_attr "mode" "SF")])
4646
4647 (define_insn "*truncdfsf_i387"
4648   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?f,?x,?*r")
4649         (float_truncate:SF
4650           (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4651    (clobber (match_operand:SF 2 "memory_operand"     "=X,m ,m ,m"))]
4652   "TARGET_80387"
4653 {
4654   switch (which_alternative)
4655     {
4656     case 0:
4657       return output_387_reg_move (insn, operands);
4658
4659     default:
4660       return "#";
4661     }
4662 }
4663   [(set_attr "type" "fmov,multi,multi,multi")
4664    (set_attr "unit" "*,i387,i387,i387")
4665    (set_attr "mode" "SF")])
4666
4667 (define_insn "*truncdfsf2_i387_1"
4668   [(set (match_operand:SF 0 "memory_operand" "=m")
4669         (float_truncate:SF
4670           (match_operand:DF 1 "register_operand" "f")))]
4671   "TARGET_80387
4672    && !(TARGET_SSE2 && TARGET_SSE_MATH)
4673    && !TARGET_MIX_SSE_I387"
4674   "* return output_387_reg_move (insn, operands);"
4675   [(set_attr "type" "fmov")
4676    (set_attr "mode" "SF")])
4677
4678 (define_split
4679   [(set (match_operand:SF 0 "register_operand" "")
4680         (float_truncate:SF
4681          (match_operand:DF 1 "fp_register_operand" "")))
4682    (clobber (match_operand 2 "" ""))]
4683   "reload_completed"
4684   [(set (match_dup 2) (match_dup 1))
4685    (set (match_dup 0) (match_dup 2))]
4686 {
4687   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4688 })
4689
4690 ;; Conversion from XFmode to {SF,DF}mode
4691
4692 (define_expand "truncxf<mode>2"
4693   [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4694                    (float_truncate:MODEF
4695                      (match_operand:XF 1 "register_operand" "")))
4696               (clobber (match_dup 2))])]
4697   "TARGET_80387"
4698 {
4699   if (flag_unsafe_math_optimizations)
4700     {
4701       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4702       emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4703       if (reg != operands[0])
4704         emit_move_insn (operands[0], reg);
4705       DONE;
4706     }
4707   else
4708     {
4709      enum ix86_stack_slot slot = (virtuals_instantiated
4710                                   ? SLOT_TEMP
4711                                   : SLOT_VIRTUAL);
4712       operands[2] = assign_386_stack_local (<MODE>mode, slot);
4713     }
4714 })
4715
4716 (define_insn "*truncxfsf2_mixed"
4717   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4718         (float_truncate:SF
4719           (match_operand:XF 1 "register_operand"   "f ,f ,f ,f")))
4720    (clobber (match_operand:SF 2 "memory_operand"   "=X,m ,m ,m"))]
4721   "TARGET_80387"
4722 {
4723   gcc_assert (!which_alternative);
4724   return output_387_reg_move (insn, operands);
4725 }
4726   [(set_attr "type" "fmov,multi,multi,multi")
4727    (set_attr "unit" "*,i387,i387,i387")
4728    (set_attr "mode" "SF")])
4729
4730 (define_insn "*truncxfdf2_mixed"
4731   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4732         (float_truncate:DF
4733           (match_operand:XF 1 "register_operand"   "f ,f ,f  ,f")))
4734    (clobber (match_operand:DF 2 "memory_operand"   "=X,m ,m  ,m"))]
4735   "TARGET_80387"
4736 {
4737   gcc_assert (!which_alternative);
4738   return output_387_reg_move (insn, operands);
4739 }
4740   [(set_attr "type" "fmov,multi,multi,multi")
4741    (set_attr "unit" "*,i387,i387,i387")
4742    (set_attr "mode" "DF")])
4743
4744 (define_insn "truncxf<mode>2_i387_noop"
4745   [(set (match_operand:MODEF 0 "register_operand" "=f")
4746         (float_truncate:MODEF
4747           (match_operand:XF 1 "register_operand" "f")))]
4748   "TARGET_80387 && flag_unsafe_math_optimizations"
4749   "* return output_387_reg_move (insn, operands);"
4750   [(set_attr "type" "fmov")
4751    (set_attr "mode" "<MODE>")])
4752
4753 (define_insn "*truncxf<mode>2_i387"
4754   [(set (match_operand:MODEF 0 "memory_operand" "=m")
4755         (float_truncate:MODEF
4756           (match_operand:XF 1 "register_operand" "f")))]
4757   "TARGET_80387"
4758   "* return output_387_reg_move (insn, operands);"
4759   [(set_attr "type" "fmov")
4760    (set_attr "mode" "<MODE>")])
4761
4762 (define_split
4763   [(set (match_operand:MODEF 0 "register_operand" "")
4764         (float_truncate:MODEF
4765           (match_operand:XF 1 "register_operand" "")))
4766    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4767   "TARGET_80387 && reload_completed"
4768   [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4769    (set (match_dup 0) (match_dup 2))]
4770   "")
4771
4772 (define_split
4773   [(set (match_operand:MODEF 0 "memory_operand" "")
4774         (float_truncate:MODEF
4775           (match_operand:XF 1 "register_operand" "")))
4776    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4777   "TARGET_80387"
4778   [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]
4779   "")
4780 \f
4781 ;; Signed conversion to DImode.
4782
4783 (define_expand "fix_truncxfdi2"
4784   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4785                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4786               (clobber (reg:CC FLAGS_REG))])]
4787   "TARGET_80387"
4788 {
4789   if (TARGET_FISTTP)
4790    {
4791      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4792      DONE;
4793    }
4794 })
4795
4796 (define_expand "fix_trunc<mode>di2"
4797   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4798                    (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4799               (clobber (reg:CC FLAGS_REG))])]
4800   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4801 {
4802   if (TARGET_FISTTP
4803       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4804    {
4805      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4806      DONE;
4807    }
4808   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4809    {
4810      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4811      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4812      if (out != operands[0])
4813         emit_move_insn (operands[0], out);
4814      DONE;
4815    }
4816 })
4817
4818 ;; Signed conversion to SImode.
4819
4820 (define_expand "fix_truncxfsi2"
4821   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4822                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4823               (clobber (reg:CC FLAGS_REG))])]
4824   "TARGET_80387"
4825 {
4826   if (TARGET_FISTTP)
4827    {
4828      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4829      DONE;
4830    }
4831 })
4832
4833 (define_expand "fix_trunc<mode>si2"
4834   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4835                    (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4836               (clobber (reg:CC FLAGS_REG))])]
4837   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4838 {
4839   if (TARGET_FISTTP
4840       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4841    {
4842      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4843      DONE;
4844    }
4845   if (SSE_FLOAT_MODE_P (<MODE>mode))
4846    {
4847      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4848      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4849      if (out != operands[0])
4850         emit_move_insn (operands[0], out);
4851      DONE;
4852    }
4853 })
4854
4855 ;; Signed conversion to HImode.
4856
4857 (define_expand "fix_trunc<mode>hi2"
4858   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4859                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4860               (clobber (reg:CC FLAGS_REG))])]
4861   "TARGET_80387
4862    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4863 {
4864   if (TARGET_FISTTP)
4865    {
4866      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4867      DONE;
4868    }
4869 })
4870
4871 ;; Unsigned conversion to SImode.
4872
4873 (define_expand "fixuns_trunc<mode>si2"
4874   [(parallel
4875     [(set (match_operand:SI 0 "register_operand" "")
4876           (unsigned_fix:SI
4877             (match_operand:MODEF 1 "nonimmediate_operand" "")))
4878      (use (match_dup 2))
4879      (clobber (match_scratch:<ssevecmode> 3 ""))
4880      (clobber (match_scratch:<ssevecmode> 4 ""))])]
4881   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4882 {
4883   enum machine_mode mode = <MODE>mode;
4884   enum machine_mode vecmode = <ssevecmode>mode;
4885   REAL_VALUE_TYPE TWO31r;
4886   rtx two31;
4887
4888   if (optimize_insn_for_size_p ())
4889     FAIL;
4890
4891   real_ldexp (&TWO31r, &dconst1, 31);
4892   two31 = const_double_from_real_value (TWO31r, mode);
4893   two31 = ix86_build_const_vector (mode, true, two31);
4894   operands[2] = force_reg (vecmode, two31);
4895 })
4896
4897 (define_insn_and_split "*fixuns_trunc<mode>_1"
4898   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4899         (unsigned_fix:SI
4900           (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4901    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
4902    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4903    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4904   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4905    && optimize_function_for_speed_p (cfun)"
4906   "#"
4907   "&& reload_completed"
4908   [(const_int 0)]
4909 {
4910   ix86_split_convert_uns_si_sse (operands);
4911   DONE;
4912 })
4913
4914 ;; Unsigned conversion to HImode.
4915 ;; Without these patterns, we'll try the unsigned SI conversion which
4916 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4917
4918 (define_expand "fixuns_trunc<mode>hi2"
4919   [(set (match_dup 2)
4920         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4921    (set (match_operand:HI 0 "nonimmediate_operand" "")
4922         (subreg:HI (match_dup 2) 0))]
4923   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4924   "operands[2] = gen_reg_rtx (SImode);")
4925
4926 ;; When SSE is available, it is always faster to use it!
4927 (define_insn "fix_trunc<mode>di_sse"
4928   [(set (match_operand:DI 0 "register_operand" "=r,r")
4929         (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4930   "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4931    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4932   "%vcvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4933   [(set_attr "type" "sseicvt")
4934    (set_attr "prefix" "maybe_vex")
4935    (set_attr "prefix_rex" "1")
4936    (set_attr "mode" "<MODE>")
4937    (set_attr "athlon_decode" "double,vector")
4938    (set_attr "amdfam10_decode" "double,double")])
4939
4940 (define_insn "fix_trunc<mode>si_sse"
4941   [(set (match_operand:SI 0 "register_operand" "=r,r")
4942         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4943   "SSE_FLOAT_MODE_P (<MODE>mode)
4944    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4945   "%vcvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4946   [(set_attr "type" "sseicvt")
4947    (set_attr "prefix" "maybe_vex")
4948    (set_attr "mode" "<MODE>")
4949    (set_attr "athlon_decode" "double,vector")
4950    (set_attr "amdfam10_decode" "double,double")])
4951
4952 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4953 (define_peephole2
4954   [(set (match_operand:MODEF 0 "register_operand" "")
4955         (match_operand:MODEF 1 "memory_operand" ""))
4956    (set (match_operand:SSEMODEI24 2 "register_operand" "")
4957         (fix:SSEMODEI24 (match_dup 0)))]
4958   "TARGET_SHORTEN_X87_SSE
4959    && peep2_reg_dead_p (2, operands[0])"
4960   [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4961   "")
4962
4963 ;; Avoid vector decoded forms of the instruction.
4964 (define_peephole2
4965   [(match_scratch:DF 2 "Y2")
4966    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4967         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4968   "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4969   [(set (match_dup 2) (match_dup 1))
4970    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4971   "")
4972
4973 (define_peephole2
4974   [(match_scratch:SF 2 "x")
4975    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4976         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4977   "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4978   [(set (match_dup 2) (match_dup 1))
4979    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4980   "")
4981
4982 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4983   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4984         (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4985   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4986    && TARGET_FISTTP
4987    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4988          && (TARGET_64BIT || <MODE>mode != DImode))
4989         && TARGET_SSE_MATH)
4990    && can_create_pseudo_p ()"
4991   "#"
4992   "&& 1"
4993   [(const_int 0)]
4994 {
4995   if (memory_operand (operands[0], VOIDmode))
4996     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4997   else
4998     {
4999       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
5000       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
5001                                                             operands[1],
5002                                                             operands[2]));
5003     }
5004   DONE;
5005 }
5006   [(set_attr "type" "fisttp")
5007    (set_attr "mode" "<MODE>")])
5008
5009 (define_insn "fix_trunc<mode>_i387_fisttp"
5010   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
5011         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
5012    (clobber (match_scratch:XF 2 "=&1f"))]
5013   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5014    && TARGET_FISTTP
5015    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5016          && (TARGET_64BIT || <MODE>mode != DImode))
5017         && TARGET_SSE_MATH)"
5018   "* return output_fix_trunc (insn, operands, 1);"
5019   [(set_attr "type" "fisttp")
5020    (set_attr "mode" "<MODE>")])
5021
5022 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
5023   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
5024         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
5025    (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
5026    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
5027   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5028    && TARGET_FISTTP
5029    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5030         && (TARGET_64BIT || <MODE>mode != DImode))
5031         && TARGET_SSE_MATH)"
5032   "#"
5033   [(set_attr "type" "fisttp")
5034    (set_attr "mode" "<MODE>")])
5035
5036 (define_split
5037   [(set (match_operand:X87MODEI 0 "register_operand" "")
5038         (fix:X87MODEI (match_operand 1 "register_operand" "")))
5039    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
5040    (clobber (match_scratch 3 ""))]
5041   "reload_completed"
5042   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
5043               (clobber (match_dup 3))])
5044    (set (match_dup 0) (match_dup 2))]
5045   "")
5046
5047 (define_split
5048   [(set (match_operand:X87MODEI 0 "memory_operand" "")
5049         (fix:X87MODEI (match_operand 1 "register_operand" "")))
5050    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
5051    (clobber (match_scratch 3 ""))]
5052   "reload_completed"
5053   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
5054               (clobber (match_dup 3))])]
5055   "")
5056
5057 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
5058 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
5059 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
5060 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
5061 ;; function in i386.c.
5062 (define_insn_and_split "*fix_trunc<mode>_i387_1"
5063   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
5064         (fix:X87MODEI (match_operand 1 "register_operand" "")))
5065    (clobber (reg:CC FLAGS_REG))]
5066   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5067    && !TARGET_FISTTP
5068    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5069          && (TARGET_64BIT || <MODE>mode != DImode))
5070    && can_create_pseudo_p ()"
5071   "#"
5072   "&& 1"
5073   [(const_int 0)]
5074 {
5075   ix86_optimize_mode_switching[I387_TRUNC] = 1;
5076
5077   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
5078   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
5079   if (memory_operand (operands[0], VOIDmode))
5080     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
5081                                          operands[2], operands[3]));
5082   else
5083     {
5084       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
5085       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
5086                                                      operands[2], operands[3],
5087                                                      operands[4]));
5088     }
5089   DONE;
5090 }
5091   [(set_attr "type" "fistp")
5092    (set_attr "i387_cw" "trunc")
5093    (set_attr "mode" "<MODE>")])
5094
5095 (define_insn "fix_truncdi_i387"
5096   [(set (match_operand:DI 0 "memory_operand" "=m")
5097         (fix:DI (match_operand 1 "register_operand" "f")))
5098    (use (match_operand:HI 2 "memory_operand" "m"))
5099    (use (match_operand:HI 3 "memory_operand" "m"))
5100    (clobber (match_scratch:XF 4 "=&1f"))]
5101   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5102    && !TARGET_FISTTP
5103    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5104   "* return output_fix_trunc (insn, operands, 0);"
5105   [(set_attr "type" "fistp")
5106    (set_attr "i387_cw" "trunc")
5107    (set_attr "mode" "DI")])
5108
5109 (define_insn "fix_truncdi_i387_with_temp"
5110   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
5111         (fix:DI (match_operand 1 "register_operand" "f,f")))
5112    (use (match_operand:HI 2 "memory_operand" "m,m"))
5113    (use (match_operand:HI 3 "memory_operand" "m,m"))
5114    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
5115    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
5116   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5117    && !TARGET_FISTTP
5118    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5119   "#"
5120   [(set_attr "type" "fistp")
5121    (set_attr "i387_cw" "trunc")
5122    (set_attr "mode" "DI")])
5123
5124 (define_split
5125   [(set (match_operand:DI 0 "register_operand" "")
5126         (fix:DI (match_operand 1 "register_operand" "")))
5127    (use (match_operand:HI 2 "memory_operand" ""))
5128    (use (match_operand:HI 3 "memory_operand" ""))
5129    (clobber (match_operand:DI 4 "memory_operand" ""))
5130    (clobber (match_scratch 5 ""))]
5131   "reload_completed"
5132   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
5133               (use (match_dup 2))
5134               (use (match_dup 3))
5135               (clobber (match_dup 5))])
5136    (set (match_dup 0) (match_dup 4))]
5137   "")
5138
5139 (define_split
5140   [(set (match_operand:DI 0 "memory_operand" "")
5141         (fix:DI (match_operand 1 "register_operand" "")))
5142    (use (match_operand:HI 2 "memory_operand" ""))
5143    (use (match_operand:HI 3 "memory_operand" ""))
5144    (clobber (match_operand:DI 4 "memory_operand" ""))
5145    (clobber (match_scratch 5 ""))]
5146   "reload_completed"
5147   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
5148               (use (match_dup 2))
5149               (use (match_dup 3))
5150               (clobber (match_dup 5))])]
5151   "")
5152
5153 (define_insn "fix_trunc<mode>_i387"
5154   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
5155         (fix:X87MODEI12 (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   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5159    && !TARGET_FISTTP
5160    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5161   "* return output_fix_trunc (insn, operands, 0);"
5162   [(set_attr "type" "fistp")
5163    (set_attr "i387_cw" "trunc")
5164    (set_attr "mode" "<MODE>")])
5165
5166 (define_insn "fix_trunc<mode>_i387_with_temp"
5167   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
5168         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
5169    (use (match_operand:HI 2 "memory_operand" "m,m"))
5170    (use (match_operand:HI 3 "memory_operand" "m,m"))
5171    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
5172   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5173    && !TARGET_FISTTP
5174    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5175   "#"
5176   [(set_attr "type" "fistp")
5177    (set_attr "i387_cw" "trunc")
5178    (set_attr "mode" "<MODE>")])
5179
5180 (define_split
5181   [(set (match_operand:X87MODEI12 0 "register_operand" "")
5182         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5183    (use (match_operand:HI 2 "memory_operand" ""))
5184    (use (match_operand:HI 3 "memory_operand" ""))
5185    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5186   "reload_completed"
5187   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
5188               (use (match_dup 2))
5189               (use (match_dup 3))])
5190    (set (match_dup 0) (match_dup 4))]
5191   "")
5192
5193 (define_split
5194   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
5195         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5196    (use (match_operand:HI 2 "memory_operand" ""))
5197    (use (match_operand:HI 3 "memory_operand" ""))
5198    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5199   "reload_completed"
5200   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
5201               (use (match_dup 2))
5202               (use (match_dup 3))])]
5203   "")
5204
5205 (define_insn "x86_fnstcw_1"
5206   [(set (match_operand:HI 0 "memory_operand" "=m")
5207         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
5208   "TARGET_80387"
5209   "fnstcw\t%0"
5210   [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5211    (set_attr "mode" "HI")
5212    (set_attr "unit" "i387")])
5213
5214 (define_insn "x86_fldcw_1"
5215   [(set (reg:HI FPCR_REG)
5216         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
5217   "TARGET_80387"
5218   "fldcw\t%0"
5219   [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5220    (set_attr "mode" "HI")
5221    (set_attr "unit" "i387")
5222    (set_attr "athlon_decode" "vector")
5223    (set_attr "amdfam10_decode" "vector")])
5224 \f
5225 ;; Conversion between fixed point and floating point.
5226
5227 ;; Even though we only accept memory inputs, the backend _really_
5228 ;; wants to be able to do this between registers.
5229
5230 (define_expand "floathi<mode>2"
5231   [(set (match_operand:X87MODEF 0 "register_operand" "")
5232         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
5233   "TARGET_80387
5234    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5235        || TARGET_MIX_SSE_I387)"
5236   "")
5237
5238 ;; Pre-reload splitter to add memory clobber to the pattern.
5239 (define_insn_and_split "*floathi<mode>2_1"
5240   [(set (match_operand:X87MODEF 0 "register_operand" "")
5241         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
5242   "TARGET_80387
5243    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5244        || TARGET_MIX_SSE_I387)
5245    && can_create_pseudo_p ()"
5246   "#"
5247   "&& 1"
5248   [(parallel [(set (match_dup 0)
5249               (float:X87MODEF (match_dup 1)))
5250    (clobber (match_dup 2))])]
5251   "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
5252
5253 (define_insn "*floathi<mode>2_i387_with_temp"
5254   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5255         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
5256   (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
5257   "TARGET_80387
5258    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5259        || TARGET_MIX_SSE_I387)"
5260   "#"
5261   [(set_attr "type" "fmov,multi")
5262    (set_attr "mode" "<MODE>")
5263    (set_attr "unit" "*,i387")
5264    (set_attr "fp_int_src" "true")])
5265
5266 (define_insn "*floathi<mode>2_i387"
5267   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5268         (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
5269   "TARGET_80387
5270    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5271        || TARGET_MIX_SSE_I387)"
5272   "fild%Z1\t%1"
5273   [(set_attr "type" "fmov")
5274    (set_attr "mode" "<MODE>")
5275    (set_attr "fp_int_src" "true")])
5276
5277 (define_split
5278   [(set (match_operand:X87MODEF 0 "register_operand" "")
5279         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
5280    (clobber (match_operand:HI 2 "memory_operand" ""))]
5281   "TARGET_80387
5282    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5283        || TARGET_MIX_SSE_I387)
5284    && reload_completed"
5285   [(set (match_dup 2) (match_dup 1))
5286    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5287   "")
5288
5289 (define_split
5290   [(set (match_operand:X87MODEF 0 "register_operand" "")
5291         (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
5292    (clobber (match_operand:HI 2 "memory_operand" ""))]
5293    "TARGET_80387
5294     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5295         || TARGET_MIX_SSE_I387)
5296     && reload_completed"
5297   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5298   "")
5299
5300 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
5301   [(set (match_operand:X87MODEF 0 "register_operand" "")
5302         (float:X87MODEF
5303           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
5304   "TARGET_80387
5305    || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5306        && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
5307 {
5308   if (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5309         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5310       && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode))
5311     {
5312       rtx reg = gen_reg_rtx (XFmode);
5313       rtx insn;
5314
5315       emit_insn (gen_float<SSEMODEI24:mode>xf2 (reg, operands[1]));
5316
5317       if (<X87MODEF:MODE>mode == SFmode)
5318         insn = gen_truncxfsf2 (operands[0], reg);
5319       else if (<X87MODEF:MODE>mode == DFmode)
5320         insn = gen_truncxfdf2 (operands[0], reg);
5321       else
5322         gcc_unreachable ();
5323
5324       emit_insn (insn);
5325       DONE;
5326     }
5327 })
5328
5329 ;; Pre-reload splitter to add memory clobber to the pattern.
5330 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
5331   [(set (match_operand:X87MODEF 0 "register_operand" "")
5332         (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
5333   "((TARGET_80387
5334      && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5335      && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5336            && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5337          || TARGET_MIX_SSE_I387))
5338     || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5339         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
5340         && ((<SSEMODEI24:MODE>mode == SImode
5341              && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
5342              && optimize_function_for_speed_p (cfun)
5343              && flag_trapping_math)
5344             || !(TARGET_INTER_UNIT_CONVERSIONS
5345                  || optimize_function_for_size_p (cfun)))))
5346    && can_create_pseudo_p ()"
5347   "#"
5348   "&& 1"
5349   [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
5350               (clobber (match_dup 2))])]
5351 {
5352   operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
5353
5354   /* Avoid store forwarding (partial memory) stall penalty
5355      by passing DImode value through XMM registers.  */
5356   if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
5357       && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5358       && optimize_function_for_speed_p (cfun))
5359     {
5360       emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
5361                                                             operands[1],
5362                                                             operands[2]));
5363       DONE;
5364     }
5365 })
5366
5367 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
5368   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
5369         (float:MODEF
5370           (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
5371    (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
5372   "TARGET_SSE2 && TARGET_MIX_SSE_I387
5373    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5374   "#"
5375   [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
5376    (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
5377    (set_attr "unit" "*,i387,*,*,*")
5378    (set_attr "athlon_decode" "*,*,double,direct,double")
5379    (set_attr "amdfam10_decode" "*,*,vector,double,double")
5380    (set_attr "fp_int_src" "true")])
5381
5382 (define_insn "*floatsi<mode>2_vector_mixed"
5383   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5384         (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
5385   "TARGET_SSE2 && TARGET_MIX_SSE_I387
5386    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5387   "@
5388    fild%Z1\t%1
5389    #"
5390   [(set_attr "type" "fmov,sseicvt")
5391    (set_attr "mode" "<MODE>,<ssevecmode>")
5392    (set_attr "unit" "i387,*")
5393    (set_attr "athlon_decode" "*,direct")
5394    (set_attr "amdfam10_decode" "*,double")
5395    (set_attr "fp_int_src" "true")])
5396
5397 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
5398   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
5399         (float:MODEF
5400           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
5401   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
5402   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5403    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
5404   "#"
5405   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5406    (set_attr "mode" "<MODEF:MODE>")
5407    (set_attr "unit" "*,i387,*,*")
5408    (set_attr "athlon_decode" "*,*,double,direct")
5409    (set_attr "amdfam10_decode" "*,*,vector,double")
5410    (set_attr "fp_int_src" "true")])
5411
5412 (define_split
5413   [(set (match_operand:MODEF 0 "register_operand" "")
5414         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5415    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5416   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5417    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5418    && TARGET_INTER_UNIT_CONVERSIONS
5419    && reload_completed
5420    && (SSE_REG_P (operands[0])
5421        || (GET_CODE (operands[0]) == SUBREG
5422            && SSE_REG_P (operands[0])))"
5423   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5424   "")
5425
5426 (define_split
5427   [(set (match_operand:MODEF 0 "register_operand" "")
5428         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5429    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5430   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5431    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5432    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5433    && reload_completed
5434    && (SSE_REG_P (operands[0])
5435        || (GET_CODE (operands[0]) == SUBREG
5436            && SSE_REG_P (operands[0])))"
5437   [(set (match_dup 2) (match_dup 1))
5438    (set (match_dup 0) (float:MODEF (match_dup 2)))]
5439   "")
5440
5441 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5442   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5443         (float:MODEF
5444           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
5445   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5446    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5447    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5448   "@
5449    fild%Z1\t%1
5450    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
5451    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5452   [(set_attr "type" "fmov,sseicvt,sseicvt")
5453    (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5454    (set_attr "mode" "<MODEF:MODE>")
5455    (set (attr "prefix_rex")
5456      (if_then_else
5457        (and (eq_attr "prefix" "maybe_vex")
5458             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5459        (const_string "1")
5460        (const_string "*")))
5461    (set_attr "unit" "i387,*,*")
5462    (set_attr "athlon_decode" "*,double,direct")
5463    (set_attr "amdfam10_decode" "*,vector,double")
5464    (set_attr "fp_int_src" "true")])
5465
5466 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5467   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5468         (float:MODEF
5469           (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5470   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5471    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5472    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5473   "@
5474    fild%Z1\t%1
5475    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5476   [(set_attr "type" "fmov,sseicvt")
5477    (set_attr "prefix" "orig,maybe_vex")
5478    (set_attr "mode" "<MODEF:MODE>")
5479    (set (attr "prefix_rex")
5480      (if_then_else
5481        (and (eq_attr "prefix" "maybe_vex")
5482             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5483        (const_string "1")
5484        (const_string "*")))
5485    (set_attr "athlon_decode" "*,direct")
5486    (set_attr "amdfam10_decode" "*,double")
5487    (set_attr "fp_int_src" "true")])
5488
5489 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5490   [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5491         (float:MODEF
5492           (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5493    (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5494   "TARGET_SSE2 && TARGET_SSE_MATH
5495    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5496   "#"
5497   [(set_attr "type" "sseicvt")
5498    (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5499    (set_attr "athlon_decode" "double,direct,double")
5500    (set_attr "amdfam10_decode" "vector,double,double")
5501    (set_attr "fp_int_src" "true")])
5502
5503 (define_insn "*floatsi<mode>2_vector_sse"
5504   [(set (match_operand:MODEF 0 "register_operand" "=x")
5505         (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5506   "TARGET_SSE2 && TARGET_SSE_MATH
5507    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5508   "#"
5509   [(set_attr "type" "sseicvt")
5510    (set_attr "mode" "<MODE>")
5511    (set_attr "athlon_decode" "direct")
5512    (set_attr "amdfam10_decode" "double")
5513    (set_attr "fp_int_src" "true")])
5514
5515 (define_split
5516   [(set (match_operand:MODEF 0 "register_operand" "")
5517         (float:MODEF (match_operand:SI 1 "register_operand" "")))
5518    (clobber (match_operand:SI 2 "memory_operand" ""))]
5519   "TARGET_SSE2 && TARGET_SSE_MATH
5520    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5521    && reload_completed
5522    && (SSE_REG_P (operands[0])
5523        || (GET_CODE (operands[0]) == SUBREG
5524            && SSE_REG_P (operands[0])))"
5525   [(const_int 0)]
5526 {
5527   rtx op1 = operands[1];
5528
5529   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5530                                      <MODE>mode, 0);
5531   if (GET_CODE (op1) == SUBREG)
5532     op1 = SUBREG_REG (op1);
5533
5534   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5535     {
5536       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5537       emit_insn (gen_sse2_loadld (operands[4],
5538                                   CONST0_RTX (V4SImode), operands[1]));
5539     }
5540   /* We can ignore possible trapping value in the
5541      high part of SSE register for non-trapping math. */
5542   else if (SSE_REG_P (op1) && !flag_trapping_math)
5543     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5544   else
5545     {
5546       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5547       emit_move_insn (operands[2], operands[1]);
5548       emit_insn (gen_sse2_loadld (operands[4],
5549                                   CONST0_RTX (V4SImode), operands[2]));
5550     }
5551   emit_insn
5552     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5553   DONE;
5554 })
5555
5556 (define_split
5557   [(set (match_operand:MODEF 0 "register_operand" "")
5558         (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5559    (clobber (match_operand:SI 2 "memory_operand" ""))]
5560   "TARGET_SSE2 && TARGET_SSE_MATH
5561    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5562    && reload_completed
5563    && (SSE_REG_P (operands[0])
5564        || (GET_CODE (operands[0]) == SUBREG
5565            && SSE_REG_P (operands[0])))"
5566   [(const_int 0)]
5567 {
5568   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5569                                      <MODE>mode, 0);
5570   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5571
5572   emit_insn (gen_sse2_loadld (operands[4],
5573                               CONST0_RTX (V4SImode), operands[1]));
5574   emit_insn
5575     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5576   DONE;
5577 })
5578
5579 (define_split
5580   [(set (match_operand:MODEF 0 "register_operand" "")
5581         (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5582   "TARGET_SSE2 && TARGET_SSE_MATH
5583    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5584    && reload_completed
5585    && (SSE_REG_P (operands[0])
5586        || (GET_CODE (operands[0]) == SUBREG
5587            && SSE_REG_P (operands[0])))"
5588   [(const_int 0)]
5589 {
5590   rtx op1 = operands[1];
5591
5592   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5593                                      <MODE>mode, 0);
5594   if (GET_CODE (op1) == SUBREG)
5595     op1 = SUBREG_REG (op1);
5596
5597   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5598     {
5599       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5600       emit_insn (gen_sse2_loadld (operands[4],
5601                                   CONST0_RTX (V4SImode), operands[1]));
5602     }
5603   /* We can ignore possible trapping value in the
5604      high part of SSE register for non-trapping math. */
5605   else if (SSE_REG_P (op1) && !flag_trapping_math)
5606     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5607   else
5608     gcc_unreachable ();
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   "TARGET_SSE2 && TARGET_SSE_MATH
5618    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5619    && reload_completed
5620    && (SSE_REG_P (operands[0])
5621        || (GET_CODE (operands[0]) == SUBREG
5622            && SSE_REG_P (operands[0])))"
5623   [(const_int 0)]
5624 {
5625   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5626                                      <MODE>mode, 0);
5627   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5628
5629   emit_insn (gen_sse2_loadld (operands[4],
5630                               CONST0_RTX (V4SImode), operands[1]));
5631   emit_insn
5632     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5633   DONE;
5634 })
5635
5636 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5637   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5638         (float:MODEF
5639           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5640   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5641   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5642    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5643   "#"
5644   [(set_attr "type" "sseicvt")
5645    (set_attr "mode" "<MODEF:MODE>")
5646    (set_attr "athlon_decode" "double,direct")
5647    (set_attr "amdfam10_decode" "vector,double")
5648    (set_attr "fp_int_src" "true")])
5649
5650 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5651   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5652         (float:MODEF
5653           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5654   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5655    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5656    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5657   "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5658   [(set_attr "type" "sseicvt")
5659    (set_attr "prefix" "maybe_vex")
5660    (set_attr "mode" "<MODEF:MODE>")
5661    (set (attr "prefix_rex")
5662      (if_then_else
5663        (and (eq_attr "prefix" "maybe_vex")
5664             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5665        (const_string "1")
5666        (const_string "*")))
5667    (set_attr "athlon_decode" "double,direct")
5668    (set_attr "amdfam10_decode" "vector,double")
5669    (set_attr "fp_int_src" "true")])
5670
5671 (define_split
5672   [(set (match_operand:MODEF 0 "register_operand" "")
5673         (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5674    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5675   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5676    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5677    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5678    && reload_completed
5679    && (SSE_REG_P (operands[0])
5680        || (GET_CODE (operands[0]) == SUBREG
5681            && SSE_REG_P (operands[0])))"
5682   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5683   "")
5684
5685 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5686   [(set (match_operand:MODEF 0 "register_operand" "=x")
5687         (float:MODEF
5688           (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5689   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5690    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5691    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5692   "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5693   [(set_attr "type" "sseicvt")
5694    (set_attr "prefix" "maybe_vex")
5695    (set_attr "mode" "<MODEF:MODE>")
5696    (set (attr "prefix_rex")
5697      (if_then_else
5698        (and (eq_attr "prefix" "maybe_vex")
5699             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5700        (const_string "1")
5701        (const_string "*")))
5702    (set_attr "athlon_decode" "direct")
5703    (set_attr "amdfam10_decode" "double")
5704    (set_attr "fp_int_src" "true")])
5705
5706 (define_split
5707   [(set (match_operand:MODEF 0 "register_operand" "")
5708         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5709    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5710   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5711    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5712    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5713    && reload_completed
5714    && (SSE_REG_P (operands[0])
5715        || (GET_CODE (operands[0]) == SUBREG
5716            && SSE_REG_P (operands[0])))"
5717   [(set (match_dup 2) (match_dup 1))
5718    (set (match_dup 0) (float:MODEF (match_dup 2)))]
5719   "")
5720
5721 (define_split
5722   [(set (match_operand:MODEF 0 "register_operand" "")
5723         (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5724    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5725   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5726    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5727    && reload_completed
5728    && (SSE_REG_P (operands[0])
5729        || (GET_CODE (operands[0]) == SUBREG
5730            && SSE_REG_P (operands[0])))"
5731   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5732   "")
5733
5734 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5735   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5736         (float:X87MODEF
5737           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5738   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5739   "TARGET_80387
5740    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5741   "@
5742    fild%Z1\t%1
5743    #"
5744   [(set_attr "type" "fmov,multi")
5745    (set_attr "mode" "<X87MODEF:MODE>")
5746    (set_attr "unit" "*,i387")
5747    (set_attr "fp_int_src" "true")])
5748
5749 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5750   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5751         (float:X87MODEF
5752           (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5753   "TARGET_80387
5754    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5755   "fild%Z1\t%1"
5756   [(set_attr "type" "fmov")
5757    (set_attr "mode" "<X87MODEF:MODE>")
5758    (set_attr "fp_int_src" "true")])
5759
5760 (define_split
5761   [(set (match_operand:X87MODEF 0 "register_operand" "")
5762         (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5763    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5764   "TARGET_80387
5765    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5766    && reload_completed
5767    && FP_REG_P (operands[0])"
5768   [(set (match_dup 2) (match_dup 1))
5769    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5770   "")
5771
5772 (define_split
5773   [(set (match_operand:X87MODEF 0 "register_operand" "")
5774         (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5775    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5776   "TARGET_80387
5777    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5778    && reload_completed
5779    && FP_REG_P (operands[0])"
5780   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5781   "")
5782
5783 ;; Avoid store forwarding (partial memory) stall penalty
5784 ;; by passing DImode value through XMM registers.  */
5785
5786 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5787   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5788         (float:X87MODEF
5789           (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5790    (clobber (match_scratch:V4SI 3 "=X,x"))
5791    (clobber (match_scratch:V4SI 4 "=X,x"))
5792    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5793   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5794    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5795    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5796   "#"
5797   [(set_attr "type" "multi")
5798    (set_attr "mode" "<X87MODEF:MODE>")
5799    (set_attr "unit" "i387")
5800    (set_attr "fp_int_src" "true")])
5801
5802 (define_split
5803   [(set (match_operand:X87MODEF 0 "register_operand" "")
5804         (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5805    (clobber (match_scratch:V4SI 3 ""))
5806    (clobber (match_scratch:V4SI 4 ""))
5807    (clobber (match_operand:DI 2 "memory_operand" ""))]
5808   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5809    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5810    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5811    && reload_completed
5812    && FP_REG_P (operands[0])"
5813   [(set (match_dup 2) (match_dup 3))
5814    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5815 {
5816   /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5817      Assemble the 64-bit DImode value in an xmm register.  */
5818   emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5819                               gen_rtx_SUBREG (SImode, operands[1], 0)));
5820   emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5821                               gen_rtx_SUBREG (SImode, operands[1], 4)));
5822   emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5823                                          operands[4]));
5824
5825   operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5826 })
5827
5828 (define_split
5829   [(set (match_operand:X87MODEF 0 "register_operand" "")
5830         (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5831    (clobber (match_scratch:V4SI 3 ""))
5832    (clobber (match_scratch:V4SI 4 ""))
5833    (clobber (match_operand:DI 2 "memory_operand" ""))]
5834   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5835    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5836    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5837    && reload_completed
5838    && FP_REG_P (operands[0])"
5839   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5840   "")
5841
5842 ;; Avoid store forwarding (partial memory) stall penalty by extending
5843 ;; SImode value to DImode through XMM register instead of pushing two
5844 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5845 ;; targets benefit from this optimization. Also note that fild
5846 ;; loads from memory only.
5847
5848 (define_insn "*floatunssi<mode>2_1"
5849   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5850         (unsigned_float:X87MODEF
5851           (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5852    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5853    (clobber (match_scratch:SI 3 "=X,x"))]
5854   "!TARGET_64BIT
5855    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5856    && TARGET_SSE"
5857   "#"
5858   [(set_attr "type" "multi")
5859    (set_attr "mode" "<MODE>")])
5860
5861 (define_split
5862   [(set (match_operand:X87MODEF 0 "register_operand" "")
5863         (unsigned_float:X87MODEF
5864           (match_operand:SI 1 "register_operand" "")))
5865    (clobber (match_operand:DI 2 "memory_operand" ""))
5866    (clobber (match_scratch:SI 3 ""))]
5867   "!TARGET_64BIT
5868    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5869    && TARGET_SSE
5870    && reload_completed"
5871   [(set (match_dup 2) (match_dup 1))
5872    (set (match_dup 0)
5873         (float:X87MODEF (match_dup 2)))]
5874   "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5875
5876 (define_split
5877   [(set (match_operand:X87MODEF 0 "register_operand" "")
5878         (unsigned_float:X87MODEF
5879           (match_operand:SI 1 "memory_operand" "")))
5880    (clobber (match_operand:DI 2 "memory_operand" ""))
5881    (clobber (match_scratch:SI 3 ""))]
5882   "!TARGET_64BIT
5883    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5884    && TARGET_SSE
5885    && reload_completed"
5886   [(set (match_dup 2) (match_dup 3))
5887    (set (match_dup 0)
5888         (float:X87MODEF (match_dup 2)))]
5889 {
5890   emit_move_insn (operands[3], operands[1]);
5891   operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5892 })
5893
5894 (define_expand "floatunssi<mode>2"
5895   [(parallel
5896      [(set (match_operand:X87MODEF 0 "register_operand" "")
5897            (unsigned_float:X87MODEF
5898              (match_operand:SI 1 "nonimmediate_operand" "")))
5899       (clobber (match_dup 2))
5900       (clobber (match_scratch:SI 3 ""))])]
5901   "!TARGET_64BIT
5902    && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5903         && TARGET_SSE)
5904        || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5905 {
5906   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5907     {
5908       ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5909       DONE;
5910     }
5911   else
5912     {
5913       enum ix86_stack_slot slot = (virtuals_instantiated
5914                                    ? SLOT_TEMP
5915                                    : SLOT_VIRTUAL);
5916       operands[2] = assign_386_stack_local (DImode, slot);
5917     }
5918 })
5919
5920 (define_expand "floatunsdisf2"
5921   [(use (match_operand:SF 0 "register_operand" ""))
5922    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5923   "TARGET_64BIT && TARGET_SSE_MATH"
5924   "x86_emit_floatuns (operands); DONE;")
5925
5926 (define_expand "floatunsdidf2"
5927   [(use (match_operand:DF 0 "register_operand" ""))
5928    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5929   "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5930    && TARGET_SSE2 && TARGET_SSE_MATH"
5931 {
5932   if (TARGET_64BIT)
5933     x86_emit_floatuns (operands);
5934   else
5935     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5936   DONE;
5937 })
5938 \f
5939 ;; Add instructions
5940
5941 (define_expand "add<mode>3"
5942   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5943         (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5944                     (match_operand:SDWIM 2 "<general_operand>" "")))]
5945   ""
5946   "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5947
5948 (define_insn_and_split "*add<dwi>3_doubleword"
5949   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5950         (plus:<DWI>
5951           (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5952           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5953    (clobber (reg:CC FLAGS_REG))]
5954   "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5955   "#"
5956   "reload_completed"
5957   [(parallel [(set (reg:CC FLAGS_REG)
5958                    (unspec:CC [(match_dup 1) (match_dup 2)]
5959                               UNSPEC_ADD_CARRY))
5960               (set (match_dup 0)
5961                    (plus:DWIH (match_dup 1) (match_dup 2)))])
5962    (parallel [(set (match_dup 3)
5963                    (plus:DWIH
5964                      (match_dup 4)
5965                      (plus:DWIH
5966                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5967                        (match_dup 5))))
5968               (clobber (reg:CC FLAGS_REG))])]
5969   "split_<dwi> (&operands[0], 3, &operands[0], &operands[3]);")
5970
5971 (define_insn "*add<mode>3_cc"
5972   [(set (reg:CC FLAGS_REG)
5973         (unspec:CC
5974           [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5975            (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5976           UNSPEC_ADD_CARRY))
5977    (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5978         (plus:SWI48 (match_dup 1) (match_dup 2)))]
5979   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5980   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5981   [(set_attr "type" "alu")
5982    (set_attr "mode" "<MODE>")])
5983
5984 (define_insn "addqi3_cc"
5985   [(set (reg:CC FLAGS_REG)
5986         (unspec:CC
5987           [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5988            (match_operand:QI 2 "general_operand" "qn,qm")]
5989           UNSPEC_ADD_CARRY))
5990    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5991         (plus:QI (match_dup 1) (match_dup 2)))]
5992   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5993   "add{b}\t{%2, %0|%0, %2}"
5994   [(set_attr "type" "alu")
5995    (set_attr "mode" "QI")])
5996
5997 (define_insn "*lea_1"
5998   [(set (match_operand:DWIH 0 "register_operand" "=r")
5999         (match_operand:DWIH 1 "no_seg_address_operand" "p"))]
6000   ""
6001   "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
6002   [(set_attr "type" "lea")
6003    (set_attr "mode" "<MODE>")])
6004
6005 (define_insn "*lea_2"
6006   [(set (match_operand:SI 0 "register_operand" "=r")
6007         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
6008   "TARGET_64BIT"
6009   "lea{l}\t{%a1, %0|%0, %a1}"
6010   [(set_attr "type" "lea")
6011    (set_attr "mode" "SI")])
6012
6013 (define_insn "*lea_2_zext"
6014   [(set (match_operand:DI 0 "register_operand" "=r")
6015         (zero_extend:DI
6016           (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
6017   "TARGET_64BIT"
6018   "lea{l}\t{%a1, %k0|%k0, %a1}"
6019   [(set_attr "type" "lea")
6020    (set_attr "mode" "SI")])
6021
6022 (define_insn "*add<mode>_1"
6023   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
6024         (plus:SWI48
6025           (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
6026           (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,0,l<i>")))
6027    (clobber (reg:CC FLAGS_REG))]
6028   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6029 {
6030   switch (get_attr_type (insn))
6031     {
6032     case TYPE_LEA:
6033       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6034       return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
6035
6036     case TYPE_INCDEC:
6037       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6038       if (operands[2] == const1_rtx)
6039         return "inc{<imodesuffix>}\t%0";
6040       else
6041         {
6042           gcc_assert (operands[2] == constm1_rtx);
6043           return "dec{<imodesuffix>}\t%0";
6044         }
6045
6046     default:
6047       /* Use add as much as possible to replace lea for AGU optimization. */
6048       if (which_alternative == 2 && TARGET_OPT_AGU)
6049         return "add{<imodesuffix>}\t{%1, %0|%0, %1}";
6050         
6051       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6052       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6053         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6054
6055       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6056     }
6057 }
6058   [(set (attr "type")
6059      (cond [(and (eq_attr "alternative" "2") 
6060                  (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
6061               (const_string "lea")
6062             (eq_attr "alternative" "3")
6063               (const_string "lea")
6064             ; Current assemblers are broken and do not allow @GOTOFF in
6065             ; ought but a memory context.
6066             (match_operand:SWI48 2 "pic_symbolic_operand" "")
6067               (const_string "lea")
6068             (match_operand:SWI48 2 "incdec_operand" "")
6069               (const_string "incdec")
6070            ]
6071            (const_string "alu")))
6072    (set (attr "length_immediate")
6073       (if_then_else
6074         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6075         (const_string "1")
6076         (const_string "*")))
6077    (set_attr "mode" "<MODE>")])
6078
6079 ;; It may seem that nonimmediate operand is proper one for operand 1.
6080 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6081 ;; we take care in ix86_binary_operator_ok to not allow two memory
6082 ;; operands so proper swapping will be done in reload.  This allow
6083 ;; patterns constructed from addsi_1 to match.
6084
6085 (define_insn "*addsi_1_zext"
6086   [(set (match_operand:DI 0 "register_operand" "=r,r")
6087         (zero_extend:DI
6088           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6089                    (match_operand:SI 2 "general_operand" "g,li"))))
6090    (clobber (reg:CC FLAGS_REG))]
6091   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6092 {
6093   switch (get_attr_type (insn))
6094     {
6095     case TYPE_LEA:
6096       operands[2] = XEXP (SET_SRC (XVECEXP (PATTERN (insn), 0, 0)), 0);
6097       return "lea{l}\t{%a2, %k0|%k0, %a2}";
6098
6099     case TYPE_INCDEC:
6100       if (operands[2] == const1_rtx)
6101         return "inc{l}\t%k0";
6102       else
6103         {
6104           gcc_assert (operands[2] == constm1_rtx);
6105           return "dec{l}\t%k0";
6106         }
6107
6108     default:
6109       if (x86_maybe_negate_const_int (&operands[2], SImode))
6110         return "sub{l}\t{%2, %k0|%k0, %2}";
6111
6112       return "add{l}\t{%2, %k0|%k0, %2}";
6113     }
6114 }
6115   [(set (attr "type")
6116      (cond [(eq_attr "alternative" "1")
6117               (const_string "lea")
6118             ; Current assemblers are broken and do not allow @GOTOFF in
6119             ; ought but a memory context.
6120             (match_operand:SI 2 "pic_symbolic_operand" "")
6121               (const_string "lea")
6122             (match_operand:SI 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" "SI")])
6132
6133 (define_insn "*addhi_1"
6134   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6135         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6136                  (match_operand:HI 2 "general_operand" "rn,rm")))
6137    (clobber (reg:CC FLAGS_REG))]
6138   "TARGET_PARTIAL_REG_STALL
6139    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6140 {
6141   switch (get_attr_type (insn))
6142     {
6143     case TYPE_INCDEC:
6144       if (operands[2] == const1_rtx)
6145         return "inc{w}\t%0";
6146       else
6147         {
6148           gcc_assert (operands[2] == constm1_rtx);
6149           return "dec{w}\t%0";
6150         }
6151
6152     default:
6153       if (x86_maybe_negate_const_int (&operands[2], HImode))
6154         return "sub{w}\t{%2, %0|%0, %2}";
6155
6156       return "add{w}\t{%2, %0|%0, %2}";
6157     }
6158 }
6159   [(set (attr "type")
6160      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6161         (const_string "incdec")
6162         (const_string "alu")))
6163    (set (attr "length_immediate")
6164       (if_then_else
6165         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6166         (const_string "1")
6167         (const_string "*")))
6168    (set_attr "mode" "HI")])
6169
6170 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6171 ;; type optimizations enabled by define-splits.  This is not important
6172 ;; for PII, and in fact harmful because of partial register stalls.
6173
6174 (define_insn "*addhi_1_lea"
6175   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6176         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6177                  (match_operand:HI 2 "general_operand" "rn,rm,ln")))
6178    (clobber (reg:CC FLAGS_REG))]
6179   "!TARGET_PARTIAL_REG_STALL
6180    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6181 {
6182   switch (get_attr_type (insn))
6183     {
6184     case TYPE_LEA:
6185       return "#";
6186     case TYPE_INCDEC:
6187       if (operands[2] == const1_rtx)
6188         return "inc{w}\t%0";
6189       else
6190         {
6191           gcc_assert (operands[2] == constm1_rtx);
6192           return "dec{w}\t%0";
6193         }
6194
6195     default:
6196       if (x86_maybe_negate_const_int (&operands[2], HImode))
6197         return "sub{w}\t{%2, %0|%0, %2}";
6198
6199       return "add{w}\t{%2, %0|%0, %2}";
6200     }
6201 }
6202   [(set (attr "type")
6203      (if_then_else (eq_attr "alternative" "2")
6204         (const_string "lea")
6205         (if_then_else (match_operand:HI 2 "incdec_operand" "")
6206            (const_string "incdec")
6207            (const_string "alu"))))
6208    (set (attr "length_immediate")
6209       (if_then_else
6210         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6211         (const_string "1")
6212         (const_string "*")))
6213    (set_attr "mode" "HI,HI,SI")])
6214
6215 (define_insn "*addqi_1"
6216   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6217         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6218                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6219    (clobber (reg:CC FLAGS_REG))]
6220   "TARGET_PARTIAL_REG_STALL
6221    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6222 {
6223   int widen = (which_alternative == 2);
6224   switch (get_attr_type (insn))
6225     {
6226     case TYPE_INCDEC:
6227       if (operands[2] == const1_rtx)
6228         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6229       else
6230         {
6231           gcc_assert (operands[2] == constm1_rtx);
6232           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6233         }
6234
6235     default:
6236       if (x86_maybe_negate_const_int (&operands[2], QImode))
6237         {
6238           if (widen)
6239             return "sub{l}\t{%2, %k0|%k0, %2}";
6240           else
6241             return "sub{b}\t{%2, %0|%0, %2}";
6242         }
6243       if (widen)
6244         return "add{l}\t{%k2, %k0|%k0, %k2}";
6245       else
6246         return "add{b}\t{%2, %0|%0, %2}";
6247     }
6248 }
6249   [(set (attr "type")
6250      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6251         (const_string "incdec")
6252         (const_string "alu")))
6253    (set (attr "length_immediate")
6254       (if_then_else
6255         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6256         (const_string "1")
6257         (const_string "*")))
6258    (set_attr "mode" "QI,QI,SI")])
6259
6260 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6261 (define_insn "*addqi_1_lea"
6262   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6263         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6264                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6265    (clobber (reg:CC FLAGS_REG))]
6266   "!TARGET_PARTIAL_REG_STALL
6267    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6268 {
6269   int widen = (which_alternative == 2);
6270   switch (get_attr_type (insn))
6271     {
6272     case TYPE_LEA:
6273       return "#";
6274     case TYPE_INCDEC:
6275       if (operands[2] == const1_rtx)
6276         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6277       else
6278         {
6279           gcc_assert (operands[2] == constm1_rtx);
6280           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6281         }
6282
6283     default:
6284       if (x86_maybe_negate_const_int (&operands[2], QImode))
6285         {
6286           if (widen)
6287             return "sub{l}\t{%2, %k0|%k0, %2}";
6288           else
6289             return "sub{b}\t{%2, %0|%0, %2}";
6290         }
6291       if (widen)
6292         return "add{l}\t{%k2, %k0|%k0, %k2}";
6293       else
6294         return "add{b}\t{%2, %0|%0, %2}";
6295     }
6296 }
6297   [(set (attr "type")
6298      (if_then_else (eq_attr "alternative" "3")
6299         (const_string "lea")
6300         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6301            (const_string "incdec")
6302            (const_string "alu"))))
6303    (set (attr "length_immediate")
6304       (if_then_else
6305         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6306         (const_string "1")
6307         (const_string "*")))
6308    (set_attr "mode" "QI,QI,SI,SI")])
6309
6310 (define_insn "*addqi_1_slp"
6311   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6312         (plus:QI (match_dup 0)
6313                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6314    (clobber (reg:CC FLAGS_REG))]
6315   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6316    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6317 {
6318   switch (get_attr_type (insn))
6319     {
6320     case TYPE_INCDEC:
6321       if (operands[1] == const1_rtx)
6322         return "inc{b}\t%0";
6323       else
6324         {
6325           gcc_assert (operands[1] == constm1_rtx);
6326           return "dec{b}\t%0";
6327         }
6328
6329     default:
6330       if (x86_maybe_negate_const_int (&operands[1], QImode))
6331         return "sub{b}\t{%1, %0|%0, %1}";
6332
6333       return "add{b}\t{%1, %0|%0, %1}";
6334     }
6335 }
6336   [(set (attr "type")
6337      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6338         (const_string "incdec")
6339         (const_string "alu1")))
6340    (set (attr "memory")
6341      (if_then_else (match_operand 1 "memory_operand" "")
6342         (const_string "load")
6343         (const_string "none")))
6344    (set_attr "mode" "QI")])
6345
6346 (define_insn "*add<mode>_2"
6347   [(set (reg FLAGS_REG)
6348         (compare
6349           (plus:SWI48
6350             (match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
6351             (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>"))
6352           (const_int 0)))
6353    (set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm")
6354         (plus:SWI48 (match_dup 1) (match_dup 2)))]
6355   "ix86_match_ccmode (insn, CCGOCmode)
6356    && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
6357    /* Current assemblers are broken and do not allow @GOTOFF in
6358       ought but a memory context.  */
6359    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6360 {
6361   switch (get_attr_type (insn))
6362     {
6363     case TYPE_INCDEC:
6364       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6365       if (operands[2] == const1_rtx)
6366         return "inc{<imodesuffix>}\t%0";
6367       else
6368         {
6369           gcc_assert (operands[2] == constm1_rtx);
6370           return "dec{<imodesuffix>}\t%0";
6371         }
6372
6373     default:
6374       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6375       /* ???? In DImode, we ought to handle there the 32bit case too
6376          - do we need new constraint?  */
6377       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6378         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6379
6380       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6381     }
6382 }
6383   [(set (attr "type")
6384      (if_then_else (match_operand:SWI48 2 "incdec_operand" "")
6385         (const_string "incdec")
6386         (const_string "alu")))
6387    (set (attr "length_immediate")
6388       (if_then_else
6389         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6390         (const_string "1")
6391         (const_string "*")))
6392    (set_attr "mode" "<MODE>")])
6393
6394 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6395 (define_insn "*addsi_2_zext"
6396   [(set (reg FLAGS_REG)
6397         (compare
6398           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6399                    (match_operand:SI 2 "general_operand" "g"))
6400           (const_int 0)))
6401    (set (match_operand:DI 0 "register_operand" "=r")
6402         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6403   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6404    && ix86_binary_operator_ok (PLUS, SImode, operands)
6405    /* Current assemblers are broken and do not allow @GOTOFF in
6406       ought but a memory context.  */
6407    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6408 {
6409   switch (get_attr_type (insn))
6410     {
6411     case TYPE_INCDEC:
6412       if (operands[2] == const1_rtx)
6413         return "inc{l}\t%k0";
6414       else
6415         {
6416           gcc_assert (operands[2] == constm1_rtx);
6417           return "dec{l}\t%k0";
6418         }
6419
6420     default:
6421       if (x86_maybe_negate_const_int (&operands[2], SImode))
6422         return "sub{l}\t{%2, %k0|%k0, %2}";
6423
6424       return "add{l}\t{%2, %k0|%k0, %2}";
6425     }
6426 }
6427   [(set (attr "type")
6428      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6429         (const_string "incdec")
6430         (const_string "alu")))
6431    (set (attr "length_immediate")
6432       (if_then_else
6433         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6434         (const_string "1")
6435         (const_string "*")))
6436    (set_attr "mode" "SI")])
6437
6438 (define_insn "*addhi_2"
6439   [(set (reg FLAGS_REG)
6440         (compare
6441           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6442                    (match_operand:HI 2 "general_operand" "rmn,rn"))
6443           (const_int 0)))
6444    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6445         (plus:HI (match_dup 1) (match_dup 2)))]
6446   "ix86_match_ccmode (insn, CCGOCmode)
6447    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6448 {
6449   switch (get_attr_type (insn))
6450     {
6451     case TYPE_INCDEC:
6452       if (operands[2] == const1_rtx)
6453         return "inc{w}\t%0";
6454       else
6455         {
6456           gcc_assert (operands[2] == constm1_rtx);
6457           return "dec{w}\t%0";
6458         }
6459
6460     default:
6461       if (x86_maybe_negate_const_int (&operands[2], HImode))
6462         return "sub{w}\t{%2, %0|%0, %2}";
6463
6464       return "add{w}\t{%2, %0|%0, %2}";
6465     }
6466 }
6467   [(set (attr "type")
6468      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6469         (const_string "incdec")
6470         (const_string "alu")))
6471    (set (attr "length_immediate")
6472       (if_then_else
6473         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6474         (const_string "1")
6475         (const_string "*")))
6476    (set_attr "mode" "HI")])
6477
6478 (define_insn "*addqi_2"
6479   [(set (reg FLAGS_REG)
6480         (compare
6481           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6482                    (match_operand:QI 2 "general_operand" "qmn,qn"))
6483           (const_int 0)))
6484    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6485         (plus:QI (match_dup 1) (match_dup 2)))]
6486   "ix86_match_ccmode (insn, CCGOCmode)
6487    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6488 {
6489   switch (get_attr_type (insn))
6490     {
6491     case TYPE_INCDEC:
6492       if (operands[2] == const1_rtx)
6493         return "inc{b}\t%0";
6494       else
6495         {
6496           gcc_assert (operands[2] == constm1_rtx
6497                       || (CONST_INT_P (operands[2])
6498                           && INTVAL (operands[2]) == 255));
6499           return "dec{b}\t%0";
6500         }
6501
6502     default:
6503       if (x86_maybe_negate_const_int (&operands[2], QImode))
6504         return "sub{b}\t{%2, %0|%0, %2}";
6505
6506       return "add{b}\t{%2, %0|%0, %2}";
6507     }
6508 }
6509   [(set (attr "type")
6510      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6511         (const_string "incdec")
6512         (const_string "alu")))
6513    (set_attr "mode" "QI")])
6514
6515 (define_insn "*add<mode>_3"
6516   [(set (reg FLAGS_REG)
6517         (compare
6518           (neg:SWI48 (match_operand:SWI48 2 "<general_operand>" "<g>"))
6519           (match_operand:SWI48 1 "nonimmediate_operand" "%0")))
6520    (clobber (match_scratch:SWI48 0 "=r"))]
6521   "ix86_match_ccmode (insn, CCZmode)
6522    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6523    /* Current assemblers are broken and do not allow @GOTOFF in
6524       ought but a memory context.  */
6525    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6526 {
6527   switch (get_attr_type (insn))
6528     {
6529     case TYPE_INCDEC:
6530       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6531       if (operands[2] == const1_rtx)
6532         return "inc{<imodesuffix>}\t%0";
6533       else
6534         {
6535           gcc_assert (operands[2] == constm1_rtx);
6536           return "dec{<imodesuffix>}\t%0";
6537         }
6538
6539     default:
6540       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6541       /* ???? In DImode, we ought to handle there the 32bit case too
6542          - do we need new constraint?  */
6543       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6544         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6545
6546       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6547     }
6548 }
6549   [(set (attr "type")
6550      (if_then_else (match_operand:SWI48 2 "incdec_operand" "")
6551         (const_string "incdec")
6552         (const_string "alu")))
6553    (set (attr "length_immediate")
6554       (if_then_else
6555         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6556         (const_string "1")
6557         (const_string "*")))
6558    (set_attr "mode" "<MODE>")])
6559
6560 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6561 (define_insn "*addsi_3_zext"
6562   [(set (reg FLAGS_REG)
6563         (compare
6564           (neg:SI (match_operand:SI 2 "general_operand" "g"))
6565           (match_operand:SI 1 "nonimmediate_operand" "%0")))
6566    (set (match_operand:DI 0 "register_operand" "=r")
6567         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6568   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6569    && ix86_binary_operator_ok (PLUS, SImode, operands)
6570    /* Current assemblers are broken and do not allow @GOTOFF in
6571       ought but a memory context.  */
6572    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6573 {
6574   switch (get_attr_type (insn))
6575     {
6576     case TYPE_INCDEC:
6577       if (operands[2] == const1_rtx)
6578         return "inc{l}\t%k0";
6579       else
6580         {
6581           gcc_assert (operands[2] == constm1_rtx);
6582           return "dec{l}\t%k0";
6583         }
6584
6585     default:
6586       if (x86_maybe_negate_const_int (&operands[2], SImode))
6587         return "sub{l}\t{%2, %k0|%k0, %2}";
6588
6589       return "add{l}\t{%2, %k0|%k0, %2}";
6590     }
6591 }
6592   [(set (attr "type")
6593      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6594         (const_string "incdec")
6595         (const_string "alu")))
6596    (set (attr "length_immediate")
6597       (if_then_else
6598         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6599         (const_string "1")
6600         (const_string "*")))
6601    (set_attr "mode" "SI")])
6602
6603 (define_insn "*addhi_3"
6604   [(set (reg FLAGS_REG)
6605         (compare
6606           (neg:HI (match_operand:HI 2 "general_operand" "rmn"))
6607           (match_operand:HI 1 "nonimmediate_operand" "%0")))
6608    (clobber (match_scratch:HI 0 "=r"))]
6609   "ix86_match_ccmode (insn, CCZmode)
6610    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6611 {
6612   switch (get_attr_type (insn))
6613     {
6614     case TYPE_INCDEC:
6615       if (operands[2] == const1_rtx)
6616         return "inc{w}\t%0";
6617       else
6618         {
6619           gcc_assert (operands[2] == constm1_rtx);
6620           return "dec{w}\t%0";
6621         }
6622
6623     default:
6624       if (x86_maybe_negate_const_int (&operands[2], HImode))
6625         return "sub{w}\t{%2, %0|%0, %2}";
6626
6627       return "add{w}\t{%2, %0|%0, %2}";
6628     }
6629 }
6630   [(set (attr "type")
6631      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6632         (const_string "incdec")
6633         (const_string "alu")))
6634    (set (attr "length_immediate")
6635       (if_then_else
6636         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6637         (const_string "1")
6638         (const_string "*")))
6639    (set_attr "mode" "HI")])
6640
6641 (define_insn "*addqi_3"
6642   [(set (reg FLAGS_REG)
6643         (compare
6644           (neg:QI (match_operand:QI 2 "general_operand" "qmn"))
6645           (match_operand:QI 1 "nonimmediate_operand" "%0")))
6646    (clobber (match_scratch:QI 0 "=q"))]
6647   "ix86_match_ccmode (insn, CCZmode)
6648    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6649 {
6650   switch (get_attr_type (insn))
6651     {
6652     case TYPE_INCDEC:
6653       if (operands[2] == const1_rtx)
6654         return "inc{b}\t%0";
6655       else
6656         {
6657           gcc_assert (operands[2] == constm1_rtx
6658                       || (CONST_INT_P (operands[2])
6659                           && INTVAL (operands[2]) == 255));
6660           return "dec{b}\t%0";
6661         }
6662
6663     default:
6664       if (x86_maybe_negate_const_int (&operands[2], QImode))
6665         return "sub{b}\t{%2, %0|%0, %2}";
6666
6667       return "add{b}\t{%2, %0|%0, %2}";
6668     }
6669 }
6670   [(set (attr "type")
6671      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6672         (const_string "incdec")
6673         (const_string "alu")))
6674    (set_attr "mode" "QI")])
6675
6676 ; For comparisons against 1, -1 and 128, we may generate better code
6677 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6678 ; is matched then.  We can't accept general immediate, because for
6679 ; case of overflows,  the result is messed up.
6680 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6681 ; only for comparisons not depending on it.
6682
6683 (define_insn "*adddi_4"
6684   [(set (reg FLAGS_REG)
6685         (compare
6686           (match_operand:DI 1 "nonimmediate_operand" "0")
6687           (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6688    (clobber (match_scratch:DI 0 "=rm"))]
6689   "TARGET_64BIT
6690    && ix86_match_ccmode (insn, CCGCmode)"
6691 {
6692   switch (get_attr_type (insn))
6693     {
6694     case TYPE_INCDEC:
6695       if (operands[2] == constm1_rtx)
6696         return "inc{q}\t%0";
6697       else
6698         {
6699           gcc_assert (operands[2] == const1_rtx);
6700           return "dec{q}\t%0";
6701         }
6702
6703     default:
6704       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6705       if (x86_maybe_negate_const_int (&operands[2], DImode))
6706         return "add{q}\t{%2, %0|%0, %2}";
6707
6708       return "sub{q}\t{%2, %0|%0, %2}";
6709     }
6710 }
6711   [(set (attr "type")
6712      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6713         (const_string "incdec")
6714         (const_string "alu")))
6715    (set (attr "length_immediate")
6716       (if_then_else
6717         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6718         (const_string "1")
6719         (const_string "*")))
6720    (set_attr "mode" "DI")])
6721
6722 ; For comparisons against 1, -1 and 128, we may generate better code
6723 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6724 ; is matched then.  We can't accept general immediate, because for
6725 ; case of overflows,  the result is messed up.
6726 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6727 ; only for comparisons not depending on it.
6728
6729 (define_insn "*addsi_4"
6730   [(set (reg FLAGS_REG)
6731         (compare
6732           (match_operand:SI 1 "nonimmediate_operand" "0")
6733           (match_operand:SI 2 "const_int_operand" "n")))
6734    (clobber (match_scratch:SI 0 "=rm"))]
6735   "ix86_match_ccmode (insn, CCGCmode)"
6736 {
6737   switch (get_attr_type (insn))
6738     {
6739     case TYPE_INCDEC:
6740       if (operands[2] == constm1_rtx)
6741         return "inc{l}\t%0";
6742       else
6743         {
6744           gcc_assert (operands[2] == const1_rtx);
6745           return "dec{l}\t%0";
6746         }
6747
6748     default:
6749       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6750       if (x86_maybe_negate_const_int (&operands[2], SImode))
6751         return "add{l}\t{%2, %0|%0, %2}";
6752
6753       return "sub{l}\t{%2, %0|%0, %2}";
6754     }
6755 }
6756   [(set (attr "type")
6757      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6758         (const_string "incdec")
6759         (const_string "alu")))
6760    (set (attr "length_immediate")
6761       (if_then_else
6762         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6763         (const_string "1")
6764         (const_string "*")))
6765    (set_attr "mode" "SI")])
6766
6767 ; See comments above addsi_4 for details.
6768
6769 (define_insn "*addhi_4"
6770   [(set (reg FLAGS_REG)
6771         (compare
6772           (match_operand:HI 1 "nonimmediate_operand" "0")
6773           (match_operand:HI 2 "const_int_operand" "n")))
6774    (clobber (match_scratch:HI 0 "=rm"))]
6775   "ix86_match_ccmode (insn, CCGCmode)"
6776 {
6777   switch (get_attr_type (insn))
6778     {
6779     case TYPE_INCDEC:
6780       if (operands[2] == constm1_rtx)
6781         return "inc{w}\t%0";
6782       else
6783         {
6784           gcc_assert (operands[2] == const1_rtx);
6785           return "dec{w}\t%0";
6786         }
6787
6788     default:
6789       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6790       if (x86_maybe_negate_const_int (&operands[2], HImode))
6791         return "add{w}\t{%2, %0|%0, %2}";
6792
6793       return "sub{w}\t{%2, %0|%0, %2}";
6794     }
6795 }
6796   [(set (attr "type")
6797      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6798         (const_string "incdec")
6799         (const_string "alu")))
6800    (set (attr "length_immediate")
6801       (if_then_else
6802         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6803         (const_string "1")
6804         (const_string "*")))
6805    (set_attr "mode" "HI")])
6806
6807 ; See comments above addsi_4 for details.
6808
6809 (define_insn "*addqi_4"
6810   [(set (reg FLAGS_REG)
6811         (compare
6812           (match_operand:QI 1 "nonimmediate_operand" "0")
6813           (match_operand:QI 2 "const_int_operand" "n")))
6814    (clobber (match_scratch:QI 0 "=qm"))]
6815   "ix86_match_ccmode (insn, CCGCmode)"
6816 {
6817   switch (get_attr_type (insn))
6818     {
6819     case TYPE_INCDEC:
6820       if (operands[2] == constm1_rtx
6821           || (CONST_INT_P (operands[2])
6822               && INTVAL (operands[2]) == 255))
6823         return "inc{b}\t%0";
6824       else
6825         {
6826           gcc_assert (operands[2] == const1_rtx);
6827           return "dec{b}\t%0";
6828         }
6829
6830     default:
6831       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6832       if (x86_maybe_negate_const_int (&operands[2], QImode))
6833         return "add{b}\t{%2, %0|%0, %2}";
6834
6835       return "sub{b}\t{%2, %0|%0, %2}";
6836     }
6837 }
6838   [(set (attr "type")
6839      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6840         (const_string "incdec")
6841         (const_string "alu")))
6842    (set_attr "mode" "QI")])
6843
6844 (define_insn "*add<mode>_5"
6845   [(set (reg FLAGS_REG)
6846         (compare
6847           (plus:SWI48
6848             (match_operand:SWI48 1 "nonimmediate_operand" "%0")
6849             (match_operand:SWI48 2 "<general_operand>" "<g>"))
6850           (const_int 0)))
6851    (clobber (match_scratch:SWI48 0 "=r"))]
6852   "ix86_match_ccmode (insn, CCGOCmode)
6853    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6854    /* Current assemblers are broken and do not allow @GOTOFF in
6855       ought but a memory context.  */
6856    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6857 {
6858   switch (get_attr_type (insn))
6859     {
6860     case TYPE_INCDEC:
6861       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6862       if (operands[2] == const1_rtx)
6863         return "inc{<imodesuffix>}\t%0";
6864       else
6865         {
6866           gcc_assert (operands[2] == constm1_rtx);
6867           return "dec{<imodesuffix>}\t%0";
6868         }
6869
6870     default:
6871       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6872       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6873         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6874
6875       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6876     }
6877 }
6878   [(set (attr "type")
6879      (if_then_else (match_operand:SWI48 2 "incdec_operand" "")
6880         (const_string "incdec")
6881         (const_string "alu")))
6882    (set (attr "length_immediate")
6883       (if_then_else
6884         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6885         (const_string "1")
6886         (const_string "*")))
6887    (set_attr "mode" "<MODE>")])
6888
6889 (define_insn "*addhi_5"
6890   [(set (reg FLAGS_REG)
6891         (compare
6892           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6893                    (match_operand:HI 2 "general_operand" "rmn"))
6894           (const_int 0)))
6895    (clobber (match_scratch:HI 0 "=r"))]
6896   "ix86_match_ccmode (insn, CCGOCmode)
6897    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6898 {
6899   switch (get_attr_type (insn))
6900     {
6901     case TYPE_INCDEC:
6902       if (operands[2] == const1_rtx)
6903         return "inc{w}\t%0";
6904       else
6905         {
6906           gcc_assert (operands[2] == constm1_rtx);
6907           return "dec{w}\t%0";
6908         }
6909
6910     default:
6911       if (x86_maybe_negate_const_int (&operands[2], HImode))
6912         return "sub{w}\t{%2, %0|%0, %2}";
6913
6914       return "add{w}\t{%2, %0|%0, %2}";
6915     }
6916 }
6917   [(set (attr "type")
6918      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6919         (const_string "incdec")
6920         (const_string "alu")))
6921    (set (attr "length_immediate")
6922       (if_then_else
6923         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6924         (const_string "1")
6925         (const_string "*")))
6926    (set_attr "mode" "HI")])
6927
6928 (define_insn "*addqi_5"
6929   [(set (reg FLAGS_REG)
6930         (compare
6931           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6932                    (match_operand:QI 2 "general_operand" "qmn"))
6933           (const_int 0)))
6934    (clobber (match_scratch:QI 0 "=q"))]
6935   "ix86_match_ccmode (insn, CCGOCmode)
6936    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6937 {
6938   switch (get_attr_type (insn))
6939     {
6940     case TYPE_INCDEC:
6941       if (operands[2] == const1_rtx)
6942         return "inc{b}\t%0";
6943       else
6944         {
6945           gcc_assert (operands[2] == constm1_rtx
6946                       || (CONST_INT_P (operands[2])
6947                           && INTVAL (operands[2]) == 255));
6948           return "dec{b}\t%0";
6949         }
6950
6951     default:
6952       if (x86_maybe_negate_const_int (&operands[2], QImode))
6953         return "sub{b}\t{%2, %0|%0, %2}";
6954
6955       return "add{b}\t{%2, %0|%0, %2}";
6956     }
6957 }
6958   [(set (attr "type")
6959      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6960         (const_string "incdec")
6961         (const_string "alu")))
6962    (set_attr "mode" "QI")])
6963
6964 (define_insn "*addqi_ext_1_rex64"
6965   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6966                          (const_int 8)
6967                          (const_int 8))
6968         (plus:SI
6969           (zero_extract:SI
6970             (match_operand 1 "ext_register_operand" "0")
6971             (const_int 8)
6972             (const_int 8))
6973           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6974    (clobber (reg:CC FLAGS_REG))]
6975   "TARGET_64BIT"
6976 {
6977   switch (get_attr_type (insn))
6978     {
6979     case TYPE_INCDEC:
6980       if (operands[2] == const1_rtx)
6981         return "inc{b}\t%h0";
6982       else
6983         {
6984           gcc_assert (operands[2] == constm1_rtx
6985                       || (CONST_INT_P (operands[2])
6986                           && INTVAL (operands[2]) == 255));
6987           return "dec{b}\t%h0";
6988         }
6989
6990     default:
6991       return "add{b}\t{%2, %h0|%h0, %2}";
6992     }
6993 }
6994   [(set (attr "type")
6995      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6996         (const_string "incdec")
6997         (const_string "alu")))
6998    (set_attr "modrm" "1")
6999    (set_attr "mode" "QI")])
7000
7001 (define_insn "addqi_ext_1"
7002   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7003                          (const_int 8)
7004                          (const_int 8))
7005         (plus:SI
7006           (zero_extract:SI
7007             (match_operand 1 "ext_register_operand" "0")
7008             (const_int 8)
7009             (const_int 8))
7010           (match_operand:QI 2 "general_operand" "Qmn")))
7011    (clobber (reg:CC FLAGS_REG))]
7012   "!TARGET_64BIT"
7013 {
7014   switch (get_attr_type (insn))
7015     {
7016     case TYPE_INCDEC:
7017       if (operands[2] == const1_rtx)
7018         return "inc{b}\t%h0";
7019       else
7020         {
7021           gcc_assert (operands[2] == constm1_rtx
7022                       || (CONST_INT_P (operands[2])
7023                           && INTVAL (operands[2]) == 255));
7024           return "dec{b}\t%h0";
7025         }
7026
7027     default:
7028       return "add{b}\t{%2, %h0|%h0, %2}";
7029     }
7030 }
7031   [(set (attr "type")
7032      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7033         (const_string "incdec")
7034         (const_string "alu")))
7035    (set_attr "modrm" "1")
7036    (set_attr "mode" "QI")])
7037
7038 (define_insn "*addqi_ext_2"
7039   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7040                          (const_int 8)
7041                          (const_int 8))
7042         (plus:SI
7043           (zero_extract:SI
7044             (match_operand 1 "ext_register_operand" "%0")
7045             (const_int 8)
7046             (const_int 8))
7047           (zero_extract:SI
7048             (match_operand 2 "ext_register_operand" "Q")
7049             (const_int 8)
7050             (const_int 8))))
7051    (clobber (reg:CC FLAGS_REG))]
7052   ""
7053   "add{b}\t{%h2, %h0|%h0, %h2}"
7054   [(set_attr "type" "alu")
7055    (set_attr "mode" "QI")])
7056
7057 ;; The lea patterns for non-Pmodes needs to be matched by
7058 ;; several insns converted to real lea by splitters.
7059
7060 (define_insn_and_split "*lea_general_1"
7061   [(set (match_operand 0 "register_operand" "=r")
7062         (plus (plus (match_operand 1 "index_register_operand" "l")
7063                     (match_operand 2 "register_operand" "r"))
7064               (match_operand 3 "immediate_operand" "i")))]
7065   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
7066     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
7067    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7068    && GET_MODE (operands[0]) == GET_MODE (operands[1])
7069    && GET_MODE (operands[0]) == GET_MODE (operands[2])
7070    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
7071        || GET_MODE (operands[3]) == VOIDmode)"
7072   "#"
7073   "&& reload_completed"
7074   [(const_int 0)]
7075 {
7076   rtx pat;
7077   operands[0] = gen_lowpart (SImode, operands[0]);
7078   operands[1] = gen_lowpart (Pmode, operands[1]);
7079   operands[2] = gen_lowpart (Pmode, operands[2]);
7080   operands[3] = gen_lowpart (Pmode, operands[3]);
7081   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
7082                       operands[3]);
7083   if (Pmode != SImode)
7084     pat = gen_rtx_SUBREG (SImode, pat, 0);
7085   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7086   DONE;
7087 }
7088   [(set_attr "type" "lea")
7089    (set_attr "mode" "SI")])
7090
7091 (define_insn_and_split "*lea_general_1_zext"
7092   [(set (match_operand:DI 0 "register_operand" "=r")
7093         (zero_extend:DI
7094           (plus:SI (plus:SI
7095                      (match_operand:SI 1 "index_register_operand" "l")
7096                      (match_operand:SI 2 "register_operand" "r"))
7097                    (match_operand:SI 3 "immediate_operand" "i"))))]
7098   "TARGET_64BIT"
7099   "#"
7100   "&& reload_completed"
7101   [(set (match_dup 0)
7102         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
7103                                                      (match_dup 2))
7104                                             (match_dup 3)) 0)))]
7105 {
7106   operands[1] = gen_lowpart (Pmode, operands[1]);
7107   operands[2] = gen_lowpart (Pmode, operands[2]);
7108   operands[3] = gen_lowpart (Pmode, operands[3]);
7109 }
7110   [(set_attr "type" "lea")
7111    (set_attr "mode" "SI")])
7112
7113 (define_insn_and_split "*lea_general_2"
7114   [(set (match_operand 0 "register_operand" "=r")
7115         (plus (mult (match_operand 1 "index_register_operand" "l")
7116                     (match_operand 2 "const248_operand" "i"))
7117               (match_operand 3 "nonmemory_operand" "ri")))]
7118   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
7119     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
7120    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7121    && GET_MODE (operands[0]) == GET_MODE (operands[1])
7122    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
7123        || GET_MODE (operands[3]) == VOIDmode)"
7124   "#"
7125   "&& reload_completed"
7126   [(const_int 0)]
7127 {
7128   rtx pat;
7129   operands[0] = gen_lowpart (SImode, operands[0]);
7130   operands[1] = gen_lowpart (Pmode, operands[1]);
7131   operands[3] = gen_lowpart (Pmode, operands[3]);
7132   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
7133                       operands[3]);
7134   if (Pmode != SImode)
7135     pat = gen_rtx_SUBREG (SImode, pat, 0);
7136   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7137   DONE;
7138 }
7139   [(set_attr "type" "lea")
7140    (set_attr "mode" "SI")])
7141
7142 (define_insn_and_split "*lea_general_2_zext"
7143   [(set (match_operand:DI 0 "register_operand" "=r")
7144         (zero_extend:DI
7145           (plus:SI (mult:SI
7146                      (match_operand:SI 1 "index_register_operand" "l")
7147                      (match_operand:SI 2 "const248_operand" "n"))
7148                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
7149   "TARGET_64BIT"
7150   "#"
7151   "&& reload_completed"
7152   [(set (match_dup 0)
7153         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
7154                                                      (match_dup 2))
7155                                             (match_dup 3)) 0)))]
7156 {
7157   operands[1] = gen_lowpart (Pmode, operands[1]);
7158   operands[3] = gen_lowpart (Pmode, operands[3]);
7159 }
7160   [(set_attr "type" "lea")
7161    (set_attr "mode" "SI")])
7162
7163 (define_insn_and_split "*lea_general_3"
7164   [(set (match_operand 0 "register_operand" "=r")
7165         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
7166                           (match_operand 2 "const248_operand" "i"))
7167                     (match_operand 3 "register_operand" "r"))
7168               (match_operand 4 "immediate_operand" "i")))]
7169   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
7170     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
7171    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7172    && GET_MODE (operands[0]) == GET_MODE (operands[1])
7173    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
7174   "#"
7175   "&& reload_completed"
7176   [(const_int 0)]
7177 {
7178   rtx pat;
7179   operands[0] = gen_lowpart (SImode, operands[0]);
7180   operands[1] = gen_lowpart (Pmode, operands[1]);
7181   operands[3] = gen_lowpart (Pmode, operands[3]);
7182   operands[4] = gen_lowpart (Pmode, operands[4]);
7183   pat = gen_rtx_PLUS (Pmode,
7184                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
7185                                                          operands[2]),
7186                                     operands[3]),
7187                       operands[4]);
7188   if (Pmode != SImode)
7189     pat = gen_rtx_SUBREG (SImode, pat, 0);
7190   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7191   DONE;
7192 }
7193   [(set_attr "type" "lea")
7194    (set_attr "mode" "SI")])
7195
7196 (define_insn_and_split "*lea_general_3_zext"
7197   [(set (match_operand:DI 0 "register_operand" "=r")
7198         (zero_extend:DI
7199           (plus:SI (plus:SI
7200                      (mult:SI
7201                        (match_operand:SI 1 "index_register_operand" "l")
7202                        (match_operand:SI 2 "const248_operand" "n"))
7203                      (match_operand:SI 3 "register_operand" "r"))
7204                    (match_operand:SI 4 "immediate_operand" "i"))))]
7205   "TARGET_64BIT"
7206   "#"
7207   "&& reload_completed"
7208   [(set (match_dup 0)
7209         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
7210                                                               (match_dup 2))
7211                                                      (match_dup 3))
7212                                             (match_dup 4)) 0)))]
7213 {
7214   operands[1] = gen_lowpart (Pmode, operands[1]);
7215   operands[3] = gen_lowpart (Pmode, operands[3]);
7216   operands[4] = gen_lowpart (Pmode, operands[4]);
7217 }
7218   [(set_attr "type" "lea")
7219    (set_attr "mode" "SI")])
7220
7221 ;; Convert lea to the lea pattern to avoid flags dependency.
7222 (define_split
7223   [(set (match_operand:DI 0 "register_operand" "")
7224         (plus:DI (match_operand:DI 1 "register_operand" "")
7225                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
7226    (clobber (reg:CC FLAGS_REG))]
7227   "TARGET_64BIT && reload_completed 
7228    && ix86_lea_for_add_ok (PLUS, insn, operands)"
7229   [(set (match_dup 0)
7230         (plus:DI (match_dup 1)
7231                  (match_dup 2)))]
7232   "")
7233
7234 ;; Convert lea to the lea pattern to avoid flags dependency.
7235 (define_split
7236   [(set (match_operand 0 "register_operand" "")
7237         (plus (match_operand 1 "register_operand" "")
7238               (match_operand 2 "nonmemory_operand" "")))
7239    (clobber (reg:CC FLAGS_REG))]
7240   "reload_completed && ix86_lea_for_add_ok (PLUS, insn, operands)" 
7241   [(const_int 0)]
7242 {
7243   rtx pat;
7244   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
7245      may confuse gen_lowpart.  */
7246   if (GET_MODE (operands[0]) != Pmode)
7247     {
7248       operands[1] = gen_lowpart (Pmode, operands[1]);
7249       operands[2] = gen_lowpart (Pmode, operands[2]);
7250     }
7251   operands[0] = gen_lowpart (SImode, operands[0]);
7252   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
7253   if (Pmode != SImode)
7254     pat = gen_rtx_SUBREG (SImode, pat, 0);
7255   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7256   DONE;
7257 })
7258
7259 ;; Convert lea to the lea pattern to avoid flags dependency.
7260 (define_split
7261   [(set (match_operand:DI 0 "register_operand" "")
7262         (zero_extend:DI
7263           (plus:SI (match_operand:SI 1 "register_operand" "")
7264                    (match_operand:SI 2 "nonmemory_operand" ""))))
7265    (clobber (reg:CC FLAGS_REG))]
7266   "TARGET_64BIT && reload_completed
7267    && true_regnum (operands[0]) != true_regnum (operands[1])"
7268   [(set (match_dup 0)
7269         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
7270 {
7271   operands[1] = gen_lowpart (Pmode, operands[1]);
7272   operands[2] = gen_lowpart (Pmode, operands[2]);
7273 })
7274 \f
7275 ;; Subtract instructions
7276
7277 (define_expand "sub<mode>3"
7278   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
7279         (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
7280                      (match_operand:SDWIM 2 "<general_operand>" "")))]
7281   ""
7282   "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
7283
7284 (define_insn_and_split "*sub<dwi>3_doubleword"
7285   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
7286         (minus:<DWI>
7287           (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
7288           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
7289    (clobber (reg:CC FLAGS_REG))]
7290   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7291   "#"
7292   "reload_completed"
7293   [(parallel [(set (reg:CC FLAGS_REG)
7294                    (compare:CC (match_dup 1) (match_dup 2)))
7295               (set (match_dup 0)
7296                    (minus:DWIH (match_dup 1) (match_dup 2)))])
7297    (parallel [(set (match_dup 3)
7298                    (minus:DWIH
7299                      (match_dup 4)
7300                      (plus:DWIH
7301                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7302                        (match_dup 5))))
7303               (clobber (reg:CC FLAGS_REG))])]
7304   "split_<dwi> (&operands[0], 3, &operands[0], &operands[3]);")
7305
7306 (define_insn "*sub<mode>_1"
7307   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7308         (minus:SWI
7309           (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7310           (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
7311    (clobber (reg:CC FLAGS_REG))]
7312   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7313   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7314   [(set_attr "type" "alu")
7315    (set_attr "mode" "<MODE>")])
7316
7317 (define_insn "*subsi_1_zext"
7318   [(set (match_operand:DI 0 "register_operand" "=r")
7319         (zero_extend:DI
7320           (minus:SI (match_operand:SI 1 "register_operand" "0")
7321                     (match_operand:SI 2 "general_operand" "g"))))
7322    (clobber (reg:CC FLAGS_REG))]
7323   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7324   "sub{l}\t{%2, %k0|%k0, %2}"
7325   [(set_attr "type" "alu")
7326    (set_attr "mode" "SI")])
7327
7328 (define_insn "*subqi_1_slp"
7329   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7330         (minus:QI (match_dup 0)
7331                   (match_operand:QI 1 "general_operand" "qn,qm")))
7332    (clobber (reg:CC FLAGS_REG))]
7333   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7334    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7335   "sub{b}\t{%1, %0|%0, %1}"
7336   [(set_attr "type" "alu1")
7337    (set_attr "mode" "QI")])
7338
7339 (define_insn "*sub<mode>_2"
7340   [(set (reg FLAGS_REG)
7341         (compare
7342           (minus:SWI
7343             (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7344             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
7345           (const_int 0)))
7346    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7347         (minus:SWI (match_dup 1) (match_dup 2)))]
7348   "ix86_match_ccmode (insn, CCGOCmode)
7349    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7350   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7351   [(set_attr "type" "alu")
7352    (set_attr "mode" "<MODE>")])
7353
7354 (define_insn "*subsi_2_zext"
7355   [(set (reg FLAGS_REG)
7356         (compare
7357           (minus:SI (match_operand:SI 1 "register_operand" "0")
7358                     (match_operand:SI 2 "general_operand" "g"))
7359           (const_int 0)))
7360    (set (match_operand:DI 0 "register_operand" "=r")
7361         (zero_extend:DI
7362           (minus:SI (match_dup 1)
7363                     (match_dup 2))))]
7364   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7365    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7366   "sub{l}\t{%2, %k0|%k0, %2}"
7367   [(set_attr "type" "alu")
7368    (set_attr "mode" "SI")])
7369
7370 (define_insn "*sub<mode>_3"
7371   [(set (reg FLAGS_REG)
7372         (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7373                  (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
7374    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7375         (minus:SWI (match_dup 1) (match_dup 2)))]
7376   "ix86_match_ccmode (insn, CCmode)
7377    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7378   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7379   [(set_attr "type" "alu")
7380    (set_attr "mode" "<MODE>")])
7381
7382 (define_insn "*subsi_3_zext"
7383   [(set (reg FLAGS_REG)
7384         (compare (match_operand:SI 1 "register_operand" "0")
7385                  (match_operand:SI 2 "general_operand" "g")))
7386    (set (match_operand:DI 0 "register_operand" "=r")
7387         (zero_extend:DI
7388           (minus:SI (match_dup 1)
7389                     (match_dup 2))))]
7390   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7391    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7392   "sub{l}\t{%2, %1|%1, %2}"
7393   [(set_attr "type" "alu")
7394    (set_attr "mode" "SI")])
7395 \f
7396 ;; Add with carry and subtract with borrow
7397
7398 (define_expand "<plusminus_insn><mode>3_carry"
7399   [(parallel
7400     [(set (match_operand:SWI 0 "nonimmediate_operand" "")
7401           (plusminus:SWI
7402             (match_operand:SWI 1 "nonimmediate_operand" "")
7403             (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
7404                        [(match_operand 3 "flags_reg_operand" "")
7405                         (const_int 0)])
7406                       (match_operand:SWI 2 "<general_operand>" ""))))
7407      (clobber (reg:CC FLAGS_REG))])]
7408   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
7409   "")
7410
7411 (define_insn "*<plusminus_insn><mode>3_carry"
7412   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7413         (plusminus:SWI
7414           (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
7415           (plus:SWI
7416             (match_operator 3 "ix86_carry_flag_operator"
7417              [(reg FLAGS_REG) (const_int 0)])
7418             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
7419    (clobber (reg:CC FLAGS_REG))]
7420   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7421   "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
7422   [(set_attr "type" "alu")
7423    (set_attr "use_carry" "1")
7424    (set_attr "pent_pair" "pu")
7425    (set_attr "mode" "<MODE>")])
7426
7427 (define_insn "*addsi3_carry_zext"
7428   [(set (match_operand:DI 0 "register_operand" "=r")
7429         (zero_extend:DI
7430           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7431                    (plus:SI (match_operator 3 "ix86_carry_flag_operator"
7432                              [(reg FLAGS_REG) (const_int 0)])
7433                             (match_operand:SI 2 "general_operand" "g")))))
7434    (clobber (reg:CC FLAGS_REG))]
7435   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
7436   "adc{l}\t{%2, %k0|%k0, %2}"
7437   [(set_attr "type" "alu")
7438    (set_attr "use_carry" "1")
7439    (set_attr "pent_pair" "pu")
7440    (set_attr "mode" "SI")])
7441
7442 (define_insn "*subsi3_carry_zext"
7443   [(set (match_operand:DI 0 "register_operand" "=r")
7444         (zero_extend:DI
7445           (minus:SI (match_operand:SI 1 "register_operand" "0")
7446                     (plus:SI (match_operator 3 "ix86_carry_flag_operator"
7447                               [(reg FLAGS_REG) (const_int 0)])
7448                              (match_operand:SI 2 "general_operand" "g")))))
7449    (clobber (reg:CC FLAGS_REG))]
7450   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7451   "sbb{l}\t{%2, %k0|%k0, %2}"
7452   [(set_attr "type" "alu")
7453    (set_attr "pent_pair" "pu")
7454    (set_attr "mode" "SI")])
7455 \f
7456 ;; Overflow setting add and subtract instructions
7457
7458 (define_insn "*add<mode>3_cconly_overflow"
7459   [(set (reg:CCC FLAGS_REG)
7460         (compare:CCC
7461           (plus:SWI
7462             (match_operand:SWI 1 "nonimmediate_operand" "%0")
7463             (match_operand:SWI 2 "<general_operand>" "<r><i>m"))
7464           (match_dup 1)))
7465    (clobber (match_scratch:SWI 0 "=<r>"))]
7466   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7467   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7468   [(set_attr "type" "alu")
7469    (set_attr "mode" "<MODE>")])
7470
7471 (define_insn "*sub<mode>3_cconly_overflow"
7472   [(set (reg:CCC FLAGS_REG)
7473         (compare:CCC
7474           (minus:SWI
7475             (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
7476             (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
7477           (match_dup 0)))]
7478   ""
7479   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
7480   [(set_attr "type" "icmp")
7481    (set_attr "mode" "<MODE>")])
7482
7483 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
7484   [(set (reg:CCC FLAGS_REG)
7485         (compare:CCC
7486             (plusminus:SWI
7487                 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
7488                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
7489             (match_dup 1)))
7490    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7491         (plusminus:SWI (match_dup 1) (match_dup 2)))]
7492   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
7493   "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
7494   [(set_attr "type" "alu")
7495    (set_attr "mode" "<MODE>")])
7496
7497 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
7498   [(set (reg:CCC FLAGS_REG)
7499         (compare:CCC
7500           (plusminus:SI
7501             (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
7502             (match_operand:SI 2 "general_operand" "g"))
7503           (match_dup 1)))
7504    (set (match_operand:DI 0 "register_operand" "=r")
7505         (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
7506   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
7507   "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
7508   [(set_attr "type" "alu")
7509    (set_attr "mode" "SI")])
7510
7511 ;; The patterns that match these are at the end of this file.
7512
7513 (define_expand "<plusminus_insn>xf3"
7514   [(set (match_operand:XF 0 "register_operand" "")
7515         (plusminus:XF
7516           (match_operand:XF 1 "register_operand" "")
7517           (match_operand:XF 2 "register_operand" "")))]
7518   "TARGET_80387"
7519   "")
7520
7521 (define_expand "<plusminus_insn><mode>3"
7522   [(set (match_operand:MODEF 0 "register_operand" "")
7523         (plusminus:MODEF
7524           (match_operand:MODEF 1 "register_operand" "")
7525           (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7526   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7527     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7528   "")
7529 \f
7530 ;; Multiply instructions
7531
7532 (define_expand "mul<mode>3"
7533   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7534                    (mult:SWIM248
7535                      (match_operand:SWIM248 1 "register_operand" "")
7536                      (match_operand:SWIM248 2 "<general_operand>" "")))
7537               (clobber (reg:CC FLAGS_REG))])]
7538   ""
7539   "")
7540
7541 (define_expand "mulqi3"
7542   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7543                    (mult:QI
7544                      (match_operand:QI 1 "register_operand" "")
7545                      (match_operand:QI 2 "nonimmediate_operand" "")))
7546               (clobber (reg:CC FLAGS_REG))])]
7547   "TARGET_QIMODE_MATH"
7548   "")
7549
7550 ;; On AMDFAM10
7551 ;; IMUL reg32/64, reg32/64, imm8        Direct
7552 ;; IMUL reg32/64, mem32/64, imm8        VectorPath
7553 ;; IMUL reg32/64, reg32/64, imm32       Direct
7554 ;; IMUL reg32/64, mem32/64, imm32       VectorPath
7555 ;; IMUL reg32/64, reg32/64              Direct
7556 ;; IMUL reg32/64, mem32/64              Direct
7557
7558 (define_insn "*mul<mode>3_1"
7559   [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
7560         (mult:SWI48
7561           (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
7562           (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
7563    (clobber (reg:CC FLAGS_REG))]
7564   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7565   "@
7566    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7567    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7568    imul{<imodesuffix>}\t{%2, %0|%0, %2}"
7569   [(set_attr "type" "imul")
7570    (set_attr "prefix_0f" "0,0,1")
7571    (set (attr "athlon_decode")
7572         (cond [(eq_attr "cpu" "athlon")
7573                   (const_string "vector")
7574                (eq_attr "alternative" "1")
7575                   (const_string "vector")
7576                (and (eq_attr "alternative" "2")
7577                     (match_operand 1 "memory_operand" ""))
7578                   (const_string "vector")]
7579               (const_string "direct")))
7580    (set (attr "amdfam10_decode")
7581         (cond [(and (eq_attr "alternative" "0,1")
7582                     (match_operand 1 "memory_operand" ""))
7583                   (const_string "vector")]
7584               (const_string "direct")))
7585    (set_attr "mode" "<MODE>")])
7586
7587 (define_insn "*mulsi3_1_zext"
7588   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7589         (zero_extend:DI
7590           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7591                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
7592    (clobber (reg:CC FLAGS_REG))]
7593   "TARGET_64BIT
7594    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7595   "@
7596    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7597    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7598    imul{l}\t{%2, %k0|%k0, %2}"
7599   [(set_attr "type" "imul")
7600    (set_attr "prefix_0f" "0,0,1")
7601    (set (attr "athlon_decode")
7602         (cond [(eq_attr "cpu" "athlon")
7603                   (const_string "vector")
7604                (eq_attr "alternative" "1")
7605                   (const_string "vector")
7606                (and (eq_attr "alternative" "2")
7607                     (match_operand 1 "memory_operand" ""))
7608                   (const_string "vector")]
7609               (const_string "direct")))
7610    (set (attr "amdfam10_decode")
7611         (cond [(and (eq_attr "alternative" "0,1")
7612                     (match_operand 1 "memory_operand" ""))
7613                   (const_string "vector")]
7614               (const_string "direct")))
7615    (set_attr "mode" "SI")])
7616
7617 ;; On AMDFAM10
7618 ;; IMUL reg16, reg16, imm8      VectorPath
7619 ;; IMUL reg16, mem16, imm8      VectorPath
7620 ;; IMUL reg16, reg16, imm16     VectorPath
7621 ;; IMUL reg16, mem16, imm16     VectorPath
7622 ;; IMUL reg16, reg16            Direct
7623 ;; IMUL reg16, mem16            Direct
7624
7625 (define_insn "*mulhi3_1"
7626   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7627         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7628                  (match_operand:HI 2 "general_operand" "K,n,mr")))
7629    (clobber (reg:CC FLAGS_REG))]
7630   "TARGET_HIMODE_MATH
7631    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7632   "@
7633    imul{w}\t{%2, %1, %0|%0, %1, %2}
7634    imul{w}\t{%2, %1, %0|%0, %1, %2}
7635    imul{w}\t{%2, %0|%0, %2}"
7636   [(set_attr "type" "imul")
7637    (set_attr "prefix_0f" "0,0,1")
7638    (set (attr "athlon_decode")
7639         (cond [(eq_attr "cpu" "athlon")
7640                   (const_string "vector")
7641                (eq_attr "alternative" "1,2")
7642                   (const_string "vector")]
7643               (const_string "direct")))
7644    (set (attr "amdfam10_decode")
7645         (cond [(eq_attr "alternative" "0,1")
7646                   (const_string "vector")]
7647               (const_string "direct")))
7648    (set_attr "mode" "HI")])
7649
7650 ;;On AMDFAM10
7651 ;; MUL reg8     Direct
7652 ;; MUL mem8     Direct
7653
7654 (define_insn "*mulqi3_1"
7655   [(set (match_operand:QI 0 "register_operand" "=a")
7656         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7657                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7658    (clobber (reg:CC FLAGS_REG))]
7659   "TARGET_QIMODE_MATH
7660    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7661   "mul{b}\t%2"
7662   [(set_attr "type" "imul")
7663    (set_attr "length_immediate" "0")
7664    (set (attr "athlon_decode")
7665      (if_then_else (eq_attr "cpu" "athlon")
7666         (const_string "vector")
7667         (const_string "direct")))
7668    (set_attr "amdfam10_decode" "direct")
7669    (set_attr "mode" "QI")])
7670
7671 (define_expand "<u>mul<mode><dwi>3"
7672   [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
7673                    (mult:<DWI>
7674                      (any_extend:<DWI>
7675                        (match_operand:DWIH 1 "nonimmediate_operand" ""))
7676                      (any_extend:<DWI>
7677                        (match_operand:DWIH 2 "register_operand" ""))))
7678               (clobber (reg:CC FLAGS_REG))])]
7679   ""
7680   "")
7681
7682 (define_expand "<u>mulqihi3"
7683   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7684                    (mult:HI
7685                      (any_extend:HI
7686                        (match_operand:QI 1 "nonimmediate_operand" ""))
7687                      (any_extend:HI
7688                        (match_operand:QI 2 "register_operand" ""))))
7689               (clobber (reg:CC FLAGS_REG))])]
7690   "TARGET_QIMODE_MATH"
7691   "")
7692
7693 (define_insn "*<u>mul<mode><dwi>3_1"
7694   [(set (match_operand:<DWI> 0 "register_operand" "=A")
7695         (mult:<DWI>
7696           (any_extend:<DWI>
7697             (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
7698           (any_extend:<DWI>
7699             (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7700    (clobber (reg:CC FLAGS_REG))]
7701   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7702   "<sgnprefix>mul{<imodesuffix>}\t%2"
7703   [(set_attr "type" "imul")
7704    (set_attr "length_immediate" "0")
7705    (set (attr "athlon_decode")
7706      (if_then_else (eq_attr "cpu" "athlon")
7707         (const_string "vector")
7708         (const_string "double")))
7709    (set_attr "amdfam10_decode" "double")
7710    (set_attr "mode" "<MODE>")])
7711
7712 (define_insn "*<u>mulqihi3_1"
7713   [(set (match_operand:HI 0 "register_operand" "=a")
7714         (mult:HI
7715           (any_extend:HI
7716             (match_operand:QI 1 "nonimmediate_operand" "%0"))
7717           (any_extend:HI
7718             (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7719    (clobber (reg:CC FLAGS_REG))]
7720   "TARGET_QIMODE_MATH
7721    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7722   "<sgnprefix>mul{b}\t%2"
7723   [(set_attr "type" "imul")
7724    (set_attr "length_immediate" "0")
7725    (set (attr "athlon_decode")
7726      (if_then_else (eq_attr "cpu" "athlon")
7727         (const_string "vector")
7728         (const_string "direct")))
7729    (set_attr "amdfam10_decode" "direct")
7730    (set_attr "mode" "QI")])
7731
7732 (define_expand "<s>mul<mode>3_highpart"
7733   [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
7734                    (truncate:SWI48
7735                      (lshiftrt:<DWI>
7736                        (mult:<DWI>
7737                          (any_extend:<DWI>
7738                            (match_operand:SWI48 1 "nonimmediate_operand" ""))
7739                          (any_extend:<DWI>
7740                            (match_operand:SWI48 2 "register_operand" "")))
7741                        (match_dup 4))))
7742               (clobber (match_scratch:SWI48 3 ""))
7743               (clobber (reg:CC FLAGS_REG))])]
7744   ""
7745   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7746
7747 (define_insn "*<s>muldi3_highpart_1"
7748   [(set (match_operand:DI 0 "register_operand" "=d")
7749         (truncate:DI
7750           (lshiftrt:TI
7751             (mult:TI
7752               (any_extend:TI
7753                 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7754               (any_extend:TI
7755                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7756             (const_int 64))))
7757    (clobber (match_scratch:DI 3 "=1"))
7758    (clobber (reg:CC FLAGS_REG))]
7759   "TARGET_64BIT
7760    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7761   "<sgnprefix>mul{q}\t%2"
7762   [(set_attr "type" "imul")
7763    (set_attr "length_immediate" "0")
7764    (set (attr "athlon_decode")
7765      (if_then_else (eq_attr "cpu" "athlon")
7766         (const_string "vector")
7767         (const_string "double")))
7768    (set_attr "amdfam10_decode" "double")
7769    (set_attr "mode" "DI")])
7770
7771 (define_insn "*<s>mulsi3_highpart_1"
7772   [(set (match_operand:SI 0 "register_operand" "=d")
7773         (truncate:SI
7774           (lshiftrt:DI
7775             (mult:DI
7776               (any_extend:DI
7777                 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7778               (any_extend:DI
7779                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7780             (const_int 32))))
7781    (clobber (match_scratch:SI 3 "=1"))
7782    (clobber (reg:CC FLAGS_REG))]
7783   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7784   "<sgnprefix>mul{l}\t%2"
7785   [(set_attr "type" "imul")
7786    (set_attr "length_immediate" "0")
7787    (set (attr "athlon_decode")
7788      (if_then_else (eq_attr "cpu" "athlon")
7789         (const_string "vector")
7790         (const_string "double")))
7791    (set_attr "amdfam10_decode" "double")
7792    (set_attr "mode" "SI")])
7793
7794 (define_insn "*<s>mulsi3_highpart_zext"
7795   [(set (match_operand:DI 0 "register_operand" "=d")
7796         (zero_extend:DI (truncate:SI
7797           (lshiftrt:DI
7798             (mult:DI (any_extend:DI
7799                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7800                      (any_extend:DI
7801                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7802             (const_int 32)))))
7803    (clobber (match_scratch:SI 3 "=1"))
7804    (clobber (reg:CC FLAGS_REG))]
7805   "TARGET_64BIT
7806    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7807   "<sgnprefix>mul{l}\t%2"
7808   [(set_attr "type" "imul")
7809    (set_attr "length_immediate" "0")
7810    (set (attr "athlon_decode")
7811      (if_then_else (eq_attr "cpu" "athlon")
7812         (const_string "vector")
7813         (const_string "double")))
7814    (set_attr "amdfam10_decode" "double")
7815    (set_attr "mode" "SI")])
7816
7817 ;; The patterns that match these are at the end of this file.
7818
7819 (define_expand "mulxf3"
7820   [(set (match_operand:XF 0 "register_operand" "")
7821         (mult:XF (match_operand:XF 1 "register_operand" "")
7822                  (match_operand:XF 2 "register_operand" "")))]
7823   "TARGET_80387"
7824   "")
7825
7826 (define_expand "mul<mode>3"
7827   [(set (match_operand:MODEF 0 "register_operand" "")
7828         (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
7829                     (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7830   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7831     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7832   "")
7833 \f
7834 ;; Divide instructions
7835
7836 (define_insn "<u>divqi3"
7837   [(set (match_operand:QI 0 "register_operand" "=a")
7838         (any_div:QI
7839           (match_operand:HI 1 "register_operand" "0")
7840           (match_operand:QI 2 "nonimmediate_operand" "qm")))
7841    (clobber (reg:CC FLAGS_REG))]
7842   "TARGET_QIMODE_MATH"
7843   "<sgnprefix>div{b}\t%2"
7844   [(set_attr "type" "idiv")
7845    (set_attr "mode" "QI")])
7846
7847 ;; The patterns that match these are at the end of this file.
7848
7849 (define_expand "divxf3"
7850   [(set (match_operand:XF 0 "register_operand" "")
7851         (div:XF (match_operand:XF 1 "register_operand" "")
7852                 (match_operand:XF 2 "register_operand" "")))]
7853   "TARGET_80387"
7854   "")
7855
7856 (define_expand "divdf3"
7857   [(set (match_operand:DF 0 "register_operand" "")
7858         (div:DF (match_operand:DF 1 "register_operand" "")
7859                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7860    "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7861     || (TARGET_SSE2 && TARGET_SSE_MATH)"
7862    "")
7863
7864 (define_expand "divsf3"
7865   [(set (match_operand:SF 0 "register_operand" "")
7866         (div:SF (match_operand:SF 1 "register_operand" "")
7867                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7868   "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7869     || TARGET_SSE_MATH"
7870 {
7871   if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
7872       && flag_finite_math_only && !flag_trapping_math
7873       && flag_unsafe_math_optimizations)
7874     {
7875       ix86_emit_swdivsf (operands[0], operands[1],
7876                          operands[2], SFmode);
7877       DONE;
7878     }
7879 })
7880 \f
7881 ;; Divmod instructions.
7882
7883 (define_expand "divmod<mode>4"
7884   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7885                    (div:SWIM248
7886                      (match_operand:SWIM248 1 "register_operand" "")
7887                      (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7888               (set (match_operand:SWIM248 3 "register_operand" "")
7889                    (mod:SWIM248 (match_dup 1) (match_dup 2)))
7890               (clobber (reg:CC FLAGS_REG))])]
7891   ""
7892   "")
7893
7894 (define_insn_and_split "*divmod<mode>4"
7895   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7896         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7897                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7898    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7899         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7900    (clobber (reg:CC FLAGS_REG))]
7901   ""
7902   "#"
7903   "&& reload_completed"
7904   [(parallel [(set (match_dup 1)
7905                    (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7906               (clobber (reg:CC FLAGS_REG))])
7907    (parallel [(set (match_dup 0)
7908                    (div:SWIM248 (match_dup 2) (match_dup 3)))
7909               (set (match_dup 1)
7910                    (mod:SWIM248 (match_dup 2) (match_dup 3)))
7911               (use (match_dup 1))
7912               (clobber (reg:CC FLAGS_REG))])]
7913 {
7914   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - 1);
7915
7916   if (<MODE>mode != HImode
7917       && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7918     operands[4] = operands[2];
7919   else
7920     {
7921       /* Avoid use of cltd in favor of a mov+shift.  */
7922       emit_move_insn (operands[1], operands[2]);
7923       operands[4] = operands[1];
7924     }
7925 }
7926   [(set_attr "type" "multi")
7927    (set_attr "mode" "<MODE>")])
7928
7929 (define_insn "*divmod<mode>4_noext"
7930   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7931         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7932                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7933    (set (match_operand:SWIM248 1 "register_operand" "=d")
7934         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7935    (use (match_operand:SWIM248 4 "register_operand" "1"))
7936    (clobber (reg:CC FLAGS_REG))]
7937   ""
7938   "idiv{<imodesuffix>}\t%3"
7939   [(set_attr "type" "idiv")
7940    (set_attr "mode" "<MODE>")])
7941
7942 (define_expand "udivmod<mode>4"
7943   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7944                    (udiv:SWIM248
7945                      (match_operand:SWIM248 1 "register_operand" "")
7946                      (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7947               (set (match_operand:SWIM248 3 "register_operand" "")
7948                    (umod:SWIM248 (match_dup 1) (match_dup 2)))
7949               (clobber (reg:CC FLAGS_REG))])]
7950   ""
7951   "")
7952
7953 (define_insn_and_split "*udivmod<mode>4"
7954   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7955         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7956                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7957    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7958         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7959    (clobber (reg:CC FLAGS_REG))]
7960   ""
7961   "#"
7962   "&& reload_completed"
7963   [(set (match_dup 1) (const_int 0))
7964    (parallel [(set (match_dup 0)
7965                    (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7966               (set (match_dup 1)
7967                    (umod:SWIM248 (match_dup 2) (match_dup 3)))
7968               (use (match_dup 1))
7969               (clobber (reg:CC FLAGS_REG))])]
7970   ""
7971   [(set_attr "type" "multi")
7972    (set_attr "mode" "<MODE>")])
7973
7974 (define_insn "*udivmod<mode>4_noext"
7975   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7976         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7977                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7978    (set (match_operand:SWIM248 1 "register_operand" "=d")
7979         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7980    (use (match_operand:SWIM248 4 "register_operand" "1"))
7981    (clobber (reg:CC FLAGS_REG))]
7982   ""
7983   "div{<imodesuffix>}\t%3"
7984   [(set_attr "type" "idiv")
7985    (set_attr "mode" "<MODE>")])
7986
7987 ;; We cannot use div/idiv for double division, because it causes
7988 ;; "division by zero" on the overflow and that's not what we expect
7989 ;; from truncate.  Because true (non truncating) double division is
7990 ;; never generated, we can't create this insn anyway.
7991 ;
7992 ;(define_insn ""
7993 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7994 ;       (truncate:SI
7995 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7996 ;                  (zero_extend:DI
7997 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7998 ;   (set (match_operand:SI 3 "register_operand" "=d")
7999 ;       (truncate:SI
8000 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8001 ;   (clobber (reg:CC FLAGS_REG))]
8002 ;  ""
8003 ;  "div{l}\t{%2, %0|%0, %2}"
8004 ;  [(set_attr "type" "idiv")])
8005 \f
8006 ;;- Logical AND instructions
8007
8008 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8009 ;; Note that this excludes ah.
8010
8011 (define_expand "testsi_ccno_1"
8012   [(set (reg:CCNO FLAGS_REG)
8013         (compare:CCNO
8014           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8015                   (match_operand:SI 1 "nonmemory_operand" ""))
8016           (const_int 0)))]
8017   ""
8018   "")
8019
8020 (define_expand "testqi_ccz_1"
8021   [(set (reg:CCZ FLAGS_REG)
8022         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8023                              (match_operand:QI 1 "nonmemory_operand" ""))
8024                  (const_int 0)))]
8025   ""
8026   "")
8027
8028 (define_insn "*testdi_1"
8029   [(set (reg FLAGS_REG)
8030         (compare
8031          (and:DI
8032           (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8033           (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8034          (const_int 0)))]
8035   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8036    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8037   "@
8038    test{l}\t{%k1, %k0|%k0, %k1}
8039    test{l}\t{%k1, %k0|%k0, %k1}
8040    test{q}\t{%1, %0|%0, %1}
8041    test{q}\t{%1, %0|%0, %1}
8042    test{q}\t{%1, %0|%0, %1}"
8043   [(set_attr "type" "test")
8044    (set_attr "modrm" "0,1,0,1,1")
8045    (set_attr "mode" "SI,SI,DI,DI,DI")])
8046
8047 (define_insn "*testqi_1_maybe_si"
8048   [(set (reg FLAGS_REG)
8049         (compare
8050           (and:QI
8051             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8052             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8053           (const_int 0)))]
8054    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8055     && ix86_match_ccmode (insn,
8056                          CONST_INT_P (operands[1])
8057                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8058 {
8059   if (which_alternative == 3)
8060     {
8061       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8062         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8063       return "test{l}\t{%1, %k0|%k0, %1}";
8064     }
8065   return "test{b}\t{%1, %0|%0, %1}";
8066 }
8067   [(set_attr "type" "test")
8068    (set_attr "modrm" "0,1,1,1")
8069    (set_attr "mode" "QI,QI,QI,SI")
8070    (set_attr "pent_pair" "uv,np,uv,np")])
8071
8072 (define_insn "*test<mode>_1"
8073   [(set (reg FLAGS_REG)
8074         (compare
8075          (and:SWI124
8076           (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
8077           (match_operand:SWI124 1 "general_operand" "<i>,<i>,<r><i>"))
8078          (const_int 0)))]
8079   "ix86_match_ccmode (insn, CCNOmode)
8080    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8081   "test{<imodesuffix>}\t{%1, %0|%0, %1}"
8082   [(set_attr "type" "test")
8083    (set_attr "modrm" "0,1,1")
8084    (set_attr "mode" "<MODE>")
8085    (set_attr "pent_pair" "uv,np,uv")])
8086
8087 (define_expand "testqi_ext_ccno_0"
8088   [(set (reg:CCNO FLAGS_REG)
8089         (compare:CCNO
8090           (and:SI
8091             (zero_extract:SI
8092               (match_operand 0 "ext_register_operand" "")
8093               (const_int 8)
8094               (const_int 8))
8095             (match_operand 1 "const_int_operand" ""))
8096           (const_int 0)))]
8097   ""
8098   "")
8099
8100 (define_insn "*testqi_ext_0"
8101   [(set (reg FLAGS_REG)
8102         (compare
8103           (and:SI
8104             (zero_extract:SI
8105               (match_operand 0 "ext_register_operand" "Q")
8106               (const_int 8)
8107               (const_int 8))
8108             (match_operand 1 "const_int_operand" "n"))
8109           (const_int 0)))]
8110   "ix86_match_ccmode (insn, CCNOmode)"
8111   "test{b}\t{%1, %h0|%h0, %1}"
8112   [(set_attr "type" "test")
8113    (set_attr "mode" "QI")
8114    (set_attr "length_immediate" "1")
8115    (set_attr "modrm" "1")
8116    (set_attr "pent_pair" "np")])
8117
8118 (define_insn "*testqi_ext_1_rex64"
8119   [(set (reg FLAGS_REG)
8120         (compare
8121           (and:SI
8122             (zero_extract:SI
8123               (match_operand 0 "ext_register_operand" "Q")
8124               (const_int 8)
8125               (const_int 8))
8126             (zero_extend:SI
8127               (match_operand:QI 1 "register_operand" "Q")))
8128           (const_int 0)))]
8129   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8130   "test{b}\t{%1, %h0|%h0, %1}"
8131   [(set_attr "type" "test")
8132    (set_attr "mode" "QI")])
8133
8134 (define_insn "*testqi_ext_1"
8135   [(set (reg FLAGS_REG)
8136         (compare
8137           (and:SI
8138             (zero_extract:SI
8139               (match_operand 0 "ext_register_operand" "Q")
8140               (const_int 8)
8141               (const_int 8))
8142             (zero_extend:SI
8143               (match_operand:QI 1 "general_operand" "Qm")))
8144           (const_int 0)))]
8145   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8146   "test{b}\t{%1, %h0|%h0, %1}"
8147   [(set_attr "type" "test")
8148    (set_attr "mode" "QI")])
8149
8150 (define_insn "*testqi_ext_2"
8151   [(set (reg FLAGS_REG)
8152         (compare
8153           (and:SI
8154             (zero_extract:SI
8155               (match_operand 0 "ext_register_operand" "Q")
8156               (const_int 8)
8157               (const_int 8))
8158             (zero_extract:SI
8159               (match_operand 1 "ext_register_operand" "Q")
8160               (const_int 8)
8161               (const_int 8)))
8162           (const_int 0)))]
8163   "ix86_match_ccmode (insn, CCNOmode)"
8164   "test{b}\t{%h1, %h0|%h0, %h1}"
8165   [(set_attr "type" "test")
8166    (set_attr "mode" "QI")])
8167
8168 (define_insn "*testqi_ext_3_rex64"
8169   [(set (reg FLAGS_REG)
8170         (compare (zero_extract:DI
8171                    (match_operand 0 "nonimmediate_operand" "rm")
8172                    (match_operand:DI 1 "const_int_operand" "")
8173                    (match_operand:DI 2 "const_int_operand" ""))
8174                  (const_int 0)))]
8175   "TARGET_64BIT
8176    && ix86_match_ccmode (insn, CCNOmode)
8177    && INTVAL (operands[1]) > 0
8178    && INTVAL (operands[2]) >= 0
8179    /* Ensure that resulting mask is zero or sign extended operand.  */
8180    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8181        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8182            && INTVAL (operands[1]) > 32))
8183    && (GET_MODE (operands[0]) == SImode
8184        || GET_MODE (operands[0]) == DImode
8185        || GET_MODE (operands[0]) == HImode
8186        || GET_MODE (operands[0]) == QImode)"
8187   "#")
8188
8189 ;; Combine likes to form bit extractions for some tests.  Humor it.
8190 (define_insn "*testqi_ext_3"
8191   [(set (reg FLAGS_REG)
8192         (compare (zero_extract:SI
8193                    (match_operand 0 "nonimmediate_operand" "rm")
8194                    (match_operand:SI 1 "const_int_operand" "")
8195                    (match_operand:SI 2 "const_int_operand" ""))
8196                  (const_int 0)))]
8197   "ix86_match_ccmode (insn, CCNOmode)
8198    && INTVAL (operands[1]) > 0
8199    && INTVAL (operands[2]) >= 0
8200    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8201    && (GET_MODE (operands[0]) == SImode
8202        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8203        || GET_MODE (operands[0]) == HImode
8204        || GET_MODE (operands[0]) == QImode)"
8205   "#")
8206
8207 (define_split
8208   [(set (match_operand 0 "flags_reg_operand" "")
8209         (match_operator 1 "compare_operator"
8210           [(zero_extract
8211              (match_operand 2 "nonimmediate_operand" "")
8212              (match_operand 3 "const_int_operand" "")
8213              (match_operand 4 "const_int_operand" ""))
8214            (const_int 0)]))]
8215   "ix86_match_ccmode (insn, CCNOmode)"
8216   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8217 {
8218   rtx val = operands[2];
8219   HOST_WIDE_INT len = INTVAL (operands[3]);
8220   HOST_WIDE_INT pos = INTVAL (operands[4]);
8221   HOST_WIDE_INT mask;
8222   enum machine_mode mode, submode;
8223
8224   mode = GET_MODE (val);
8225   if (MEM_P (val))
8226     {
8227       /* ??? Combine likes to put non-volatile mem extractions in QImode
8228          no matter the size of the test.  So find a mode that works.  */
8229       if (! MEM_VOLATILE_P (val))
8230         {
8231           mode = smallest_mode_for_size (pos + len, MODE_INT);
8232           val = adjust_address (val, mode, 0);
8233         }
8234     }
8235   else if (GET_CODE (val) == SUBREG
8236            && (submode = GET_MODE (SUBREG_REG (val)),
8237                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8238            && pos + len <= GET_MODE_BITSIZE (submode)
8239            && GET_MODE_CLASS (submode) == MODE_INT)
8240     {
8241       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
8242       mode = submode;
8243       val = SUBREG_REG (val);
8244     }
8245   else if (mode == HImode && pos + len <= 8)
8246     {
8247       /* Small HImode tests can be converted to QImode.  */
8248       mode = QImode;
8249       val = gen_lowpart (QImode, val);
8250     }
8251
8252   if (len == HOST_BITS_PER_WIDE_INT)
8253     mask = -1;
8254   else
8255     mask = ((HOST_WIDE_INT)1 << len) - 1;
8256   mask <<= pos;
8257
8258   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8259 })
8260
8261 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8262 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8263 ;; this is relatively important trick.
8264 ;; Do the conversion only post-reload to avoid limiting of the register class
8265 ;; to QI regs.
8266 (define_split
8267   [(set (match_operand 0 "flags_reg_operand" "")
8268         (match_operator 1 "compare_operator"
8269           [(and (match_operand 2 "register_operand" "")
8270                 (match_operand 3 "const_int_operand" ""))
8271            (const_int 0)]))]
8272    "reload_completed
8273     && QI_REG_P (operands[2])
8274     && GET_MODE (operands[2]) != QImode
8275     && ((ix86_match_ccmode (insn, CCZmode)
8276          && !(INTVAL (operands[3]) & ~(255 << 8)))
8277         || (ix86_match_ccmode (insn, CCNOmode)
8278             && !(INTVAL (operands[3]) & ~(127 << 8))))"
8279   [(set (match_dup 0)
8280         (match_op_dup 1
8281           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8282                    (match_dup 3))
8283            (const_int 0)]))]
8284   "operands[2] = gen_lowpart (SImode, operands[2]);
8285    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8286
8287 (define_split
8288   [(set (match_operand 0 "flags_reg_operand" "")
8289         (match_operator 1 "compare_operator"
8290           [(and (match_operand 2 "nonimmediate_operand" "")
8291                 (match_operand 3 "const_int_operand" ""))
8292            (const_int 0)]))]
8293    "reload_completed
8294     && GET_MODE (operands[2]) != QImode
8295     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8296     && ((ix86_match_ccmode (insn, CCZmode)
8297          && !(INTVAL (operands[3]) & ~255))
8298         || (ix86_match_ccmode (insn, CCNOmode)
8299             && !(INTVAL (operands[3]) & ~127)))"
8300   [(set (match_dup 0)
8301         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8302                          (const_int 0)]))]
8303   "operands[2] = gen_lowpart (QImode, operands[2]);
8304    operands[3] = gen_lowpart (QImode, operands[3]);")
8305
8306 ;; %%% This used to optimize known byte-wide and operations to memory,
8307 ;; and sometimes to QImode registers.  If this is considered useful,
8308 ;; it should be done with splitters.
8309
8310 (define_expand "and<mode>3"
8311   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8312         (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8313                   (match_operand:SWIM 2 "<general_szext_operand>" "")))]
8314   ""
8315   "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
8316
8317 (define_insn "*anddi_1"
8318   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8319         (and:DI
8320          (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8321          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8322    (clobber (reg:CC FLAGS_REG))]
8323   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8324 {
8325   switch (get_attr_type (insn))
8326     {
8327     case TYPE_IMOVX:
8328       {
8329         enum machine_mode mode;
8330
8331         gcc_assert (CONST_INT_P (operands[2]));
8332         if (INTVAL (operands[2]) == 0xff)
8333           mode = QImode;
8334         else
8335           {
8336             gcc_assert (INTVAL (operands[2]) == 0xffff);
8337             mode = HImode;
8338           }
8339
8340         operands[1] = gen_lowpart (mode, operands[1]);
8341         if (mode == QImode)
8342           return "movz{bl|x}\t{%1, %k0|%k0, %1}";
8343         else
8344           return "movz{wl|x}\t{%1, %k0|%k0, %1}";
8345       }
8346
8347     default:
8348       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8349       if (get_attr_mode (insn) == MODE_SI)
8350         return "and{l}\t{%k2, %k0|%k0, %k2}";
8351       else
8352         return "and{q}\t{%2, %0|%0, %2}";
8353     }
8354 }
8355   [(set_attr "type" "alu,alu,alu,imovx")
8356    (set_attr "length_immediate" "*,*,*,0")
8357    (set (attr "prefix_rex")
8358      (if_then_else
8359        (and (eq_attr "type" "imovx")
8360             (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
8361                  (match_operand 1 "ext_QIreg_nomode_operand" "")))
8362        (const_string "1")
8363        (const_string "*")))
8364    (set_attr "mode" "SI,DI,DI,SI")])
8365
8366 (define_insn "*andsi_1"
8367   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8368         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8369                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8370    (clobber (reg:CC FLAGS_REG))]
8371   "ix86_binary_operator_ok (AND, SImode, operands)"
8372 {
8373   switch (get_attr_type (insn))
8374     {
8375     case TYPE_IMOVX:
8376       {
8377         enum machine_mode mode;
8378
8379         gcc_assert (CONST_INT_P (operands[2]));
8380         if (INTVAL (operands[2]) == 0xff)
8381           mode = QImode;
8382         else
8383           {
8384             gcc_assert (INTVAL (operands[2]) == 0xffff);
8385             mode = HImode;
8386           }
8387
8388         operands[1] = gen_lowpart (mode, operands[1]);
8389         if (mode == QImode)
8390           return "movz{bl|x}\t{%1, %0|%0, %1}";
8391         else
8392           return "movz{wl|x}\t{%1, %0|%0, %1}";
8393       }
8394
8395     default:
8396       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8397       return "and{l}\t{%2, %0|%0, %2}";
8398     }
8399 }
8400   [(set_attr "type" "alu,alu,imovx")
8401    (set (attr "prefix_rex")
8402      (if_then_else
8403        (and (eq_attr "type" "imovx")
8404             (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
8405                  (match_operand 1 "ext_QIreg_nomode_operand" "")))
8406        (const_string "1")
8407        (const_string "*")))
8408    (set_attr "length_immediate" "*,*,0")
8409    (set_attr "mode" "SI")])
8410
8411 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8412 (define_insn "*andsi_1_zext"
8413   [(set (match_operand:DI 0 "register_operand" "=r")
8414         (zero_extend:DI
8415           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8416                   (match_operand:SI 2 "general_operand" "g"))))
8417    (clobber (reg:CC FLAGS_REG))]
8418   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8419   "and{l}\t{%2, %k0|%k0, %2}"
8420   [(set_attr "type" "alu")
8421    (set_attr "mode" "SI")])
8422
8423 (define_insn "*andhi_1"
8424   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8425         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8426                 (match_operand:HI 2 "general_operand" "rn,rm,L")))
8427    (clobber (reg:CC FLAGS_REG))]
8428   "ix86_binary_operator_ok (AND, HImode, operands)"
8429 {
8430   switch (get_attr_type (insn))
8431     {
8432     case TYPE_IMOVX:
8433       gcc_assert (CONST_INT_P (operands[2]));
8434       gcc_assert (INTVAL (operands[2]) == 0xff);
8435       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8436
8437     default:
8438       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8439
8440       return "and{w}\t{%2, %0|%0, %2}";
8441     }
8442 }
8443   [(set_attr "type" "alu,alu,imovx")
8444    (set_attr "length_immediate" "*,*,0")
8445    (set (attr "prefix_rex")
8446      (if_then_else
8447        (and (eq_attr "type" "imovx")
8448             (match_operand 1 "ext_QIreg_nomode_operand" ""))
8449        (const_string "1")
8450        (const_string "*")))
8451    (set_attr "mode" "HI,HI,SI")])
8452
8453 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8454 (define_insn "*andqi_1"
8455   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8456         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8457                 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
8458    (clobber (reg:CC FLAGS_REG))]
8459   "ix86_binary_operator_ok (AND, QImode, operands)"
8460   "@
8461    and{b}\t{%2, %0|%0, %2}
8462    and{b}\t{%2, %0|%0, %2}
8463    and{l}\t{%k2, %k0|%k0, %k2}"
8464   [(set_attr "type" "alu")
8465    (set_attr "mode" "QI,QI,SI")])
8466
8467 (define_insn "*andqi_1_slp"
8468   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8469         (and:QI (match_dup 0)
8470                 (match_operand:QI 1 "general_operand" "qn,qmn")))
8471    (clobber (reg:CC FLAGS_REG))]
8472   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8473    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8474   "and{b}\t{%1, %0|%0, %1}"
8475   [(set_attr "type" "alu1")
8476    (set_attr "mode" "QI")])
8477
8478 (define_split
8479   [(set (match_operand 0 "register_operand" "")
8480         (and (match_dup 0)
8481              (const_int -65536)))
8482    (clobber (reg:CC FLAGS_REG))]
8483   "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
8484     || optimize_function_for_size_p (cfun)"
8485   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8486   "operands[1] = gen_lowpart (HImode, operands[0]);")
8487
8488 (define_split
8489   [(set (match_operand 0 "ext_register_operand" "")
8490         (and (match_dup 0)
8491              (const_int -256)))
8492    (clobber (reg:CC FLAGS_REG))]
8493   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8494    && reload_completed"
8495   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8496   "operands[1] = gen_lowpart (QImode, operands[0]);")
8497
8498 (define_split
8499   [(set (match_operand 0 "ext_register_operand" "")
8500         (and (match_dup 0)
8501              (const_int -65281)))
8502    (clobber (reg:CC FLAGS_REG))]
8503   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8504    && reload_completed"
8505   [(parallel [(set (zero_extract:SI (match_dup 0)
8506                                     (const_int 8)
8507                                     (const_int 8))
8508                    (xor:SI
8509                      (zero_extract:SI (match_dup 0)
8510                                       (const_int 8)
8511                                       (const_int 8))
8512                      (zero_extract:SI (match_dup 0)
8513                                       (const_int 8)
8514                                       (const_int 8))))
8515               (clobber (reg:CC FLAGS_REG))])]
8516   "operands[0] = gen_lowpart (SImode, operands[0]);")
8517
8518 (define_insn "*anddi_2"
8519   [(set (reg FLAGS_REG)
8520         (compare
8521          (and:DI
8522           (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8523           (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8524          (const_int 0)))
8525    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8526         (and:DI (match_dup 1) (match_dup 2)))]
8527   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8528    && ix86_binary_operator_ok (AND, DImode, operands)"
8529   "@
8530    and{l}\t{%k2, %k0|%k0, %k2}
8531    and{q}\t{%2, %0|%0, %2}
8532    and{q}\t{%2, %0|%0, %2}"
8533   [(set_attr "type" "alu")
8534    (set_attr "mode" "SI,DI,DI")])
8535
8536 (define_insn "*andqi_2_maybe_si"
8537   [(set (reg FLAGS_REG)
8538         (compare (and:QI
8539                   (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8540                   (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8541                  (const_int 0)))
8542    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8543         (and:QI (match_dup 1) (match_dup 2)))]
8544   "ix86_binary_operator_ok (AND, QImode, operands)
8545    && ix86_match_ccmode (insn,
8546                          CONST_INT_P (operands[2])
8547                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8548 {
8549   if (which_alternative == 2)
8550     {
8551       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8552         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8553       return "and{l}\t{%2, %k0|%k0, %2}";
8554     }
8555   return "and{b}\t{%2, %0|%0, %2}";
8556 }
8557   [(set_attr "type" "alu")
8558    (set_attr "mode" "QI,QI,SI")])
8559
8560 (define_insn "*and<mode>_2"
8561   [(set (reg FLAGS_REG)
8562         (compare (and:SWI124
8563                   (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8564                   (match_operand:SWI124 2 "general_operand" "<g>,<r><i>"))
8565                  (const_int 0)))
8566    (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8567         (and:SWI124 (match_dup 1) (match_dup 2)))]
8568   "ix86_match_ccmode (insn, CCNOmode)
8569    && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8570   "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8571   [(set_attr "type" "alu")
8572    (set_attr "mode" "<MODE>")])
8573
8574 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8575 (define_insn "*andsi_2_zext"
8576   [(set (reg FLAGS_REG)
8577         (compare (and:SI
8578                   (match_operand:SI 1 "nonimmediate_operand" "%0")
8579                   (match_operand:SI 2 "general_operand" "g"))
8580                  (const_int 0)))
8581    (set (match_operand:DI 0 "register_operand" "=r")
8582         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8583   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8584    && ix86_binary_operator_ok (AND, SImode, operands)"
8585   "and{l}\t{%2, %k0|%k0, %2}"
8586   [(set_attr "type" "alu")
8587    (set_attr "mode" "SI")])
8588
8589 (define_insn "*andqi_2_slp"
8590   [(set (reg FLAGS_REG)
8591         (compare (and:QI
8592                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8593                    (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8594                  (const_int 0)))
8595    (set (strict_low_part (match_dup 0))
8596         (and:QI (match_dup 0) (match_dup 1)))]
8597   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8598    && ix86_match_ccmode (insn, CCNOmode)
8599    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8600   "and{b}\t{%1, %0|%0, %1}"
8601   [(set_attr "type" "alu1")
8602    (set_attr "mode" "QI")])
8603
8604 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8605 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8606 ;; for a QImode operand, which of course failed.
8607 (define_insn "andqi_ext_0"
8608   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8609                          (const_int 8)
8610                          (const_int 8))
8611         (and:SI
8612           (zero_extract:SI
8613             (match_operand 1 "ext_register_operand" "0")
8614             (const_int 8)
8615             (const_int 8))
8616           (match_operand 2 "const_int_operand" "n")))
8617    (clobber (reg:CC FLAGS_REG))]
8618   ""
8619   "and{b}\t{%2, %h0|%h0, %2}"
8620   [(set_attr "type" "alu")
8621    (set_attr "length_immediate" "1")
8622    (set_attr "modrm" "1")
8623    (set_attr "mode" "QI")])
8624
8625 ;; Generated by peephole translating test to and.  This shows up
8626 ;; often in fp comparisons.
8627 (define_insn "*andqi_ext_0_cc"
8628   [(set (reg FLAGS_REG)
8629         (compare
8630           (and:SI
8631             (zero_extract:SI
8632               (match_operand 1 "ext_register_operand" "0")
8633               (const_int 8)
8634               (const_int 8))
8635             (match_operand 2 "const_int_operand" "n"))
8636           (const_int 0)))
8637    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8638                          (const_int 8)
8639                          (const_int 8))
8640         (and:SI
8641           (zero_extract:SI
8642             (match_dup 1)
8643             (const_int 8)
8644             (const_int 8))
8645           (match_dup 2)))]
8646   "ix86_match_ccmode (insn, CCNOmode)"
8647   "and{b}\t{%2, %h0|%h0, %2}"
8648   [(set_attr "type" "alu")
8649    (set_attr "length_immediate" "1")
8650    (set_attr "modrm" "1")
8651    (set_attr "mode" "QI")])
8652
8653 (define_insn "*andqi_ext_1_rex64"
8654   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8655                          (const_int 8)
8656                          (const_int 8))
8657         (and:SI
8658           (zero_extract:SI
8659             (match_operand 1 "ext_register_operand" "0")
8660             (const_int 8)
8661             (const_int 8))
8662           (zero_extend:SI
8663             (match_operand 2 "ext_register_operand" "Q"))))
8664    (clobber (reg:CC FLAGS_REG))]
8665   "TARGET_64BIT"
8666   "and{b}\t{%2, %h0|%h0, %2}"
8667   [(set_attr "type" "alu")
8668    (set_attr "length_immediate" "0")
8669    (set_attr "mode" "QI")])
8670
8671 (define_insn "*andqi_ext_1"
8672   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8673                          (const_int 8)
8674                          (const_int 8))
8675         (and:SI
8676           (zero_extract:SI
8677             (match_operand 1 "ext_register_operand" "0")
8678             (const_int 8)
8679             (const_int 8))
8680           (zero_extend:SI
8681             (match_operand:QI 2 "general_operand" "Qm"))))
8682    (clobber (reg:CC FLAGS_REG))]
8683   "!TARGET_64BIT"
8684   "and{b}\t{%2, %h0|%h0, %2}"
8685   [(set_attr "type" "alu")
8686    (set_attr "length_immediate" "0")
8687    (set_attr "mode" "QI")])
8688
8689 (define_insn "*andqi_ext_2"
8690   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8691                          (const_int 8)
8692                          (const_int 8))
8693         (and:SI
8694           (zero_extract:SI
8695             (match_operand 1 "ext_register_operand" "%0")
8696             (const_int 8)
8697             (const_int 8))
8698           (zero_extract:SI
8699             (match_operand 2 "ext_register_operand" "Q")
8700             (const_int 8)
8701             (const_int 8))))
8702    (clobber (reg:CC FLAGS_REG))]
8703   ""
8704   "and{b}\t{%h2, %h0|%h0, %h2}"
8705   [(set_attr "type" "alu")
8706    (set_attr "length_immediate" "0")
8707    (set_attr "mode" "QI")])
8708
8709 ;; Convert wide AND instructions with immediate operand to shorter QImode
8710 ;; equivalents when possible.
8711 ;; Don't do the splitting with memory operands, since it introduces risk
8712 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8713 ;; for size, but that can (should?) be handled by generic code instead.
8714 (define_split
8715   [(set (match_operand 0 "register_operand" "")
8716         (and (match_operand 1 "register_operand" "")
8717              (match_operand 2 "const_int_operand" "")))
8718    (clobber (reg:CC FLAGS_REG))]
8719    "reload_completed
8720     && QI_REG_P (operands[0])
8721     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8722     && !(~INTVAL (operands[2]) & ~(255 << 8))
8723     && GET_MODE (operands[0]) != QImode"
8724   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8725                    (and:SI (zero_extract:SI (match_dup 1)
8726                                             (const_int 8) (const_int 8))
8727                            (match_dup 2)))
8728               (clobber (reg:CC FLAGS_REG))])]
8729   "operands[0] = gen_lowpart (SImode, operands[0]);
8730    operands[1] = gen_lowpart (SImode, operands[1]);
8731    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8732
8733 ;; Since AND can be encoded with sign extended immediate, this is only
8734 ;; profitable when 7th bit is not set.
8735 (define_split
8736   [(set (match_operand 0 "register_operand" "")
8737         (and (match_operand 1 "general_operand" "")
8738              (match_operand 2 "const_int_operand" "")))
8739    (clobber (reg:CC FLAGS_REG))]
8740    "reload_completed
8741     && ANY_QI_REG_P (operands[0])
8742     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8743     && !(~INTVAL (operands[2]) & ~255)
8744     && !(INTVAL (operands[2]) & 128)
8745     && GET_MODE (operands[0]) != QImode"
8746   [(parallel [(set (strict_low_part (match_dup 0))
8747                    (and:QI (match_dup 1)
8748                            (match_dup 2)))
8749               (clobber (reg:CC FLAGS_REG))])]
8750   "operands[0] = gen_lowpart (QImode, operands[0]);
8751    operands[1] = gen_lowpart (QImode, operands[1]);
8752    operands[2] = gen_lowpart (QImode, operands[2]);")
8753 \f
8754 ;; Logical inclusive and exclusive OR instructions
8755
8756 ;; %%% This used to optimize known byte-wide and operations to memory.
8757 ;; If this is considered useful, it should be done with splitters.
8758
8759 (define_expand "<code><mode>3"
8760   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8761         (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8762                      (match_operand:SWIM 2 "<general_operand>" "")))]
8763   ""
8764   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8765
8766 (define_insn "*<code><mode>_1"
8767   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8768         (any_or:SWI248
8769          (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8770          (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8771    (clobber (reg:CC FLAGS_REG))]
8772   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8773   "<logicprefix>{<imodesuffix>}\t{%2, %0|%0, %2}"
8774   [(set_attr "type" "alu")
8775    (set_attr "mode" "<MODE>")])
8776
8777 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8778 (define_insn "*<code>qi_1"
8779   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8780         (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8781                    (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8782    (clobber (reg:CC FLAGS_REG))]
8783   "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8784   "@
8785    <logicprefix>{b}\t{%2, %0|%0, %2}
8786    <logicprefix>{b}\t{%2, %0|%0, %2}
8787    <logicprefix>{l}\t{%k2, %k0|%k0, %k2}"
8788   [(set_attr "type" "alu")
8789    (set_attr "mode" "QI,QI,SI")])
8790
8791 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8792 (define_insn "*<code>si_1_zext"
8793   [(set (match_operand:DI 0 "register_operand" "=r")
8794         (zero_extend:DI
8795          (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8796                     (match_operand:SI 2 "general_operand" "g"))))
8797    (clobber (reg:CC FLAGS_REG))]
8798   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8799   "<logicprefix>{l}\t{%2, %k0|%k0, %2}"
8800   [(set_attr "type" "alu")
8801    (set_attr "mode" "SI")])
8802
8803 (define_insn "*<code>si_1_zext_imm"
8804   [(set (match_operand:DI 0 "register_operand" "=r")
8805         (any_or:DI
8806          (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8807          (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8808    (clobber (reg:CC FLAGS_REG))]
8809   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8810   "<logicprefix>{l}\t{%2, %k0|%k0, %2}"
8811   [(set_attr "type" "alu")
8812    (set_attr "mode" "SI")])
8813
8814 (define_insn "*<code>qi_1_slp"
8815   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8816         (any_or:QI (match_dup 0)
8817                    (match_operand:QI 1 "general_operand" "qmn,qn")))
8818    (clobber (reg:CC FLAGS_REG))]
8819   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8820    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8821   "<logicprefix>{b}\t{%1, %0|%0, %1}"
8822   [(set_attr "type" "alu1")
8823    (set_attr "mode" "QI")])
8824
8825 (define_insn "*<code><mode>_2"
8826   [(set (reg FLAGS_REG)
8827         (compare (any_or:SWI
8828                   (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8829                   (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8830                  (const_int 0)))
8831    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8832         (any_or:SWI (match_dup 1) (match_dup 2)))]
8833   "ix86_match_ccmode (insn, CCNOmode)
8834    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8835   "<logicprefix>{<imodesuffix>}\t{%2, %0|%0, %2}"
8836   [(set_attr "type" "alu")
8837    (set_attr "mode" "<MODE>")])
8838
8839 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8840 ;; ??? Special case for immediate operand is missing - it is tricky.
8841 (define_insn "*<code>si_2_zext"
8842   [(set (reg FLAGS_REG)
8843         (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8844                             (match_operand:SI 2 "general_operand" "g"))
8845                  (const_int 0)))
8846    (set (match_operand:DI 0 "register_operand" "=r")
8847         (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8848   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8849    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8850   "<logicprefix>{l}\t{%2, %k0|%k0, %2}"
8851   [(set_attr "type" "alu")
8852    (set_attr "mode" "SI")])
8853
8854 (define_insn "*<code>si_2_zext_imm"
8855   [(set (reg FLAGS_REG)
8856         (compare (any_or:SI
8857                   (match_operand:SI 1 "nonimmediate_operand" "%0")
8858                   (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8859                  (const_int 0)))
8860    (set (match_operand:DI 0 "register_operand" "=r")
8861         (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8862   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8863    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8864   "<logicprefix>{l}\t{%2, %k0|%k0, %2}"
8865   [(set_attr "type" "alu")
8866    (set_attr "mode" "SI")])
8867
8868 (define_insn "*<code>qi_2_slp"
8869   [(set (reg FLAGS_REG)
8870         (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8871                             (match_operand:QI 1 "general_operand" "qmn,qn"))
8872                  (const_int 0)))
8873    (set (strict_low_part (match_dup 0))
8874         (any_or:QI (match_dup 0) (match_dup 1)))]
8875   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8876    && ix86_match_ccmode (insn, CCNOmode)
8877    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8878   "<logicprefix>{b}\t{%1, %0|%0, %1}"
8879   [(set_attr "type" "alu1")
8880    (set_attr "mode" "QI")])
8881
8882 (define_insn "*<code><mode>_3"
8883   [(set (reg FLAGS_REG)
8884         (compare (any_or:SWI
8885                   (match_operand:SWI 1 "nonimmediate_operand" "%0")
8886                   (match_operand:SWI 2 "<general_operand>" "<g>"))
8887                  (const_int 0)))
8888    (clobber (match_scratch:SWI 0 "=<r>"))]
8889   "ix86_match_ccmode (insn, CCNOmode)
8890    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8891   "<logicprefix>{<imodesuffix>}\t{%2, %0|%0, %2}"
8892   [(set_attr "type" "alu")
8893    (set_attr "mode" "<MODE>")])
8894
8895 (define_insn "*<code>qi_ext_0"
8896   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8897                          (const_int 8)
8898                          (const_int 8))
8899         (any_or:SI
8900           (zero_extract:SI
8901             (match_operand 1 "ext_register_operand" "0")
8902             (const_int 8)
8903             (const_int 8))
8904           (match_operand 2 "const_int_operand" "n")))
8905    (clobber (reg:CC FLAGS_REG))]
8906   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8907   "<logicprefix>{b}\t{%2, %h0|%h0, %2}"
8908   [(set_attr "type" "alu")
8909    (set_attr "length_immediate" "1")
8910    (set_attr "modrm" "1")
8911    (set_attr "mode" "QI")])
8912
8913 (define_insn "*<code>qi_ext_1_rex64"
8914   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8915                          (const_int 8)
8916                          (const_int 8))
8917         (any_or:SI
8918           (zero_extract:SI
8919             (match_operand 1 "ext_register_operand" "0")
8920             (const_int 8)
8921             (const_int 8))
8922           (zero_extend:SI
8923             (match_operand 2 "ext_register_operand" "Q"))))
8924    (clobber (reg:CC FLAGS_REG))]
8925   "TARGET_64BIT
8926    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8927   "<logicprefix>{b}\t{%2, %h0|%h0, %2}"
8928   [(set_attr "type" "alu")
8929    (set_attr "length_immediate" "0")
8930    (set_attr "mode" "QI")])
8931
8932 (define_insn "*<code>qi_ext_1"
8933   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8934                          (const_int 8)
8935                          (const_int 8))
8936         (any_or:SI
8937           (zero_extract:SI
8938             (match_operand 1 "ext_register_operand" "0")
8939             (const_int 8)
8940             (const_int 8))
8941           (zero_extend:SI
8942             (match_operand:QI 2 "general_operand" "Qm"))))
8943    (clobber (reg:CC FLAGS_REG))]
8944   "!TARGET_64BIT
8945    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8946   "<logicprefix>{b}\t{%2, %h0|%h0, %2}"
8947   [(set_attr "type" "alu")
8948    (set_attr "length_immediate" "0")
8949    (set_attr "mode" "QI")])
8950
8951 (define_insn "*<code>qi_ext_2"
8952   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8953                          (const_int 8)
8954                          (const_int 8))
8955         (any_or:SI
8956           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8957                            (const_int 8)
8958                            (const_int 8))
8959           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8960                            (const_int 8)
8961                            (const_int 8))))
8962    (clobber (reg:CC FLAGS_REG))]
8963   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8964   "<logicprefix>{b}\t{%h2, %h0|%h0, %h2}"
8965   [(set_attr "type" "alu")
8966    (set_attr "length_immediate" "0")
8967    (set_attr "mode" "QI")])
8968
8969 (define_split
8970   [(set (match_operand 0 "register_operand" "")
8971         (any_or (match_operand 1 "register_operand" "")
8972                 (match_operand 2 "const_int_operand" "")))
8973    (clobber (reg:CC FLAGS_REG))]
8974    "reload_completed
8975     && QI_REG_P (operands[0])
8976     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8977     && !(INTVAL (operands[2]) & ~(255 << 8))
8978     && GET_MODE (operands[0]) != QImode"
8979   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8980                    (any_or:SI (zero_extract:SI (match_dup 1)
8981                                                (const_int 8) (const_int 8))
8982                               (match_dup 2)))
8983               (clobber (reg:CC FLAGS_REG))])]
8984   "operands[0] = gen_lowpart (SImode, operands[0]);
8985    operands[1] = gen_lowpart (SImode, operands[1]);
8986    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8987
8988 ;; Since OR can be encoded with sign extended immediate, this is only
8989 ;; profitable when 7th bit is set.
8990 (define_split
8991   [(set (match_operand 0 "register_operand" "")
8992         (any_or (match_operand 1 "general_operand" "")
8993                 (match_operand 2 "const_int_operand" "")))
8994    (clobber (reg:CC FLAGS_REG))]
8995    "reload_completed
8996     && ANY_QI_REG_P (operands[0])
8997     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8998     && !(INTVAL (operands[2]) & ~255)
8999     && (INTVAL (operands[2]) & 128)
9000     && GET_MODE (operands[0]) != QImode"
9001   [(parallel [(set (strict_low_part (match_dup 0))
9002                    (any_or:QI (match_dup 1)
9003                               (match_dup 2)))
9004               (clobber (reg:CC FLAGS_REG))])]
9005   "operands[0] = gen_lowpart (QImode, operands[0]);
9006    operands[1] = gen_lowpart (QImode, operands[1]);
9007    operands[2] = gen_lowpart (QImode, operands[2]);")
9008
9009 (define_expand "xorqi_cc_ext_1"
9010   [(parallel [
9011      (set (reg:CCNO FLAGS_REG)
9012           (compare:CCNO
9013             (xor:SI
9014               (zero_extract:SI
9015                 (match_operand 1 "ext_register_operand" "")
9016                 (const_int 8)
9017                 (const_int 8))
9018               (match_operand:QI 2 "general_operand" ""))
9019             (const_int 0)))
9020      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9021                            (const_int 8)
9022                            (const_int 8))
9023           (xor:SI
9024             (zero_extract:SI
9025              (match_dup 1)
9026              (const_int 8)
9027              (const_int 8))
9028             (match_dup 2)))])]
9029   ""
9030   "")
9031
9032 (define_insn "*xorqi_cc_ext_1_rex64"
9033   [(set (reg FLAGS_REG)
9034         (compare
9035           (xor:SI
9036             (zero_extract:SI
9037               (match_operand 1 "ext_register_operand" "0")
9038               (const_int 8)
9039               (const_int 8))
9040             (match_operand:QI 2 "nonmemory_operand" "Qn"))
9041           (const_int 0)))
9042    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9043                          (const_int 8)
9044                          (const_int 8))
9045         (xor:SI
9046           (zero_extract:SI
9047            (match_dup 1)
9048            (const_int 8)
9049            (const_int 8))
9050           (match_dup 2)))]
9051   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9052   "xor{b}\t{%2, %h0|%h0, %2}"
9053   [(set_attr "type" "alu")
9054    (set_attr "modrm" "1")
9055    (set_attr "mode" "QI")])
9056
9057 (define_insn "*xorqi_cc_ext_1"
9058   [(set (reg FLAGS_REG)
9059         (compare
9060           (xor:SI
9061             (zero_extract:SI
9062               (match_operand 1 "ext_register_operand" "0")
9063               (const_int 8)
9064               (const_int 8))
9065             (match_operand:QI 2 "general_operand" "qmn"))
9066           (const_int 0)))
9067    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9068                          (const_int 8)
9069                          (const_int 8))
9070         (xor:SI
9071           (zero_extract:SI
9072            (match_dup 1)
9073            (const_int 8)
9074            (const_int 8))
9075           (match_dup 2)))]
9076   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9077   "xor{b}\t{%2, %h0|%h0, %2}"
9078   [(set_attr "type" "alu")
9079    (set_attr "modrm" "1")
9080    (set_attr "mode" "QI")])
9081 \f
9082 ;; Negation instructions
9083
9084 (define_expand "neg<mode>2"
9085   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
9086         (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
9087   ""
9088   "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
9089
9090 (define_insn_and_split "*neg<dwi>2_doubleword"
9091   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
9092         (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
9093    (clobber (reg:CC FLAGS_REG))]
9094   "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
9095   "#"
9096   "reload_completed"
9097   [(parallel
9098     [(set (reg:CCZ FLAGS_REG)
9099           (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
9100      (set (match_dup 0) (neg:DWIH (match_dup 1)))])
9101    (parallel
9102     [(set (match_dup 2)
9103           (plus:DWIH (match_dup 3)
9104                      (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
9105                                 (const_int 0))))
9106      (clobber (reg:CC FLAGS_REG))])
9107    (parallel
9108     [(set (match_dup 2)
9109           (neg:DWIH (match_dup 2)))
9110      (clobber (reg:CC FLAGS_REG))])]
9111   "split_<dwi> (&operands[0], 2, &operands[0], &operands[2]);")
9112
9113 (define_insn "*neg<mode>2_1"
9114   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9115         (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
9116    (clobber (reg:CC FLAGS_REG))]
9117   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9118   "neg{<imodesuffix>}\t%0"
9119   [(set_attr "type" "negnot")
9120    (set_attr "mode" "<MODE>")])
9121
9122 ;; Combine is quite creative about this pattern.
9123 (define_insn "*negsi2_1_zext"
9124   [(set (match_operand:DI 0 "register_operand" "=r")
9125         (lshiftrt:DI
9126           (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9127                              (const_int 32)))
9128         (const_int 32)))
9129    (clobber (reg:CC FLAGS_REG))]
9130   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9131   "neg{l}\t%k0"
9132   [(set_attr "type" "negnot")
9133    (set_attr "mode" "SI")])
9134
9135 ;; The problem with neg is that it does not perform (compare x 0),
9136 ;; it really performs (compare 0 x), which leaves us with the zero
9137 ;; flag being the only useful item.
9138
9139 (define_insn "*neg<mode>2_cmpz"
9140   [(set (reg:CCZ FLAGS_REG)
9141         (compare:CCZ
9142           (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9143                    (const_int 0)))
9144    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9145         (neg:SWI (match_dup 1)))]
9146   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9147   "neg{<imodesuffix>}\t%0"
9148   [(set_attr "type" "negnot")
9149    (set_attr "mode" "<MODE>")])
9150
9151 (define_insn "*negsi2_cmpz_zext"
9152   [(set (reg:CCZ FLAGS_REG)
9153         (compare:CCZ
9154           (lshiftrt:DI
9155             (neg:DI (ashift:DI
9156                       (match_operand:DI 1 "register_operand" "0")
9157                       (const_int 32)))
9158             (const_int 32))
9159           (const_int 0)))
9160    (set (match_operand:DI 0 "register_operand" "=r")
9161         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9162                                         (const_int 32)))
9163                      (const_int 32)))]
9164   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9165   "neg{l}\t%k0"
9166   [(set_attr "type" "negnot")
9167    (set_attr "mode" "SI")])
9168
9169 ;; Changing of sign for FP values is doable using integer unit too.
9170
9171 (define_expand "<code><mode>2"
9172   [(set (match_operand:X87MODEF 0 "register_operand" "")
9173         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
9174   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9175   "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
9176
9177 (define_insn "*absneg<mode>2_mixed"
9178   [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
9179         (match_operator:MODEF 3 "absneg_operator"
9180           [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
9181    (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
9182    (clobber (reg:CC FLAGS_REG))]
9183   "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
9184   "#")
9185
9186 (define_insn "*absneg<mode>2_sse"
9187   [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
9188         (match_operator:MODEF 3 "absneg_operator"
9189           [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
9190    (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
9191    (clobber (reg:CC FLAGS_REG))]
9192   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
9193   "#")
9194
9195 (define_insn "*absneg<mode>2_i387"
9196   [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
9197         (match_operator:X87MODEF 3 "absneg_operator"
9198           [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
9199    (use (match_operand 2 "" ""))
9200    (clobber (reg:CC FLAGS_REG))]
9201   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9202   "#")
9203
9204 (define_expand "<code>tf2"
9205   [(set (match_operand:TF 0 "register_operand" "")
9206         (absneg:TF (match_operand:TF 1 "register_operand" "")))]
9207   "TARGET_SSE2"
9208   "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
9209
9210 (define_insn "*absnegtf2_sse"
9211   [(set (match_operand:TF 0 "register_operand" "=x,x")
9212         (match_operator:TF 3 "absneg_operator"
9213           [(match_operand:TF 1 "register_operand" "0,x")]))
9214    (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
9215    (clobber (reg:CC FLAGS_REG))]
9216   "TARGET_SSE2"
9217   "#")
9218
9219 ;; Splitters for fp abs and neg.
9220
9221 (define_split
9222   [(set (match_operand 0 "fp_register_operand" "")
9223         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9224    (use (match_operand 2 "" ""))
9225    (clobber (reg:CC FLAGS_REG))]
9226   "reload_completed"
9227   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9228
9229 (define_split
9230   [(set (match_operand 0 "register_operand" "")
9231         (match_operator 3 "absneg_operator"
9232           [(match_operand 1 "register_operand" "")]))
9233    (use (match_operand 2 "nonimmediate_operand" ""))
9234    (clobber (reg:CC FLAGS_REG))]
9235   "reload_completed && SSE_REG_P (operands[0])"
9236   [(set (match_dup 0) (match_dup 3))]
9237 {
9238   enum machine_mode mode = GET_MODE (operands[0]);
9239   enum machine_mode vmode = GET_MODE (operands[2]);
9240   rtx tmp;
9241
9242   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9243   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9244   if (operands_match_p (operands[0], operands[2]))
9245     {
9246       tmp = operands[1];
9247       operands[1] = operands[2];
9248       operands[2] = tmp;
9249     }
9250   if (GET_CODE (operands[3]) == ABS)
9251     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9252   else
9253     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9254   operands[3] = tmp;
9255 })
9256
9257 (define_split
9258   [(set (match_operand:SF 0 "register_operand" "")
9259         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9260    (use (match_operand:V4SF 2 "" ""))
9261    (clobber (reg:CC FLAGS_REG))]
9262   "reload_completed"
9263   [(parallel [(set (match_dup 0) (match_dup 1))
9264               (clobber (reg:CC FLAGS_REG))])]
9265 {
9266   rtx tmp;
9267   operands[0] = gen_lowpart (SImode, operands[0]);
9268   if (GET_CODE (operands[1]) == ABS)
9269     {
9270       tmp = gen_int_mode (0x7fffffff, SImode);
9271       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9272     }
9273   else
9274     {
9275       tmp = gen_int_mode (0x80000000, SImode);
9276       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9277     }
9278   operands[1] = tmp;
9279 })
9280
9281 (define_split
9282   [(set (match_operand:DF 0 "register_operand" "")
9283         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9284    (use (match_operand 2 "" ""))
9285    (clobber (reg:CC FLAGS_REG))]
9286   "reload_completed"
9287   [(parallel [(set (match_dup 0) (match_dup 1))
9288               (clobber (reg:CC FLAGS_REG))])]
9289 {
9290   rtx tmp;
9291   if (TARGET_64BIT)
9292     {
9293       tmp = gen_lowpart (DImode, operands[0]);
9294       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9295       operands[0] = tmp;
9296
9297       if (GET_CODE (operands[1]) == ABS)
9298         tmp = const0_rtx;
9299       else
9300         tmp = gen_rtx_NOT (DImode, tmp);
9301     }
9302   else
9303     {
9304       operands[0] = gen_highpart (SImode, operands[0]);
9305       if (GET_CODE (operands[1]) == ABS)
9306         {
9307           tmp = gen_int_mode (0x7fffffff, SImode);
9308           tmp = gen_rtx_AND (SImode, operands[0], tmp);
9309         }
9310       else
9311         {
9312           tmp = gen_int_mode (0x80000000, SImode);
9313           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9314         }
9315     }
9316   operands[1] = tmp;
9317 })
9318
9319 (define_split
9320   [(set (match_operand:XF 0 "register_operand" "")
9321         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9322    (use (match_operand 2 "" ""))
9323    (clobber (reg:CC FLAGS_REG))]
9324   "reload_completed"
9325   [(parallel [(set (match_dup 0) (match_dup 1))
9326               (clobber (reg:CC FLAGS_REG))])]
9327 {
9328   rtx tmp;
9329   operands[0] = gen_rtx_REG (SImode,
9330                              true_regnum (operands[0])
9331                              + (TARGET_64BIT ? 1 : 2));
9332   if (GET_CODE (operands[1]) == ABS)
9333     {
9334       tmp = GEN_INT (0x7fff);
9335       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9336     }
9337   else
9338     {
9339       tmp = GEN_INT (0x8000);
9340       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9341     }
9342   operands[1] = tmp;
9343 })
9344
9345 ;; Conditionalize these after reload. If they match before reload, we
9346 ;; lose the clobber and ability to use integer instructions.
9347
9348 (define_insn "*<code><mode>2_1"
9349   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
9350         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
9351   "TARGET_80387
9352    && (reload_completed
9353        || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
9354   "f<absnegprefix>"
9355   [(set_attr "type" "fsgn")
9356    (set_attr "mode" "<MODE>")])
9357
9358 (define_insn "*<code>extendsfdf2"
9359   [(set (match_operand:DF 0 "register_operand" "=f")
9360         (absneg:DF (float_extend:DF
9361                      (match_operand:SF 1 "register_operand" "0"))))]
9362   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9363   "f<absnegprefix>"
9364   [(set_attr "type" "fsgn")
9365    (set_attr "mode" "DF")])
9366
9367 (define_insn "*<code>extendsfxf2"
9368   [(set (match_operand:XF 0 "register_operand" "=f")
9369         (absneg:XF (float_extend:XF
9370                      (match_operand:SF 1 "register_operand" "0"))))]
9371   "TARGET_80387"
9372   "f<absnegprefix>"
9373   [(set_attr "type" "fsgn")
9374    (set_attr "mode" "XF")])
9375
9376 (define_insn "*<code>extenddfxf2"
9377   [(set (match_operand:XF 0 "register_operand" "=f")
9378         (absneg:XF (float_extend:XF
9379                       (match_operand:DF 1 "register_operand" "0"))))]
9380   "TARGET_80387"
9381   "f<absnegprefix>"
9382   [(set_attr "type" "fsgn")
9383    (set_attr "mode" "XF")])
9384
9385 ;; Copysign instructions
9386
9387 (define_mode_iterator CSGNMODE [SF DF TF])
9388 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
9389
9390 (define_expand "copysign<mode>3"
9391   [(match_operand:CSGNMODE 0 "register_operand" "")
9392    (match_operand:CSGNMODE 1 "nonmemory_operand" "")
9393    (match_operand:CSGNMODE 2 "register_operand" "")]
9394   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9395    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
9396 {
9397   ix86_expand_copysign (operands);
9398   DONE;
9399 })
9400
9401 (define_insn_and_split "copysign<mode>3_const"
9402   [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
9403         (unspec:CSGNMODE
9404           [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
9405            (match_operand:CSGNMODE 2 "register_operand" "0")
9406            (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
9407           UNSPEC_COPYSIGN))]
9408   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9409    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
9410   "#"
9411   "&& reload_completed"
9412   [(const_int 0)]
9413 {
9414   ix86_split_copysign_const (operands);
9415   DONE;
9416 })
9417
9418 (define_insn "copysign<mode>3_var"
9419   [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
9420         (unspec:CSGNMODE
9421           [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
9422            (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
9423            (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
9424            (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
9425           UNSPEC_COPYSIGN))
9426    (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
9427   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9428    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
9429   "#")
9430
9431 (define_split
9432   [(set (match_operand:CSGNMODE 0 "register_operand" "")
9433         (unspec:CSGNMODE
9434           [(match_operand:CSGNMODE 2 "register_operand" "")
9435            (match_operand:CSGNMODE 3 "register_operand" "")
9436            (match_operand:<CSGNVMODE> 4 "" "")
9437            (match_operand:<CSGNVMODE> 5 "" "")]
9438           UNSPEC_COPYSIGN))
9439    (clobber (match_scratch:<CSGNVMODE> 1 ""))]
9440   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9441     || (TARGET_SSE2 && (<MODE>mode == TFmode)))
9442    && reload_completed"
9443   [(const_int 0)]
9444 {
9445   ix86_split_copysign_var (operands);
9446   DONE;
9447 })
9448 \f
9449 ;; One complement instructions
9450
9451 (define_expand "one_cmpl<mode>2"
9452   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
9453         (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
9454   ""
9455   "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
9456
9457 (define_insn "*one_cmpl<mode>2_1"
9458   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
9459         (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
9460   "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9461   "not{<imodesuffix>}\t%0"
9462   [(set_attr "type" "negnot")
9463    (set_attr "mode" "<MODE>")])
9464
9465 ;; %%% Potential partial reg stall on alternative 1.  What to do?
9466 (define_insn "*one_cmplqi2_1"
9467   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9468         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
9469   "ix86_unary_operator_ok (NOT, QImode, operands)"
9470   "@
9471    not{b}\t%0
9472    not{l}\t%k0"
9473   [(set_attr "type" "negnot")
9474    (set_attr "mode" "QI,SI")])
9475
9476 ;; ??? Currently never generated - xor is used instead.
9477 (define_insn "*one_cmplsi2_1_zext"
9478   [(set (match_operand:DI 0 "register_operand" "=r")
9479         (zero_extend:DI
9480           (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9481   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9482   "not{l}\t%k0"
9483   [(set_attr "type" "negnot")
9484    (set_attr "mode" "SI")])
9485
9486 (define_insn "*one_cmpl<mode>2_2"
9487   [(set (reg FLAGS_REG)
9488         (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9489                  (const_int 0)))
9490    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9491         (not:SWI (match_dup 1)))]
9492   "ix86_match_ccmode (insn, CCNOmode)
9493    && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9494   "#"
9495   [(set_attr "type" "alu1")
9496    (set_attr "mode" "<MODE>")])
9497
9498 (define_split
9499   [(set (match_operand 0 "flags_reg_operand" "")
9500         (match_operator 2 "compare_operator"
9501           [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
9502            (const_int 0)]))
9503    (set (match_operand:SWI 1 "nonimmediate_operand" "")
9504         (not:SWI (match_dup 3)))]
9505   "ix86_match_ccmode (insn, CCNOmode)"
9506   [(parallel [(set (match_dup 0)
9507                    (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9508                                     (const_int 0)]))
9509               (set (match_dup 1)
9510                    (xor:SWI (match_dup 3) (const_int -1)))])]
9511   "")
9512
9513 ;; ??? Currently never generated - xor is used instead.
9514 (define_insn "*one_cmplsi2_2_zext"
9515   [(set (reg FLAGS_REG)
9516         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9517                  (const_int 0)))
9518    (set (match_operand:DI 0 "register_operand" "=r")
9519         (zero_extend:DI (not:SI (match_dup 1))))]
9520   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9521    && ix86_unary_operator_ok (NOT, SImode, operands)"
9522   "#"
9523   [(set_attr "type" "alu1")
9524    (set_attr "mode" "SI")])
9525
9526 (define_split
9527   [(set (match_operand 0 "flags_reg_operand" "")
9528         (match_operator 2 "compare_operator"
9529           [(not:SI (match_operand:SI 3 "register_operand" ""))
9530            (const_int 0)]))
9531    (set (match_operand:DI 1 "register_operand" "")
9532         (zero_extend:DI (not:SI (match_dup 3))))]
9533   "ix86_match_ccmode (insn, CCNOmode)"
9534   [(parallel [(set (match_dup 0)
9535                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9536                                     (const_int 0)]))
9537               (set (match_dup 1)
9538                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
9539   "")
9540 \f
9541 ;; Shift instructions
9542
9543 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9544 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
9545 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9546 ;; from the assembler input.
9547 ;;
9548 ;; This instruction shifts the target reg/mem as usual, but instead of
9549 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
9550 ;; is a left shift double, bits are taken from the high order bits of
9551 ;; reg, else if the insn is a shift right double, bits are taken from the
9552 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
9553 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9554 ;;
9555 ;; Since sh[lr]d does not change the `reg' operand, that is done
9556 ;; separately, making all shifts emit pairs of shift double and normal
9557 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
9558 ;; support a 63 bit shift, each shift where the count is in a reg expands
9559 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9560 ;;
9561 ;; If the shift count is a constant, we need never emit more than one
9562 ;; shift pair, instead using moves and sign extension for counts greater
9563 ;; than 31.
9564
9565 (define_expand "ashl<mode>3"
9566   [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9567         (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
9568                       (match_operand:QI 2 "nonmemory_operand" "")))]
9569   ""
9570   "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9571
9572 (define_insn "*ashl<mode>3_doubleword"
9573   [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9574         (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9575                     (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9576    (clobber (reg:CC FLAGS_REG))]
9577   ""
9578   "#"
9579   [(set_attr "type" "multi")])
9580
9581 (define_split
9582   [(set (match_operand:DWI 0 "register_operand" "")
9583         (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
9584                     (match_operand:QI 2 "nonmemory_operand" "")))
9585    (clobber (reg:CC FLAGS_REG))]
9586   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9587   [(const_int 0)]
9588   "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9589
9590 ;; By default we don't ask for a scratch register, because when DWImode
9591 ;; values are manipulated, registers are already at a premium.  But if
9592 ;; we have one handy, we won't turn it away.
9593
9594 (define_peephole2
9595   [(match_scratch:DWIH 3 "r")
9596    (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9597                    (ashift:<DWI>
9598                      (match_operand:<DWI> 1 "nonmemory_operand" "")
9599                      (match_operand:QI 2 "nonmemory_operand" "")))
9600               (clobber (reg:CC FLAGS_REG))])
9601    (match_dup 3)]
9602   "TARGET_CMOVE"
9603   [(const_int 0)]
9604   "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9605
9606 (define_insn "x86_64_shld"
9607   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9608         (ior:DI (ashift:DI (match_dup 0)
9609                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
9610                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9611                   (minus:QI (const_int 64) (match_dup 2)))))
9612    (clobber (reg:CC FLAGS_REG))]
9613   "TARGET_64BIT"
9614   "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9615   [(set_attr "type" "ishift")
9616    (set_attr "prefix_0f" "1")
9617    (set_attr "mode" "DI")
9618    (set_attr "athlon_decode" "vector")
9619    (set_attr "amdfam10_decode" "vector")])
9620
9621 (define_insn "x86_shld"
9622   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9623         (ior:SI (ashift:SI (match_dup 0)
9624                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
9625                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9626                   (minus:QI (const_int 32) (match_dup 2)))))
9627    (clobber (reg:CC FLAGS_REG))]
9628   ""
9629   "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9630   [(set_attr "type" "ishift")
9631    (set_attr "prefix_0f" "1")
9632    (set_attr "mode" "SI")
9633    (set_attr "pent_pair" "np")
9634    (set_attr "athlon_decode" "vector")
9635    (set_attr "amdfam10_decode" "vector")])
9636
9637 (define_expand "x86_shift<mode>_adj_1"
9638   [(set (reg:CCZ FLAGS_REG)
9639         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
9640                              (match_dup 4))
9641                      (const_int 0)))
9642    (set (match_operand:SWI48 0 "register_operand" "")
9643         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9644                             (match_operand:SWI48 1 "register_operand" "")
9645                             (match_dup 0)))
9646    (set (match_dup 1)
9647         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9648                             (match_operand:SWI48 3 "register_operand" "r")
9649                             (match_dup 1)))]
9650   "TARGET_CMOVE"
9651   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9652
9653 (define_expand "x86_shift<mode>_adj_2"
9654   [(use (match_operand:SWI48 0 "register_operand" ""))
9655    (use (match_operand:SWI48 1 "register_operand" ""))
9656    (use (match_operand:QI 2 "register_operand" ""))]
9657   ""
9658 {
9659   rtx label = gen_label_rtx ();
9660   rtx tmp;
9661
9662   emit_insn (gen_testqi_ccz_1 (operands[2],
9663                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9664
9665   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9666   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9667   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9668                               gen_rtx_LABEL_REF (VOIDmode, label),
9669                               pc_rtx);
9670   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9671   JUMP_LABEL (tmp) = label;
9672
9673   emit_move_insn (operands[0], operands[1]);
9674   ix86_expand_clear (operands[1]);
9675
9676   emit_label (label);
9677   LABEL_NUSES (label) = 1;
9678
9679   DONE;
9680 })
9681
9682 (define_insn "*ashl<mode>3_1"
9683   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9684         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l")
9685                       (match_operand:QI 2 "nonmemory_operand" "c<S>,M")))
9686    (clobber (reg:CC FLAGS_REG))]
9687   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9688 {
9689   switch (get_attr_type (insn))
9690     {
9691     case TYPE_ALU:
9692       gcc_assert (operands[2] == const1_rtx);
9693       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9694       return "add{<imodesuffix>}\t%0, %0";
9695
9696     case TYPE_LEA:
9697       return "#";
9698
9699     default:
9700       if (REG_P (operands[2]))
9701         return "sal{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9702       else if (operands[2] == const1_rtx
9703                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9704         return "sal{<imodesuffix>}\t%0";
9705       else
9706         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9707     }
9708 }
9709   [(set (attr "type")
9710      (cond [(eq_attr "alternative" "1")
9711               (const_string "lea")
9712             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9713                           (const_int 0))
9714                       (match_operand 0 "register_operand" ""))
9715                  (match_operand 2 "const1_operand" ""))
9716               (const_string "alu")
9717            ]
9718            (const_string "ishift")))
9719    (set (attr "length_immediate")
9720      (if_then_else
9721        (ior (eq_attr "type" "alu")
9722             (and (eq_attr "type" "ishift")
9723                  (and (match_operand 2 "const1_operand" "")
9724                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9725                           (const_int 0)))))
9726        (const_string "0")
9727        (const_string "*")))
9728    (set_attr "mode" "<MODE>")])
9729
9730 (define_insn "*ashlsi3_1_zext"
9731   [(set (match_operand:DI 0 "register_operand" "=r,r")
9732         (zero_extend:DI
9733           (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
9734                      (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
9735    (clobber (reg:CC FLAGS_REG))]
9736   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9737 {
9738   switch (get_attr_type (insn))
9739     {
9740     case TYPE_ALU:
9741       gcc_assert (operands[2] == const1_rtx);
9742       return "add{l}\t%k0, %k0";
9743
9744     case TYPE_LEA:
9745       return "#";
9746
9747     default:
9748       if (REG_P (operands[2]))
9749         return "sal{l}\t{%b2, %k0|%k0, %b2}";
9750       else if (operands[2] == const1_rtx
9751                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9752         return "sal{l}\t%k0";
9753       else
9754         return "sal{l}\t{%2, %k0|%k0, %2}";
9755     }
9756 }
9757   [(set (attr "type")
9758      (cond [(eq_attr "alternative" "1")
9759               (const_string "lea")
9760             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9761                      (const_int 0))
9762                  (match_operand 2 "const1_operand" ""))
9763               (const_string "alu")
9764            ]
9765            (const_string "ishift")))
9766    (set (attr "length_immediate")
9767      (if_then_else
9768        (ior (eq_attr "type" "alu")
9769             (and (eq_attr "type" "ishift")
9770                  (and (match_operand 2 "const1_operand" "")
9771                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9772                           (const_int 0)))))
9773        (const_string "0")
9774        (const_string "*")))
9775    (set_attr "mode" "SI")])
9776
9777 (define_insn "*ashlhi3_1"
9778   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9779         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
9780                    (match_operand:QI 2 "nonmemory_operand" "cI")))
9781    (clobber (reg:CC FLAGS_REG))]
9782   "TARGET_PARTIAL_REG_STALL
9783    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9784 {
9785   switch (get_attr_type (insn))
9786     {
9787     case TYPE_ALU:
9788       gcc_assert (operands[2] == const1_rtx);
9789       return "add{w}\t%0, %0";
9790
9791     default:
9792       if (REG_P (operands[2]))
9793         return "sal{w}\t{%b2, %0|%0, %b2}";
9794       else if (operands[2] == const1_rtx
9795                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9796         return "sal{w}\t%0";
9797       else
9798         return "sal{w}\t{%2, %0|%0, %2}";
9799     }
9800 }
9801   [(set (attr "type")
9802      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9803                           (const_int 0))
9804                       (match_operand 0 "register_operand" ""))
9805                  (match_operand 2 "const1_operand" ""))
9806               (const_string "alu")
9807            ]
9808            (const_string "ishift")))
9809    (set (attr "length_immediate")
9810      (if_then_else
9811        (ior (eq_attr "type" "alu")
9812             (and (eq_attr "type" "ishift")
9813                  (and (match_operand 2 "const1_operand" "")
9814                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9815                           (const_int 0)))))
9816        (const_string "0")
9817        (const_string "*")))
9818    (set_attr "mode" "HI")])
9819
9820 (define_insn "*ashlhi3_1_lea"
9821   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
9822         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9823                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9824    (clobber (reg:CC FLAGS_REG))]
9825   "!TARGET_PARTIAL_REG_STALL
9826    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9827 {
9828   switch (get_attr_type (insn))
9829     {
9830     case TYPE_LEA:
9831       return "#";
9832     case TYPE_ALU:
9833       gcc_assert (operands[2] == const1_rtx);
9834       return "add{w}\t%0, %0";
9835
9836     default:
9837       if (REG_P (operands[2]))
9838         return "sal{w}\t{%b2, %0|%0, %b2}";
9839       else if (operands[2] == const1_rtx
9840                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9841         return "sal{w}\t%0";
9842       else
9843         return "sal{w}\t{%2, %0|%0, %2}";
9844     }
9845 }
9846   [(set (attr "type")
9847      (cond [(eq_attr "alternative" "1")
9848               (const_string "lea")
9849             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9850                           (const_int 0))
9851                       (match_operand 0 "register_operand" ""))
9852                  (match_operand 2 "const1_operand" ""))
9853               (const_string "alu")
9854            ]
9855            (const_string "ishift")))
9856    (set (attr "length_immediate")
9857      (if_then_else
9858        (ior (eq_attr "type" "alu")
9859             (and (eq_attr "type" "ishift")
9860                  (and (match_operand 2 "const1_operand" "")
9861                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9862                           (const_int 0)))))
9863        (const_string "0")
9864        (const_string "*")))
9865    (set_attr "mode" "HI,SI")])
9866
9867 (define_insn "*ashlqi3_1"
9868   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9869         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
9870                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
9871    (clobber (reg:CC FLAGS_REG))]
9872   "TARGET_PARTIAL_REG_STALL
9873    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9874 {
9875   switch (get_attr_type (insn))
9876     {
9877     case TYPE_ALU:
9878       gcc_assert (operands[2] == const1_rtx);
9879       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9880         return "add{l}\t%k0, %k0";
9881       else
9882         return "add{b}\t%0, %0";
9883
9884     default:
9885       if (REG_P (operands[2]))
9886         {
9887           if (get_attr_mode (insn) == MODE_SI)
9888             return "sal{l}\t{%b2, %k0|%k0, %b2}";
9889           else
9890             return "sal{b}\t{%b2, %0|%0, %b2}";
9891         }
9892       else if (operands[2] == const1_rtx
9893                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9894         {
9895           if (get_attr_mode (insn) == MODE_SI)
9896             return "sal{l}\t%0";
9897           else
9898             return "sal{b}\t%0";
9899         }
9900       else
9901         {
9902           if (get_attr_mode (insn) == MODE_SI)
9903             return "sal{l}\t{%2, %k0|%k0, %2}";
9904           else
9905             return "sal{b}\t{%2, %0|%0, %2}";
9906         }
9907     }
9908 }
9909   [(set (attr "type")
9910      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9911                           (const_int 0))
9912                       (match_operand 0 "register_operand" ""))
9913                  (match_operand 2 "const1_operand" ""))
9914               (const_string "alu")
9915            ]
9916            (const_string "ishift")))
9917    (set (attr "length_immediate")
9918      (if_then_else
9919        (ior (eq_attr "type" "alu")
9920             (and (eq_attr "type" "ishift")
9921                  (and (match_operand 2 "const1_operand" "")
9922                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9923                           (const_int 0)))))
9924        (const_string "0")
9925        (const_string "*")))
9926    (set_attr "mode" "QI,SI")])
9927
9928 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9929 (define_insn "*ashlqi3_1_lea"
9930   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
9931         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9932                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9933    (clobber (reg:CC FLAGS_REG))]
9934   "!TARGET_PARTIAL_REG_STALL
9935    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9936 {
9937   switch (get_attr_type (insn))
9938     {
9939     case TYPE_LEA:
9940       return "#";
9941     case TYPE_ALU:
9942       gcc_assert (operands[2] == const1_rtx);
9943       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9944         return "add{l}\t%k0, %k0";
9945       else
9946         return "add{b}\t%0, %0";
9947
9948     default:
9949       if (REG_P (operands[2]))
9950         {
9951           if (get_attr_mode (insn) == MODE_SI)
9952             return "sal{l}\t{%b2, %k0|%k0, %b2}";
9953           else
9954             return "sal{b}\t{%b2, %0|%0, %b2}";
9955         }
9956       else if (operands[2] == const1_rtx
9957                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9958         {
9959           if (get_attr_mode (insn) == MODE_SI)
9960             return "sal{l}\t%0";
9961           else
9962             return "sal{b}\t%0";
9963         }
9964       else
9965         {
9966           if (get_attr_mode (insn) == MODE_SI)
9967             return "sal{l}\t{%2, %k0|%k0, %2}";
9968           else
9969             return "sal{b}\t{%2, %0|%0, %2}";
9970         }
9971     }
9972 }
9973   [(set (attr "type")
9974      (cond [(eq_attr "alternative" "2")
9975               (const_string "lea")
9976             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9977                           (const_int 0))
9978                       (match_operand 0 "register_operand" ""))
9979                  (match_operand 2 "const1_operand" ""))
9980               (const_string "alu")
9981            ]
9982            (const_string "ishift")))
9983    (set (attr "length_immediate")
9984      (if_then_else
9985        (ior (eq_attr "type" "alu")
9986             (and (eq_attr "type" "ishift")
9987                  (and (match_operand 2 "const1_operand" "")
9988                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9989                           (const_int 0)))))
9990        (const_string "0")
9991        (const_string "*")))
9992    (set_attr "mode" "QI,SI,SI")])
9993
9994 ;; Convert lea to the lea pattern to avoid flags dependency.
9995 (define_split
9996   [(set (match_operand:DI 0 "register_operand" "")
9997         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
9998                    (match_operand:QI 2 "const_int_operand" "")))
9999    (clobber (reg:CC FLAGS_REG))]
10000   "TARGET_64BIT && reload_completed
10001    && true_regnum (operands[0]) != true_regnum (operands[1])"
10002   [(set (match_dup 0)
10003         (mult:DI (match_dup 1)
10004                  (match_dup 2)))]
10005   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10006
10007 ;; Convert lea to the lea pattern to avoid flags dependency.
10008 (define_split
10009   [(set (match_operand 0 "register_operand" "")
10010         (ashift (match_operand 1 "index_register_operand" "")
10011                 (match_operand:QI 2 "const_int_operand" "")))
10012    (clobber (reg:CC FLAGS_REG))]
10013   "reload_completed
10014    && true_regnum (operands[0]) != true_regnum (operands[1])
10015    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10016   [(const_int 0)]
10017 {
10018   rtx pat;
10019   enum machine_mode mode = GET_MODE (operands[0]);
10020
10021   if (GET_MODE_SIZE (mode) < 4)
10022     operands[0] = gen_lowpart (SImode, operands[0]);
10023   if (mode != Pmode)
10024     operands[1] = gen_lowpart (Pmode, operands[1]);
10025   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10026
10027   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10028   if (Pmode != SImode)
10029     pat = gen_rtx_SUBREG (SImode, pat, 0);
10030   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10031   DONE;
10032 })
10033
10034 ;; Rare case of shifting RSP is handled by generating move and shift
10035 (define_split
10036   [(set (match_operand 0 "register_operand" "")
10037         (ashift (match_operand 1 "register_operand" "")
10038                 (match_operand:QI 2 "const_int_operand" "")))
10039    (clobber (reg:CC FLAGS_REG))]
10040   "reload_completed
10041    && true_regnum (operands[0]) != true_regnum (operands[1])"
10042   [(const_int 0)]
10043 {
10044   rtx pat, clob;
10045   emit_move_insn (operands[0], operands[1]);
10046   pat = gen_rtx_SET (VOIDmode, operands[0],
10047                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
10048                                      operands[0], operands[2]));
10049   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10050   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10051   DONE;
10052 })
10053
10054 ;; Convert lea to the lea pattern to avoid flags dependency.
10055 (define_split
10056   [(set (match_operand:DI 0 "register_operand" "")
10057         (zero_extend:DI
10058           (ashift:SI (match_operand:SI 1 "register_operand" "")
10059                      (match_operand:QI 2 "const_int_operand" ""))))
10060    (clobber (reg:CC FLAGS_REG))]
10061   "TARGET_64BIT && reload_completed
10062    && true_regnum (operands[0]) != true_regnum (operands[1])"
10063   [(set (match_dup 0)
10064         (zero_extend:DI (subreg:SI (mult:SI (match_dup 1) (match_dup 2)) 0)))]
10065 {
10066   operands[1] = gen_lowpart (Pmode, operands[1]);
10067   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10068 })
10069
10070 ;; This pattern can't accept a variable shift count, since shifts by
10071 ;; zero don't affect the flags.  We assume that shifts by constant
10072 ;; zero are optimized away.
10073 (define_insn "*ashl<mode>3_cmp"
10074   [(set (reg FLAGS_REG)
10075         (compare
10076           (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10077                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10078           (const_int 0)))
10079    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10080         (ashift:SWI (match_dup 1) (match_dup 2)))]
10081   "(optimize_function_for_size_p (cfun)
10082     || !TARGET_PARTIAL_FLAG_REG_STALL
10083     || (operands[2] == const1_rtx
10084         && (TARGET_SHIFT1
10085             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
10086    && ix86_match_ccmode (insn, CCGOCmode)
10087    && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
10088 {
10089   switch (get_attr_type (insn))
10090     {
10091     case TYPE_ALU:
10092       gcc_assert (operands[2] == const1_rtx);
10093       return "add{<imodesuffix>}\t%0, %0";
10094
10095     default:
10096       if (operands[2] == const1_rtx
10097           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10098         return "sal{<imodesuffix>}\t%0";
10099       else
10100         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10101     }
10102 }
10103   [(set (attr "type")
10104      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10105                           (const_int 0))
10106                       (match_operand 0 "register_operand" ""))
10107                  (match_operand 2 "const1_operand" ""))
10108               (const_string "alu")
10109            ]
10110            (const_string "ishift")))
10111    (set (attr "length_immediate")
10112      (if_then_else
10113        (ior (eq_attr "type" "alu")
10114             (and (eq_attr "type" "ishift")
10115                  (and (match_operand 2 "const1_operand" "")
10116                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10117                           (const_int 0)))))
10118        (const_string "0")
10119        (const_string "*")))
10120    (set_attr "mode" "<MODE>")])
10121
10122 (define_insn "*ashlsi3_cmp_zext"
10123   [(set (reg FLAGS_REG)
10124         (compare
10125           (ashift:SI (match_operand:SI 1 "register_operand" "0")
10126                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10127           (const_int 0)))
10128    (set (match_operand:DI 0 "register_operand" "=r")
10129         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10130   "TARGET_64BIT
10131    && (optimize_function_for_size_p (cfun)
10132        || !TARGET_PARTIAL_FLAG_REG_STALL
10133        || (operands[2] == const1_rtx
10134            && (TARGET_SHIFT1
10135                || TARGET_DOUBLE_WITH_ADD)))
10136    && ix86_match_ccmode (insn, CCGOCmode)
10137    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10138 {
10139   switch (get_attr_type (insn))
10140     {
10141     case TYPE_ALU:
10142       gcc_assert (operands[2] == const1_rtx);
10143       return "add{l}\t%k0, %k0";
10144
10145     default:
10146       if (operands[2] == const1_rtx
10147           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10148         return "sal{l}\t%k0";
10149       else
10150         return "sal{l}\t{%2, %k0|%k0, %2}";
10151     }
10152 }
10153   [(set (attr "type")
10154      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10155                      (const_int 0))
10156                  (match_operand 2 "const1_operand" ""))
10157               (const_string "alu")
10158            ]
10159            (const_string "ishift")))
10160    (set (attr "length_immediate")
10161      (if_then_else
10162        (ior (eq_attr "type" "alu")
10163             (and (eq_attr "type" "ishift")
10164                  (and (match_operand 2 "const1_operand" "")
10165                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10166                           (const_int 0)))))
10167        (const_string "0")
10168        (const_string "*")))
10169    (set_attr "mode" "SI")])
10170
10171 (define_insn "*ashl<mode>3_cconly"
10172   [(set (reg FLAGS_REG)
10173         (compare
10174           (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10175                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10176           (const_int 0)))
10177    (clobber (match_scratch:SWI 0 "=<r>"))]
10178   "(optimize_function_for_size_p (cfun)
10179     || !TARGET_PARTIAL_FLAG_REG_STALL
10180     || (operands[2] == const1_rtx
10181         && (TARGET_SHIFT1
10182             || TARGET_DOUBLE_WITH_ADD)))
10183    && ix86_match_ccmode (insn, CCGOCmode)
10184    && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
10185 {
10186   switch (get_attr_type (insn))
10187     {
10188     case TYPE_ALU:
10189       gcc_assert (operands[2] == const1_rtx);
10190       return "add{<imodesuffix>}\t%0, %0";
10191
10192     default:
10193       if (operands[2] == const1_rtx
10194           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10195         return "sal{<imodesuffix>}\t%0";
10196       else
10197         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10198     }
10199 }
10200   [(set (attr "type")
10201      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10202                           (const_int 0))
10203                       (match_operand 0 "register_operand" ""))
10204                  (match_operand 2 "const1_operand" ""))
10205               (const_string "alu")
10206            ]
10207            (const_string "ishift")))
10208    (set (attr "length_immediate")
10209      (if_then_else
10210        (ior (eq_attr "type" "alu")
10211             (and (eq_attr "type" "ishift")
10212                  (and (match_operand 2 "const1_operand" "")
10213                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10214                           (const_int 0)))))
10215        (const_string "0")
10216        (const_string "*")))
10217    (set_attr "mode" "<MODE>")])
10218
10219 ;; See comment above `ashl<mode>3' about how this works.
10220
10221 (define_expand "<shiftrt_insn><mode>3"
10222   [(set (match_operand:SDWIM 0 "<shift_operand>" "")
10223         (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
10224                            (match_operand:QI 2 "nonmemory_operand" "")))]
10225   ""
10226   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10227
10228 (define_insn_and_split "*<shiftrt_insn><mode>3_doubleword"
10229   [(set (match_operand:DWI 0 "register_operand" "=r")
10230         (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
10231                          (match_operand:QI 2 "nonmemory_operand" "<S>c")))
10232    (clobber (reg:CC FLAGS_REG))]
10233   ""
10234   "#"
10235   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
10236   [(const_int 0)]
10237   "ix86_split_<shiftrt_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
10238   [(set_attr "type" "multi")])
10239
10240 ;; By default we don't ask for a scratch register, because when DWImode
10241 ;; values are manipulated, registers are already at a premium.  But if
10242 ;; we have one handy, we won't turn it away.
10243
10244 (define_peephole2
10245   [(match_scratch:DWIH 3 "r")
10246    (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
10247                    (any_shiftrt:<DWI>
10248                      (match_operand:<DWI> 1 "register_operand" "")
10249                      (match_operand:QI 2 "nonmemory_operand" "")))
10250               (clobber (reg:CC FLAGS_REG))])
10251    (match_dup 3)]
10252   "TARGET_CMOVE"
10253   [(const_int 0)]
10254   "ix86_split_<shiftrt_insn> (operands, operands[3], <DWI>mode); DONE;")
10255
10256 (define_insn "x86_64_shrd"
10257   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
10258         (ior:DI (ashiftrt:DI (match_dup 0)
10259                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
10260                 (ashift:DI (match_operand:DI 1 "register_operand" "r")
10261                   (minus:QI (const_int 64) (match_dup 2)))))
10262    (clobber (reg:CC FLAGS_REG))]
10263   "TARGET_64BIT"
10264   "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
10265   [(set_attr "type" "ishift")
10266    (set_attr "prefix_0f" "1")
10267    (set_attr "mode" "DI")
10268    (set_attr "athlon_decode" "vector")
10269    (set_attr "amdfam10_decode" "vector")])
10270
10271 (define_insn "x86_shrd"
10272   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
10273         (ior:SI (ashiftrt:SI (match_dup 0)
10274                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
10275                 (ashift:SI (match_operand:SI 1 "register_operand" "r")
10276                   (minus:QI (const_int 32) (match_dup 2)))))
10277    (clobber (reg:CC FLAGS_REG))]
10278   ""
10279   "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
10280   [(set_attr "type" "ishift")
10281    (set_attr "prefix_0f" "1")
10282    (set_attr "pent_pair" "np")
10283    (set_attr "mode" "SI")])
10284
10285 (define_insn "ashrdi3_cvt"
10286   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
10287         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
10288                      (match_operand:QI 2 "const_int_operand" "")))
10289    (clobber (reg:CC FLAGS_REG))]
10290   "TARGET_64BIT && INTVAL (operands[2]) == 63
10291    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10292    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10293   "@
10294    {cqto|cqo}
10295    sar{q}\t{%2, %0|%0, %2}"
10296   [(set_attr "type" "imovx,ishift")
10297    (set_attr "prefix_0f" "0,*")
10298    (set_attr "length_immediate" "0,*")
10299    (set_attr "modrm" "0,1")
10300    (set_attr "mode" "DI")])
10301
10302 (define_insn "ashrsi3_cvt"
10303   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
10304         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
10305                      (match_operand:QI 2 "const_int_operand" "")))
10306    (clobber (reg:CC FLAGS_REG))]
10307   "INTVAL (operands[2]) == 31
10308    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10309    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10310   "@
10311    {cltd|cdq}
10312    sar{l}\t{%2, %0|%0, %2}"
10313   [(set_attr "type" "imovx,ishift")
10314    (set_attr "prefix_0f" "0,*")
10315    (set_attr "length_immediate" "0,*")
10316    (set_attr "modrm" "0,1")
10317    (set_attr "mode" "SI")])
10318
10319 (define_insn "*ashrsi3_cvt_zext"
10320   [(set (match_operand:DI 0 "register_operand" "=*d,r")
10321         (zero_extend:DI
10322           (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
10323                        (match_operand:QI 2 "const_int_operand" ""))))
10324    (clobber (reg:CC FLAGS_REG))]
10325   "TARGET_64BIT && INTVAL (operands[2]) == 31
10326    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10327    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10328   "@
10329    {cltd|cdq}
10330    sar{l}\t{%2, %k0|%k0, %2}"
10331   [(set_attr "type" "imovx,ishift")
10332    (set_attr "prefix_0f" "0,*")
10333    (set_attr "length_immediate" "0,*")
10334    (set_attr "modrm" "0,1")
10335    (set_attr "mode" "SI")])
10336
10337 (define_expand "x86_shift<mode>_adj_3"
10338   [(use (match_operand:SWI48 0 "register_operand" ""))
10339    (use (match_operand:SWI48 1 "register_operand" ""))
10340    (use (match_operand:QI 2 "register_operand" ""))]
10341   ""
10342 {
10343   rtx label = gen_label_rtx ();
10344   rtx tmp;
10345
10346   emit_insn (gen_testqi_ccz_1 (operands[2],
10347                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
10348
10349   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10350   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10351   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10352                               gen_rtx_LABEL_REF (VOIDmode, label),
10353                               pc_rtx);
10354   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10355   JUMP_LABEL (tmp) = label;
10356
10357   emit_move_insn (operands[0], operands[1]);
10358   emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
10359                                   GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
10360   emit_label (label);
10361   LABEL_NUSES (label) = 1;
10362
10363   DONE;
10364 })
10365
10366 (define_insn "*<shiftrt_insn><mode>3_1"
10367   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10368         (any_shiftrt:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10369                          (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10370    (clobber (reg:CC FLAGS_REG))]
10371   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10372 {
10373   if (REG_P (operands[2]))
10374     return "<shiftrt>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
10375   else if (operands[2] == const1_rtx
10376            && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10377     return "<shiftrt>{<imodesuffix>}\t%0";
10378   else
10379     return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
10380 }
10381   [(set_attr "type" "ishift")
10382    (set (attr "length_immediate")
10383      (if_then_else
10384        (and (match_operand 2 "const1_operand" "")
10385             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10386                 (const_int 0)))
10387        (const_string "0")
10388        (const_string "*")))
10389    (set_attr "mode" "<MODE>")])
10390
10391 (define_insn "*<shiftrt_insn>si3_1_zext"
10392   [(set (match_operand:DI 0 "register_operand" "=r")
10393         (zero_extend:DI
10394           (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10395                           (match_operand:QI 2 "nonmemory_operand" "cI"))))
10396    (clobber (reg:CC FLAGS_REG))]
10397   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10398 {
10399   if (REG_P (operands[2]))
10400     return "<shiftrt>{l}\t{%b2, %k0|%k0, %b2}";
10401   else if (operands[2] == const1_rtx
10402            && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10403     return "<shiftrt>{l}\t%k0";
10404   else
10405     return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
10406 }
10407   [(set_attr "type" "ishift")
10408    (set (attr "length_immediate")
10409      (if_then_else
10410        (and (match_operand 2 "const1_operand" "")
10411             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10412                 (const_int 0)))
10413        (const_string "0")
10414        (const_string "*")))
10415    (set_attr "mode" "SI")])
10416
10417 (define_insn "*<shiftrt_insn>qi3_1_slp"
10418   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10419         (any_shiftrt:QI (match_dup 0)
10420                         (match_operand:QI 1 "nonmemory_operand" "cI")))
10421    (clobber (reg:CC FLAGS_REG))]
10422   "(optimize_function_for_size_p (cfun)
10423     || !TARGET_PARTIAL_REG_STALL
10424     || (operands[1] == const1_rtx
10425         && TARGET_SHIFT1))"
10426 {
10427   if (REG_P (operands[1]))
10428     return "<shiftrt>{b}\t{%b1, %0|%0, %b1}";
10429   else if (operands[1] == const1_rtx
10430            && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10431     return "<shiftrt>{b}\t%0";
10432   else
10433     return "<shiftrt>{b}\t{%1, %0|%0, %1}";
10434 }
10435   [(set_attr "type" "ishift1")
10436    (set (attr "length_immediate")
10437      (if_then_else
10438        (and (match_operand 1 "const1_operand" "")
10439             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10440                 (const_int 0)))
10441        (const_string "0")
10442        (const_string "*")))
10443    (set_attr "mode" "QI")])
10444
10445 ;; This pattern can't accept a variable shift count, since shifts by
10446 ;; zero don't affect the flags.  We assume that shifts by constant
10447 ;; zero are optimized away.
10448 (define_insn "*<shiftrt_insn><mode>3_cmp"
10449   [(set (reg FLAGS_REG)
10450         (compare
10451           (any_shiftrt:SWI
10452             (match_operand:SWI 1 "nonimmediate_operand" "0")
10453             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10454           (const_int 0)))
10455    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10456         (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
10457   "(optimize_function_for_size_p (cfun)
10458     || !TARGET_PARTIAL_FLAG_REG_STALL
10459     || (operands[2] == const1_rtx
10460         && TARGET_SHIFT1))
10461    && ix86_match_ccmode (insn, CCGOCmode)
10462    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10463 {
10464   if (operands[2] == const1_rtx
10465       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10466     return "<shiftrt>{<imodesuffix>}\t%0";
10467   else
10468     return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
10469 }
10470   [(set_attr "type" "ishift")
10471    (set (attr "length_immediate")
10472      (if_then_else
10473        (and (match_operand 2 "const1_operand" "")
10474             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10475                 (const_int 0)))
10476        (const_string "0")
10477        (const_string "*")))
10478    (set_attr "mode" "<MODE>")])
10479
10480 (define_insn "*<shiftrt_insn>si3_cmp_zext"
10481   [(set (reg FLAGS_REG)
10482         (compare
10483           (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10484                           (match_operand:QI 2 "const_1_to_31_operand" "I"))
10485           (const_int 0)))
10486    (set (match_operand:DI 0 "register_operand" "=r")
10487         (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10488   "TARGET_64BIT
10489    && (optimize_function_for_size_p (cfun)
10490        || !TARGET_PARTIAL_FLAG_REG_STALL
10491        || (operands[2] == const1_rtx
10492            && TARGET_SHIFT1))
10493    && ix86_match_ccmode (insn, CCGOCmode)
10494    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10495 {
10496   if (operands[2] == const1_rtx
10497       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10498     return "<shiftrt>{l}\t%k0";
10499   else
10500     return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
10501 }
10502   [(set_attr "type" "ishift")
10503    (set (attr "length_immediate")
10504      (if_then_else
10505        (and (match_operand 2 "const1_operand" "")
10506             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10507                 (const_int 0)))
10508        (const_string "0")
10509        (const_string "*")))
10510    (set_attr "mode" "SI")])
10511
10512 (define_insn "*<shiftrt_insn><mode>3_cconly"
10513   [(set (reg FLAGS_REG)
10514         (compare
10515           (any_shiftrt:SWI
10516             (match_operand:SWI 1 "nonimmediate_operand" "0")
10517             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10518           (const_int 0)))
10519    (clobber (match_scratch:SWI 0 "=<r>"))]
10520   "(optimize_function_for_size_p (cfun)
10521     || !TARGET_PARTIAL_FLAG_REG_STALL
10522     || (operands[2] == const1_rtx
10523         && TARGET_SHIFT1))
10524    && ix86_match_ccmode (insn, CCGOCmode)
10525    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10526 {
10527   if (operands[2] == const1_rtx
10528       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10529     return "<shiftrt>{<imodesuffix>}\t%0";
10530   else
10531     return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
10532 }
10533   [(set_attr "type" "ishift")
10534    (set (attr "length_immediate")
10535      (if_then_else
10536        (and (match_operand 2 "const1_operand" "")
10537             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10538                 (const_int 0)))
10539        (const_string "0")
10540        (const_string "*")))
10541    (set_attr "mode" "<MODE>")])
10542 \f
10543 ;; Rotate instructions
10544
10545 (define_expand "rotldi3"
10546   [(set (match_operand:DI 0 "shiftdi_operand" "")
10547         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
10548                    (match_operand:QI 2 "nonmemory_operand" "")))]
10549  ""
10550 {
10551   if (TARGET_64BIT)
10552     {
10553       ix86_expand_binary_operator (ROTATE, DImode, operands);
10554       DONE;
10555     }
10556   if (!const_1_to_31_operand (operands[2], VOIDmode))
10557     FAIL;
10558   emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
10559   DONE;
10560 })
10561
10562 ;; Implement rotation using two double-precision shift instructions
10563 ;; and a scratch register.
10564 (define_insn_and_split "ix86_rotldi3"
10565  [(set (match_operand:DI 0 "register_operand" "=r")
10566        (rotate:DI (match_operand:DI 1 "register_operand" "0")
10567                   (match_operand:QI 2 "const_1_to_31_operand" "I")))
10568   (clobber (reg:CC FLAGS_REG))
10569   (clobber (match_scratch:SI 3 "=&r"))]
10570  "!TARGET_64BIT"
10571  ""
10572  "&& reload_completed"
10573  [(set (match_dup 3) (match_dup 4))
10574   (parallel
10575    [(set (match_dup 4)
10576          (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
10577                  (lshiftrt:SI (match_dup 5)
10578                               (minus:QI (const_int 32) (match_dup 2)))))
10579     (clobber (reg:CC FLAGS_REG))])
10580   (parallel
10581    [(set (match_dup 5)
10582          (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
10583                  (lshiftrt:SI (match_dup 3)
10584                               (minus:QI (const_int 32) (match_dup 2)))))
10585     (clobber (reg:CC FLAGS_REG))])]
10586  "split_di (&operands[0], 1, &operands[4], &operands[5]);")
10587
10588 (define_insn "*rotlsi3_1_one_bit_rex64"
10589   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10590         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10591                    (match_operand:QI 2 "const1_operand" "")))
10592    (clobber (reg:CC FLAGS_REG))]
10593   "TARGET_64BIT
10594    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
10595    && ix86_binary_operator_ok (ROTATE, DImode, operands)"
10596   "rol{q}\t%0"
10597   [(set_attr "type" "rotate")
10598    (set_attr "length_immediate" "0")
10599    (set_attr "mode" "DI")])
10600
10601 (define_insn "*rotldi3_1_rex64"
10602   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
10603         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
10604                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
10605    (clobber (reg:CC FLAGS_REG))]
10606   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
10607   "@
10608    rol{q}\t{%2, %0|%0, %2}
10609    rol{q}\t{%b2, %0|%0, %b2}"
10610   [(set_attr "type" "rotate")
10611    (set_attr "mode" "DI")])
10612
10613 (define_expand "rotlsi3"
10614   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10615         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
10616                    (match_operand:QI 2 "nonmemory_operand" "")))]
10617   ""
10618   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
10619
10620 (define_insn "*rotlsi3_1_one_bit"
10621   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10622         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10623                    (match_operand:QI 2 "const1_operand" "")))
10624    (clobber (reg:CC FLAGS_REG))]
10625   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
10626    && ix86_binary_operator_ok (ROTATE, SImode, operands)"
10627   "rol{l}\t%0"
10628   [(set_attr "type" "rotate")
10629    (set_attr "length_immediate" "0")
10630    (set_attr "mode" "SI")])
10631
10632 (define_insn "*rotlsi3_1_one_bit_zext"
10633   [(set (match_operand:DI 0 "register_operand" "=r")
10634         (zero_extend:DI
10635           (rotate:SI (match_operand:SI 1 "register_operand" "0")
10636                      (match_operand:QI 2 "const1_operand" ""))))
10637    (clobber (reg:CC FLAGS_REG))]
10638   "TARGET_64BIT
10639    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
10640    && ix86_binary_operator_ok (ROTATE, SImode, operands)"
10641   "rol{l}\t%k0"
10642   [(set_attr "type" "rotate")
10643    (set_attr "length_immediate" "0")
10644    (set_attr "mode" "SI")])
10645
10646 (define_insn "*rotlsi3_1"
10647   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
10648         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
10649                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
10650    (clobber (reg:CC FLAGS_REG))]
10651   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
10652   "@
10653    rol{l}\t{%2, %0|%0, %2}
10654    rol{l}\t{%b2, %0|%0, %b2}"
10655   [(set_attr "type" "rotate")
10656    (set_attr "mode" "SI")])
10657
10658 (define_insn "*rotlsi3_1_zext"
10659   [(set (match_operand:DI 0 "register_operand" "=r,r")
10660         (zero_extend:DI
10661           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
10662                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
10663    (clobber (reg:CC FLAGS_REG))]
10664   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
10665   "@
10666    rol{l}\t{%2, %k0|%k0, %2}
10667    rol{l}\t{%b2, %k0|%k0, %b2}"
10668   [(set_attr "type" "rotate")
10669    (set_attr "mode" "SI")])
10670
10671 (define_expand "rotlhi3"
10672   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10673         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
10674                    (match_operand:QI 2 "nonmemory_operand" "")))]
10675   "TARGET_HIMODE_MATH"
10676   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
10677
10678 (define_insn "*rotlhi3_1_one_bit"
10679   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10680         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10681                    (match_operand:QI 2 "const1_operand" "")))
10682    (clobber (reg:CC FLAGS_REG))]
10683   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
10684    && ix86_binary_operator_ok (ROTATE, HImode, operands)"
10685   "rol{w}\t%0"
10686   [(set_attr "type" "rotate")
10687    (set_attr "length_immediate" "0")
10688    (set_attr "mode" "HI")])
10689
10690 (define_insn "*rotlhi3_1"
10691   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
10692         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
10693                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
10694    (clobber (reg:CC FLAGS_REG))]
10695   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
10696   "@
10697    rol{w}\t{%2, %0|%0, %2}
10698    rol{w}\t{%b2, %0|%0, %b2}"
10699   [(set_attr "type" "rotate")
10700    (set_attr "mode" "HI")])
10701
10702 (define_split
10703  [(set (match_operand:HI 0 "register_operand" "")
10704        (rotate:HI (match_dup 0) (const_int 8)))
10705   (clobber (reg:CC FLAGS_REG))]
10706  "reload_completed"
10707  [(parallel [(set (strict_low_part (match_dup 0))
10708                   (bswap:HI (match_dup 0)))
10709              (clobber (reg:CC FLAGS_REG))])]
10710  "")
10711
10712 (define_expand "rotlqi3"
10713   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10714         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
10715                    (match_operand:QI 2 "nonmemory_operand" "")))]
10716   "TARGET_QIMODE_MATH"
10717   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
10718
10719 (define_insn "*rotlqi3_1_one_bit_slp"
10720   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10721         (rotate:QI (match_dup 0)
10722                    (match_operand:QI 1 "const1_operand" "")))
10723    (clobber (reg:CC FLAGS_REG))]
10724   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10725    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
10726   "rol{b}\t%0"
10727   [(set_attr "type" "rotate1")
10728    (set_attr "length_immediate" "0")
10729    (set_attr "mode" "QI")])
10730
10731 (define_insn "*rotlqi3_1_one_bit"
10732   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10733         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
10734                    (match_operand:QI 2 "const1_operand" "")))
10735    (clobber (reg:CC FLAGS_REG))]
10736   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
10737    && ix86_binary_operator_ok (ROTATE, QImode, operands)"
10738   "rol{b}\t%0"
10739   [(set_attr "type" "rotate")
10740    (set_attr "length_immediate" "0")
10741    (set_attr "mode" "QI")])
10742
10743 (define_insn "*rotlqi3_1_slp"
10744   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
10745         (rotate:QI (match_dup 0)
10746                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
10747    (clobber (reg:CC FLAGS_REG))]
10748   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10749    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
10750   "@
10751    rol{b}\t{%1, %0|%0, %1}
10752    rol{b}\t{%b1, %0|%0, %b1}"
10753   [(set_attr "type" "rotate1")
10754    (set_attr "mode" "QI")])
10755
10756 (define_insn "*rotlqi3_1"
10757   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
10758         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
10759                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
10760    (clobber (reg:CC FLAGS_REG))]
10761   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
10762   "@
10763    rol{b}\t{%2, %0|%0, %2}
10764    rol{b}\t{%b2, %0|%0, %b2}"
10765   [(set_attr "type" "rotate")
10766    (set_attr "mode" "QI")])
10767
10768 (define_expand "rotrdi3"
10769   [(set (match_operand:DI 0 "shiftdi_operand" "")
10770         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
10771                    (match_operand:QI 2 "nonmemory_operand" "")))]
10772  ""
10773 {
10774   if (TARGET_64BIT)
10775     {
10776       ix86_expand_binary_operator (ROTATERT, DImode, operands);
10777       DONE;
10778     }
10779   if (!const_1_to_31_operand (operands[2], VOIDmode))
10780     FAIL;
10781   emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
10782   DONE;
10783 })
10784
10785 ;; Implement rotation using two double-precision shift instructions
10786 ;; and a scratch register.
10787 (define_insn_and_split "ix86_rotrdi3"
10788  [(set (match_operand:DI 0 "register_operand" "=r")
10789        (rotatert:DI (match_operand:DI 1 "register_operand" "0")
10790                     (match_operand:QI 2 "const_1_to_31_operand" "I")))
10791   (clobber (reg:CC FLAGS_REG))
10792   (clobber (match_scratch:SI 3 "=&r"))]
10793  "!TARGET_64BIT"
10794  ""
10795  "&& reload_completed"
10796  [(set (match_dup 3) (match_dup 4))
10797   (parallel
10798    [(set (match_dup 4)
10799          (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
10800                  (ashift:SI (match_dup 5)
10801                             (minus:QI (const_int 32) (match_dup 2)))))
10802     (clobber (reg:CC FLAGS_REG))])
10803   (parallel
10804    [(set (match_dup 5)
10805          (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
10806                  (ashift:SI (match_dup 3)
10807                             (minus:QI (const_int 32) (match_dup 2)))))
10808     (clobber (reg:CC FLAGS_REG))])]
10809  "split_di (&operands[0], 1, &operands[4], &operands[5]);")
10810
10811 (define_insn "*rotrdi3_1_one_bit_rex64"
10812   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10813         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10814                      (match_operand:QI 2 "const1_operand" "")))
10815    (clobber (reg:CC FLAGS_REG))]
10816   "TARGET_64BIT
10817    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
10818    && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
10819   "ror{q}\t%0"
10820   [(set_attr "type" "rotate")
10821    (set_attr "length_immediate" "0")
10822    (set_attr "mode" "DI")])
10823
10824 (define_insn "*rotrdi3_1_rex64"
10825   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
10826         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
10827                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
10828    (clobber (reg:CC FLAGS_REG))]
10829   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
10830   "@
10831    ror{q}\t{%2, %0|%0, %2}
10832    ror{q}\t{%b2, %0|%0, %b2}"
10833   [(set_attr "type" "rotate")
10834    (set_attr "mode" "DI")])
10835
10836 (define_expand "rotrsi3"
10837   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10838         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
10839                      (match_operand:QI 2 "nonmemory_operand" "")))]
10840   ""
10841   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
10842
10843 (define_insn "*rotrsi3_1_one_bit"
10844   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10845         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10846                      (match_operand:QI 2 "const1_operand" "")))
10847    (clobber (reg:CC FLAGS_REG))]
10848   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
10849    && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
10850   "ror{l}\t%0"
10851   [(set_attr "type" "rotate")
10852    (set_attr "length_immediate" "0")
10853    (set_attr "mode" "SI")])
10854
10855 (define_insn "*rotrsi3_1_one_bit_zext"
10856   [(set (match_operand:DI 0 "register_operand" "=r")
10857         (zero_extend:DI
10858           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
10859                        (match_operand:QI 2 "const1_operand" ""))))
10860    (clobber (reg:CC FLAGS_REG))]
10861   "TARGET_64BIT
10862    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
10863    && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
10864   "ror{l}\t%k0"
10865   [(set_attr "type" "rotate")
10866    (set_attr "length_immediate" "0")
10867    (set_attr "mode" "SI")])
10868
10869 (define_insn "*rotrsi3_1"
10870   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
10871         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
10872                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
10873    (clobber (reg:CC FLAGS_REG))]
10874   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
10875   "@
10876    ror{l}\t{%2, %0|%0, %2}
10877    ror{l}\t{%b2, %0|%0, %b2}"
10878   [(set_attr "type" "rotate")
10879    (set_attr "mode" "SI")])
10880
10881 (define_insn "*rotrsi3_1_zext"
10882   [(set (match_operand:DI 0 "register_operand" "=r,r")
10883         (zero_extend:DI
10884           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
10885                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
10886    (clobber (reg:CC FLAGS_REG))]
10887   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
10888   "@
10889    ror{l}\t{%2, %k0|%k0, %2}
10890    ror{l}\t{%b2, %k0|%k0, %b2}"
10891   [(set_attr "type" "rotate")
10892    (set_attr "mode" "SI")])
10893
10894 (define_expand "rotrhi3"
10895   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10896         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
10897                      (match_operand:QI 2 "nonmemory_operand" "")))]
10898   "TARGET_HIMODE_MATH"
10899   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
10900
10901 (define_insn "*rotrhi3_one_bit"
10902   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10903         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10904                      (match_operand:QI 2 "const1_operand" "")))
10905    (clobber (reg:CC FLAGS_REG))]
10906   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
10907    && ix86_binary_operator_ok (ROTATERT, HImode, operands)"
10908   "ror{w}\t%0"
10909   [(set_attr "type" "rotate")
10910    (set_attr "length_immediate" "0")
10911    (set_attr "mode" "HI")])
10912
10913 (define_insn "*rotrhi3_1"
10914   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
10915         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
10916                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
10917    (clobber (reg:CC FLAGS_REG))]
10918   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
10919   "@
10920    ror{w}\t{%2, %0|%0, %2}
10921    ror{w}\t{%b2, %0|%0, %b2}"
10922   [(set_attr "type" "rotate")
10923    (set_attr "mode" "HI")])
10924
10925 (define_split
10926  [(set (match_operand:HI 0 "register_operand" "")
10927        (rotatert:HI (match_dup 0) (const_int 8)))
10928   (clobber (reg:CC FLAGS_REG))]
10929  "reload_completed"
10930  [(parallel [(set (strict_low_part (match_dup 0))
10931                   (bswap:HI (match_dup 0)))
10932              (clobber (reg:CC FLAGS_REG))])]
10933  "")
10934
10935 (define_expand "rotrqi3"
10936   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10937         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
10938                      (match_operand:QI 2 "nonmemory_operand" "")))]
10939   "TARGET_QIMODE_MATH"
10940   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
10941
10942 (define_insn "*rotrqi3_1_one_bit"
10943   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10944         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
10945                      (match_operand:QI 2 "const1_operand" "")))
10946    (clobber (reg:CC FLAGS_REG))]
10947   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
10948    && ix86_binary_operator_ok (ROTATERT, QImode, operands)"
10949   "ror{b}\t%0"
10950   [(set_attr "type" "rotate")
10951    (set_attr "length_immediate" "0")
10952    (set_attr "mode" "QI")])
10953
10954 (define_insn "*rotrqi3_1_one_bit_slp"
10955   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10956         (rotatert:QI (match_dup 0)
10957                      (match_operand:QI 1 "const1_operand" "")))
10958    (clobber (reg:CC FLAGS_REG))]
10959   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10960    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
10961   "ror{b}\t%0"
10962   [(set_attr "type" "rotate1")
10963    (set_attr "length_immediate" "0")
10964    (set_attr "mode" "QI")])
10965
10966 (define_insn "*rotrqi3_1"
10967   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
10968         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
10969                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
10970    (clobber (reg:CC FLAGS_REG))]
10971   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
10972   "@
10973    ror{b}\t{%2, %0|%0, %2}
10974    ror{b}\t{%b2, %0|%0, %b2}"
10975   [(set_attr "type" "rotate")
10976    (set_attr "mode" "QI")])
10977
10978 (define_insn "*rotrqi3_1_slp"
10979   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
10980         (rotatert:QI (match_dup 0)
10981                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
10982    (clobber (reg:CC FLAGS_REG))]
10983   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10984    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
10985   "@
10986    ror{b}\t{%1, %0|%0, %1}
10987    ror{b}\t{%b1, %0|%0, %b1}"
10988   [(set_attr "type" "rotate1")
10989    (set_attr "mode" "QI")])
10990 \f
10991 ;; Bit set / bit test instructions
10992
10993 (define_expand "extv"
10994   [(set (match_operand:SI 0 "register_operand" "")
10995         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10996                          (match_operand:SI 2 "const8_operand" "")
10997                          (match_operand:SI 3 "const8_operand" "")))]
10998   ""
10999 {
11000   /* Handle extractions from %ah et al.  */
11001   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
11002     FAIL;
11003
11004   /* From mips.md: extract_bit_field doesn't verify that our source
11005      matches the predicate, so check it again here.  */
11006   if (! ext_register_operand (operands[1], VOIDmode))
11007     FAIL;
11008 })
11009
11010 (define_expand "extzv"
11011   [(set (match_operand:SI 0 "register_operand" "")
11012         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
11013                          (match_operand:SI 2 "const8_operand" "")
11014                          (match_operand:SI 3 "const8_operand" "")))]
11015   ""
11016 {
11017   /* Handle extractions from %ah et al.  */
11018   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
11019     FAIL;
11020
11021   /* From mips.md: extract_bit_field doesn't verify that our source
11022      matches the predicate, so check it again here.  */
11023   if (! ext_register_operand (operands[1], VOIDmode))
11024     FAIL;
11025 })
11026
11027 (define_expand "insv"
11028   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
11029                       (match_operand 1 "const8_operand" "")
11030                       (match_operand 2 "const8_operand" ""))
11031         (match_operand 3 "register_operand" ""))]
11032   ""
11033 {
11034   /* Handle insertions to %ah et al.  */
11035   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
11036     FAIL;
11037
11038   /* From mips.md: insert_bit_field doesn't verify that our source
11039      matches the predicate, so check it again here.  */
11040   if (! ext_register_operand (operands[0], VOIDmode))
11041     FAIL;
11042
11043   if (TARGET_64BIT)
11044     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
11045   else
11046     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
11047
11048   DONE;
11049 })
11050
11051 ;; %%% bts, btr, btc, bt.
11052 ;; In general these instructions are *slow* when applied to memory,
11053 ;; since they enforce atomic operation.  When applied to registers,
11054 ;; it depends on the cpu implementation.  They're never faster than
11055 ;; the corresponding and/ior/xor operations, so with 32-bit there's
11056 ;; no point.  But in 64-bit, we can't hold the relevant immediates
11057 ;; within the instruction itself, so operating on bits in the high
11058 ;; 32-bits of a register becomes easier.
11059 ;;
11060 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
11061 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
11062 ;; negdf respectively, so they can never be disabled entirely.
11063
11064 (define_insn "*btsq"
11065   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
11066                          (const_int 1)
11067                          (match_operand:DI 1 "const_0_to_63_operand" ""))
11068         (const_int 1))
11069    (clobber (reg:CC FLAGS_REG))]
11070   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
11071   "bts{q}\t{%1, %0|%0, %1}"
11072   [(set_attr "type" "alu1")
11073    (set_attr "prefix_0f" "1")
11074    (set_attr "mode" "DI")])
11075
11076 (define_insn "*btrq"
11077   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
11078                          (const_int 1)
11079                          (match_operand:DI 1 "const_0_to_63_operand" ""))
11080         (const_int 0))
11081    (clobber (reg:CC FLAGS_REG))]
11082   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
11083   "btr{q}\t{%1, %0|%0, %1}"
11084   [(set_attr "type" "alu1")
11085    (set_attr "prefix_0f" "1")
11086    (set_attr "mode" "DI")])
11087
11088 (define_insn "*btcq"
11089   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
11090                          (const_int 1)
11091                          (match_operand:DI 1 "const_0_to_63_operand" ""))
11092         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
11093    (clobber (reg:CC FLAGS_REG))]
11094   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
11095   "btc{q}\t{%1, %0|%0, %1}"
11096   [(set_attr "type" "alu1")
11097    (set_attr "prefix_0f" "1")
11098    (set_attr "mode" "DI")])
11099
11100 ;; Allow Nocona to avoid these instructions if a register is available.
11101
11102 (define_peephole2
11103   [(match_scratch:DI 2 "r")
11104    (parallel [(set (zero_extract:DI
11105                      (match_operand:DI 0 "register_operand" "")
11106                      (const_int 1)
11107                      (match_operand:DI 1 "const_0_to_63_operand" ""))
11108                    (const_int 1))
11109               (clobber (reg:CC FLAGS_REG))])]
11110   "TARGET_64BIT && !TARGET_USE_BT"
11111   [(const_int 0)]
11112 {
11113   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
11114   rtx op1;
11115
11116   if (HOST_BITS_PER_WIDE_INT >= 64)
11117     lo = (HOST_WIDE_INT)1 << i, hi = 0;
11118   else if (i < HOST_BITS_PER_WIDE_INT)
11119     lo = (HOST_WIDE_INT)1 << i, hi = 0;
11120   else
11121     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
11122
11123   op1 = immed_double_const (lo, hi, DImode);
11124   if (i >= 31)
11125     {
11126       emit_move_insn (operands[2], op1);
11127       op1 = operands[2];
11128     }
11129
11130   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
11131   DONE;
11132 })
11133
11134 (define_peephole2
11135   [(match_scratch:DI 2 "r")
11136    (parallel [(set (zero_extract:DI
11137                      (match_operand:DI 0 "register_operand" "")
11138                      (const_int 1)
11139                      (match_operand:DI 1 "const_0_to_63_operand" ""))
11140                    (const_int 0))
11141               (clobber (reg:CC FLAGS_REG))])]
11142   "TARGET_64BIT && !TARGET_USE_BT"
11143   [(const_int 0)]
11144 {
11145   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
11146   rtx op1;
11147
11148   if (HOST_BITS_PER_WIDE_INT >= 64)
11149     lo = (HOST_WIDE_INT)1 << i, hi = 0;
11150   else if (i < HOST_BITS_PER_WIDE_INT)
11151     lo = (HOST_WIDE_INT)1 << i, hi = 0;
11152   else
11153     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
11154
11155   op1 = immed_double_const (~lo, ~hi, DImode);
11156   if (i >= 32)
11157     {
11158       emit_move_insn (operands[2], op1);
11159       op1 = operands[2];
11160     }
11161
11162   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
11163   DONE;
11164 })
11165
11166 (define_peephole2
11167   [(match_scratch:DI 2 "r")
11168    (parallel [(set (zero_extract:DI
11169                      (match_operand:DI 0 "register_operand" "")
11170                      (const_int 1)
11171                      (match_operand:DI 1 "const_0_to_63_operand" ""))
11172               (not:DI (zero_extract:DI
11173                         (match_dup 0) (const_int 1) (match_dup 1))))
11174               (clobber (reg:CC FLAGS_REG))])]
11175   "TARGET_64BIT && !TARGET_USE_BT"
11176   [(const_int 0)]
11177 {
11178   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
11179   rtx op1;
11180
11181   if (HOST_BITS_PER_WIDE_INT >= 64)
11182     lo = (HOST_WIDE_INT)1 << i, hi = 0;
11183   else if (i < HOST_BITS_PER_WIDE_INT)
11184     lo = (HOST_WIDE_INT)1 << i, hi = 0;
11185   else
11186     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
11187
11188   op1 = immed_double_const (lo, hi, DImode);
11189   if (i >= 31)
11190     {
11191       emit_move_insn (operands[2], op1);
11192       op1 = operands[2];
11193     }
11194
11195   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
11196   DONE;
11197 })
11198
11199 (define_insn "*btdi_rex64"
11200   [(set (reg:CCC FLAGS_REG)
11201         (compare:CCC
11202           (zero_extract:DI
11203             (match_operand:DI 0 "register_operand" "r")
11204             (const_int 1)
11205             (match_operand:DI 1 "nonmemory_operand" "rN"))
11206           (const_int 0)))]
11207   "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
11208   "bt{q}\t{%1, %0|%0, %1}"
11209   [(set_attr "type" "alu1")
11210    (set_attr "prefix_0f" "1")
11211    (set_attr "mode" "DI")])
11212
11213 (define_insn "*btsi"
11214   [(set (reg:CCC FLAGS_REG)
11215         (compare:CCC
11216           (zero_extract:SI
11217             (match_operand:SI 0 "register_operand" "r")
11218             (const_int 1)
11219             (match_operand:SI 1 "nonmemory_operand" "rN"))
11220           (const_int 0)))]
11221   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
11222   "bt{l}\t{%1, %0|%0, %1}"
11223   [(set_attr "type" "alu1")
11224    (set_attr "prefix_0f" "1")
11225    (set_attr "mode" "SI")])
11226 \f
11227 ;; Store-flag instructions.
11228
11229 ;; For all sCOND expanders, also expand the compare or test insn that
11230 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
11231
11232 (define_insn_and_split "*setcc_di_1"
11233   [(set (match_operand:DI 0 "register_operand" "=q")
11234         (match_operator:DI 1 "ix86_comparison_operator"
11235           [(reg FLAGS_REG) (const_int 0)]))]
11236   "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
11237   "#"
11238   "&& reload_completed"
11239   [(set (match_dup 2) (match_dup 1))
11240    (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
11241 {
11242   PUT_MODE (operands[1], QImode);
11243   operands[2] = gen_lowpart (QImode, operands[0]);
11244 })
11245
11246 (define_insn_and_split "*setcc_si_1_and"
11247   [(set (match_operand:SI 0 "register_operand" "=q")
11248         (match_operator:SI 1 "ix86_comparison_operator"
11249           [(reg FLAGS_REG) (const_int 0)]))
11250    (clobber (reg:CC FLAGS_REG))]
11251   "!TARGET_PARTIAL_REG_STALL
11252    && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
11253   "#"
11254   "&& reload_completed"
11255   [(set (match_dup 2) (match_dup 1))
11256    (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
11257               (clobber (reg:CC FLAGS_REG))])]
11258 {
11259   PUT_MODE (operands[1], QImode);
11260   operands[2] = gen_lowpart (QImode, operands[0]);
11261 })
11262
11263 (define_insn_and_split "*setcc_si_1_movzbl"
11264   [(set (match_operand:SI 0 "register_operand" "=q")
11265         (match_operator:SI 1 "ix86_comparison_operator"
11266           [(reg FLAGS_REG) (const_int 0)]))]
11267   "!TARGET_PARTIAL_REG_STALL
11268    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
11269   "#"
11270   "&& reload_completed"
11271   [(set (match_dup 2) (match_dup 1))
11272    (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
11273 {
11274   PUT_MODE (operands[1], QImode);
11275   operands[2] = gen_lowpart (QImode, operands[0]);
11276 })
11277
11278 (define_insn "*setcc_qi"
11279   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11280         (match_operator:QI 1 "ix86_comparison_operator"
11281           [(reg FLAGS_REG) (const_int 0)]))]
11282   ""
11283   "set%C1\t%0"
11284   [(set_attr "type" "setcc")
11285    (set_attr "mode" "QI")])
11286
11287 (define_insn "*setcc_qi_slp"
11288   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11289         (match_operator:QI 1 "ix86_comparison_operator"
11290           [(reg FLAGS_REG) (const_int 0)]))]
11291   ""
11292   "set%C1\t%0"
11293   [(set_attr "type" "setcc")
11294    (set_attr "mode" "QI")])
11295
11296 ;; In general it is not safe to assume too much about CCmode registers,
11297 ;; so simplify-rtx stops when it sees a second one.  Under certain
11298 ;; conditions this is safe on x86, so help combine not create
11299 ;;
11300 ;;      seta    %al
11301 ;;      testb   %al, %al
11302 ;;      sete    %al
11303
11304 (define_split
11305   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11306         (ne:QI (match_operator 1 "ix86_comparison_operator"
11307                  [(reg FLAGS_REG) (const_int 0)])
11308             (const_int 0)))]
11309   ""
11310   [(set (match_dup 0) (match_dup 1))]
11311 {
11312   PUT_MODE (operands[1], QImode);
11313 })
11314
11315 (define_split
11316   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
11317         (ne:QI (match_operator 1 "ix86_comparison_operator"
11318                  [(reg FLAGS_REG) (const_int 0)])
11319             (const_int 0)))]
11320   ""
11321   [(set (match_dup 0) (match_dup 1))]
11322 {
11323   PUT_MODE (operands[1], QImode);
11324 })
11325
11326 (define_split
11327   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11328         (eq:QI (match_operator 1 "ix86_comparison_operator"
11329                  [(reg FLAGS_REG) (const_int 0)])
11330             (const_int 0)))]
11331   ""
11332   [(set (match_dup 0) (match_dup 1))]
11333 {
11334   rtx new_op1 = copy_rtx (operands[1]);
11335   operands[1] = new_op1;
11336   PUT_MODE (new_op1, QImode);
11337   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
11338                                              GET_MODE (XEXP (new_op1, 0))));
11339
11340   /* Make sure that (a) the CCmode we have for the flags is strong
11341      enough for the reversed compare or (b) we have a valid FP compare.  */
11342   if (! ix86_comparison_operator (new_op1, VOIDmode))
11343     FAIL;
11344 })
11345
11346 (define_split
11347   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
11348         (eq:QI (match_operator 1 "ix86_comparison_operator"
11349                  [(reg FLAGS_REG) (const_int 0)])
11350             (const_int 0)))]
11351   ""
11352   [(set (match_dup 0) (match_dup 1))]
11353 {
11354   rtx new_op1 = copy_rtx (operands[1]);
11355   operands[1] = new_op1;
11356   PUT_MODE (new_op1, QImode);
11357   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
11358                                              GET_MODE (XEXP (new_op1, 0))));
11359
11360   /* Make sure that (a) the CCmode we have for the flags is strong
11361      enough for the reversed compare or (b) we have a valid FP compare.  */
11362   if (! ix86_comparison_operator (new_op1, VOIDmode))
11363     FAIL;
11364 })
11365
11366 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
11367 ;; subsequent logical operations are used to imitate conditional moves.
11368 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
11369 ;; it directly.
11370
11371 (define_insn "*avx_setcc<mode>"
11372   [(set (match_operand:MODEF 0 "register_operand" "=x")
11373         (match_operator:MODEF 1 "avx_comparison_float_operator"
11374           [(match_operand:MODEF 2 "register_operand" "x")
11375            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
11376   "TARGET_AVX"
11377   "vcmp%D1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
11378   [(set_attr "type" "ssecmp")
11379    (set_attr "prefix" "vex")
11380    (set_attr "length_immediate" "1")
11381    (set_attr "mode" "<MODE>")])
11382
11383 (define_insn "*sse_setcc<mode>"
11384   [(set (match_operand:MODEF 0 "register_operand" "=x")
11385         (match_operator:MODEF 1 "sse_comparison_operator"
11386           [(match_operand:MODEF 2 "register_operand" "0")
11387            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
11388   "SSE_FLOAT_MODE_P (<MODE>mode)"
11389   "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
11390   [(set_attr "type" "ssecmp")
11391    (set_attr "length_immediate" "1")
11392    (set_attr "mode" "<MODE>")])
11393 \f
11394 ;; Basic conditional jump instructions.
11395 ;; We ignore the overflow flag for signed branch instructions.
11396
11397 (define_insn "*jcc_1"
11398   [(set (pc)
11399         (if_then_else (match_operator 1 "ix86_comparison_operator"
11400                                       [(reg FLAGS_REG) (const_int 0)])
11401                       (label_ref (match_operand 0 "" ""))
11402                       (pc)))]
11403   ""
11404   "%+j%C1\t%l0"
11405   [(set_attr "type" "ibr")
11406    (set_attr "modrm" "0")
11407    (set (attr "length")
11408            (if_then_else (and (ge (minus (match_dup 0) (pc))
11409                                   (const_int -126))
11410                               (lt (minus (match_dup 0) (pc))
11411                                   (const_int 128)))
11412              (const_int 2)
11413              (const_int 6)))])
11414
11415 (define_insn "*jcc_2"
11416   [(set (pc)
11417         (if_then_else (match_operator 1 "ix86_comparison_operator"
11418                                       [(reg FLAGS_REG) (const_int 0)])
11419                       (pc)
11420                       (label_ref (match_operand 0 "" ""))))]
11421   ""
11422   "%+j%c1\t%l0"
11423   [(set_attr "type" "ibr")
11424    (set_attr "modrm" "0")
11425    (set (attr "length")
11426            (if_then_else (and (ge (minus (match_dup 0) (pc))
11427                                   (const_int -126))
11428                               (lt (minus (match_dup 0) (pc))
11429                                   (const_int 128)))
11430              (const_int 2)
11431              (const_int 6)))])
11432
11433 ;; In general it is not safe to assume too much about CCmode registers,
11434 ;; so simplify-rtx stops when it sees a second one.  Under certain
11435 ;; conditions this is safe on x86, so help combine not create
11436 ;;
11437 ;;      seta    %al
11438 ;;      testb   %al, %al
11439 ;;      je      Lfoo
11440
11441 (define_split
11442   [(set (pc)
11443         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
11444                                       [(reg FLAGS_REG) (const_int 0)])
11445                           (const_int 0))
11446                       (label_ref (match_operand 1 "" ""))
11447                       (pc)))]
11448   ""
11449   [(set (pc)
11450         (if_then_else (match_dup 0)
11451                       (label_ref (match_dup 1))
11452                       (pc)))]
11453 {
11454   PUT_MODE (operands[0], VOIDmode);
11455 })
11456
11457 (define_split
11458   [(set (pc)
11459         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
11460                                       [(reg FLAGS_REG) (const_int 0)])
11461                           (const_int 0))
11462                       (label_ref (match_operand 1 "" ""))
11463                       (pc)))]
11464   ""
11465   [(set (pc)
11466         (if_then_else (match_dup 0)
11467                       (label_ref (match_dup 1))
11468                       (pc)))]
11469 {
11470   rtx new_op0 = copy_rtx (operands[0]);
11471   operands[0] = new_op0;
11472   PUT_MODE (new_op0, VOIDmode);
11473   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
11474                                              GET_MODE (XEXP (new_op0, 0))));
11475
11476   /* Make sure that (a) the CCmode we have for the flags is strong
11477      enough for the reversed compare or (b) we have a valid FP compare.  */
11478   if (! ix86_comparison_operator (new_op0, VOIDmode))
11479     FAIL;
11480 })
11481
11482 ;; zero_extend in SImode is correct, since this is what combine pass
11483 ;; generates from shift insn with QImode operand.  Actually, the mode of
11484 ;; operand 2 (bit offset operand) doesn't matter since bt insn takes
11485 ;; appropriate modulo of the bit offset value.
11486
11487 (define_insn_and_split "*jcc_btdi_rex64"
11488   [(set (pc)
11489         (if_then_else (match_operator 0 "bt_comparison_operator"
11490                         [(zero_extract:DI
11491                            (match_operand:DI 1 "register_operand" "r")
11492                            (const_int 1)
11493                            (zero_extend:SI
11494                              (match_operand:QI 2 "register_operand" "r")))
11495                          (const_int 0)])
11496                       (label_ref (match_operand 3 "" ""))
11497                       (pc)))
11498    (clobber (reg:CC FLAGS_REG))]
11499   "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
11500   "#"
11501   "&& 1"
11502   [(set (reg:CCC FLAGS_REG)
11503         (compare:CCC
11504           (zero_extract:DI
11505             (match_dup 1)
11506             (const_int 1)
11507             (match_dup 2))
11508           (const_int 0)))
11509    (set (pc)
11510         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11511                       (label_ref (match_dup 3))
11512                       (pc)))]
11513 {
11514   operands[2] = simplify_gen_subreg (DImode, operands[2], QImode, 0);
11515
11516   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11517 })
11518
11519 ;; avoid useless masking of bit offset operand
11520 (define_insn_and_split "*jcc_btdi_mask_rex64"
11521   [(set (pc)
11522         (if_then_else (match_operator 0 "bt_comparison_operator"
11523                         [(zero_extract:DI
11524                            (match_operand:DI 1 "register_operand" "r")
11525                            (const_int 1)
11526                            (and:SI
11527                              (match_operand:SI 2 "register_operand" "r")
11528                              (match_operand:SI 3 "const_int_operand" "n")))])
11529                       (label_ref (match_operand 4 "" ""))
11530                       (pc)))
11531    (clobber (reg:CC FLAGS_REG))]
11532   "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))
11533    && (INTVAL (operands[3]) & 0x3f) == 0x3f"
11534   "#"
11535   "&& 1"
11536   [(set (reg:CCC FLAGS_REG)
11537         (compare:CCC
11538           (zero_extract:DI
11539             (match_dup 1)
11540             (const_int 1)
11541             (match_dup 2))
11542           (const_int 0)))
11543    (set (pc)
11544         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11545                       (label_ref (match_dup 4))
11546                       (pc)))]
11547 {
11548   operands[2] = simplify_gen_subreg (DImode, operands[2], SImode, 0);
11549
11550   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11551 })
11552
11553 (define_insn_and_split "*jcc_btsi"
11554   [(set (pc)
11555         (if_then_else (match_operator 0 "bt_comparison_operator"
11556                         [(zero_extract:SI
11557                            (match_operand:SI 1 "register_operand" "r")
11558                            (const_int 1)
11559                            (zero_extend:SI
11560                              (match_operand:QI 2 "register_operand" "r")))
11561                          (const_int 0)])
11562                       (label_ref (match_operand 3 "" ""))
11563                       (pc)))
11564    (clobber (reg:CC FLAGS_REG))]
11565   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
11566   "#"
11567   "&& 1"
11568   [(set (reg:CCC FLAGS_REG)
11569         (compare:CCC
11570           (zero_extract:SI
11571             (match_dup 1)
11572             (const_int 1)
11573             (match_dup 2))
11574           (const_int 0)))
11575    (set (pc)
11576         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11577                       (label_ref (match_dup 3))
11578                       (pc)))]
11579 {
11580   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
11581
11582   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11583 })
11584
11585 ;; avoid useless masking of bit offset operand
11586 (define_insn_and_split "*jcc_btsi_mask"
11587   [(set (pc)
11588         (if_then_else (match_operator 0 "bt_comparison_operator"
11589                         [(zero_extract:SI
11590                            (match_operand:SI 1 "register_operand" "r")
11591                            (const_int 1)
11592                            (and:SI
11593                              (match_operand:SI 2 "register_operand" "r")
11594                              (match_operand:SI 3 "const_int_operand" "n")))])
11595                       (label_ref (match_operand 4 "" ""))
11596                       (pc)))
11597    (clobber (reg:CC FLAGS_REG))]
11598   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11599    && (INTVAL (operands[3]) & 0x1f) == 0x1f"
11600   "#"
11601   "&& 1"
11602   [(set (reg:CCC FLAGS_REG)
11603         (compare:CCC
11604           (zero_extract:SI
11605             (match_dup 1)
11606             (const_int 1)
11607             (match_dup 2))
11608           (const_int 0)))
11609    (set (pc)
11610         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11611                       (label_ref (match_dup 4))
11612                       (pc)))]
11613   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
11614
11615 (define_insn_and_split "*jcc_btsi_1"
11616   [(set (pc)
11617         (if_then_else (match_operator 0 "bt_comparison_operator"
11618                         [(and:SI
11619                            (lshiftrt:SI
11620                              (match_operand:SI 1 "register_operand" "r")
11621                              (match_operand:QI 2 "register_operand" "r"))
11622                            (const_int 1))
11623                          (const_int 0)])
11624                       (label_ref (match_operand 3 "" ""))
11625                       (pc)))
11626    (clobber (reg:CC FLAGS_REG))]
11627   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
11628   "#"
11629   "&& 1"
11630   [(set (reg:CCC FLAGS_REG)
11631         (compare:CCC
11632           (zero_extract:SI
11633             (match_dup 1)
11634             (const_int 1)
11635             (match_dup 2))
11636           (const_int 0)))
11637    (set (pc)
11638         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11639                       (label_ref (match_dup 3))
11640                       (pc)))]
11641 {
11642   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
11643
11644   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11645 })
11646
11647 ;; avoid useless masking of bit offset operand
11648 (define_insn_and_split "*jcc_btsi_mask_1"
11649   [(set (pc)
11650         (if_then_else
11651           (match_operator 0 "bt_comparison_operator"
11652             [(and:SI
11653                (lshiftrt:SI
11654                  (match_operand:SI 1 "register_operand" "r")
11655                  (subreg:QI
11656                    (and:SI
11657                      (match_operand:SI 2 "register_operand" "r")
11658                      (match_operand:SI 3 "const_int_operand" "n")) 0))
11659                (const_int 1))
11660              (const_int 0)])
11661           (label_ref (match_operand 4 "" ""))
11662           (pc)))
11663    (clobber (reg:CC FLAGS_REG))]
11664   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11665    && (INTVAL (operands[3]) & 0x1f) == 0x1f"
11666   "#"
11667   "&& 1"
11668   [(set (reg:CCC FLAGS_REG)
11669         (compare:CCC
11670           (zero_extract:SI
11671             (match_dup 1)
11672             (const_int 1)
11673             (match_dup 2))
11674           (const_int 0)))
11675    (set (pc)
11676         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11677                       (label_ref (match_dup 4))
11678                       (pc)))]
11679   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
11680
11681 ;; Define combination compare-and-branch fp compare instructions to help
11682 ;; combine.
11683
11684 (define_insn "*fp_jcc_3_387"
11685   [(set (pc)
11686         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11687                         [(match_operand 1 "register_operand" "f")
11688                          (match_operand 2 "nonimmediate_operand" "fm")])
11689           (label_ref (match_operand 3 "" ""))
11690           (pc)))
11691    (clobber (reg:CCFP FPSR_REG))
11692    (clobber (reg:CCFP FLAGS_REG))
11693    (clobber (match_scratch:HI 4 "=a"))]
11694   "TARGET_80387
11695    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
11696    && GET_MODE (operands[1]) == GET_MODE (operands[2])
11697    && SELECT_CC_MODE (GET_CODE (operands[0]),
11698                       operands[1], operands[2]) == CCFPmode
11699    && !TARGET_CMOVE"
11700   "#")
11701
11702 (define_insn "*fp_jcc_4_387"
11703   [(set (pc)
11704         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11705                         [(match_operand 1 "register_operand" "f")
11706                          (match_operand 2 "nonimmediate_operand" "fm")])
11707           (pc)
11708           (label_ref (match_operand 3 "" ""))))
11709    (clobber (reg:CCFP FPSR_REG))
11710    (clobber (reg:CCFP FLAGS_REG))
11711    (clobber (match_scratch:HI 4 "=a"))]
11712   "TARGET_80387
11713    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
11714    && GET_MODE (operands[1]) == GET_MODE (operands[2])
11715    && SELECT_CC_MODE (GET_CODE (operands[0]),
11716                       operands[1], operands[2]) == CCFPmode
11717    && !TARGET_CMOVE"
11718   "#")
11719
11720 (define_insn "*fp_jcc_5_387"
11721   [(set (pc)
11722         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11723                         [(match_operand 1 "register_operand" "f")
11724                          (match_operand 2 "register_operand" "f")])
11725           (label_ref (match_operand 3 "" ""))
11726           (pc)))
11727    (clobber (reg:CCFP FPSR_REG))
11728    (clobber (reg:CCFP FLAGS_REG))
11729    (clobber (match_scratch:HI 4 "=a"))]
11730   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11731    && GET_MODE (operands[1]) == GET_MODE (operands[2])
11732    && !TARGET_CMOVE"
11733   "#")
11734
11735 (define_insn "*fp_jcc_6_387"
11736   [(set (pc)
11737         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11738                         [(match_operand 1 "register_operand" "f")
11739                          (match_operand 2 "register_operand" "f")])
11740           (pc)
11741           (label_ref (match_operand 3 "" ""))))
11742    (clobber (reg:CCFP FPSR_REG))
11743    (clobber (reg:CCFP FLAGS_REG))
11744    (clobber (match_scratch:HI 4 "=a"))]
11745   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11746    && GET_MODE (operands[1]) == GET_MODE (operands[2])
11747    && !TARGET_CMOVE"
11748   "#")
11749
11750 (define_insn "*fp_jcc_7_387"
11751   [(set (pc)
11752         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11753                         [(match_operand 1 "register_operand" "f")
11754                          (match_operand 2 "const0_operand" "")])
11755           (label_ref (match_operand 3 "" ""))
11756           (pc)))
11757    (clobber (reg:CCFP FPSR_REG))
11758    (clobber (reg:CCFP FLAGS_REG))
11759    (clobber (match_scratch:HI 4 "=a"))]
11760   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11761    && GET_MODE (operands[1]) == GET_MODE (operands[2])
11762    && SELECT_CC_MODE (GET_CODE (operands[0]),
11763                       operands[1], operands[2]) == CCFPmode
11764    && !TARGET_CMOVE"
11765   "#")
11766
11767 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
11768 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11769 ;; with a precedence over other operators and is always put in the first
11770 ;; place. Swap condition and operands to match ficom instruction.
11771
11772 (define_insn "*fp_jcc_8<mode>_387"
11773   [(set (pc)
11774         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11775                         [(match_operator 1 "float_operator"
11776                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
11777                            (match_operand 3 "register_operand" "f,f")])
11778           (label_ref (match_operand 4 "" ""))
11779           (pc)))
11780    (clobber (reg:CCFP FPSR_REG))
11781    (clobber (reg:CCFP FLAGS_REG))
11782    (clobber (match_scratch:HI 5 "=a,a"))]
11783   "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
11784    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
11785    && GET_MODE (operands[1]) == GET_MODE (operands[3])
11786    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
11787    && !TARGET_CMOVE"
11788   "#")
11789
11790 (define_split
11791   [(set (pc)
11792         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11793                         [(match_operand 1 "register_operand" "")
11794                          (match_operand 2 "nonimmediate_operand" "")])
11795           (match_operand 3 "" "")
11796           (match_operand 4 "" "")))
11797    (clobber (reg:CCFP FPSR_REG))
11798    (clobber (reg:CCFP FLAGS_REG))]
11799   "reload_completed"
11800   [(const_int 0)]
11801 {
11802   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11803                         operands[3], operands[4], NULL_RTX, NULL_RTX);
11804   DONE;
11805 })
11806
11807 (define_split
11808   [(set (pc)
11809         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11810                         [(match_operand 1 "register_operand" "")
11811                          (match_operand 2 "general_operand" "")])
11812           (match_operand 3 "" "")
11813           (match_operand 4 "" "")))
11814    (clobber (reg:CCFP FPSR_REG))
11815    (clobber (reg:CCFP FLAGS_REG))
11816    (clobber (match_scratch:HI 5 "=a"))]
11817   "reload_completed"
11818   [(const_int 0)]
11819 {
11820   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11821                         operands[3], operands[4], operands[5], NULL_RTX);
11822   DONE;
11823 })
11824
11825 (define_split
11826   [(set (pc)
11827         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11828                         [(match_operator 1 "float_operator"
11829                            [(match_operand:X87MODEI12 2 "memory_operand" "")])
11830                            (match_operand 3 "register_operand" "")])
11831           (match_operand 4 "" "")
11832           (match_operand 5 "" "")))
11833    (clobber (reg:CCFP FPSR_REG))
11834    (clobber (reg:CCFP FLAGS_REG))
11835    (clobber (match_scratch:HI 6 "=a"))]
11836   "reload_completed"
11837   [(const_int 0)]
11838 {
11839   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
11840   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11841                         operands[3], operands[7],
11842                         operands[4], operands[5], operands[6], NULL_RTX);
11843   DONE;
11844 })
11845
11846 ;; %%% Kill this when reload knows how to do it.
11847 (define_split
11848   [(set (pc)
11849         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11850                         [(match_operator 1 "float_operator"
11851                            [(match_operand:X87MODEI12 2 "register_operand" "")])
11852                            (match_operand 3 "register_operand" "")])
11853           (match_operand 4 "" "")
11854           (match_operand 5 "" "")))
11855    (clobber (reg:CCFP FPSR_REG))
11856    (clobber (reg:CCFP FLAGS_REG))
11857    (clobber (match_scratch:HI 6 "=a"))]
11858   "reload_completed"
11859   [(const_int 0)]
11860 {
11861   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11862   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
11863   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11864                         operands[3], operands[7],
11865                         operands[4], operands[5], operands[6], operands[2]);
11866   DONE;
11867 })
11868 \f
11869 ;; Unconditional and other jump instructions
11870
11871 (define_insn "jump"
11872   [(set (pc)
11873         (label_ref (match_operand 0 "" "")))]
11874   ""
11875   "jmp\t%l0"
11876   [(set_attr "type" "ibr")
11877    (set (attr "length")
11878            (if_then_else (and (ge (minus (match_dup 0) (pc))
11879                                   (const_int -126))
11880                               (lt (minus (match_dup 0) (pc))
11881                                   (const_int 128)))
11882              (const_int 2)
11883              (const_int 5)))
11884    (set_attr "modrm" "0")])
11885
11886 (define_expand "indirect_jump"
11887   [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
11888   ""
11889   "")
11890
11891 (define_insn "*indirect_jump"
11892   [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
11893   ""
11894   "jmp\t%A0"
11895   [(set_attr "type" "ibr")
11896    (set_attr "length_immediate" "0")])
11897
11898 (define_expand "tablejump"
11899   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
11900               (use (label_ref (match_operand 1 "" "")))])]
11901   ""
11902 {
11903   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11904      relative.  Convert the relative address to an absolute address.  */
11905   if (flag_pic)
11906     {
11907       rtx op0, op1;
11908       enum rtx_code code;
11909
11910       /* We can't use @GOTOFF for text labels on VxWorks;
11911          see gotoff_operand.  */
11912       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11913         {
11914           code = PLUS;
11915           op0 = operands[0];
11916           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11917         }
11918       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11919         {
11920           code = PLUS;
11921           op0 = operands[0];
11922           op1 = pic_offset_table_rtx;
11923         }
11924       else
11925         {
11926           code = MINUS;
11927           op0 = pic_offset_table_rtx;
11928           op1 = operands[0];
11929         }
11930
11931       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11932                                          OPTAB_DIRECT);
11933     }
11934 })
11935
11936 (define_insn "*tablejump_1"
11937   [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
11938    (use (label_ref (match_operand 1 "" "")))]
11939   ""
11940   "jmp\t%A0"
11941   [(set_attr "type" "ibr")
11942    (set_attr "length_immediate" "0")])
11943 \f
11944 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11945
11946 (define_peephole2
11947   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11948    (set (match_operand:QI 1 "register_operand" "")
11949         (match_operator:QI 2 "ix86_comparison_operator"
11950           [(reg FLAGS_REG) (const_int 0)]))
11951    (set (match_operand 3 "q_regs_operand" "")
11952         (zero_extend (match_dup 1)))]
11953   "(peep2_reg_dead_p (3, operands[1])
11954     || operands_match_p (operands[1], operands[3]))
11955    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11956   [(set (match_dup 4) (match_dup 0))
11957    (set (strict_low_part (match_dup 5))
11958         (match_dup 2))]
11959 {
11960   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11961   operands[5] = gen_lowpart (QImode, operands[3]);
11962   ix86_expand_clear (operands[3]);
11963 })
11964
11965 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
11966
11967 (define_peephole2
11968   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11969    (set (match_operand:QI 1 "register_operand" "")
11970         (match_operator:QI 2 "ix86_comparison_operator"
11971           [(reg FLAGS_REG) (const_int 0)]))
11972    (parallel [(set (match_operand 3 "q_regs_operand" "")
11973                    (zero_extend (match_dup 1)))
11974               (clobber (reg:CC FLAGS_REG))])]
11975   "(peep2_reg_dead_p (3, operands[1])
11976     || operands_match_p (operands[1], operands[3]))
11977    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11978   [(set (match_dup 4) (match_dup 0))
11979    (set (strict_low_part (match_dup 5))
11980         (match_dup 2))]
11981 {
11982   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11983   operands[5] = gen_lowpart (QImode, operands[3]);
11984   ix86_expand_clear (operands[3]);
11985 })
11986 \f
11987 ;; Call instructions.
11988
11989 ;; The predicates normally associated with named expanders are not properly
11990 ;; checked for calls.  This is a bug in the generic code, but it isn't that
11991 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
11992
11993 ;; P6 processors will jump to the address after the decrement when %esp
11994 ;; is used as a call operand, so they will execute return address as a code.
11995 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11996  
11997 ;; Call subroutine returning no value.
11998
11999 (define_expand "call_pop"
12000   [(parallel [(call (match_operand:QI 0 "" "")
12001                     (match_operand:SI 1 "" ""))
12002               (set (reg:SI SP_REG)
12003                    (plus:SI (reg:SI SP_REG)
12004                             (match_operand:SI 3 "" "")))])]
12005   "!TARGET_64BIT"
12006 {
12007   ix86_expand_call (NULL, operands[0], operands[1],
12008                     operands[2], operands[3], 0);
12009   DONE;
12010 })
12011
12012 (define_insn "*call_pop_0"
12013   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
12014          (match_operand:SI 1 "" ""))
12015    (set (reg:SI SP_REG)
12016         (plus:SI (reg:SI SP_REG)
12017                  (match_operand:SI 2 "immediate_operand" "")))]
12018   "!TARGET_64BIT"
12019 {
12020   if (SIBLING_CALL_P (insn))
12021     return "jmp\t%P0";
12022   else
12023     return "call\t%P0";
12024 }
12025   [(set_attr "type" "call")])
12026
12027 (define_insn "*call_pop_1"
12028   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
12029          (match_operand:SI 1 "" ""))
12030    (set (reg:SI SP_REG)
12031         (plus:SI (reg:SI SP_REG)
12032                  (match_operand:SI 2 "immediate_operand" "i")))]
12033   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
12034 {
12035   if (constant_call_address_operand (operands[0], Pmode))
12036     return "call\t%P0";
12037   return "call\t%A0";
12038 }
12039   [(set_attr "type" "call")])
12040
12041 (define_insn "*sibcall_pop_1"
12042   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
12043          (match_operand:SI 1 "" ""))
12044    (set (reg:SI SP_REG)
12045         (plus:SI (reg:SI SP_REG)
12046                  (match_operand:SI 2 "immediate_operand" "i,i")))]
12047   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
12048   "@
12049    jmp\t%P0
12050    jmp\t%A0"
12051   [(set_attr "type" "call")])
12052
12053 (define_expand "call"
12054   [(call (match_operand:QI 0 "" "")
12055          (match_operand 1 "" ""))
12056    (use (match_operand 2 "" ""))]
12057   ""
12058 {
12059   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
12060   DONE;
12061 })
12062
12063 (define_expand "sibcall"
12064   [(call (match_operand:QI 0 "" "")
12065          (match_operand 1 "" ""))
12066    (use (match_operand 2 "" ""))]
12067   ""
12068 {
12069   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
12070   DONE;
12071 })
12072
12073 (define_insn "*call_0"
12074   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
12075          (match_operand 1 "" ""))]
12076   ""
12077 {
12078   if (SIBLING_CALL_P (insn))
12079     return "jmp\t%P0";
12080   else
12081     return "call\t%P0";
12082 }
12083   [(set_attr "type" "call")])
12084
12085 (define_insn "*call_1"
12086   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
12087          (match_operand 1 "" ""))]
12088   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
12089 {
12090   if (constant_call_address_operand (operands[0], Pmode))
12091     return "call\t%P0";
12092   return "call\t%A0";
12093 }
12094   [(set_attr "type" "call")])
12095
12096 (define_insn "*sibcall_1"
12097   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
12098          (match_operand 1 "" ""))]
12099   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
12100   "@
12101    jmp\t%P0
12102    jmp\t%A0"
12103   [(set_attr "type" "call")])
12104
12105 (define_insn "*call_1_rex64"
12106   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
12107          (match_operand 1 "" ""))]
12108   "TARGET_64BIT && !SIBLING_CALL_P (insn)
12109    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
12110 {
12111   if (constant_call_address_operand (operands[0], Pmode))
12112     return "call\t%P0";
12113   return "call\t%A0";
12114 }
12115   [(set_attr "type" "call")])
12116
12117 (define_insn "*call_1_rex64_ms_sysv"
12118   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
12119          (match_operand 1 "" ""))
12120    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
12121    (clobber (reg:TI XMM6_REG))
12122    (clobber (reg:TI XMM7_REG))
12123    (clobber (reg:TI XMM8_REG))
12124    (clobber (reg:TI XMM9_REG))
12125    (clobber (reg:TI XMM10_REG))
12126    (clobber (reg:TI XMM11_REG))
12127    (clobber (reg:TI XMM12_REG))
12128    (clobber (reg:TI XMM13_REG))
12129    (clobber (reg:TI XMM14_REG))
12130    (clobber (reg:TI XMM15_REG))
12131    (clobber (reg:DI SI_REG))
12132    (clobber (reg:DI DI_REG))]
12133   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
12134 {
12135   if (constant_call_address_operand (operands[0], Pmode))
12136     return "call\t%P0";
12137   return "call\t%A0";
12138 }
12139   [(set_attr "type" "call")])
12140
12141 (define_insn "*call_1_rex64_large"
12142   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
12143          (match_operand 1 "" ""))]
12144   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
12145   "call\t%A0"
12146   [(set_attr "type" "call")])
12147
12148 (define_insn "*sibcall_1_rex64"
12149   [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
12150          (match_operand 1 "" ""))]
12151   "TARGET_64BIT && SIBLING_CALL_P (insn)"
12152   "@
12153    jmp\t%P0
12154    jmp\t%A0"
12155   [(set_attr "type" "call")])
12156
12157 ;; Call subroutine, returning value in operand 0
12158 (define_expand "call_value_pop"
12159   [(parallel [(set (match_operand 0 "" "")
12160                    (call (match_operand:QI 1 "" "")
12161                          (match_operand:SI 2 "" "")))
12162               (set (reg:SI SP_REG)
12163                    (plus:SI (reg:SI SP_REG)
12164                             (match_operand:SI 4 "" "")))])]
12165   "!TARGET_64BIT"
12166 {
12167   ix86_expand_call (operands[0], operands[1], operands[2],
12168                     operands[3], operands[4], 0);
12169   DONE;
12170 })
12171
12172 (define_expand "call_value"
12173   [(set (match_operand 0 "" "")
12174         (call (match_operand:QI 1 "" "")
12175               (match_operand:SI 2 "" "")))
12176    (use (match_operand:SI 3 "" ""))]
12177   ;; Operand 3 is not used on the i386.
12178   ""
12179 {
12180   ix86_expand_call (operands[0], operands[1], operands[2],
12181                     operands[3], NULL, 0);
12182   DONE;
12183 })
12184
12185 (define_expand "sibcall_value"
12186   [(set (match_operand 0 "" "")
12187         (call (match_operand:QI 1 "" "")
12188               (match_operand:SI 2 "" "")))
12189    (use (match_operand:SI 3 "" ""))]
12190   ;; Operand 3 is not used on the i386.
12191   ""
12192 {
12193   ix86_expand_call (operands[0], operands[1], operands[2],
12194                     operands[3], NULL, 1);
12195   DONE;
12196 })
12197
12198 ;; Call subroutine returning any type.
12199
12200 (define_expand "untyped_call"
12201   [(parallel [(call (match_operand 0 "" "")
12202                     (const_int 0))
12203               (match_operand 1 "" "")
12204               (match_operand 2 "" "")])]
12205   ""
12206 {
12207   int i;
12208
12209   /* In order to give reg-stack an easier job in validating two
12210      coprocessor registers as containing a possible return value,
12211      simply pretend the untyped call returns a complex long double
12212      value. 
12213
12214      We can't use SSE_REGPARM_MAX here since callee is unprototyped
12215      and should have the default ABI.  */
12216
12217   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
12218                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
12219                     operands[0], const0_rtx,
12220                     GEN_INT ((TARGET_64BIT
12221                               ? (ix86_abi == SYSV_ABI
12222                                  ? X86_64_SSE_REGPARM_MAX
12223                                  : X86_64_MS_SSE_REGPARM_MAX)
12224                               : X86_32_SSE_REGPARM_MAX)
12225                              - 1),
12226                     NULL, 0);
12227
12228   for (i = 0; i < XVECLEN (operands[2], 0); i++)
12229     {
12230       rtx set = XVECEXP (operands[2], 0, i);
12231       emit_move_insn (SET_DEST (set), SET_SRC (set));
12232     }
12233
12234   /* The optimizer does not know that the call sets the function value
12235      registers we stored in the result block.  We avoid problems by
12236      claiming that all hard registers are used and clobbered at this
12237      point.  */
12238   emit_insn (gen_blockage ());
12239
12240   DONE;
12241 })
12242 \f
12243 ;; Prologue and epilogue instructions
12244
12245 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
12246 ;; all of memory.  This blocks insns from being moved across this point.
12247
12248 (define_insn "blockage"
12249   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
12250   ""
12251   ""
12252   [(set_attr "length" "0")])
12253
12254 ;; Do not schedule instructions accessing memory across this point.
12255
12256 (define_expand "memory_blockage"
12257   [(set (match_dup 0)
12258         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
12259   ""
12260 {
12261   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
12262   MEM_VOLATILE_P (operands[0]) = 1;
12263 })
12264
12265 (define_insn "*memory_blockage"
12266   [(set (match_operand:BLK 0 "" "")
12267         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
12268   ""
12269   ""
12270   [(set_attr "length" "0")])
12271
12272 ;; As USE insns aren't meaningful after reload, this is used instead
12273 ;; to prevent deleting instructions setting registers for PIC code
12274 (define_insn "prologue_use"
12275   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
12276   ""
12277   ""
12278   [(set_attr "length" "0")])
12279
12280 ;; Insn emitted into the body of a function to return from a function.
12281 ;; This is only done if the function's epilogue is known to be simple.
12282 ;; See comments for ix86_can_use_return_insn_p in i386.c.
12283
12284 (define_expand "return"
12285   [(return)]
12286   "ix86_can_use_return_insn_p ()"
12287 {
12288   if (crtl->args.pops_args)
12289     {
12290       rtx popc = GEN_INT (crtl->args.pops_args);
12291       emit_jump_insn (gen_return_pop_internal (popc));
12292       DONE;
12293     }
12294 })
12295
12296 (define_insn "return_internal"
12297   [(return)]
12298   "reload_completed"
12299   "ret"
12300   [(set_attr "length" "1")
12301    (set_attr "atom_unit" "jeu")
12302    (set_attr "length_immediate" "0")
12303    (set_attr "modrm" "0")])
12304
12305 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
12306 ;; instruction Athlon and K8 have.
12307
12308 (define_insn "return_internal_long"
12309   [(return)
12310    (unspec [(const_int 0)] UNSPEC_REP)]
12311   "reload_completed"
12312   "rep\;ret"
12313   [(set_attr "length" "2")
12314    (set_attr "atom_unit" "jeu")
12315    (set_attr "length_immediate" "0")
12316    (set_attr "prefix_rep" "1")
12317    (set_attr "modrm" "0")])
12318
12319 (define_insn "return_pop_internal"
12320   [(return)
12321    (use (match_operand:SI 0 "const_int_operand" ""))]
12322   "reload_completed"
12323   "ret\t%0"
12324   [(set_attr "length" "3")
12325    (set_attr "atom_unit" "jeu")
12326    (set_attr "length_immediate" "2")
12327    (set_attr "modrm" "0")])
12328
12329 (define_insn "return_indirect_internal"
12330   [(return)
12331    (use (match_operand:SI 0 "register_operand" "r"))]
12332   "reload_completed"
12333   "jmp\t%A0"
12334   [(set_attr "type" "ibr")
12335    (set_attr "length_immediate" "0")])
12336
12337 (define_insn "nop"
12338   [(const_int 0)]
12339   ""
12340   "nop"
12341   [(set_attr "length" "1")
12342    (set_attr "length_immediate" "0")
12343    (set_attr "modrm" "0")])
12344
12345 (define_insn "vswapmov"
12346   [(set (match_operand:SI 0 "register_operand" "=r")
12347         (match_operand:SI 1 "register_operand" "r"))
12348    (unspec_volatile [(const_int 0)] UNSPECV_VSWAPMOV)]
12349   ""
12350   "movl.s\t{%1, %0|%0, %1}"
12351   [(set_attr "length" "2")
12352    (set_attr "length_immediate" "0")
12353    (set_attr "modrm" "0")])
12354
12355 ;; Pad to 16-byte boundary, max skip in op0.  Used to avoid
12356 ;; branch prediction penalty for the third jump in a 16-byte
12357 ;; block on K8.
12358
12359 (define_insn "pad"
12360   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
12361   ""
12362 {
12363 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
12364   ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
12365 #else
12366   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
12367      The align insn is used to avoid 3 jump instructions in the row to improve
12368      branch prediction and the benefits hardly outweigh the cost of extra 8
12369      nops on the average inserted by full alignment pseudo operation.  */
12370 #endif
12371   return "";
12372 }
12373   [(set_attr "length" "16")])
12374
12375 (define_expand "prologue"
12376   [(const_int 0)]
12377   ""
12378   "ix86_expand_prologue (); DONE;")
12379
12380 (define_insn "set_got"
12381   [(set (match_operand:SI 0 "register_operand" "=r")
12382         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
12383    (clobber (reg:CC FLAGS_REG))]
12384   "!TARGET_64BIT"
12385   { return output_set_got (operands[0], NULL_RTX); }
12386   [(set_attr "type" "multi")
12387    (set_attr "length" "12")])
12388
12389 (define_insn "set_got_labelled"
12390   [(set (match_operand:SI 0 "register_operand" "=r")
12391         (unspec:SI [(label_ref (match_operand 1 "" ""))]
12392          UNSPEC_SET_GOT))
12393    (clobber (reg:CC FLAGS_REG))]
12394   "!TARGET_64BIT"
12395   { return output_set_got (operands[0], operands[1]); }
12396   [(set_attr "type" "multi")
12397    (set_attr "length" "12")])
12398
12399 (define_insn "set_got_rex64"
12400   [(set (match_operand:DI 0 "register_operand" "=r")
12401         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
12402   "TARGET_64BIT"
12403   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
12404   [(set_attr "type" "lea")
12405    (set_attr "length_address" "4")
12406    (set_attr "mode" "DI")])
12407
12408 (define_insn "set_rip_rex64"
12409   [(set (match_operand:DI 0 "register_operand" "=r")
12410         (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
12411   "TARGET_64BIT"
12412   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
12413   [(set_attr "type" "lea")
12414    (set_attr "length_address" "4")
12415    (set_attr "mode" "DI")])
12416
12417 (define_insn "set_got_offset_rex64"
12418   [(set (match_operand:DI 0 "register_operand" "=r")
12419         (unspec:DI
12420           [(label_ref (match_operand 1 "" ""))]
12421           UNSPEC_SET_GOT_OFFSET))]
12422   "TARGET_64BIT"
12423   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
12424   [(set_attr "type" "imov")
12425    (set_attr "length_immediate" "0")
12426    (set_attr "length_address" "8")
12427    (set_attr "mode" "DI")])
12428
12429 (define_expand "epilogue"
12430   [(const_int 0)]
12431   ""
12432   "ix86_expand_epilogue (1); DONE;")
12433
12434 (define_expand "sibcall_epilogue"
12435   [(const_int 0)]
12436   ""
12437   "ix86_expand_epilogue (0); DONE;")
12438
12439 (define_expand "eh_return"
12440   [(use (match_operand 0 "register_operand" ""))]
12441   ""
12442 {
12443   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
12444
12445   /* Tricky bit: we write the address of the handler to which we will
12446      be returning into someone else's stack frame, one word below the
12447      stack address we wish to restore.  */
12448   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
12449   tmp = plus_constant (tmp, -UNITS_PER_WORD);
12450   tmp = gen_rtx_MEM (Pmode, tmp);
12451   emit_move_insn (tmp, ra);
12452
12453   emit_jump_insn (gen_eh_return_internal ());
12454   emit_barrier ();
12455   DONE;
12456 })
12457
12458 (define_insn_and_split "eh_return_internal"
12459   [(eh_return)]
12460   ""
12461   "#"
12462   "epilogue_completed"
12463   [(const_int 0)]
12464   "ix86_expand_epilogue (2); DONE;")
12465
12466 (define_insn "leave"
12467   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
12468    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
12469    (clobber (mem:BLK (scratch)))]
12470   "!TARGET_64BIT"
12471   "leave"
12472   [(set_attr "type" "leave")])
12473
12474 (define_insn "leave_rex64"
12475   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
12476    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
12477    (clobber (mem:BLK (scratch)))]
12478   "TARGET_64BIT"
12479   "leave"
12480   [(set_attr "type" "leave")])
12481 \f
12482 (define_expand "ffssi2"
12483   [(parallel
12484      [(set (match_operand:SI 0 "register_operand" "")
12485            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
12486       (clobber (match_scratch:SI 2 ""))
12487       (clobber (reg:CC FLAGS_REG))])]
12488   ""
12489 {
12490   if (TARGET_CMOVE)
12491     {
12492       emit_insn (gen_ffs_cmove (operands[0], operands[1]));
12493       DONE;
12494     }
12495 })
12496
12497 (define_expand "ffs_cmove"
12498   [(set (match_dup 2) (const_int -1))
12499    (parallel [(set (reg:CCZ FLAGS_REG)
12500                    (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "")
12501                                 (const_int 0)))
12502               (set (match_operand:SI 0 "register_operand" "")
12503                    (ctz:SI (match_dup 1)))])
12504    (set (match_dup 0) (if_then_else:SI
12505                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
12506                         (match_dup 2)
12507                         (match_dup 0)))
12508    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12509               (clobber (reg:CC FLAGS_REG))])]
12510   "TARGET_CMOVE"
12511   "operands[2] = gen_reg_rtx (SImode);")
12512
12513 (define_insn_and_split "*ffs_no_cmove"
12514   [(set (match_operand:SI 0 "register_operand" "=r")
12515         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12516    (clobber (match_scratch:SI 2 "=&q"))
12517    (clobber (reg:CC FLAGS_REG))]
12518   "!TARGET_CMOVE"
12519   "#"
12520   "&& reload_completed"
12521   [(parallel [(set (reg:CCZ FLAGS_REG)
12522                    (compare:CCZ (match_dup 1) (const_int 0)))
12523               (set (match_dup 0) (ctz:SI (match_dup 1)))])
12524    (set (strict_low_part (match_dup 3))
12525         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
12526    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12527               (clobber (reg:CC FLAGS_REG))])
12528    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12529               (clobber (reg:CC FLAGS_REG))])
12530    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12531               (clobber (reg:CC FLAGS_REG))])]
12532 {
12533   operands[3] = gen_lowpart (QImode, operands[2]);
12534   ix86_expand_clear (operands[2]);
12535 })
12536
12537 (define_insn "*ffssi_1"
12538   [(set (reg:CCZ FLAGS_REG)
12539         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
12540                      (const_int 0)))
12541    (set (match_operand:SI 0 "register_operand" "=r")
12542         (ctz:SI (match_dup 1)))]
12543   ""
12544   "bsf{l}\t{%1, %0|%0, %1}"
12545   [(set_attr "type" "alu1")
12546    (set_attr "prefix_0f" "1")
12547    (set_attr "mode" "SI")])
12548
12549 (define_expand "ffsdi2"
12550   [(set (match_dup 2) (const_int -1))
12551    (parallel [(set (reg:CCZ FLAGS_REG)
12552                    (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "")
12553                                 (const_int 0)))
12554               (set (match_operand:DI 0 "register_operand" "")
12555                    (ctz:DI (match_dup 1)))])
12556    (set (match_dup 0) (if_then_else:DI
12557                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
12558                         (match_dup 2)
12559                         (match_dup 0)))
12560    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
12561               (clobber (reg:CC FLAGS_REG))])]
12562   "TARGET_64BIT"
12563   "operands[2] = gen_reg_rtx (DImode);")
12564
12565 (define_insn "*ffsdi_1"
12566   [(set (reg:CCZ FLAGS_REG)
12567         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
12568                      (const_int 0)))
12569    (set (match_operand:DI 0 "register_operand" "=r")
12570         (ctz:DI (match_dup 1)))]
12571   "TARGET_64BIT"
12572   "bsf{q}\t{%1, %0|%0, %1}"
12573   [(set_attr "type" "alu1")
12574    (set_attr "prefix_0f" "1")
12575    (set_attr "mode" "DI")])
12576
12577 (define_insn "ctzsi2"
12578   [(set (match_operand:SI 0 "register_operand" "=r")
12579         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12580    (clobber (reg:CC FLAGS_REG))]
12581   ""
12582   "bsf{l}\t{%1, %0|%0, %1}"
12583   [(set_attr "type" "alu1")
12584    (set_attr "prefix_0f" "1")
12585    (set_attr "mode" "SI")])
12586
12587 (define_insn "ctzdi2"
12588   [(set (match_operand:DI 0 "register_operand" "=r")
12589         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
12590    (clobber (reg:CC FLAGS_REG))]
12591   "TARGET_64BIT"
12592   "bsf{q}\t{%1, %0|%0, %1}"
12593   [(set_attr "type" "alu1")
12594    (set_attr "prefix_0f" "1")
12595    (set_attr "mode" "DI")])
12596
12597 (define_expand "clzsi2"
12598   [(parallel
12599      [(set (match_operand:SI 0 "register_operand" "")
12600            (minus:SI (const_int 31)
12601                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
12602       (clobber (reg:CC FLAGS_REG))])
12603    (parallel
12604      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
12605       (clobber (reg:CC FLAGS_REG))])]
12606   ""
12607 {
12608   if (TARGET_ABM)
12609     {
12610       emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
12611       DONE;
12612     }
12613 })
12614
12615 (define_insn "clzsi2_abm"
12616   [(set (match_operand:SI 0 "register_operand" "=r")
12617         (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12618    (clobber (reg:CC FLAGS_REG))]
12619   "TARGET_ABM"
12620   "lzcnt{l}\t{%1, %0|%0, %1}"
12621   [(set_attr "prefix_rep" "1")
12622    (set_attr "type" "bitmanip")
12623    (set_attr "mode" "SI")])
12624
12625 (define_insn "bsr"
12626   [(set (match_operand:SI 0 "register_operand" "=r")
12627         (minus:SI (const_int 31)
12628                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12629    (clobber (reg:CC FLAGS_REG))]
12630   ""
12631   "bsr{l}\t{%1, %0|%0, %1}"
12632   [(set_attr "type" "alu1")
12633    (set_attr "prefix_0f" "1")
12634    (set_attr "mode" "SI")])
12635
12636 (define_insn "popcount<mode>2"
12637   [(set (match_operand:SWI248 0 "register_operand" "=r")
12638         (popcount:SWI248
12639           (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12640    (clobber (reg:CC FLAGS_REG))]
12641   "TARGET_POPCNT"
12642 {
12643 #if TARGET_MACHO
12644   return "popcnt\t{%1, %0|%0, %1}";
12645 #else
12646   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12647 #endif
12648 }
12649   [(set_attr "prefix_rep" "1")
12650    (set_attr "type" "bitmanip")
12651    (set_attr "mode" "<MODE>")])
12652
12653 (define_insn "*popcount<mode>2_cmp"
12654   [(set (reg FLAGS_REG)
12655         (compare
12656           (popcount:SWI248
12657             (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12658           (const_int 0)))
12659    (set (match_operand:SWI248 0 "register_operand" "=r")
12660         (popcount:SWI248 (match_dup 1)))]
12661   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12662 {
12663 #if TARGET_MACHO
12664   return "popcnt\t{%1, %0|%0, %1}";
12665 #else
12666   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12667 #endif
12668 }
12669   [(set_attr "prefix_rep" "1")
12670    (set_attr "type" "bitmanip")
12671    (set_attr "mode" "<MODE>")])
12672
12673 (define_insn "*popcountsi2_cmp_zext"
12674   [(set (reg FLAGS_REG)
12675         (compare
12676           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12677           (const_int 0)))
12678    (set (match_operand:DI 0 "register_operand" "=r")
12679         (zero_extend:DI(popcount:SI (match_dup 1))))]
12680   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12681 {
12682 #if TARGET_MACHO
12683   return "popcnt\t{%1, %0|%0, %1}";
12684 #else
12685   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12686 #endif
12687 }
12688   [(set_attr "prefix_rep" "1")
12689    (set_attr "type" "bitmanip")
12690    (set_attr "mode" "SI")])
12691
12692 (define_expand "bswapsi2"
12693   [(set (match_operand:SI 0 "register_operand" "")
12694         (bswap:SI (match_operand:SI 1 "register_operand" "")))]
12695   ""
12696 {
12697   if (!(TARGET_BSWAP || TARGET_MOVBE))
12698     {
12699       rtx x = operands[0];
12700
12701       emit_move_insn (x, operands[1]);
12702       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12703       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12704       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12705       DONE;
12706     }
12707 })
12708
12709 (define_insn "*bswapsi_movbe"
12710   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,m")
12711         (bswap:SI (match_operand:SI 1 "nonimmediate_operand" "0,m,r")))]
12712   "TARGET_MOVBE && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12713   "@
12714     bswap\t%0
12715     movbe\t{%1, %0|%0, %1}
12716     movbe\t{%1, %0|%0, %1}"
12717   [(set_attr "type" "*,imov,imov")
12718    (set_attr "modrm" "*,1,1")
12719    (set_attr "prefix_0f" "1")
12720    (set_attr "prefix_extra" "*,1,1")
12721    (set_attr "length" "2,*,*")
12722    (set_attr "mode" "SI")])
12723
12724 (define_insn "*bswapsi_1"
12725   [(set (match_operand:SI 0 "register_operand" "=r")
12726         (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
12727   "TARGET_BSWAP"
12728   "bswap\t%0"
12729   [(set_attr "prefix_0f" "1")
12730    (set_attr "length" "2")])
12731
12732 (define_insn "*bswaphi_lowpart_1"
12733   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12734         (bswap:HI (match_dup 0)))
12735    (clobber (reg:CC FLAGS_REG))]
12736   "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12737   "@
12738     xchg{b}\t{%h0, %b0|%b0, %h0}
12739     rol{w}\t{$8, %0|%0, 8}"
12740   [(set_attr "length" "2,4")
12741    (set_attr "mode" "QI,HI")])
12742
12743 (define_insn "bswaphi_lowpart"
12744   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12745         (bswap:HI (match_dup 0)))
12746    (clobber (reg:CC FLAGS_REG))]
12747   ""
12748   "rol{w}\t{$8, %0|%0, 8}"
12749   [(set_attr "length" "4")
12750    (set_attr "mode" "HI")])
12751
12752 (define_expand "bswapdi2"
12753   [(set (match_operand:DI 0 "register_operand" "")
12754         (bswap:DI (match_operand:DI 1 "register_operand" "")))]
12755   "TARGET_64BIT"
12756   "")
12757
12758 (define_insn "*bswapdi_movbe"
12759   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m")
12760         (bswap:DI (match_operand:DI 1 "nonimmediate_operand" "0,m,r")))]
12761   "TARGET_64BIT && TARGET_MOVBE
12762    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12763   "@
12764     bswap\t%0
12765     movbe\t{%1, %0|%0, %1}
12766     movbe\t{%1, %0|%0, %1}"
12767   [(set_attr "type" "*,imov,imov")
12768    (set_attr "modrm" "*,1,1")
12769    (set_attr "prefix_0f" "1")
12770    (set_attr "prefix_extra" "*,1,1")
12771    (set_attr "length" "3,*,*")
12772    (set_attr "mode" "DI")])
12773
12774 (define_insn "*bswapdi_1"
12775   [(set (match_operand:DI 0 "register_operand" "=r")
12776         (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
12777   "TARGET_64BIT"
12778   "bswap\t%0"
12779   [(set_attr "prefix_0f" "1")
12780    (set_attr "length" "3")])
12781
12782 (define_expand "clzdi2"
12783   [(parallel
12784      [(set (match_operand:DI 0 "register_operand" "")
12785            (minus:DI (const_int 63)
12786                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
12787       (clobber (reg:CC FLAGS_REG))])
12788    (parallel
12789      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
12790       (clobber (reg:CC FLAGS_REG))])]
12791   "TARGET_64BIT"
12792 {
12793   if (TARGET_ABM)
12794     {
12795       emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
12796       DONE;
12797     }
12798 })
12799
12800 (define_insn "clzdi2_abm"
12801   [(set (match_operand:DI 0 "register_operand" "=r")
12802         (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
12803    (clobber (reg:CC FLAGS_REG))]
12804   "TARGET_64BIT && TARGET_ABM"
12805   "lzcnt{q}\t{%1, %0|%0, %1}"
12806   [(set_attr "prefix_rep" "1")
12807    (set_attr "type" "bitmanip")
12808    (set_attr "mode" "DI")])
12809
12810 (define_insn "bsr_rex64"
12811   [(set (match_operand:DI 0 "register_operand" "=r")
12812         (minus:DI (const_int 63)
12813                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12814    (clobber (reg:CC FLAGS_REG))]
12815   "TARGET_64BIT"
12816   "bsr{q}\t{%1, %0|%0, %1}"
12817   [(set_attr "type" "alu1")
12818    (set_attr "prefix_0f" "1")
12819    (set_attr "mode" "DI")])
12820
12821 (define_expand "clzhi2"
12822   [(parallel
12823      [(set (match_operand:HI 0 "register_operand" "")
12824            (minus:HI (const_int 15)
12825                      (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
12826       (clobber (reg:CC FLAGS_REG))])
12827    (parallel
12828      [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
12829       (clobber (reg:CC FLAGS_REG))])]
12830   ""
12831 {
12832   if (TARGET_ABM)
12833     {
12834       emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
12835       DONE;
12836     }
12837 })
12838
12839 (define_insn "clzhi2_abm"
12840   [(set (match_operand:HI 0 "register_operand" "=r")
12841         (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm")))
12842    (clobber (reg:CC FLAGS_REG))]
12843   "TARGET_ABM"
12844   "lzcnt{w}\t{%1, %0|%0, %1}"
12845   [(set_attr "prefix_rep" "1")
12846    (set_attr "type" "bitmanip")
12847    (set_attr "mode" "HI")])
12848
12849 (define_insn "*bsrhi"
12850   [(set (match_operand:HI 0 "register_operand" "=r")
12851         (minus:HI (const_int 15)
12852                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12853    (clobber (reg:CC FLAGS_REG))]
12854   ""
12855   "bsr{w}\t{%1, %0|%0, %1}"
12856   [(set_attr "type" "alu1")
12857    (set_attr "prefix_0f" "1")
12858    (set_attr "mode" "HI")])
12859
12860 (define_expand "paritydi2"
12861   [(set (match_operand:DI 0 "register_operand" "")
12862         (parity:DI (match_operand:DI 1 "register_operand" "")))]
12863   "! TARGET_POPCNT"
12864 {
12865   rtx scratch = gen_reg_rtx (QImode);
12866   rtx cond;
12867
12868   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12869                                 NULL_RTX, operands[1]));
12870
12871   cond = gen_rtx_fmt_ee (ORDERED, QImode,
12872                          gen_rtx_REG (CCmode, FLAGS_REG),
12873                          const0_rtx);
12874   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12875
12876   if (TARGET_64BIT)
12877     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12878   else
12879     {
12880       rtx tmp = gen_reg_rtx (SImode);
12881
12882       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12883       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12884     }
12885   DONE;
12886 })
12887
12888 (define_insn_and_split "paritydi2_cmp"
12889   [(set (reg:CC FLAGS_REG)
12890         (parity:CC (match_operand:DI 3 "register_operand" "0")))
12891    (clobber (match_scratch:DI 0 "=r"))
12892    (clobber (match_scratch:SI 1 "=&r"))
12893    (clobber (match_scratch:HI 2 "=Q"))]
12894   "! TARGET_POPCNT"
12895   "#"
12896   "&& reload_completed"
12897   [(parallel
12898      [(set (match_dup 1)
12899            (xor:SI (match_dup 1) (match_dup 4)))
12900       (clobber (reg:CC FLAGS_REG))])
12901    (parallel
12902      [(set (reg:CC FLAGS_REG)
12903            (parity:CC (match_dup 1)))
12904       (clobber (match_dup 1))
12905       (clobber (match_dup 2))])]
12906 {
12907   operands[4] = gen_lowpart (SImode, operands[3]);
12908
12909   if (TARGET_64BIT)
12910     {
12911       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12912       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12913     }
12914   else
12915     operands[1] = gen_highpart (SImode, operands[3]);
12916 })
12917
12918 (define_expand "paritysi2"
12919   [(set (match_operand:SI 0 "register_operand" "")
12920         (parity:SI (match_operand:SI 1 "register_operand" "")))]
12921   "! TARGET_POPCNT"
12922 {
12923   rtx scratch = gen_reg_rtx (QImode);
12924   rtx cond;
12925
12926   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12927
12928   cond = gen_rtx_fmt_ee (ORDERED, QImode,
12929                          gen_rtx_REG (CCmode, FLAGS_REG),
12930                          const0_rtx);
12931   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12932
12933   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12934   DONE;
12935 })
12936
12937 (define_insn_and_split "paritysi2_cmp"
12938   [(set (reg:CC FLAGS_REG)
12939         (parity:CC (match_operand:SI 2 "register_operand" "0")))
12940    (clobber (match_scratch:SI 0 "=r"))
12941    (clobber (match_scratch:HI 1 "=&Q"))]
12942   "! TARGET_POPCNT"
12943   "#"
12944   "&& reload_completed"
12945   [(parallel
12946      [(set (match_dup 1)
12947            (xor:HI (match_dup 1) (match_dup 3)))
12948       (clobber (reg:CC FLAGS_REG))])
12949    (parallel
12950      [(set (reg:CC FLAGS_REG)
12951            (parity:CC (match_dup 1)))
12952       (clobber (match_dup 1))])]
12953 {
12954   operands[3] = gen_lowpart (HImode, operands[2]);
12955
12956   emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12957   emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12958 })
12959
12960 (define_insn "*parityhi2_cmp"
12961   [(set (reg:CC FLAGS_REG)
12962         (parity:CC (match_operand:HI 1 "register_operand" "0")))
12963    (clobber (match_scratch:HI 0 "=Q"))]
12964   "! TARGET_POPCNT"
12965   "xor{b}\t{%h0, %b0|%b0, %h0}"
12966   [(set_attr "length" "2")
12967    (set_attr "mode" "HI")])
12968
12969 (define_insn "*parityqi2_cmp"
12970   [(set (reg:CC FLAGS_REG)
12971         (parity:CC (match_operand:QI 0 "register_operand" "q")))]
12972   "! TARGET_POPCNT"
12973   "test{b}\t%0, %0"
12974   [(set_attr "length" "2")
12975    (set_attr "mode" "QI")])
12976 \f
12977 ;; Thread-local storage patterns for ELF.
12978 ;;
12979 ;; Note that these code sequences must appear exactly as shown
12980 ;; in order to allow linker relaxation.
12981
12982 (define_insn "*tls_global_dynamic_32_gnu"
12983   [(set (match_operand:SI 0 "register_operand" "=a")
12984         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12985                     (match_operand:SI 2 "tls_symbolic_operand" "")
12986                     (match_operand:SI 3 "call_insn_operand" "")]
12987                     UNSPEC_TLS_GD))
12988    (clobber (match_scratch:SI 4 "=d"))
12989    (clobber (match_scratch:SI 5 "=c"))
12990    (clobber (reg:CC FLAGS_REG))]
12991   "!TARGET_64BIT && TARGET_GNU_TLS"
12992   "lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}\;call\t%P3"
12993   [(set_attr "type" "multi")
12994    (set_attr "length" "12")])
12995
12996 (define_expand "tls_global_dynamic_32"
12997   [(parallel [(set (match_operand:SI 0 "register_operand" "")
12998                    (unspec:SI
12999                     [(match_dup 2)
13000                      (match_operand:SI 1 "tls_symbolic_operand" "")
13001                      (match_dup 3)]
13002                     UNSPEC_TLS_GD))
13003               (clobber (match_scratch:SI 4 ""))
13004               (clobber (match_scratch:SI 5 ""))
13005               (clobber (reg:CC FLAGS_REG))])]
13006   ""
13007 {
13008   if (flag_pic)
13009     operands[2] = pic_offset_table_rtx;
13010   else
13011     {
13012       operands[2] = gen_reg_rtx (Pmode);
13013       emit_insn (gen_set_got (operands[2]));
13014     }
13015   if (TARGET_GNU2_TLS)
13016     {
13017        emit_insn (gen_tls_dynamic_gnu2_32
13018                   (operands[0], operands[1], operands[2]));
13019        DONE;
13020     }
13021   operands[3] = ix86_tls_get_addr ();
13022 })
13023
13024 (define_insn "*tls_global_dynamic_64"
13025   [(set (match_operand:DI 0 "register_operand" "=a")
13026         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
13027                  (match_operand:DI 3 "" "")))
13028    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
13029               UNSPEC_TLS_GD)]
13030   "TARGET_64BIT"
13031   { 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"; }
13032   [(set_attr "type" "multi")
13033    (set_attr "length" "16")])
13034
13035 (define_expand "tls_global_dynamic_64"
13036   [(parallel [(set (match_operand:DI 0 "register_operand" "")
13037                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
13038               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
13039                          UNSPEC_TLS_GD)])]
13040   ""
13041 {
13042   if (TARGET_GNU2_TLS)
13043     {
13044        emit_insn (gen_tls_dynamic_gnu2_64
13045                   (operands[0], operands[1]));
13046        DONE;
13047     }
13048   operands[2] = ix86_tls_get_addr ();
13049 })
13050
13051 (define_insn "*tls_local_dynamic_base_32_gnu"
13052   [(set (match_operand:SI 0 "register_operand" "=a")
13053         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13054                     (match_operand:SI 2 "call_insn_operand" "")]
13055                    UNSPEC_TLS_LD_BASE))
13056    (clobber (match_scratch:SI 3 "=d"))
13057    (clobber (match_scratch:SI 4 "=c"))
13058    (clobber (reg:CC FLAGS_REG))]
13059   "!TARGET_64BIT && TARGET_GNU_TLS"
13060   "lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}\;call\t%P2"
13061   [(set_attr "type" "multi")
13062    (set_attr "length" "11")])
13063
13064 (define_expand "tls_local_dynamic_base_32"
13065   [(parallel [(set (match_operand:SI 0 "register_operand" "")
13066                    (unspec:SI [(match_dup 1) (match_dup 2)]
13067                               UNSPEC_TLS_LD_BASE))
13068               (clobber (match_scratch:SI 3 ""))
13069               (clobber (match_scratch:SI 4 ""))
13070               (clobber (reg:CC FLAGS_REG))])]
13071   ""
13072 {
13073   if (flag_pic)
13074     operands[1] = pic_offset_table_rtx;
13075   else
13076     {
13077       operands[1] = gen_reg_rtx (Pmode);
13078       emit_insn (gen_set_got (operands[1]));
13079     }
13080   if (TARGET_GNU2_TLS)
13081     {
13082        emit_insn (gen_tls_dynamic_gnu2_32
13083                   (operands[0], ix86_tls_module_base (), operands[1]));
13084        DONE;
13085     }
13086   operands[2] = ix86_tls_get_addr ();
13087 })
13088
13089 (define_insn "*tls_local_dynamic_base_64"
13090   [(set (match_operand:DI 0 "register_operand" "=a")
13091         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
13092                  (match_operand:DI 2 "" "")))
13093    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
13094   "TARGET_64BIT"
13095   "lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}\;call\t%P1"
13096   [(set_attr "type" "multi")
13097    (set_attr "length" "12")])
13098
13099 (define_expand "tls_local_dynamic_base_64"
13100   [(parallel [(set (match_operand:DI 0 "register_operand" "")
13101                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
13102               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
13103   ""
13104 {
13105   if (TARGET_GNU2_TLS)
13106     {
13107        emit_insn (gen_tls_dynamic_gnu2_64
13108                   (operands[0], ix86_tls_module_base ()));
13109        DONE;
13110     }
13111   operands[1] = ix86_tls_get_addr ();
13112 })
13113
13114 ;; Local dynamic of a single variable is a lose.  Show combine how
13115 ;; to convert that back to global dynamic.
13116
13117 (define_insn_and_split "*tls_local_dynamic_32_once"
13118   [(set (match_operand:SI 0 "register_operand" "=a")
13119         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13120                              (match_operand:SI 2 "call_insn_operand" "")]
13121                             UNSPEC_TLS_LD_BASE)
13122                  (const:SI (unspec:SI
13123                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
13124                             UNSPEC_DTPOFF))))
13125    (clobber (match_scratch:SI 4 "=d"))
13126    (clobber (match_scratch:SI 5 "=c"))
13127    (clobber (reg:CC FLAGS_REG))]
13128   ""
13129   "#"
13130   ""
13131   [(parallel [(set (match_dup 0)
13132                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
13133                               UNSPEC_TLS_GD))
13134               (clobber (match_dup 4))
13135               (clobber (match_dup 5))
13136               (clobber (reg:CC FLAGS_REG))])]
13137   "")
13138
13139 ;; Load and add the thread base pointer from %gs:0.
13140
13141 (define_insn "*load_tp_si"
13142   [(set (match_operand:SI 0 "register_operand" "=r")
13143         (unspec:SI [(const_int 0)] UNSPEC_TP))]
13144   "!TARGET_64BIT"
13145   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
13146   [(set_attr "type" "imov")
13147    (set_attr "modrm" "0")
13148    (set_attr "length" "7")
13149    (set_attr "memory" "load")
13150    (set_attr "imm_disp" "false")])
13151
13152 (define_insn "*add_tp_si"
13153   [(set (match_operand:SI 0 "register_operand" "=r")
13154         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13155                  (match_operand:SI 1 "register_operand" "0")))
13156    (clobber (reg:CC FLAGS_REG))]
13157   "!TARGET_64BIT"
13158   "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
13159   [(set_attr "type" "alu")
13160    (set_attr "modrm" "0")
13161    (set_attr "length" "7")
13162    (set_attr "memory" "load")
13163    (set_attr "imm_disp" "false")])
13164
13165 (define_insn "*load_tp_di"
13166   [(set (match_operand:DI 0 "register_operand" "=r")
13167         (unspec:DI [(const_int 0)] UNSPEC_TP))]
13168   "TARGET_64BIT"
13169   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
13170   [(set_attr "type" "imov")
13171    (set_attr "modrm" "0")
13172    (set_attr "length" "7")
13173    (set_attr "memory" "load")
13174    (set_attr "imm_disp" "false")])
13175
13176 (define_insn "*add_tp_di"
13177   [(set (match_operand:DI 0 "register_operand" "=r")
13178         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
13179                  (match_operand:DI 1 "register_operand" "0")))
13180    (clobber (reg:CC FLAGS_REG))]
13181   "TARGET_64BIT"
13182   "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
13183   [(set_attr "type" "alu")
13184    (set_attr "modrm" "0")
13185    (set_attr "length" "7")
13186    (set_attr "memory" "load")
13187    (set_attr "imm_disp" "false")])
13188
13189 ;; GNU2 TLS patterns can be split.
13190
13191 (define_expand "tls_dynamic_gnu2_32"
13192   [(set (match_dup 3)
13193         (plus:SI (match_operand:SI 2 "register_operand" "")
13194                  (const:SI
13195                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
13196                              UNSPEC_TLSDESC))))
13197    (parallel
13198     [(set (match_operand:SI 0 "register_operand" "")
13199           (unspec:SI [(match_dup 1) (match_dup 3)
13200                       (match_dup 2) (reg:SI SP_REG)]
13201                       UNSPEC_TLSDESC))
13202      (clobber (reg:CC FLAGS_REG))])]
13203   "!TARGET_64BIT && TARGET_GNU2_TLS"
13204 {
13205   operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13206   ix86_tls_descriptor_calls_expanded_in_cfun = true;
13207 })
13208
13209 (define_insn "*tls_dynamic_lea_32"
13210   [(set (match_operand:SI 0 "register_operand" "=r")
13211         (plus:SI (match_operand:SI 1 "register_operand" "b")
13212                  (const:SI
13213                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
13214                               UNSPEC_TLSDESC))))]
13215   "!TARGET_64BIT && TARGET_GNU2_TLS"
13216   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
13217   [(set_attr "type" "lea")
13218    (set_attr "mode" "SI")
13219    (set_attr "length" "6")
13220    (set_attr "length_address" "4")])
13221
13222 (define_insn "*tls_dynamic_call_32"
13223   [(set (match_operand:SI 0 "register_operand" "=a")
13224         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
13225                     (match_operand:SI 2 "register_operand" "0")
13226                     ;; we have to make sure %ebx still points to the GOT
13227                     (match_operand:SI 3 "register_operand" "b")
13228                     (reg:SI SP_REG)]
13229                    UNSPEC_TLSDESC))
13230    (clobber (reg:CC FLAGS_REG))]
13231   "!TARGET_64BIT && TARGET_GNU2_TLS"
13232   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
13233   [(set_attr "type" "call")
13234    (set_attr "length" "2")
13235    (set_attr "length_address" "0")])
13236
13237 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
13238   [(set (match_operand:SI 0 "register_operand" "=&a")
13239         (plus:SI
13240          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
13241                      (match_operand:SI 4 "" "")
13242                      (match_operand:SI 2 "register_operand" "b")
13243                      (reg:SI SP_REG)]
13244                     UNSPEC_TLSDESC)
13245          (const:SI (unspec:SI
13246                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
13247                     UNSPEC_DTPOFF))))
13248    (clobber (reg:CC FLAGS_REG))]
13249   "!TARGET_64BIT && TARGET_GNU2_TLS"
13250   "#"
13251   ""
13252   [(set (match_dup 0) (match_dup 5))]
13253 {
13254   operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13255   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
13256 })
13257
13258 (define_expand "tls_dynamic_gnu2_64"
13259   [(set (match_dup 2)
13260         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
13261                    UNSPEC_TLSDESC))
13262    (parallel
13263     [(set (match_operand:DI 0 "register_operand" "")
13264           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
13265                      UNSPEC_TLSDESC))
13266      (clobber (reg:CC FLAGS_REG))])]
13267   "TARGET_64BIT && TARGET_GNU2_TLS"
13268 {
13269   operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13270   ix86_tls_descriptor_calls_expanded_in_cfun = true;
13271 })
13272
13273 (define_insn "*tls_dynamic_lea_64"
13274   [(set (match_operand:DI 0 "register_operand" "=r")
13275         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
13276                    UNSPEC_TLSDESC))]
13277   "TARGET_64BIT && TARGET_GNU2_TLS"
13278   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
13279   [(set_attr "type" "lea")
13280    (set_attr "mode" "DI")
13281    (set_attr "length" "7")
13282    (set_attr "length_address" "4")])
13283
13284 (define_insn "*tls_dynamic_call_64"
13285   [(set (match_operand:DI 0 "register_operand" "=a")
13286         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
13287                     (match_operand:DI 2 "register_operand" "0")
13288                     (reg:DI SP_REG)]
13289                    UNSPEC_TLSDESC))
13290    (clobber (reg:CC FLAGS_REG))]
13291   "TARGET_64BIT && TARGET_GNU2_TLS"
13292   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
13293   [(set_attr "type" "call")
13294    (set_attr "length" "2")
13295    (set_attr "length_address" "0")])
13296
13297 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
13298   [(set (match_operand:DI 0 "register_operand" "=&a")
13299         (plus:DI
13300          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
13301                      (match_operand:DI 3 "" "")
13302                      (reg:DI SP_REG)]
13303                     UNSPEC_TLSDESC)
13304          (const:DI (unspec:DI
13305                     [(match_operand:DI 1 "tls_symbolic_operand" "")]
13306                     UNSPEC_DTPOFF))))
13307    (clobber (reg:CC FLAGS_REG))]
13308   "TARGET_64BIT && TARGET_GNU2_TLS"
13309   "#"
13310   ""
13311   [(set (match_dup 0) (match_dup 4))]
13312 {
13313   operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13314   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
13315 })
13316
13317 ;;
13318 \f
13319 ;; These patterns match the binary 387 instructions for addM3, subM3,
13320 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
13321 ;; SFmode.  The first is the normal insn, the second the same insn but
13322 ;; with one operand a conversion, and the third the same insn but with
13323 ;; the other operand a conversion.  The conversion may be SFmode or
13324 ;; SImode if the target mode DFmode, but only SImode if the target mode
13325 ;; is SFmode.
13326
13327 ;; Gcc is slightly more smart about handling normal two address instructions
13328 ;; so use special patterns for add and mull.
13329
13330 (define_insn "*fop_<mode>_comm_mixed_avx"
13331   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
13332         (match_operator:MODEF 3 "binary_fp_operator"
13333           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
13334            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
13335   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13336    && COMMUTATIVE_ARITH_P (operands[3])
13337    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13338   "* return output_387_binary_op (insn, operands);"
13339   [(set (attr "type")
13340         (if_then_else (eq_attr "alternative" "1")
13341            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13342               (const_string "ssemul")
13343               (const_string "sseadd"))
13344            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13345               (const_string "fmul")
13346               (const_string "fop"))))
13347    (set_attr "prefix" "orig,maybe_vex")
13348    (set_attr "mode" "<MODE>")])
13349
13350 (define_insn "*fop_<mode>_comm_mixed"
13351   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
13352         (match_operator:MODEF 3 "binary_fp_operator"
13353           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
13354            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
13355   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13356    && COMMUTATIVE_ARITH_P (operands[3])
13357    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13358   "* return output_387_binary_op (insn, operands);"
13359   [(set (attr "type")
13360         (if_then_else (eq_attr "alternative" "1")
13361            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13362               (const_string "ssemul")
13363               (const_string "sseadd"))
13364            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13365               (const_string "fmul")
13366               (const_string "fop"))))
13367    (set_attr "mode" "<MODE>")])
13368
13369 (define_insn "*fop_<mode>_comm_avx"
13370   [(set (match_operand:MODEF 0 "register_operand" "=x")
13371         (match_operator:MODEF 3 "binary_fp_operator"
13372           [(match_operand:MODEF 1 "nonimmediate_operand" "%x")
13373            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
13374   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13375    && COMMUTATIVE_ARITH_P (operands[3])
13376    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13377   "* return output_387_binary_op (insn, operands);"
13378   [(set (attr "type")
13379         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13380            (const_string "ssemul")
13381            (const_string "sseadd")))
13382    (set_attr "prefix" "vex")
13383    (set_attr "mode" "<MODE>")])
13384
13385 (define_insn "*fop_<mode>_comm_sse"
13386   [(set (match_operand:MODEF 0 "register_operand" "=x")
13387         (match_operator:MODEF 3 "binary_fp_operator"
13388           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13389            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
13390   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13391    && COMMUTATIVE_ARITH_P (operands[3])
13392    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13393   "* return output_387_binary_op (insn, operands);"
13394   [(set (attr "type")
13395         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13396            (const_string "ssemul")
13397            (const_string "sseadd")))
13398    (set_attr "mode" "<MODE>")])
13399
13400 (define_insn "*fop_<mode>_comm_i387"
13401   [(set (match_operand:MODEF 0 "register_operand" "=f")
13402         (match_operator:MODEF 3 "binary_fp_operator"
13403           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13404            (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
13405   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13406    && COMMUTATIVE_ARITH_P (operands[3])
13407    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13408   "* return output_387_binary_op (insn, operands);"
13409   [(set (attr "type")
13410         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13411            (const_string "fmul")
13412            (const_string "fop")))
13413    (set_attr "mode" "<MODE>")])
13414
13415 (define_insn "*fop_<mode>_1_mixed_avx"
13416   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
13417         (match_operator:MODEF 3 "binary_fp_operator"
13418           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,x")
13419            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
13420   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13421    && !COMMUTATIVE_ARITH_P (operands[3])
13422    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13423   "* return output_387_binary_op (insn, operands);"
13424   [(set (attr "type")
13425         (cond [(and (eq_attr "alternative" "2")
13426                     (match_operand:MODEF 3 "mult_operator" ""))
13427                  (const_string "ssemul")
13428                (and (eq_attr "alternative" "2")
13429                     (match_operand:MODEF 3 "div_operator" ""))
13430                  (const_string "ssediv")
13431                (eq_attr "alternative" "2")
13432                  (const_string "sseadd")
13433                (match_operand:MODEF 3 "mult_operator" "")
13434                  (const_string "fmul")
13435                (match_operand:MODEF 3 "div_operator" "")
13436                  (const_string "fdiv")
13437               ]
13438               (const_string "fop")))
13439    (set_attr "prefix" "orig,orig,maybe_vex")
13440    (set_attr "mode" "<MODE>")])
13441
13442 (define_insn "*fop_<mode>_1_mixed"
13443   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
13444         (match_operator:MODEF 3 "binary_fp_operator"
13445           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
13446            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
13447   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13448    && !COMMUTATIVE_ARITH_P (operands[3])
13449    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13450   "* return output_387_binary_op (insn, operands);"
13451   [(set (attr "type")
13452         (cond [(and (eq_attr "alternative" "2")
13453                     (match_operand:MODEF 3 "mult_operator" ""))
13454                  (const_string "ssemul")
13455                (and (eq_attr "alternative" "2")
13456                     (match_operand:MODEF 3 "div_operator" ""))
13457                  (const_string "ssediv")
13458                (eq_attr "alternative" "2")
13459                  (const_string "sseadd")
13460                (match_operand:MODEF 3 "mult_operator" "")
13461                  (const_string "fmul")
13462                (match_operand:MODEF 3 "div_operator" "")
13463                  (const_string "fdiv")
13464               ]
13465               (const_string "fop")))
13466    (set_attr "mode" "<MODE>")])
13467
13468 (define_insn "*rcpsf2_sse"
13469   [(set (match_operand:SF 0 "register_operand" "=x")
13470         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13471                    UNSPEC_RCP))]
13472   "TARGET_SSE_MATH"
13473   "%vrcpss\t{%1, %d0|%d0, %1}"
13474   [(set_attr "type" "sse")
13475    (set_attr "atom_sse_attr" "rcp")
13476    (set_attr "prefix" "maybe_vex")
13477    (set_attr "mode" "SF")])
13478
13479 (define_insn "*fop_<mode>_1_avx"
13480   [(set (match_operand:MODEF 0 "register_operand" "=x")
13481         (match_operator:MODEF 3 "binary_fp_operator"
13482           [(match_operand:MODEF 1 "register_operand" "x")
13483            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
13484   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13485    && !COMMUTATIVE_ARITH_P (operands[3])"
13486   "* return output_387_binary_op (insn, operands);"
13487   [(set (attr "type")
13488         (cond [(match_operand:MODEF 3 "mult_operator" "")
13489                  (const_string "ssemul")
13490                (match_operand:MODEF 3 "div_operator" "")
13491                  (const_string "ssediv")
13492               ]
13493               (const_string "sseadd")))
13494    (set_attr "prefix" "vex")
13495    (set_attr "mode" "<MODE>")])
13496
13497 (define_insn "*fop_<mode>_1_sse"
13498   [(set (match_operand:MODEF 0 "register_operand" "=x")
13499         (match_operator:MODEF 3 "binary_fp_operator"
13500           [(match_operand:MODEF 1 "register_operand" "0")
13501            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
13502   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13503    && !COMMUTATIVE_ARITH_P (operands[3])"
13504   "* return output_387_binary_op (insn, operands);"
13505   [(set (attr "type")
13506         (cond [(match_operand:MODEF 3 "mult_operator" "")
13507                  (const_string "ssemul")
13508                (match_operand:MODEF 3 "div_operator" "")
13509                  (const_string "ssediv")
13510               ]
13511               (const_string "sseadd")))
13512    (set_attr "mode" "<MODE>")])
13513
13514 ;; This pattern is not fully shadowed by the pattern above.
13515 (define_insn "*fop_<mode>_1_i387"
13516   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13517         (match_operator:MODEF 3 "binary_fp_operator"
13518           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13519            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13520   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13521    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13522    && !COMMUTATIVE_ARITH_P (operands[3])
13523    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13524   "* return output_387_binary_op (insn, operands);"
13525   [(set (attr "type")
13526         (cond [(match_operand:MODEF 3 "mult_operator" "")
13527                  (const_string "fmul")
13528                (match_operand:MODEF 3 "div_operator" "")
13529                  (const_string "fdiv")
13530               ]
13531               (const_string "fop")))
13532    (set_attr "mode" "<MODE>")])
13533
13534 ;; ??? Add SSE splitters for these!
13535 (define_insn "*fop_<MODEF:mode>_2_i387"
13536   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13537         (match_operator:MODEF 3 "binary_fp_operator"
13538           [(float:MODEF
13539              (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
13540            (match_operand:MODEF 2 "register_operand" "0,0")]))]
13541   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
13542    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13543    && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13544   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13545   [(set (attr "type")
13546         (cond [(match_operand:MODEF 3 "mult_operator" "")
13547                  (const_string "fmul")
13548                (match_operand:MODEF 3 "div_operator" "")
13549                  (const_string "fdiv")
13550               ]
13551               (const_string "fop")))
13552    (set_attr "fp_int_src" "true")
13553    (set_attr "mode" "<X87MODEI12:MODE>")])
13554
13555 (define_insn "*fop_<MODEF:mode>_3_i387"
13556   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13557         (match_operator:MODEF 3 "binary_fp_operator"
13558           [(match_operand:MODEF 1 "register_operand" "0,0")
13559            (float:MODEF
13560              (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
13561   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
13562    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13563    && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13564   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13565   [(set (attr "type")
13566         (cond [(match_operand:MODEF 3 "mult_operator" "")
13567                  (const_string "fmul")
13568                (match_operand:MODEF 3 "div_operator" "")
13569                  (const_string "fdiv")
13570               ]
13571               (const_string "fop")))
13572    (set_attr "fp_int_src" "true")
13573    (set_attr "mode" "<MODE>")])
13574
13575 (define_insn "*fop_df_4_i387"
13576   [(set (match_operand:DF 0 "register_operand" "=f,f")
13577         (match_operator:DF 3 "binary_fp_operator"
13578            [(float_extend:DF
13579              (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13580             (match_operand:DF 2 "register_operand" "0,f")]))]
13581   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13582    && !(TARGET_SSE2 && TARGET_SSE_MATH)
13583    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13584   "* return output_387_binary_op (insn, operands);"
13585   [(set (attr "type")
13586         (cond [(match_operand:DF 3 "mult_operator" "")
13587                  (const_string "fmul")
13588                (match_operand:DF 3 "div_operator" "")
13589                  (const_string "fdiv")
13590               ]
13591               (const_string "fop")))
13592    (set_attr "mode" "SF")])
13593
13594 (define_insn "*fop_df_5_i387"
13595   [(set (match_operand:DF 0 "register_operand" "=f,f")
13596         (match_operator:DF 3 "binary_fp_operator"
13597           [(match_operand:DF 1 "register_operand" "0,f")
13598            (float_extend:DF
13599             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13600   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13601    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13602   "* return output_387_binary_op (insn, operands);"
13603   [(set (attr "type")
13604         (cond [(match_operand:DF 3 "mult_operator" "")
13605                  (const_string "fmul")
13606                (match_operand:DF 3 "div_operator" "")
13607                  (const_string "fdiv")
13608               ]
13609               (const_string "fop")))
13610    (set_attr "mode" "SF")])
13611
13612 (define_insn "*fop_df_6_i387"
13613   [(set (match_operand:DF 0 "register_operand" "=f,f")
13614         (match_operator:DF 3 "binary_fp_operator"
13615           [(float_extend:DF
13616             (match_operand:SF 1 "register_operand" "0,f"))
13617            (float_extend:DF
13618             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13619   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13620    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13621   "* return output_387_binary_op (insn, operands);"
13622   [(set (attr "type")
13623         (cond [(match_operand:DF 3 "mult_operator" "")
13624                  (const_string "fmul")
13625                (match_operand:DF 3 "div_operator" "")
13626                  (const_string "fdiv")
13627               ]
13628               (const_string "fop")))
13629    (set_attr "mode" "SF")])
13630
13631 (define_insn "*fop_xf_comm_i387"
13632   [(set (match_operand:XF 0 "register_operand" "=f")
13633         (match_operator:XF 3 "binary_fp_operator"
13634                         [(match_operand:XF 1 "register_operand" "%0")
13635                          (match_operand:XF 2 "register_operand" "f")]))]
13636   "TARGET_80387
13637    && COMMUTATIVE_ARITH_P (operands[3])"
13638   "* return output_387_binary_op (insn, operands);"
13639   [(set (attr "type")
13640         (if_then_else (match_operand:XF 3 "mult_operator" "")
13641            (const_string "fmul")
13642            (const_string "fop")))
13643    (set_attr "mode" "XF")])
13644
13645 (define_insn "*fop_xf_1_i387"
13646   [(set (match_operand:XF 0 "register_operand" "=f,f")
13647         (match_operator:XF 3 "binary_fp_operator"
13648                         [(match_operand:XF 1 "register_operand" "0,f")
13649                          (match_operand:XF 2 "register_operand" "f,0")]))]
13650   "TARGET_80387
13651    && !COMMUTATIVE_ARITH_P (operands[3])"
13652   "* return output_387_binary_op (insn, operands);"
13653   [(set (attr "type")
13654         (cond [(match_operand:XF 3 "mult_operator" "")
13655                  (const_string "fmul")
13656                (match_operand:XF 3 "div_operator" "")
13657                  (const_string "fdiv")
13658               ]
13659               (const_string "fop")))
13660    (set_attr "mode" "XF")])
13661
13662 (define_insn "*fop_xf_2_i387"
13663   [(set (match_operand:XF 0 "register_operand" "=f,f")
13664         (match_operator:XF 3 "binary_fp_operator"
13665           [(float:XF
13666              (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
13667            (match_operand:XF 2 "register_operand" "0,0")]))]
13668   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13669   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13670   [(set (attr "type")
13671         (cond [(match_operand:XF 3 "mult_operator" "")
13672                  (const_string "fmul")
13673                (match_operand:XF 3 "div_operator" "")
13674                  (const_string "fdiv")
13675               ]
13676               (const_string "fop")))
13677    (set_attr "fp_int_src" "true")
13678    (set_attr "mode" "<MODE>")])
13679
13680 (define_insn "*fop_xf_3_i387"
13681   [(set (match_operand:XF 0 "register_operand" "=f,f")
13682         (match_operator:XF 3 "binary_fp_operator"
13683           [(match_operand:XF 1 "register_operand" "0,0")
13684            (float:XF
13685              (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
13686   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13687   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13688   [(set (attr "type")
13689         (cond [(match_operand:XF 3 "mult_operator" "")
13690                  (const_string "fmul")
13691                (match_operand:XF 3 "div_operator" "")
13692                  (const_string "fdiv")
13693               ]
13694               (const_string "fop")))
13695    (set_attr "fp_int_src" "true")
13696    (set_attr "mode" "<MODE>")])
13697
13698 (define_insn "*fop_xf_4_i387"
13699   [(set (match_operand:XF 0 "register_operand" "=f,f")
13700         (match_operator:XF 3 "binary_fp_operator"
13701            [(float_extend:XF
13702               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13703             (match_operand:XF 2 "register_operand" "0,f")]))]
13704   "TARGET_80387"
13705   "* return output_387_binary_op (insn, operands);"
13706   [(set (attr "type")
13707         (cond [(match_operand:XF 3 "mult_operator" "")
13708                  (const_string "fmul")
13709                (match_operand:XF 3 "div_operator" "")
13710                  (const_string "fdiv")
13711               ]
13712               (const_string "fop")))
13713    (set_attr "mode" "<MODE>")])
13714
13715 (define_insn "*fop_xf_5_i387"
13716   [(set (match_operand:XF 0 "register_operand" "=f,f")
13717         (match_operator:XF 3 "binary_fp_operator"
13718           [(match_operand:XF 1 "register_operand" "0,f")
13719            (float_extend:XF
13720              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13721   "TARGET_80387"
13722   "* return output_387_binary_op (insn, operands);"
13723   [(set (attr "type")
13724         (cond [(match_operand:XF 3 "mult_operator" "")
13725                  (const_string "fmul")
13726                (match_operand:XF 3 "div_operator" "")
13727                  (const_string "fdiv")
13728               ]
13729               (const_string "fop")))
13730    (set_attr "mode" "<MODE>")])
13731
13732 (define_insn "*fop_xf_6_i387"
13733   [(set (match_operand:XF 0 "register_operand" "=f,f")
13734         (match_operator:XF 3 "binary_fp_operator"
13735           [(float_extend:XF
13736              (match_operand:MODEF 1 "register_operand" "0,f"))
13737            (float_extend:XF
13738              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13739   "TARGET_80387"
13740   "* return output_387_binary_op (insn, operands);"
13741   [(set (attr "type")
13742         (cond [(match_operand:XF 3 "mult_operator" "")
13743                  (const_string "fmul")
13744                (match_operand:XF 3 "div_operator" "")
13745                  (const_string "fdiv")
13746               ]
13747               (const_string "fop")))
13748    (set_attr "mode" "<MODE>")])
13749
13750 (define_split
13751   [(set (match_operand 0 "register_operand" "")
13752         (match_operator 3 "binary_fp_operator"
13753            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
13754             (match_operand 2 "register_operand" "")]))]
13755   "reload_completed
13756    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13757    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13758   [(const_int 0)]
13759 {
13760   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13761   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13762   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13763                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
13764                                           GET_MODE (operands[3]),
13765                                           operands[4],
13766                                           operands[2])));
13767   ix86_free_from_memory (GET_MODE (operands[1]));
13768   DONE;
13769 })
13770
13771 (define_split
13772   [(set (match_operand 0 "register_operand" "")
13773         (match_operator 3 "binary_fp_operator"
13774            [(match_operand 1 "register_operand" "")
13775             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
13776   "reload_completed
13777    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13778    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13779   [(const_int 0)]
13780 {
13781   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13782   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13783   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13784                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
13785                                           GET_MODE (operands[3]),
13786                                           operands[1],
13787                                           operands[4])));
13788   ix86_free_from_memory (GET_MODE (operands[2]));
13789   DONE;
13790 })
13791 \f
13792 ;; FPU special functions.
13793
13794 ;; This pattern implements a no-op XFmode truncation for
13795 ;; all fancy i386 XFmode math functions.
13796
13797 (define_insn "truncxf<mode>2_i387_noop_unspec"
13798   [(set (match_operand:MODEF 0 "register_operand" "=f")
13799         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13800         UNSPEC_TRUNC_NOOP))]
13801   "TARGET_USE_FANCY_MATH_387"
13802   "* return output_387_reg_move (insn, operands);"
13803   [(set_attr "type" "fmov")
13804    (set_attr "mode" "<MODE>")])
13805
13806 (define_insn "sqrtxf2"
13807   [(set (match_operand:XF 0 "register_operand" "=f")
13808         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13809   "TARGET_USE_FANCY_MATH_387"
13810   "fsqrt"
13811   [(set_attr "type" "fpspc")
13812    (set_attr "mode" "XF")
13813    (set_attr "athlon_decode" "direct")
13814    (set_attr "amdfam10_decode" "direct")])
13815
13816 (define_insn "sqrt_extend<mode>xf2_i387"
13817   [(set (match_operand:XF 0 "register_operand" "=f")
13818         (sqrt:XF
13819           (float_extend:XF
13820             (match_operand:MODEF 1 "register_operand" "0"))))]
13821   "TARGET_USE_FANCY_MATH_387"
13822   "fsqrt"
13823   [(set_attr "type" "fpspc")
13824    (set_attr "mode" "XF")
13825    (set_attr "athlon_decode" "direct")
13826    (set_attr "amdfam10_decode" "direct")])
13827
13828 (define_insn "*rsqrtsf2_sse"
13829   [(set (match_operand:SF 0 "register_operand" "=x")
13830         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13831                    UNSPEC_RSQRT))]
13832   "TARGET_SSE_MATH"
13833   "%vrsqrtss\t{%1, %d0|%d0, %1}"
13834   [(set_attr "type" "sse")
13835    (set_attr "atom_sse_attr" "rcp")
13836    (set_attr "prefix" "maybe_vex")
13837    (set_attr "mode" "SF")])
13838
13839 (define_expand "rsqrtsf2"
13840   [(set (match_operand:SF 0 "register_operand" "")
13841         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
13842                    UNSPEC_RSQRT))]
13843   "TARGET_SSE_MATH"
13844 {
13845   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13846   DONE;
13847 })
13848
13849 (define_insn "*sqrt<mode>2_sse"
13850   [(set (match_operand:MODEF 0 "register_operand" "=x")
13851         (sqrt:MODEF
13852           (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13853   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13854   "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}"
13855   [(set_attr "type" "sse")
13856    (set_attr "atom_sse_attr" "sqrt")
13857    (set_attr "prefix" "maybe_vex")
13858    (set_attr "mode" "<MODE>")
13859    (set_attr "athlon_decode" "*")
13860    (set_attr "amdfam10_decode" "*")])
13861
13862 (define_expand "sqrt<mode>2"
13863   [(set (match_operand:MODEF 0 "register_operand" "")
13864         (sqrt:MODEF
13865           (match_operand:MODEF 1 "nonimmediate_operand" "")))]
13866   "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13867    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13868 {
13869   if (<MODE>mode == SFmode
13870       && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
13871       && flag_finite_math_only && !flag_trapping_math
13872       && flag_unsafe_math_optimizations)
13873     {
13874       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13875       DONE;
13876     }
13877
13878   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13879     {
13880       rtx op0 = gen_reg_rtx (XFmode);
13881       rtx op1 = force_reg (<MODE>mode, operands[1]);
13882
13883       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13884       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13885       DONE;
13886    }
13887 })
13888
13889 (define_insn "fpremxf4_i387"
13890   [(set (match_operand:XF 0 "register_operand" "=f")
13891         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13892                     (match_operand:XF 3 "register_operand" "1")]
13893                    UNSPEC_FPREM_F))
13894    (set (match_operand:XF 1 "register_operand" "=u")
13895         (unspec:XF [(match_dup 2) (match_dup 3)]
13896                    UNSPEC_FPREM_U))
13897    (set (reg:CCFP FPSR_REG)
13898         (unspec:CCFP [(match_dup 2) (match_dup 3)]
13899                      UNSPEC_C2_FLAG))]
13900   "TARGET_USE_FANCY_MATH_387"
13901   "fprem"
13902   [(set_attr "type" "fpspc")
13903    (set_attr "mode" "XF")])
13904
13905 (define_expand "fmodxf3"
13906   [(use (match_operand:XF 0 "register_operand" ""))
13907    (use (match_operand:XF 1 "general_operand" ""))
13908    (use (match_operand:XF 2 "general_operand" ""))]
13909   "TARGET_USE_FANCY_MATH_387"
13910 {
13911   rtx label = gen_label_rtx ();
13912
13913   rtx op1 = gen_reg_rtx (XFmode);
13914   rtx op2 = gen_reg_rtx (XFmode);
13915
13916   emit_move_insn (op2, operands[2]);
13917   emit_move_insn (op1, operands[1]);
13918
13919   emit_label (label);
13920   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13921   ix86_emit_fp_unordered_jump (label);
13922   LABEL_NUSES (label) = 1;
13923
13924   emit_move_insn (operands[0], op1);
13925   DONE;
13926 })
13927
13928 (define_expand "fmod<mode>3"
13929   [(use (match_operand:MODEF 0 "register_operand" ""))
13930    (use (match_operand:MODEF 1 "general_operand" ""))
13931    (use (match_operand:MODEF 2 "general_operand" ""))]
13932   "TARGET_USE_FANCY_MATH_387"
13933 {
13934   rtx label = gen_label_rtx ();
13935
13936   rtx op1 = gen_reg_rtx (XFmode);
13937   rtx op2 = gen_reg_rtx (XFmode);
13938
13939   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13940   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13941
13942   emit_label (label);
13943   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13944   ix86_emit_fp_unordered_jump (label);
13945   LABEL_NUSES (label) = 1;
13946
13947   /* Truncate the result properly for strict SSE math.  */
13948   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13949       && !TARGET_MIX_SSE_I387)
13950     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
13951   else
13952     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
13953
13954   DONE;
13955 })
13956
13957 (define_insn "fprem1xf4_i387"
13958   [(set (match_operand:XF 0 "register_operand" "=f")
13959         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13960                     (match_operand:XF 3 "register_operand" "1")]
13961                    UNSPEC_FPREM1_F))
13962    (set (match_operand:XF 1 "register_operand" "=u")
13963         (unspec:XF [(match_dup 2) (match_dup 3)]
13964                    UNSPEC_FPREM1_U))
13965    (set (reg:CCFP FPSR_REG)
13966         (unspec:CCFP [(match_dup 2) (match_dup 3)]
13967                      UNSPEC_C2_FLAG))]
13968   "TARGET_USE_FANCY_MATH_387"
13969   "fprem1"
13970   [(set_attr "type" "fpspc")
13971    (set_attr "mode" "XF")])
13972
13973 (define_expand "remainderxf3"
13974   [(use (match_operand:XF 0 "register_operand" ""))
13975    (use (match_operand:XF 1 "general_operand" ""))
13976    (use (match_operand:XF 2 "general_operand" ""))]
13977   "TARGET_USE_FANCY_MATH_387"
13978 {
13979   rtx label = gen_label_rtx ();
13980
13981   rtx op1 = gen_reg_rtx (XFmode);
13982   rtx op2 = gen_reg_rtx (XFmode);
13983
13984   emit_move_insn (op2, operands[2]);
13985   emit_move_insn (op1, operands[1]);
13986
13987   emit_label (label);
13988   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13989   ix86_emit_fp_unordered_jump (label);
13990   LABEL_NUSES (label) = 1;
13991
13992   emit_move_insn (operands[0], op1);
13993   DONE;
13994 })
13995
13996 (define_expand "remainder<mode>3"
13997   [(use (match_operand:MODEF 0 "register_operand" ""))
13998    (use (match_operand:MODEF 1 "general_operand" ""))
13999    (use (match_operand:MODEF 2 "general_operand" ""))]
14000   "TARGET_USE_FANCY_MATH_387"
14001 {
14002   rtx label = gen_label_rtx ();
14003
14004   rtx op1 = gen_reg_rtx (XFmode);
14005   rtx op2 = gen_reg_rtx (XFmode);
14006
14007   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14008   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14009
14010   emit_label (label);
14011
14012   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
14013   ix86_emit_fp_unordered_jump (label);
14014   LABEL_NUSES (label) = 1;
14015
14016   /* Truncate the result properly for strict SSE math.  */
14017   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14018       && !TARGET_MIX_SSE_I387)
14019     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
14020   else
14021     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
14022
14023   DONE;
14024 })
14025
14026 (define_insn "*sinxf2_i387"
14027   [(set (match_operand:XF 0 "register_operand" "=f")
14028         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
14029   "TARGET_USE_FANCY_MATH_387
14030    && flag_unsafe_math_optimizations"
14031   "fsin"
14032   [(set_attr "type" "fpspc")
14033    (set_attr "mode" "XF")])
14034
14035 (define_insn "*sin_extend<mode>xf2_i387"
14036   [(set (match_operand:XF 0 "register_operand" "=f")
14037         (unspec:XF [(float_extend:XF
14038                       (match_operand:MODEF 1 "register_operand" "0"))]
14039                    UNSPEC_SIN))]
14040   "TARGET_USE_FANCY_MATH_387
14041    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14042        || TARGET_MIX_SSE_I387)
14043    && flag_unsafe_math_optimizations"
14044   "fsin"
14045   [(set_attr "type" "fpspc")
14046    (set_attr "mode" "XF")])
14047
14048 (define_insn "*cosxf2_i387"
14049   [(set (match_operand:XF 0 "register_operand" "=f")
14050         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
14051   "TARGET_USE_FANCY_MATH_387
14052    && flag_unsafe_math_optimizations"
14053   "fcos"
14054   [(set_attr "type" "fpspc")
14055    (set_attr "mode" "XF")])
14056
14057 (define_insn "*cos_extend<mode>xf2_i387"
14058   [(set (match_operand:XF 0 "register_operand" "=f")
14059         (unspec:XF [(float_extend:XF
14060                       (match_operand:MODEF 1 "register_operand" "0"))]
14061                    UNSPEC_COS))]
14062   "TARGET_USE_FANCY_MATH_387
14063    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14064        || TARGET_MIX_SSE_I387)
14065    && flag_unsafe_math_optimizations"
14066   "fcos"
14067   [(set_attr "type" "fpspc")
14068    (set_attr "mode" "XF")])
14069
14070 ;; When sincos pattern is defined, sin and cos builtin functions will be
14071 ;; expanded to sincos pattern with one of its outputs left unused.
14072 ;; CSE pass will figure out if two sincos patterns can be combined,
14073 ;; otherwise sincos pattern will be split back to sin or cos pattern,
14074 ;; depending on the unused output.
14075
14076 (define_insn "sincosxf3"
14077   [(set (match_operand:XF 0 "register_operand" "=f")
14078         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14079                    UNSPEC_SINCOS_COS))
14080    (set (match_operand:XF 1 "register_operand" "=u")
14081         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14082   "TARGET_USE_FANCY_MATH_387
14083    && flag_unsafe_math_optimizations"
14084   "fsincos"
14085   [(set_attr "type" "fpspc")
14086    (set_attr "mode" "XF")])
14087
14088 (define_split
14089   [(set (match_operand:XF 0 "register_operand" "")
14090         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
14091                    UNSPEC_SINCOS_COS))
14092    (set (match_operand:XF 1 "register_operand" "")
14093         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14094   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14095    && !(reload_completed || reload_in_progress)"
14096   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
14097   "")
14098
14099 (define_split
14100   [(set (match_operand:XF 0 "register_operand" "")
14101         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
14102                    UNSPEC_SINCOS_COS))
14103    (set (match_operand:XF 1 "register_operand" "")
14104         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14105   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14106    && !(reload_completed || reload_in_progress)"
14107   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
14108   "")
14109
14110 (define_insn "sincos_extend<mode>xf3_i387"
14111   [(set (match_operand:XF 0 "register_operand" "=f")
14112         (unspec:XF [(float_extend:XF
14113                       (match_operand:MODEF 2 "register_operand" "0"))]
14114                    UNSPEC_SINCOS_COS))
14115    (set (match_operand:XF 1 "register_operand" "=u")
14116         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14117   "TARGET_USE_FANCY_MATH_387
14118    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14119        || TARGET_MIX_SSE_I387)
14120    && flag_unsafe_math_optimizations"
14121   "fsincos"
14122   [(set_attr "type" "fpspc")
14123    (set_attr "mode" "XF")])
14124
14125 (define_split
14126   [(set (match_operand:XF 0 "register_operand" "")
14127         (unspec:XF [(float_extend:XF
14128                       (match_operand:MODEF 2 "register_operand" ""))]
14129                    UNSPEC_SINCOS_COS))
14130    (set (match_operand:XF 1 "register_operand" "")
14131         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14132   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14133    && !(reload_completed || reload_in_progress)"
14134   [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
14135   "")
14136
14137 (define_split
14138   [(set (match_operand:XF 0 "register_operand" "")
14139         (unspec:XF [(float_extend:XF
14140                       (match_operand:MODEF 2 "register_operand" ""))]
14141                    UNSPEC_SINCOS_COS))
14142    (set (match_operand:XF 1 "register_operand" "")
14143         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14144   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14145    && !(reload_completed || reload_in_progress)"
14146   [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
14147   "")
14148
14149 (define_expand "sincos<mode>3"
14150   [(use (match_operand:MODEF 0 "register_operand" ""))
14151    (use (match_operand:MODEF 1 "register_operand" ""))
14152    (use (match_operand:MODEF 2 "register_operand" ""))]
14153   "TARGET_USE_FANCY_MATH_387
14154    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14155        || TARGET_MIX_SSE_I387)
14156    && flag_unsafe_math_optimizations"
14157 {
14158   rtx op0 = gen_reg_rtx (XFmode);
14159   rtx op1 = gen_reg_rtx (XFmode);
14160
14161   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
14162   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14163   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
14164   DONE;
14165 })
14166
14167 (define_insn "fptanxf4_i387"
14168   [(set (match_operand:XF 0 "register_operand" "=f")
14169         (match_operand:XF 3 "const_double_operand" "F"))
14170    (set (match_operand:XF 1 "register_operand" "=u")
14171         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14172                    UNSPEC_TAN))]
14173   "TARGET_USE_FANCY_MATH_387
14174    && flag_unsafe_math_optimizations
14175    && standard_80387_constant_p (operands[3]) == 2"
14176   "fptan"
14177   [(set_attr "type" "fpspc")
14178    (set_attr "mode" "XF")])
14179
14180 (define_insn "fptan_extend<mode>xf4_i387"
14181   [(set (match_operand:MODEF 0 "register_operand" "=f")
14182         (match_operand:MODEF 3 "const_double_operand" "F"))
14183    (set (match_operand:XF 1 "register_operand" "=u")
14184         (unspec:XF [(float_extend:XF
14185                       (match_operand:MODEF 2 "register_operand" "0"))]
14186                    UNSPEC_TAN))]
14187   "TARGET_USE_FANCY_MATH_387
14188    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14189        || TARGET_MIX_SSE_I387)
14190    && flag_unsafe_math_optimizations
14191    && standard_80387_constant_p (operands[3]) == 2"
14192   "fptan"
14193   [(set_attr "type" "fpspc")
14194    (set_attr "mode" "XF")])
14195
14196 (define_expand "tanxf2"
14197   [(use (match_operand:XF 0 "register_operand" ""))
14198    (use (match_operand:XF 1 "register_operand" ""))]
14199   "TARGET_USE_FANCY_MATH_387
14200    && flag_unsafe_math_optimizations"
14201 {
14202   rtx one = gen_reg_rtx (XFmode);
14203   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
14204
14205   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
14206   DONE;
14207 })
14208
14209 (define_expand "tan<mode>2"
14210   [(use (match_operand:MODEF 0 "register_operand" ""))
14211    (use (match_operand:MODEF 1 "register_operand" ""))]
14212   "TARGET_USE_FANCY_MATH_387
14213    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14214        || TARGET_MIX_SSE_I387)
14215    && flag_unsafe_math_optimizations"
14216 {
14217   rtx op0 = gen_reg_rtx (XFmode);
14218
14219   rtx one = gen_reg_rtx (<MODE>mode);
14220   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
14221
14222   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
14223                                              operands[1], op2));
14224   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14225   DONE;
14226 })
14227
14228 (define_insn "*fpatanxf3_i387"
14229   [(set (match_operand:XF 0 "register_operand" "=f")
14230         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14231                     (match_operand:XF 2 "register_operand" "u")]
14232                    UNSPEC_FPATAN))
14233    (clobber (match_scratch:XF 3 "=2"))]
14234   "TARGET_USE_FANCY_MATH_387
14235    && flag_unsafe_math_optimizations"
14236   "fpatan"
14237   [(set_attr "type" "fpspc")
14238    (set_attr "mode" "XF")])
14239
14240 (define_insn "fpatan_extend<mode>xf3_i387"
14241   [(set (match_operand:XF 0 "register_operand" "=f")
14242         (unspec:XF [(float_extend:XF
14243                       (match_operand:MODEF 1 "register_operand" "0"))
14244                     (float_extend:XF
14245                       (match_operand:MODEF 2 "register_operand" "u"))]
14246                    UNSPEC_FPATAN))
14247    (clobber (match_scratch:XF 3 "=2"))]
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   "fpatan"
14253   [(set_attr "type" "fpspc")
14254    (set_attr "mode" "XF")])
14255
14256 (define_expand "atan2xf3"
14257   [(parallel [(set (match_operand:XF 0 "register_operand" "")
14258                    (unspec:XF [(match_operand:XF 2 "register_operand" "")
14259                                (match_operand:XF 1 "register_operand" "")]
14260                               UNSPEC_FPATAN))
14261               (clobber (match_scratch:XF 3 ""))])]
14262   "TARGET_USE_FANCY_MATH_387
14263    && flag_unsafe_math_optimizations"
14264   "")
14265
14266 (define_expand "atan2<mode>3"
14267   [(use (match_operand:MODEF 0 "register_operand" ""))
14268    (use (match_operand:MODEF 1 "register_operand" ""))
14269    (use (match_operand:MODEF 2 "register_operand" ""))]
14270   "TARGET_USE_FANCY_MATH_387
14271    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14272        || TARGET_MIX_SSE_I387)
14273    && flag_unsafe_math_optimizations"
14274 {
14275   rtx op0 = gen_reg_rtx (XFmode);
14276
14277   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
14278   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14279   DONE;
14280 })
14281
14282 (define_expand "atanxf2"
14283   [(parallel [(set (match_operand:XF 0 "register_operand" "")
14284                    (unspec:XF [(match_dup 2)
14285                                (match_operand:XF 1 "register_operand" "")]
14286                               UNSPEC_FPATAN))
14287               (clobber (match_scratch:XF 3 ""))])]
14288   "TARGET_USE_FANCY_MATH_387
14289    && flag_unsafe_math_optimizations"
14290 {
14291   operands[2] = gen_reg_rtx (XFmode);
14292   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
14293 })
14294
14295 (define_expand "atan<mode>2"
14296   [(use (match_operand:MODEF 0 "register_operand" ""))
14297    (use (match_operand:MODEF 1 "register_operand" ""))]
14298   "TARGET_USE_FANCY_MATH_387
14299    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14300        || TARGET_MIX_SSE_I387)
14301    && flag_unsafe_math_optimizations"
14302 {
14303   rtx op0 = gen_reg_rtx (XFmode);
14304
14305   rtx op2 = gen_reg_rtx (<MODE>mode);
14306   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
14307
14308   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
14309   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14310   DONE;
14311 })
14312
14313 (define_expand "asinxf2"
14314   [(set (match_dup 2)
14315         (mult:XF (match_operand:XF 1 "register_operand" "")
14316                  (match_dup 1)))
14317    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14318    (set (match_dup 5) (sqrt:XF (match_dup 4)))
14319    (parallel [(set (match_operand:XF 0 "register_operand" "")
14320                    (unspec:XF [(match_dup 5) (match_dup 1)]
14321                               UNSPEC_FPATAN))
14322               (clobber (match_scratch:XF 6 ""))])]
14323   "TARGET_USE_FANCY_MATH_387
14324    && flag_unsafe_math_optimizations"
14325 {
14326   int i;
14327
14328   if (optimize_insn_for_size_p ())
14329     FAIL;
14330
14331   for (i = 2; i < 6; i++)
14332     operands[i] = gen_reg_rtx (XFmode);
14333
14334   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
14335 })
14336
14337 (define_expand "asin<mode>2"
14338   [(use (match_operand:MODEF 0 "register_operand" ""))
14339    (use (match_operand:MODEF 1 "general_operand" ""))]
14340  "TARGET_USE_FANCY_MATH_387
14341    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14342        || TARGET_MIX_SSE_I387)
14343    && flag_unsafe_math_optimizations"
14344 {
14345   rtx op0 = gen_reg_rtx (XFmode);
14346   rtx op1 = gen_reg_rtx (XFmode);
14347
14348   if (optimize_insn_for_size_p ())
14349     FAIL;
14350
14351   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14352   emit_insn (gen_asinxf2 (op0, op1));
14353   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14354   DONE;
14355 })
14356
14357 (define_expand "acosxf2"
14358   [(set (match_dup 2)
14359         (mult:XF (match_operand:XF 1 "register_operand" "")
14360                  (match_dup 1)))
14361    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14362    (set (match_dup 5) (sqrt:XF (match_dup 4)))
14363    (parallel [(set (match_operand:XF 0 "register_operand" "")
14364                    (unspec:XF [(match_dup 1) (match_dup 5)]
14365                               UNSPEC_FPATAN))
14366               (clobber (match_scratch:XF 6 ""))])]
14367   "TARGET_USE_FANCY_MATH_387
14368    && flag_unsafe_math_optimizations"
14369 {
14370   int i;
14371
14372   if (optimize_insn_for_size_p ())
14373     FAIL;
14374
14375   for (i = 2; i < 6; i++)
14376     operands[i] = gen_reg_rtx (XFmode);
14377
14378   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
14379 })
14380
14381 (define_expand "acos<mode>2"
14382   [(use (match_operand:MODEF 0 "register_operand" ""))
14383    (use (match_operand:MODEF 1 "general_operand" ""))]
14384  "TARGET_USE_FANCY_MATH_387
14385    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14386        || TARGET_MIX_SSE_I387)
14387    && flag_unsafe_math_optimizations"
14388 {
14389   rtx op0 = gen_reg_rtx (XFmode);
14390   rtx op1 = gen_reg_rtx (XFmode);
14391
14392   if (optimize_insn_for_size_p ())
14393     FAIL;
14394
14395   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14396   emit_insn (gen_acosxf2 (op0, op1));
14397   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14398   DONE;
14399 })
14400
14401 (define_insn "fyl2xxf3_i387"
14402   [(set (match_operand:XF 0 "register_operand" "=f")
14403         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14404                     (match_operand:XF 2 "register_operand" "u")]
14405                    UNSPEC_FYL2X))
14406    (clobber (match_scratch:XF 3 "=2"))]
14407   "TARGET_USE_FANCY_MATH_387
14408    && flag_unsafe_math_optimizations"
14409   "fyl2x"
14410   [(set_attr "type" "fpspc")
14411    (set_attr "mode" "XF")])
14412
14413 (define_insn "fyl2x_extend<mode>xf3_i387"
14414   [(set (match_operand:XF 0 "register_operand" "=f")
14415         (unspec:XF [(float_extend:XF
14416                       (match_operand:MODEF 1 "register_operand" "0"))
14417                     (match_operand:XF 2 "register_operand" "u")]
14418                    UNSPEC_FYL2X))
14419    (clobber (match_scratch:XF 3 "=2"))]
14420   "TARGET_USE_FANCY_MATH_387
14421    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14422        || TARGET_MIX_SSE_I387)
14423    && flag_unsafe_math_optimizations"
14424   "fyl2x"
14425   [(set_attr "type" "fpspc")
14426    (set_attr "mode" "XF")])
14427
14428 (define_expand "logxf2"
14429   [(parallel [(set (match_operand:XF 0 "register_operand" "")
14430                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
14431                                (match_dup 2)] UNSPEC_FYL2X))
14432               (clobber (match_scratch:XF 3 ""))])]
14433   "TARGET_USE_FANCY_MATH_387
14434    && flag_unsafe_math_optimizations"
14435 {
14436   operands[2] = gen_reg_rtx (XFmode);
14437   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
14438 })
14439
14440 (define_expand "log<mode>2"
14441   [(use (match_operand:MODEF 0 "register_operand" ""))
14442    (use (match_operand:MODEF 1 "register_operand" ""))]
14443   "TARGET_USE_FANCY_MATH_387
14444    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14445        || TARGET_MIX_SSE_I387)
14446    && flag_unsafe_math_optimizations"
14447 {
14448   rtx op0 = gen_reg_rtx (XFmode);
14449
14450   rtx op2 = gen_reg_rtx (XFmode);
14451   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
14452
14453   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14454   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14455   DONE;
14456 })
14457
14458 (define_expand "log10xf2"
14459   [(parallel [(set (match_operand:XF 0 "register_operand" "")
14460                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
14461                                (match_dup 2)] UNSPEC_FYL2X))
14462               (clobber (match_scratch:XF 3 ""))])]
14463   "TARGET_USE_FANCY_MATH_387
14464    && flag_unsafe_math_optimizations"
14465 {
14466   operands[2] = gen_reg_rtx (XFmode);
14467   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14468 })
14469
14470 (define_expand "log10<mode>2"
14471   [(use (match_operand:MODEF 0 "register_operand" ""))
14472    (use (match_operand:MODEF 1 "register_operand" ""))]
14473   "TARGET_USE_FANCY_MATH_387
14474    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14475        || TARGET_MIX_SSE_I387)
14476    && flag_unsafe_math_optimizations"
14477 {
14478   rtx op0 = gen_reg_rtx (XFmode);
14479
14480   rtx op2 = gen_reg_rtx (XFmode);
14481   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14482
14483   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14484   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14485   DONE;
14486 })
14487
14488 (define_expand "log2xf2"
14489   [(parallel [(set (match_operand:XF 0 "register_operand" "")
14490                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
14491                                (match_dup 2)] UNSPEC_FYL2X))
14492               (clobber (match_scratch:XF 3 ""))])]
14493   "TARGET_USE_FANCY_MATH_387
14494    && flag_unsafe_math_optimizations"
14495 {
14496   operands[2] = gen_reg_rtx (XFmode);
14497   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14498 })
14499
14500 (define_expand "log2<mode>2"
14501   [(use (match_operand:MODEF 0 "register_operand" ""))
14502    (use (match_operand:MODEF 1 "register_operand" ""))]
14503   "TARGET_USE_FANCY_MATH_387
14504    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14505        || TARGET_MIX_SSE_I387)
14506    && flag_unsafe_math_optimizations"
14507 {
14508   rtx op0 = gen_reg_rtx (XFmode);
14509
14510   rtx op2 = gen_reg_rtx (XFmode);
14511   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14512
14513   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14514   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14515   DONE;
14516 })
14517
14518 (define_insn "fyl2xp1xf3_i387"
14519   [(set (match_operand:XF 0 "register_operand" "=f")
14520         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14521                     (match_operand:XF 2 "register_operand" "u")]
14522                    UNSPEC_FYL2XP1))
14523    (clobber (match_scratch:XF 3 "=2"))]
14524   "TARGET_USE_FANCY_MATH_387
14525    && flag_unsafe_math_optimizations"
14526   "fyl2xp1"
14527   [(set_attr "type" "fpspc")
14528    (set_attr "mode" "XF")])
14529
14530 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14531   [(set (match_operand:XF 0 "register_operand" "=f")
14532         (unspec:XF [(float_extend:XF
14533                       (match_operand:MODEF 1 "register_operand" "0"))
14534                     (match_operand:XF 2 "register_operand" "u")]
14535                    UNSPEC_FYL2XP1))
14536    (clobber (match_scratch:XF 3 "=2"))]
14537   "TARGET_USE_FANCY_MATH_387
14538    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14539        || TARGET_MIX_SSE_I387)
14540    && flag_unsafe_math_optimizations"
14541   "fyl2xp1"
14542   [(set_attr "type" "fpspc")
14543    (set_attr "mode" "XF")])
14544
14545 (define_expand "log1pxf2"
14546   [(use (match_operand:XF 0 "register_operand" ""))
14547    (use (match_operand:XF 1 "register_operand" ""))]
14548   "TARGET_USE_FANCY_MATH_387
14549    && flag_unsafe_math_optimizations"
14550 {
14551   if (optimize_insn_for_size_p ())
14552     FAIL;
14553
14554   ix86_emit_i387_log1p (operands[0], operands[1]);
14555   DONE;
14556 })
14557
14558 (define_expand "log1p<mode>2"
14559   [(use (match_operand:MODEF 0 "register_operand" ""))
14560    (use (match_operand:MODEF 1 "register_operand" ""))]
14561   "TARGET_USE_FANCY_MATH_387
14562    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14563        || TARGET_MIX_SSE_I387)
14564    && flag_unsafe_math_optimizations"
14565 {
14566   rtx op0;
14567
14568   if (optimize_insn_for_size_p ())
14569     FAIL;
14570
14571   op0 = gen_reg_rtx (XFmode);
14572
14573   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14574
14575   ix86_emit_i387_log1p (op0, operands[1]);
14576   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14577   DONE;
14578 })
14579
14580 (define_insn "fxtractxf3_i387"
14581   [(set (match_operand:XF 0 "register_operand" "=f")
14582         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14583                    UNSPEC_XTRACT_FRACT))
14584    (set (match_operand:XF 1 "register_operand" "=u")
14585         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14586   "TARGET_USE_FANCY_MATH_387
14587    && flag_unsafe_math_optimizations"
14588   "fxtract"
14589   [(set_attr "type" "fpspc")
14590    (set_attr "mode" "XF")])
14591
14592 (define_insn "fxtract_extend<mode>xf3_i387"
14593   [(set (match_operand:XF 0 "register_operand" "=f")
14594         (unspec:XF [(float_extend:XF
14595                       (match_operand:MODEF 2 "register_operand" "0"))]
14596                    UNSPEC_XTRACT_FRACT))
14597    (set (match_operand:XF 1 "register_operand" "=u")
14598         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14599   "TARGET_USE_FANCY_MATH_387
14600    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14601        || TARGET_MIX_SSE_I387)
14602    && flag_unsafe_math_optimizations"
14603   "fxtract"
14604   [(set_attr "type" "fpspc")
14605    (set_attr "mode" "XF")])
14606
14607 (define_expand "logbxf2"
14608   [(parallel [(set (match_dup 2)
14609                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14610                               UNSPEC_XTRACT_FRACT))
14611               (set (match_operand:XF 0 "register_operand" "")
14612                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14613   "TARGET_USE_FANCY_MATH_387
14614    && flag_unsafe_math_optimizations"
14615 {
14616   operands[2] = gen_reg_rtx (XFmode);
14617 })
14618
14619 (define_expand "logb<mode>2"
14620   [(use (match_operand:MODEF 0 "register_operand" ""))
14621    (use (match_operand:MODEF 1 "register_operand" ""))]
14622   "TARGET_USE_FANCY_MATH_387
14623    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14624        || TARGET_MIX_SSE_I387)
14625    && flag_unsafe_math_optimizations"
14626 {
14627   rtx op0 = gen_reg_rtx (XFmode);
14628   rtx op1 = gen_reg_rtx (XFmode);
14629
14630   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14631   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14632   DONE;
14633 })
14634
14635 (define_expand "ilogbxf2"
14636   [(use (match_operand:SI 0 "register_operand" ""))
14637    (use (match_operand:XF 1 "register_operand" ""))]
14638   "TARGET_USE_FANCY_MATH_387
14639    && flag_unsafe_math_optimizations"
14640 {
14641   rtx op0, op1;
14642
14643   if (optimize_insn_for_size_p ())
14644     FAIL;
14645
14646   op0 = gen_reg_rtx (XFmode);
14647   op1 = gen_reg_rtx (XFmode);
14648
14649   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14650   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14651   DONE;
14652 })
14653
14654 (define_expand "ilogb<mode>2"
14655   [(use (match_operand:SI 0 "register_operand" ""))
14656    (use (match_operand:MODEF 1 "register_operand" ""))]
14657   "TARGET_USE_FANCY_MATH_387
14658    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14659        || TARGET_MIX_SSE_I387)
14660    && flag_unsafe_math_optimizations"
14661 {
14662   rtx op0, op1;
14663
14664   if (optimize_insn_for_size_p ())
14665     FAIL;
14666
14667   op0 = gen_reg_rtx (XFmode);
14668   op1 = gen_reg_rtx (XFmode);
14669
14670   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14671   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14672   DONE;
14673 })
14674
14675 (define_insn "*f2xm1xf2_i387"
14676   [(set (match_operand:XF 0 "register_operand" "=f")
14677         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14678                    UNSPEC_F2XM1))]
14679   "TARGET_USE_FANCY_MATH_387
14680    && flag_unsafe_math_optimizations"
14681   "f2xm1"
14682   [(set_attr "type" "fpspc")
14683    (set_attr "mode" "XF")])
14684
14685 (define_insn "*fscalexf4_i387"
14686   [(set (match_operand:XF 0 "register_operand" "=f")
14687         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14688                     (match_operand:XF 3 "register_operand" "1")]
14689                    UNSPEC_FSCALE_FRACT))
14690    (set (match_operand:XF 1 "register_operand" "=u")
14691         (unspec:XF [(match_dup 2) (match_dup 3)]
14692                    UNSPEC_FSCALE_EXP))]
14693   "TARGET_USE_FANCY_MATH_387
14694    && flag_unsafe_math_optimizations"
14695   "fscale"
14696   [(set_attr "type" "fpspc")
14697    (set_attr "mode" "XF")])
14698
14699 (define_expand "expNcorexf3"
14700   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14701                                (match_operand:XF 2 "register_operand" "")))
14702    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14703    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14704    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14705    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14706    (parallel [(set (match_operand:XF 0 "register_operand" "")
14707                    (unspec:XF [(match_dup 8) (match_dup 4)]
14708                               UNSPEC_FSCALE_FRACT))
14709               (set (match_dup 9)
14710                    (unspec:XF [(match_dup 8) (match_dup 4)]
14711                               UNSPEC_FSCALE_EXP))])]
14712   "TARGET_USE_FANCY_MATH_387
14713    && flag_unsafe_math_optimizations"
14714 {
14715   int i;
14716
14717   if (optimize_insn_for_size_p ())
14718     FAIL;
14719
14720   for (i = 3; i < 10; i++)
14721     operands[i] = gen_reg_rtx (XFmode);
14722
14723   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
14724 })
14725
14726 (define_expand "expxf2"
14727   [(use (match_operand:XF 0 "register_operand" ""))
14728    (use (match_operand:XF 1 "register_operand" ""))]
14729   "TARGET_USE_FANCY_MATH_387
14730    && flag_unsafe_math_optimizations"
14731 {
14732   rtx op2;
14733
14734   if (optimize_insn_for_size_p ())
14735     FAIL;
14736
14737   op2 = gen_reg_rtx (XFmode);
14738   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14739
14740   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14741   DONE;
14742 })
14743
14744 (define_expand "exp<mode>2"
14745   [(use (match_operand:MODEF 0 "register_operand" ""))
14746    (use (match_operand:MODEF 1 "general_operand" ""))]
14747  "TARGET_USE_FANCY_MATH_387
14748    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14749        || TARGET_MIX_SSE_I387)
14750    && flag_unsafe_math_optimizations"
14751 {
14752   rtx op0, op1;
14753
14754   if (optimize_insn_for_size_p ())
14755     FAIL;
14756
14757   op0 = gen_reg_rtx (XFmode);
14758   op1 = gen_reg_rtx (XFmode);
14759
14760   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14761   emit_insn (gen_expxf2 (op0, op1));
14762   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14763   DONE;
14764 })
14765
14766 (define_expand "exp10xf2"
14767   [(use (match_operand:XF 0 "register_operand" ""))
14768    (use (match_operand:XF 1 "register_operand" ""))]
14769   "TARGET_USE_FANCY_MATH_387
14770    && flag_unsafe_math_optimizations"
14771 {
14772   rtx op2;
14773
14774   if (optimize_insn_for_size_p ())
14775     FAIL;
14776
14777   op2 = gen_reg_rtx (XFmode);
14778   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14779
14780   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14781   DONE;
14782 })
14783
14784 (define_expand "exp10<mode>2"
14785   [(use (match_operand:MODEF 0 "register_operand" ""))
14786    (use (match_operand:MODEF 1 "general_operand" ""))]
14787  "TARGET_USE_FANCY_MATH_387
14788    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14789        || TARGET_MIX_SSE_I387)
14790    && flag_unsafe_math_optimizations"
14791 {
14792   rtx op0, op1;
14793
14794   if (optimize_insn_for_size_p ())
14795     FAIL;
14796
14797   op0 = gen_reg_rtx (XFmode);
14798   op1 = gen_reg_rtx (XFmode);
14799
14800   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14801   emit_insn (gen_exp10xf2 (op0, op1));
14802   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14803   DONE;
14804 })
14805
14806 (define_expand "exp2xf2"
14807   [(use (match_operand:XF 0 "register_operand" ""))
14808    (use (match_operand:XF 1 "register_operand" ""))]
14809   "TARGET_USE_FANCY_MATH_387
14810    && flag_unsafe_math_optimizations"
14811 {
14812   rtx op2;
14813
14814   if (optimize_insn_for_size_p ())
14815     FAIL;
14816
14817   op2 = gen_reg_rtx (XFmode);
14818   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
14819
14820   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14821   DONE;
14822 })
14823
14824 (define_expand "exp2<mode>2"
14825   [(use (match_operand:MODEF 0 "register_operand" ""))
14826    (use (match_operand:MODEF 1 "general_operand" ""))]
14827  "TARGET_USE_FANCY_MATH_387
14828    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14829        || TARGET_MIX_SSE_I387)
14830    && flag_unsafe_math_optimizations"
14831 {
14832   rtx op0, op1;
14833
14834   if (optimize_insn_for_size_p ())
14835     FAIL;
14836
14837   op0 = gen_reg_rtx (XFmode);
14838   op1 = gen_reg_rtx (XFmode);
14839
14840   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14841   emit_insn (gen_exp2xf2 (op0, op1));
14842   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14843   DONE;
14844 })
14845
14846 (define_expand "expm1xf2"
14847   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14848                                (match_dup 2)))
14849    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14850    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14851    (set (match_dup 9) (float_extend:XF (match_dup 13)))
14852    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14853    (parallel [(set (match_dup 7)
14854                    (unspec:XF [(match_dup 6) (match_dup 4)]
14855                               UNSPEC_FSCALE_FRACT))
14856               (set (match_dup 8)
14857                    (unspec:XF [(match_dup 6) (match_dup 4)]
14858                               UNSPEC_FSCALE_EXP))])
14859    (parallel [(set (match_dup 10)
14860                    (unspec:XF [(match_dup 9) (match_dup 8)]
14861                               UNSPEC_FSCALE_FRACT))
14862               (set (match_dup 11)
14863                    (unspec:XF [(match_dup 9) (match_dup 8)]
14864                               UNSPEC_FSCALE_EXP))])
14865    (set (match_dup 12) (minus:XF (match_dup 10)
14866                                  (float_extend:XF (match_dup 13))))
14867    (set (match_operand:XF 0 "register_operand" "")
14868         (plus:XF (match_dup 12) (match_dup 7)))]
14869   "TARGET_USE_FANCY_MATH_387
14870    && flag_unsafe_math_optimizations"
14871 {
14872   int i;
14873
14874   if (optimize_insn_for_size_p ())
14875     FAIL;
14876
14877   for (i = 2; i < 13; i++)
14878     operands[i] = gen_reg_rtx (XFmode);
14879
14880   operands[13]
14881     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14882
14883   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14884 })
14885
14886 (define_expand "expm1<mode>2"
14887   [(use (match_operand:MODEF 0 "register_operand" ""))
14888    (use (match_operand:MODEF 1 "general_operand" ""))]
14889  "TARGET_USE_FANCY_MATH_387
14890    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14891        || TARGET_MIX_SSE_I387)
14892    && flag_unsafe_math_optimizations"
14893 {
14894   rtx op0, op1;
14895
14896   if (optimize_insn_for_size_p ())
14897     FAIL;
14898
14899   op0 = gen_reg_rtx (XFmode);
14900   op1 = gen_reg_rtx (XFmode);
14901
14902   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14903   emit_insn (gen_expm1xf2 (op0, op1));
14904   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14905   DONE;
14906 })
14907
14908 (define_expand "ldexpxf3"
14909   [(set (match_dup 3)
14910         (float:XF (match_operand:SI 2 "register_operand" "")))
14911    (parallel [(set (match_operand:XF 0 " register_operand" "")
14912                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
14913                                (match_dup 3)]
14914                               UNSPEC_FSCALE_FRACT))
14915               (set (match_dup 4)
14916                    (unspec:XF [(match_dup 1) (match_dup 3)]
14917                               UNSPEC_FSCALE_EXP))])]
14918   "TARGET_USE_FANCY_MATH_387
14919    && flag_unsafe_math_optimizations"
14920 {
14921   if (optimize_insn_for_size_p ())
14922     FAIL;
14923
14924   operands[3] = gen_reg_rtx (XFmode);
14925   operands[4] = gen_reg_rtx (XFmode);
14926 })
14927
14928 (define_expand "ldexp<mode>3"
14929   [(use (match_operand:MODEF 0 "register_operand" ""))
14930    (use (match_operand:MODEF 1 "general_operand" ""))
14931    (use (match_operand:SI 2 "register_operand" ""))]
14932  "TARGET_USE_FANCY_MATH_387
14933    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14934        || TARGET_MIX_SSE_I387)
14935    && flag_unsafe_math_optimizations"
14936 {
14937   rtx op0, op1;
14938
14939   if (optimize_insn_for_size_p ())
14940     FAIL;
14941
14942   op0 = gen_reg_rtx (XFmode);
14943   op1 = gen_reg_rtx (XFmode);
14944
14945   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14946   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14947   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14948   DONE;
14949 })
14950
14951 (define_expand "scalbxf3"
14952   [(parallel [(set (match_operand:XF 0 " register_operand" "")
14953                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
14954                                (match_operand:XF 2 "register_operand" "")]
14955                               UNSPEC_FSCALE_FRACT))
14956               (set (match_dup 3)
14957                    (unspec:XF [(match_dup 1) (match_dup 2)]
14958                               UNSPEC_FSCALE_EXP))])]
14959   "TARGET_USE_FANCY_MATH_387
14960    && flag_unsafe_math_optimizations"
14961 {
14962   if (optimize_insn_for_size_p ())
14963     FAIL;
14964
14965   operands[3] = gen_reg_rtx (XFmode);
14966 })
14967
14968 (define_expand "scalb<mode>3"
14969   [(use (match_operand:MODEF 0 "register_operand" ""))
14970    (use (match_operand:MODEF 1 "general_operand" ""))
14971    (use (match_operand:MODEF 2 "general_operand" ""))]
14972  "TARGET_USE_FANCY_MATH_387
14973    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14974        || TARGET_MIX_SSE_I387)
14975    && flag_unsafe_math_optimizations"
14976 {
14977   rtx op0, op1, op2;
14978
14979   if (optimize_insn_for_size_p ())
14980     FAIL;
14981
14982   op0 = gen_reg_rtx (XFmode);
14983   op1 = gen_reg_rtx (XFmode);
14984   op2 = gen_reg_rtx (XFmode);
14985
14986   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14987   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14988   emit_insn (gen_scalbxf3 (op0, op1, op2));
14989   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14990   DONE;
14991 })
14992
14993 (define_expand "significandxf2"
14994   [(parallel [(set (match_operand:XF 0 "register_operand" "")
14995                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14996                               UNSPEC_XTRACT_FRACT))
14997               (set (match_dup 2)
14998                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14999   "TARGET_USE_FANCY_MATH_387
15000    && flag_unsafe_math_optimizations"
15001 {
15002   operands[2] = gen_reg_rtx (XFmode);
15003 })
15004
15005 (define_expand "significand<mode>2"
15006   [(use (match_operand:MODEF 0 "register_operand" ""))
15007    (use (match_operand:MODEF 1 "register_operand" ""))]
15008   "TARGET_USE_FANCY_MATH_387
15009    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15010        || TARGET_MIX_SSE_I387)
15011    && flag_unsafe_math_optimizations"
15012 {
15013   rtx op0 = gen_reg_rtx (XFmode);
15014   rtx op1 = gen_reg_rtx (XFmode);
15015
15016   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
15017   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15018   DONE;
15019 })
15020 \f
15021
15022 (define_insn "sse4_1_round<mode>2"
15023   [(set (match_operand:MODEF 0 "register_operand" "=x")
15024         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
15025                        (match_operand:SI 2 "const_0_to_15_operand" "n")]
15026                       UNSPEC_ROUND))]
15027   "TARGET_ROUND"
15028   "%vrounds<ssemodefsuffix>\t{%2, %1, %d0|%d0, %1, %2}"
15029   [(set_attr "type" "ssecvt")
15030    (set_attr "prefix_extra" "1")
15031    (set_attr "prefix" "maybe_vex")
15032    (set_attr "mode" "<MODE>")])
15033
15034 (define_insn "rintxf2"
15035   [(set (match_operand:XF 0 "register_operand" "=f")
15036         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15037                    UNSPEC_FRNDINT))]
15038   "TARGET_USE_FANCY_MATH_387
15039    && flag_unsafe_math_optimizations"
15040   "frndint"
15041   [(set_attr "type" "fpspc")
15042    (set_attr "mode" "XF")])
15043
15044 (define_expand "rint<mode>2"
15045   [(use (match_operand:MODEF 0 "register_operand" ""))
15046    (use (match_operand:MODEF 1 "register_operand" ""))]
15047   "(TARGET_USE_FANCY_MATH_387
15048     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15049         || TARGET_MIX_SSE_I387)
15050     && flag_unsafe_math_optimizations)
15051    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15052        && !flag_trapping_math)"
15053 {
15054   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15055       && !flag_trapping_math)
15056     {
15057       if (!TARGET_ROUND && optimize_insn_for_size_p ())
15058         FAIL;
15059       if (TARGET_ROUND)
15060         emit_insn (gen_sse4_1_round<mode>2
15061                    (operands[0], operands[1], GEN_INT (0x04)));
15062       else
15063         ix86_expand_rint (operand0, operand1);
15064     }
15065   else
15066     {
15067       rtx op0 = gen_reg_rtx (XFmode);
15068       rtx op1 = gen_reg_rtx (XFmode);
15069
15070       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15071       emit_insn (gen_rintxf2 (op0, op1));
15072
15073       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15074     }
15075   DONE;
15076 })
15077
15078 (define_expand "round<mode>2"
15079   [(match_operand:MODEF 0 "register_operand" "")
15080    (match_operand:MODEF 1 "nonimmediate_operand" "")]
15081   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15082    && !flag_trapping_math && !flag_rounding_math"
15083 {
15084   if (optimize_insn_for_size_p ())
15085     FAIL;
15086   if (TARGET_64BIT || (<MODE>mode != DFmode))
15087     ix86_expand_round (operand0, operand1);
15088   else
15089     ix86_expand_rounddf_32 (operand0, operand1);
15090   DONE;
15091 })
15092
15093 (define_insn_and_split "*fistdi2_1"
15094   [(set (match_operand:DI 0 "nonimmediate_operand" "")
15095         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15096                    UNSPEC_FIST))]
15097   "TARGET_USE_FANCY_MATH_387
15098    && can_create_pseudo_p ()"
15099   "#"
15100   "&& 1"
15101   [(const_int 0)]
15102 {
15103   if (memory_operand (operands[0], VOIDmode))
15104     emit_insn (gen_fistdi2 (operands[0], operands[1]));
15105   else
15106     {
15107       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
15108       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
15109                                          operands[2]));
15110     }
15111   DONE;
15112 }
15113   [(set_attr "type" "fpspc")
15114    (set_attr "mode" "DI")])
15115
15116 (define_insn "fistdi2"
15117   [(set (match_operand:DI 0 "memory_operand" "=m")
15118         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15119                    UNSPEC_FIST))
15120    (clobber (match_scratch:XF 2 "=&1f"))]
15121   "TARGET_USE_FANCY_MATH_387"
15122   "* return output_fix_trunc (insn, operands, 0);"
15123   [(set_attr "type" "fpspc")
15124    (set_attr "mode" "DI")])
15125
15126 (define_insn "fistdi2_with_temp"
15127   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15128         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15129                    UNSPEC_FIST))
15130    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
15131    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
15132   "TARGET_USE_FANCY_MATH_387"
15133   "#"
15134   [(set_attr "type" "fpspc")
15135    (set_attr "mode" "DI")])
15136
15137 (define_split
15138   [(set (match_operand:DI 0 "register_operand" "")
15139         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15140                    UNSPEC_FIST))
15141    (clobber (match_operand:DI 2 "memory_operand" ""))
15142    (clobber (match_scratch 3 ""))]
15143   "reload_completed"
15144   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
15145               (clobber (match_dup 3))])
15146    (set (match_dup 0) (match_dup 2))]
15147   "")
15148
15149 (define_split
15150   [(set (match_operand:DI 0 "memory_operand" "")
15151         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15152                    UNSPEC_FIST))
15153    (clobber (match_operand:DI 2 "memory_operand" ""))
15154    (clobber (match_scratch 3 ""))]
15155   "reload_completed"
15156   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
15157               (clobber (match_dup 3))])]
15158   "")
15159
15160 (define_insn_and_split "*fist<mode>2_1"
15161   [(set (match_operand:X87MODEI12 0 "register_operand" "")
15162         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
15163                            UNSPEC_FIST))]
15164   "TARGET_USE_FANCY_MATH_387
15165    && can_create_pseudo_p ()"
15166   "#"
15167   "&& 1"
15168   [(const_int 0)]
15169 {
15170   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15171   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
15172                                         operands[2]));
15173   DONE;
15174 }
15175   [(set_attr "type" "fpspc")
15176    (set_attr "mode" "<MODE>")])
15177
15178 (define_insn "fist<mode>2"
15179   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
15180         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
15181                            UNSPEC_FIST))]
15182   "TARGET_USE_FANCY_MATH_387"
15183   "* return output_fix_trunc (insn, operands, 0);"
15184   [(set_attr "type" "fpspc")
15185    (set_attr "mode" "<MODE>")])
15186
15187 (define_insn "fist<mode>2_with_temp"
15188   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
15189         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
15190                            UNSPEC_FIST))
15191    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
15192   "TARGET_USE_FANCY_MATH_387"
15193   "#"
15194   [(set_attr "type" "fpspc")
15195    (set_attr "mode" "<MODE>")])
15196
15197 (define_split
15198   [(set (match_operand:X87MODEI12 0 "register_operand" "")
15199         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
15200                            UNSPEC_FIST))
15201    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
15202   "reload_completed"
15203   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
15204    (set (match_dup 0) (match_dup 2))]
15205   "")
15206
15207 (define_split
15208   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
15209         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
15210                            UNSPEC_FIST))
15211    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
15212   "reload_completed"
15213   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
15214   "")
15215
15216 (define_expand "lrintxf<mode>2"
15217   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
15218      (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
15219                       UNSPEC_FIST))]
15220   "TARGET_USE_FANCY_MATH_387"
15221   "")
15222
15223 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
15224   [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
15225      (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
15226                         UNSPEC_FIX_NOTRUNC))]
15227   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15228    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
15229   "")
15230
15231 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
15232   [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
15233    (match_operand:MODEF 1 "register_operand" "")]
15234   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15235    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
15236    && !flag_trapping_math && !flag_rounding_math"
15237 {
15238   if (optimize_insn_for_size_p ())
15239     FAIL;
15240   ix86_expand_lround (operand0, operand1);
15241   DONE;
15242 })
15243
15244 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15245 (define_insn_and_split "frndintxf2_floor"
15246   [(set (match_operand:XF 0 "register_operand" "")
15247         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15248          UNSPEC_FRNDINT_FLOOR))
15249    (clobber (reg:CC FLAGS_REG))]
15250   "TARGET_USE_FANCY_MATH_387
15251    && flag_unsafe_math_optimizations
15252    && can_create_pseudo_p ()"
15253   "#"
15254   "&& 1"
15255   [(const_int 0)]
15256 {
15257   ix86_optimize_mode_switching[I387_FLOOR] = 1;
15258
15259   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15260   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
15261
15262   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
15263                                         operands[2], operands[3]));
15264   DONE;
15265 }
15266   [(set_attr "type" "frndint")
15267    (set_attr "i387_cw" "floor")
15268    (set_attr "mode" "XF")])
15269
15270 (define_insn "frndintxf2_floor_i387"
15271   [(set (match_operand:XF 0 "register_operand" "=f")
15272         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15273          UNSPEC_FRNDINT_FLOOR))
15274    (use (match_operand:HI 2 "memory_operand" "m"))
15275    (use (match_operand:HI 3 "memory_operand" "m"))]
15276   "TARGET_USE_FANCY_MATH_387
15277    && flag_unsafe_math_optimizations"
15278   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15279   [(set_attr "type" "frndint")
15280    (set_attr "i387_cw" "floor")
15281    (set_attr "mode" "XF")])
15282
15283 (define_expand "floorxf2"
15284   [(use (match_operand:XF 0 "register_operand" ""))
15285    (use (match_operand:XF 1 "register_operand" ""))]
15286   "TARGET_USE_FANCY_MATH_387
15287    && flag_unsafe_math_optimizations"
15288 {
15289   if (optimize_insn_for_size_p ())
15290     FAIL;
15291   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
15292   DONE;
15293 })
15294
15295 (define_expand "floor<mode>2"
15296   [(use (match_operand:MODEF 0 "register_operand" ""))
15297    (use (match_operand:MODEF 1 "register_operand" ""))]
15298   "(TARGET_USE_FANCY_MATH_387
15299     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15300         || TARGET_MIX_SSE_I387)
15301     && flag_unsafe_math_optimizations)
15302    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15303        && !flag_trapping_math)"
15304 {
15305   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15306       && !flag_trapping_math
15307       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
15308     {
15309       if (!TARGET_ROUND && optimize_insn_for_size_p ())
15310         FAIL;
15311       if (TARGET_ROUND)
15312         emit_insn (gen_sse4_1_round<mode>2
15313                    (operands[0], operands[1], GEN_INT (0x01)));
15314       else if (TARGET_64BIT || (<MODE>mode != DFmode))
15315         ix86_expand_floorceil (operand0, operand1, true);
15316       else
15317         ix86_expand_floorceildf_32 (operand0, operand1, true);
15318     }
15319   else
15320     {
15321       rtx op0, op1;
15322
15323       if (optimize_insn_for_size_p ())
15324         FAIL;
15325
15326       op0 = gen_reg_rtx (XFmode);
15327       op1 = gen_reg_rtx (XFmode);
15328       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15329       emit_insn (gen_frndintxf2_floor (op0, op1));
15330
15331       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15332     }
15333   DONE;
15334 })
15335
15336 (define_insn_and_split "*fist<mode>2_floor_1"
15337   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
15338         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
15339          UNSPEC_FIST_FLOOR))
15340    (clobber (reg:CC FLAGS_REG))]
15341   "TARGET_USE_FANCY_MATH_387
15342    && flag_unsafe_math_optimizations
15343    && can_create_pseudo_p ()"
15344   "#"
15345   "&& 1"
15346   [(const_int 0)]
15347 {
15348   ix86_optimize_mode_switching[I387_FLOOR] = 1;
15349
15350   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15351   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
15352   if (memory_operand (operands[0], VOIDmode))
15353     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
15354                                       operands[2], operands[3]));
15355   else
15356     {
15357       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15358       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
15359                                                   operands[2], operands[3],
15360                                                   operands[4]));
15361     }
15362   DONE;
15363 }
15364   [(set_attr "type" "fistp")
15365    (set_attr "i387_cw" "floor")
15366    (set_attr "mode" "<MODE>")])
15367
15368 (define_insn "fistdi2_floor"
15369   [(set (match_operand:DI 0 "memory_operand" "=m")
15370         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15371          UNSPEC_FIST_FLOOR))
15372    (use (match_operand:HI 2 "memory_operand" "m"))
15373    (use (match_operand:HI 3 "memory_operand" "m"))
15374    (clobber (match_scratch:XF 4 "=&1f"))]
15375   "TARGET_USE_FANCY_MATH_387
15376    && flag_unsafe_math_optimizations"
15377   "* return output_fix_trunc (insn, operands, 0);"
15378   [(set_attr "type" "fistp")
15379    (set_attr "i387_cw" "floor")
15380    (set_attr "mode" "DI")])
15381
15382 (define_insn "fistdi2_floor_with_temp"
15383   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15384         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15385          UNSPEC_FIST_FLOOR))
15386    (use (match_operand:HI 2 "memory_operand" "m,m"))
15387    (use (match_operand:HI 3 "memory_operand" "m,m"))
15388    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15389    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15390   "TARGET_USE_FANCY_MATH_387
15391    && flag_unsafe_math_optimizations"
15392   "#"
15393   [(set_attr "type" "fistp")
15394    (set_attr "i387_cw" "floor")
15395    (set_attr "mode" "DI")])
15396
15397 (define_split
15398   [(set (match_operand:DI 0 "register_operand" "")
15399         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15400          UNSPEC_FIST_FLOOR))
15401    (use (match_operand:HI 2 "memory_operand" ""))
15402    (use (match_operand:HI 3 "memory_operand" ""))
15403    (clobber (match_operand:DI 4 "memory_operand" ""))
15404    (clobber (match_scratch 5 ""))]
15405   "reload_completed"
15406   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
15407               (use (match_dup 2))
15408               (use (match_dup 3))
15409               (clobber (match_dup 5))])
15410    (set (match_dup 0) (match_dup 4))]
15411   "")
15412
15413 (define_split
15414   [(set (match_operand:DI 0 "memory_operand" "")
15415         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15416          UNSPEC_FIST_FLOOR))
15417    (use (match_operand:HI 2 "memory_operand" ""))
15418    (use (match_operand:HI 3 "memory_operand" ""))
15419    (clobber (match_operand:DI 4 "memory_operand" ""))
15420    (clobber (match_scratch 5 ""))]
15421   "reload_completed"
15422   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
15423               (use (match_dup 2))
15424               (use (match_dup 3))
15425               (clobber (match_dup 5))])]
15426   "")
15427
15428 (define_insn "fist<mode>2_floor"
15429   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
15430         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
15431          UNSPEC_FIST_FLOOR))
15432    (use (match_operand:HI 2 "memory_operand" "m"))
15433    (use (match_operand:HI 3 "memory_operand" "m"))]
15434   "TARGET_USE_FANCY_MATH_387
15435    && flag_unsafe_math_optimizations"
15436   "* return output_fix_trunc (insn, operands, 0);"
15437   [(set_attr "type" "fistp")
15438    (set_attr "i387_cw" "floor")
15439    (set_attr "mode" "<MODE>")])
15440
15441 (define_insn "fist<mode>2_floor_with_temp"
15442   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
15443         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
15444          UNSPEC_FIST_FLOOR))
15445    (use (match_operand:HI 2 "memory_operand" "m,m"))
15446    (use (match_operand:HI 3 "memory_operand" "m,m"))
15447    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
15448   "TARGET_USE_FANCY_MATH_387
15449    && flag_unsafe_math_optimizations"
15450   "#"
15451   [(set_attr "type" "fistp")
15452    (set_attr "i387_cw" "floor")
15453    (set_attr "mode" "<MODE>")])
15454
15455 (define_split
15456   [(set (match_operand:X87MODEI12 0 "register_operand" "")
15457         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
15458          UNSPEC_FIST_FLOOR))
15459    (use (match_operand:HI 2 "memory_operand" ""))
15460    (use (match_operand:HI 3 "memory_operand" ""))
15461    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
15462   "reload_completed"
15463   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
15464                                   UNSPEC_FIST_FLOOR))
15465               (use (match_dup 2))
15466               (use (match_dup 3))])
15467    (set (match_dup 0) (match_dup 4))]
15468   "")
15469
15470 (define_split
15471   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
15472         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
15473          UNSPEC_FIST_FLOOR))
15474    (use (match_operand:HI 2 "memory_operand" ""))
15475    (use (match_operand:HI 3 "memory_operand" ""))
15476    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
15477   "reload_completed"
15478   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
15479                                   UNSPEC_FIST_FLOOR))
15480               (use (match_dup 2))
15481               (use (match_dup 3))])]
15482   "")
15483
15484 (define_expand "lfloorxf<mode>2"
15485   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
15486                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
15487                     UNSPEC_FIST_FLOOR))
15488               (clobber (reg:CC FLAGS_REG))])]
15489   "TARGET_USE_FANCY_MATH_387
15490    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15491    && flag_unsafe_math_optimizations"
15492   "")
15493
15494 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
15495   [(match_operand:SWI48 0 "nonimmediate_operand" "")
15496    (match_operand:MODEF 1 "register_operand" "")]
15497   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15498    && !flag_trapping_math"
15499 {
15500   if (TARGET_64BIT && optimize_insn_for_size_p ())
15501     FAIL;
15502   ix86_expand_lfloorceil (operand0, operand1, true);
15503   DONE;
15504 })
15505
15506 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15507 (define_insn_and_split "frndintxf2_ceil"
15508   [(set (match_operand:XF 0 "register_operand" "")
15509         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15510          UNSPEC_FRNDINT_CEIL))
15511    (clobber (reg:CC FLAGS_REG))]
15512   "TARGET_USE_FANCY_MATH_387
15513    && flag_unsafe_math_optimizations
15514    && can_create_pseudo_p ()"
15515   "#"
15516   "&& 1"
15517   [(const_int 0)]
15518 {
15519   ix86_optimize_mode_switching[I387_CEIL] = 1;
15520
15521   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15522   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15523
15524   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
15525                                        operands[2], operands[3]));
15526   DONE;
15527 }
15528   [(set_attr "type" "frndint")
15529    (set_attr "i387_cw" "ceil")
15530    (set_attr "mode" "XF")])
15531
15532 (define_insn "frndintxf2_ceil_i387"
15533   [(set (match_operand:XF 0 "register_operand" "=f")
15534         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15535          UNSPEC_FRNDINT_CEIL))
15536    (use (match_operand:HI 2 "memory_operand" "m"))
15537    (use (match_operand:HI 3 "memory_operand" "m"))]
15538   "TARGET_USE_FANCY_MATH_387
15539    && flag_unsafe_math_optimizations"
15540   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15541   [(set_attr "type" "frndint")
15542    (set_attr "i387_cw" "ceil")
15543    (set_attr "mode" "XF")])
15544
15545 (define_expand "ceilxf2"
15546   [(use (match_operand:XF 0 "register_operand" ""))
15547    (use (match_operand:XF 1 "register_operand" ""))]
15548   "TARGET_USE_FANCY_MATH_387
15549    && flag_unsafe_math_optimizations"
15550 {
15551   if (optimize_insn_for_size_p ())
15552     FAIL;
15553   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
15554   DONE;
15555 })
15556
15557 (define_expand "ceil<mode>2"
15558   [(use (match_operand:MODEF 0 "register_operand" ""))
15559    (use (match_operand:MODEF 1 "register_operand" ""))]
15560   "(TARGET_USE_FANCY_MATH_387
15561     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15562         || TARGET_MIX_SSE_I387)
15563     && flag_unsafe_math_optimizations)
15564    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15565        && !flag_trapping_math)"
15566 {
15567   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15568       && !flag_trapping_math
15569       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
15570     {
15571       if (TARGET_ROUND)
15572         emit_insn (gen_sse4_1_round<mode>2
15573                    (operands[0], operands[1], GEN_INT (0x02)));
15574       else if (optimize_insn_for_size_p ())
15575         FAIL;
15576       else if (TARGET_64BIT || (<MODE>mode != DFmode))
15577         ix86_expand_floorceil (operand0, operand1, false);
15578       else
15579         ix86_expand_floorceildf_32 (operand0, operand1, false);
15580     }
15581   else
15582     {
15583       rtx op0, op1;
15584
15585       if (optimize_insn_for_size_p ())
15586         FAIL;
15587
15588       op0 = gen_reg_rtx (XFmode);
15589       op1 = gen_reg_rtx (XFmode);
15590       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15591       emit_insn (gen_frndintxf2_ceil (op0, op1));
15592
15593       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15594     }
15595   DONE;
15596 })
15597
15598 (define_insn_and_split "*fist<mode>2_ceil_1"
15599   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
15600         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
15601          UNSPEC_FIST_CEIL))
15602    (clobber (reg:CC FLAGS_REG))]
15603   "TARGET_USE_FANCY_MATH_387
15604    && flag_unsafe_math_optimizations
15605    && can_create_pseudo_p ()"
15606   "#"
15607   "&& 1"
15608   [(const_int 0)]
15609 {
15610   ix86_optimize_mode_switching[I387_CEIL] = 1;
15611
15612   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15613   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15614   if (memory_operand (operands[0], VOIDmode))
15615     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
15616                                      operands[2], operands[3]));
15617   else
15618     {
15619       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15620       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
15621                                                  operands[2], operands[3],
15622                                                  operands[4]));
15623     }
15624   DONE;
15625 }
15626   [(set_attr "type" "fistp")
15627    (set_attr "i387_cw" "ceil")
15628    (set_attr "mode" "<MODE>")])
15629
15630 (define_insn "fistdi2_ceil"
15631   [(set (match_operand:DI 0 "memory_operand" "=m")
15632         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15633          UNSPEC_FIST_CEIL))
15634    (use (match_operand:HI 2 "memory_operand" "m"))
15635    (use (match_operand:HI 3 "memory_operand" "m"))
15636    (clobber (match_scratch:XF 4 "=&1f"))]
15637   "TARGET_USE_FANCY_MATH_387
15638    && flag_unsafe_math_optimizations"
15639   "* return output_fix_trunc (insn, operands, 0);"
15640   [(set_attr "type" "fistp")
15641    (set_attr "i387_cw" "ceil")
15642    (set_attr "mode" "DI")])
15643
15644 (define_insn "fistdi2_ceil_with_temp"
15645   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15646         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15647          UNSPEC_FIST_CEIL))
15648    (use (match_operand:HI 2 "memory_operand" "m,m"))
15649    (use (match_operand:HI 3 "memory_operand" "m,m"))
15650    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15651    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15652   "TARGET_USE_FANCY_MATH_387
15653    && flag_unsafe_math_optimizations"
15654   "#"
15655   [(set_attr "type" "fistp")
15656    (set_attr "i387_cw" "ceil")
15657    (set_attr "mode" "DI")])
15658
15659 (define_split
15660   [(set (match_operand:DI 0 "register_operand" "")
15661         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15662          UNSPEC_FIST_CEIL))
15663    (use (match_operand:HI 2 "memory_operand" ""))
15664    (use (match_operand:HI 3 "memory_operand" ""))
15665    (clobber (match_operand:DI 4 "memory_operand" ""))
15666    (clobber (match_scratch 5 ""))]
15667   "reload_completed"
15668   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15669               (use (match_dup 2))
15670               (use (match_dup 3))
15671               (clobber (match_dup 5))])
15672    (set (match_dup 0) (match_dup 4))]
15673   "")
15674
15675 (define_split
15676   [(set (match_operand:DI 0 "memory_operand" "")
15677         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15678          UNSPEC_FIST_CEIL))
15679    (use (match_operand:HI 2 "memory_operand" ""))
15680    (use (match_operand:HI 3 "memory_operand" ""))
15681    (clobber (match_operand:DI 4 "memory_operand" ""))
15682    (clobber (match_scratch 5 ""))]
15683   "reload_completed"
15684   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15685               (use (match_dup 2))
15686               (use (match_dup 3))
15687               (clobber (match_dup 5))])]
15688   "")
15689
15690 (define_insn "fist<mode>2_ceil"
15691   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
15692         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
15693          UNSPEC_FIST_CEIL))
15694    (use (match_operand:HI 2 "memory_operand" "m"))
15695    (use (match_operand:HI 3 "memory_operand" "m"))]
15696   "TARGET_USE_FANCY_MATH_387
15697    && flag_unsafe_math_optimizations"
15698   "* return output_fix_trunc (insn, operands, 0);"
15699   [(set_attr "type" "fistp")
15700    (set_attr "i387_cw" "ceil")
15701    (set_attr "mode" "<MODE>")])
15702
15703 (define_insn "fist<mode>2_ceil_with_temp"
15704   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
15705         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
15706          UNSPEC_FIST_CEIL))
15707    (use (match_operand:HI 2 "memory_operand" "m,m"))
15708    (use (match_operand:HI 3 "memory_operand" "m,m"))
15709    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
15710   "TARGET_USE_FANCY_MATH_387
15711    && flag_unsafe_math_optimizations"
15712   "#"
15713   [(set_attr "type" "fistp")
15714    (set_attr "i387_cw" "ceil")
15715    (set_attr "mode" "<MODE>")])
15716
15717 (define_split
15718   [(set (match_operand:X87MODEI12 0 "register_operand" "")
15719         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
15720          UNSPEC_FIST_CEIL))
15721    (use (match_operand:HI 2 "memory_operand" ""))
15722    (use (match_operand:HI 3 "memory_operand" ""))
15723    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
15724   "reload_completed"
15725   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
15726                                   UNSPEC_FIST_CEIL))
15727               (use (match_dup 2))
15728               (use (match_dup 3))])
15729    (set (match_dup 0) (match_dup 4))]
15730   "")
15731
15732 (define_split
15733   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
15734         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
15735          UNSPEC_FIST_CEIL))
15736    (use (match_operand:HI 2 "memory_operand" ""))
15737    (use (match_operand:HI 3 "memory_operand" ""))
15738    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
15739   "reload_completed"
15740   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
15741                                   UNSPEC_FIST_CEIL))
15742               (use (match_dup 2))
15743               (use (match_dup 3))])]
15744   "")
15745
15746 (define_expand "lceilxf<mode>2"
15747   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
15748                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
15749                     UNSPEC_FIST_CEIL))
15750               (clobber (reg:CC FLAGS_REG))])]
15751   "TARGET_USE_FANCY_MATH_387
15752    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15753    && flag_unsafe_math_optimizations"
15754   "")
15755
15756 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
15757   [(match_operand:SWI48 0 "nonimmediate_operand" "")
15758    (match_operand:MODEF 1 "register_operand" "")]
15759   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15760    && !flag_trapping_math"
15761 {
15762   ix86_expand_lfloorceil (operand0, operand1, false);
15763   DONE;
15764 })
15765
15766 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15767 (define_insn_and_split "frndintxf2_trunc"
15768   [(set (match_operand:XF 0 "register_operand" "")
15769         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15770          UNSPEC_FRNDINT_TRUNC))
15771    (clobber (reg:CC FLAGS_REG))]
15772   "TARGET_USE_FANCY_MATH_387
15773    && flag_unsafe_math_optimizations
15774    && can_create_pseudo_p ()"
15775   "#"
15776   "&& 1"
15777   [(const_int 0)]
15778 {
15779   ix86_optimize_mode_switching[I387_TRUNC] = 1;
15780
15781   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15782   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
15783
15784   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
15785                                         operands[2], operands[3]));
15786   DONE;
15787 }
15788   [(set_attr "type" "frndint")
15789    (set_attr "i387_cw" "trunc")
15790    (set_attr "mode" "XF")])
15791
15792 (define_insn "frndintxf2_trunc_i387"
15793   [(set (match_operand:XF 0 "register_operand" "=f")
15794         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15795          UNSPEC_FRNDINT_TRUNC))
15796    (use (match_operand:HI 2 "memory_operand" "m"))
15797    (use (match_operand:HI 3 "memory_operand" "m"))]
15798   "TARGET_USE_FANCY_MATH_387
15799    && flag_unsafe_math_optimizations"
15800   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15801   [(set_attr "type" "frndint")
15802    (set_attr "i387_cw" "trunc")
15803    (set_attr "mode" "XF")])
15804
15805 (define_expand "btruncxf2"
15806   [(use (match_operand:XF 0 "register_operand" ""))
15807    (use (match_operand:XF 1 "register_operand" ""))]
15808   "TARGET_USE_FANCY_MATH_387
15809    && flag_unsafe_math_optimizations"
15810 {
15811   if (optimize_insn_for_size_p ())
15812     FAIL;
15813   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
15814   DONE;
15815 })
15816
15817 (define_expand "btrunc<mode>2"
15818   [(use (match_operand:MODEF 0 "register_operand" ""))
15819    (use (match_operand:MODEF 1 "register_operand" ""))]
15820   "(TARGET_USE_FANCY_MATH_387
15821     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15822         || TARGET_MIX_SSE_I387)
15823     && flag_unsafe_math_optimizations)
15824    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15825        && !flag_trapping_math)"
15826 {
15827   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15828       && !flag_trapping_math
15829       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
15830     {
15831       if (TARGET_ROUND)
15832         emit_insn (gen_sse4_1_round<mode>2
15833                    (operands[0], operands[1], GEN_INT (0x03)));
15834       else if (optimize_insn_for_size_p ())
15835         FAIL;
15836       else if (TARGET_64BIT || (<MODE>mode != DFmode))
15837         ix86_expand_trunc (operand0, operand1);
15838       else
15839         ix86_expand_truncdf_32 (operand0, operand1);
15840     }
15841   else
15842     {
15843       rtx op0, op1;
15844
15845       if (optimize_insn_for_size_p ())
15846         FAIL;
15847
15848       op0 = gen_reg_rtx (XFmode);
15849       op1 = gen_reg_rtx (XFmode);
15850       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15851       emit_insn (gen_frndintxf2_trunc (op0, op1));
15852
15853       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15854     }
15855   DONE;
15856 })
15857
15858 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15859 (define_insn_and_split "frndintxf2_mask_pm"
15860   [(set (match_operand:XF 0 "register_operand" "")
15861         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15862          UNSPEC_FRNDINT_MASK_PM))
15863    (clobber (reg:CC FLAGS_REG))]
15864   "TARGET_USE_FANCY_MATH_387
15865    && flag_unsafe_math_optimizations
15866    && can_create_pseudo_p ()"
15867   "#"
15868   "&& 1"
15869   [(const_int 0)]
15870 {
15871   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15872
15873   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15874   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15875
15876   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15877                                           operands[2], operands[3]));
15878   DONE;
15879 }
15880   [(set_attr "type" "frndint")
15881    (set_attr "i387_cw" "mask_pm")
15882    (set_attr "mode" "XF")])
15883
15884 (define_insn "frndintxf2_mask_pm_i387"
15885   [(set (match_operand:XF 0 "register_operand" "=f")
15886         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15887          UNSPEC_FRNDINT_MASK_PM))
15888    (use (match_operand:HI 2 "memory_operand" "m"))
15889    (use (match_operand:HI 3 "memory_operand" "m"))]
15890   "TARGET_USE_FANCY_MATH_387
15891    && flag_unsafe_math_optimizations"
15892   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15893   [(set_attr "type" "frndint")
15894    (set_attr "i387_cw" "mask_pm")
15895    (set_attr "mode" "XF")])
15896
15897 (define_expand "nearbyintxf2"
15898   [(use (match_operand:XF 0 "register_operand" ""))
15899    (use (match_operand:XF 1 "register_operand" ""))]
15900   "TARGET_USE_FANCY_MATH_387
15901    && flag_unsafe_math_optimizations"
15902 {
15903   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15904
15905   DONE;
15906 })
15907
15908 (define_expand "nearbyint<mode>2"
15909   [(use (match_operand:MODEF 0 "register_operand" ""))
15910    (use (match_operand:MODEF 1 "register_operand" ""))]
15911   "TARGET_USE_FANCY_MATH_387
15912    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15913        || TARGET_MIX_SSE_I387)
15914    && flag_unsafe_math_optimizations"
15915 {
15916   rtx op0 = gen_reg_rtx (XFmode);
15917   rtx op1 = gen_reg_rtx (XFmode);
15918
15919   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15920   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15921
15922   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15923   DONE;
15924 })
15925
15926 (define_insn "fxam<mode>2_i387"
15927   [(set (match_operand:HI 0 "register_operand" "=a")
15928         (unspec:HI
15929           [(match_operand:X87MODEF 1 "register_operand" "f")]
15930           UNSPEC_FXAM))]
15931   "TARGET_USE_FANCY_MATH_387"
15932   "fxam\n\tfnstsw\t%0"
15933   [(set_attr "type" "multi")
15934    (set_attr "length" "4")
15935    (set_attr "unit" "i387")
15936    (set_attr "mode" "<MODE>")])
15937
15938 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15939   [(set (match_operand:HI 0 "register_operand" "")
15940         (unspec:HI
15941           [(match_operand:MODEF 1 "memory_operand" "")]
15942           UNSPEC_FXAM_MEM))]
15943   "TARGET_USE_FANCY_MATH_387
15944    && can_create_pseudo_p ()"
15945   "#"
15946   "&& 1"
15947   [(set (match_dup 2)(match_dup 1))
15948    (set (match_dup 0)
15949         (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15950 {
15951   operands[2] = gen_reg_rtx (<MODE>mode);
15952
15953   MEM_VOLATILE_P (operands[1]) = 1;
15954 }
15955   [(set_attr "type" "multi")
15956    (set_attr "unit" "i387")
15957    (set_attr "mode" "<MODE>")])
15958
15959 (define_expand "isinfxf2"
15960   [(use (match_operand:SI 0 "register_operand" ""))
15961    (use (match_operand:XF 1 "register_operand" ""))]
15962   "TARGET_USE_FANCY_MATH_387
15963    && TARGET_C99_FUNCTIONS"
15964 {
15965   rtx mask = GEN_INT (0x45);
15966   rtx val = GEN_INT (0x05);
15967
15968   rtx cond;
15969
15970   rtx scratch = gen_reg_rtx (HImode);
15971   rtx res = gen_reg_rtx (QImode);
15972
15973   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15974
15975   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15976   emit_insn (gen_cmpqi_ext_3 (scratch, val));
15977   cond = gen_rtx_fmt_ee (EQ, QImode,
15978                          gen_rtx_REG (CCmode, FLAGS_REG),
15979                          const0_rtx);
15980   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15981   emit_insn (gen_zero_extendqisi2 (operands[0], res));
15982   DONE;
15983 })
15984
15985 (define_expand "isinf<mode>2"
15986   [(use (match_operand:SI 0 "register_operand" ""))
15987    (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15988   "TARGET_USE_FANCY_MATH_387
15989    && TARGET_C99_FUNCTIONS
15990    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15991 {
15992   rtx mask = GEN_INT (0x45);
15993   rtx val = GEN_INT (0x05);
15994
15995   rtx cond;
15996
15997   rtx scratch = gen_reg_rtx (HImode);
15998   rtx res = gen_reg_rtx (QImode);
15999
16000   /* Remove excess precision by forcing value through memory. */
16001   if (memory_operand (operands[1], VOIDmode))
16002     emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
16003   else
16004     {
16005       enum ix86_stack_slot slot = (virtuals_instantiated
16006                                    ? SLOT_TEMP
16007                                    : SLOT_VIRTUAL);
16008       rtx temp = assign_386_stack_local (<MODE>mode, slot);
16009
16010       emit_move_insn (temp, operands[1]);
16011       emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
16012     }
16013
16014   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
16015   emit_insn (gen_cmpqi_ext_3 (scratch, val));
16016   cond = gen_rtx_fmt_ee (EQ, QImode,
16017                          gen_rtx_REG (CCmode, FLAGS_REG),
16018                          const0_rtx);
16019   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
16020   emit_insn (gen_zero_extendqisi2 (operands[0], res));
16021   DONE;
16022 })
16023
16024 (define_expand "signbit<mode>2"
16025   [(use (match_operand:SI 0 "register_operand" ""))
16026    (use (match_operand:X87MODEF 1 "register_operand" ""))]
16027   "TARGET_USE_FANCY_MATH_387
16028    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16029 {
16030   rtx mask = GEN_INT (0x0200);
16031
16032   rtx scratch = gen_reg_rtx (HImode);
16033
16034   emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
16035   emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
16036   DONE;
16037 })
16038 \f
16039 ;; Block operation instructions
16040
16041 (define_insn "cld"
16042   [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
16043   ""
16044   "cld"
16045   [(set_attr "length" "1")
16046    (set_attr "length_immediate" "0")
16047    (set_attr "modrm" "0")])
16048
16049 (define_expand "movmemsi"
16050   [(use (match_operand:BLK 0 "memory_operand" ""))
16051    (use (match_operand:BLK 1 "memory_operand" ""))
16052    (use (match_operand:SI 2 "nonmemory_operand" ""))
16053    (use (match_operand:SI 3 "const_int_operand" ""))
16054    (use (match_operand:SI 4 "const_int_operand" ""))
16055    (use (match_operand:SI 5 "const_int_operand" ""))]
16056   ""
16057 {
16058  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
16059                          operands[4], operands[5]))
16060    DONE;
16061  else
16062    FAIL;
16063 })
16064
16065 (define_expand "movmemdi"
16066   [(use (match_operand:BLK 0 "memory_operand" ""))
16067    (use (match_operand:BLK 1 "memory_operand" ""))
16068    (use (match_operand:DI 2 "nonmemory_operand" ""))
16069    (use (match_operand:DI 3 "const_int_operand" ""))
16070    (use (match_operand:SI 4 "const_int_operand" ""))
16071    (use (match_operand:SI 5 "const_int_operand" ""))]
16072   "TARGET_64BIT"
16073 {
16074  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
16075                          operands[4], operands[5]))
16076    DONE;
16077  else
16078    FAIL;
16079 })
16080
16081 ;; Most CPUs don't like single string operations
16082 ;; Handle this case here to simplify previous expander.
16083
16084 (define_expand "strmov"
16085   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
16086    (set (match_operand 1 "memory_operand" "") (match_dup 4))
16087    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
16088               (clobber (reg:CC FLAGS_REG))])
16089    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
16090               (clobber (reg:CC FLAGS_REG))])]
16091   ""
16092 {
16093   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
16094
16095   /* If .md ever supports :P for Pmode, these can be directly
16096      in the pattern above.  */
16097   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
16098   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
16099
16100   /* Can't use this if the user has appropriated esi or edi.  */
16101   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
16102       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
16103     {
16104       emit_insn (gen_strmov_singleop (operands[0], operands[1],
16105                                       operands[2], operands[3],
16106                                       operands[5], operands[6]));
16107       DONE;
16108     }
16109
16110   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
16111 })
16112
16113 (define_expand "strmov_singleop"
16114   [(parallel [(set (match_operand 1 "memory_operand" "")
16115                    (match_operand 3 "memory_operand" ""))
16116               (set (match_operand 0 "register_operand" "")
16117                    (match_operand 4 "" ""))
16118               (set (match_operand 2 "register_operand" "")
16119                    (match_operand 5 "" ""))])]
16120   ""
16121   "ix86_current_function_needs_cld = 1;")
16122
16123 (define_insn "*strmovdi_rex_1"
16124   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
16125         (mem:DI (match_operand:DI 3 "register_operand" "1")))
16126    (set (match_operand:DI 0 "register_operand" "=D")
16127         (plus:DI (match_dup 2)
16128                  (const_int 8)))
16129    (set (match_operand:DI 1 "register_operand" "=S")
16130         (plus:DI (match_dup 3)
16131                  (const_int 8)))]
16132   "TARGET_64BIT"
16133   "movsq"
16134   [(set_attr "type" "str")
16135    (set_attr "mode" "DI")
16136    (set_attr "memory" "both")])
16137
16138 (define_insn "*strmovsi_1"
16139   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
16140         (mem:SI (match_operand:SI 3 "register_operand" "1")))
16141    (set (match_operand:SI 0 "register_operand" "=D")
16142         (plus:SI (match_dup 2)
16143                  (const_int 4)))
16144    (set (match_operand:SI 1 "register_operand" "=S")
16145         (plus:SI (match_dup 3)
16146                  (const_int 4)))]
16147   "!TARGET_64BIT"
16148   "movs{l|d}"
16149   [(set_attr "type" "str")
16150    (set_attr "mode" "SI")
16151    (set_attr "memory" "both")])
16152
16153 (define_insn "*strmovsi_rex_1"
16154   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
16155         (mem:SI (match_operand:DI 3 "register_operand" "1")))
16156    (set (match_operand:DI 0 "register_operand" "=D")
16157         (plus:DI (match_dup 2)
16158                  (const_int 4)))
16159    (set (match_operand:DI 1 "register_operand" "=S")
16160         (plus:DI (match_dup 3)
16161                  (const_int 4)))]
16162   "TARGET_64BIT"
16163   "movs{l|d}"
16164   [(set_attr "type" "str")
16165    (set_attr "mode" "SI")
16166    (set_attr "memory" "both")])
16167
16168 (define_insn "*strmovhi_1"
16169   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
16170         (mem:HI (match_operand:SI 3 "register_operand" "1")))
16171    (set (match_operand:SI 0 "register_operand" "=D")
16172         (plus:SI (match_dup 2)
16173                  (const_int 2)))
16174    (set (match_operand:SI 1 "register_operand" "=S")
16175         (plus:SI (match_dup 3)
16176                  (const_int 2)))]
16177   "!TARGET_64BIT"
16178   "movsw"
16179   [(set_attr "type" "str")
16180    (set_attr "memory" "both")
16181    (set_attr "mode" "HI")])
16182
16183 (define_insn "*strmovhi_rex_1"
16184   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
16185         (mem:HI (match_operand:DI 3 "register_operand" "1")))
16186    (set (match_operand:DI 0 "register_operand" "=D")
16187         (plus:DI (match_dup 2)
16188                  (const_int 2)))
16189    (set (match_operand:DI 1 "register_operand" "=S")
16190         (plus:DI (match_dup 3)
16191                  (const_int 2)))]
16192   "TARGET_64BIT"
16193   "movsw"
16194   [(set_attr "type" "str")
16195    (set_attr "memory" "both")
16196    (set_attr "mode" "HI")])
16197
16198 (define_insn "*strmovqi_1"
16199   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
16200         (mem:QI (match_operand:SI 3 "register_operand" "1")))
16201    (set (match_operand:SI 0 "register_operand" "=D")
16202         (plus:SI (match_dup 2)
16203                  (const_int 1)))
16204    (set (match_operand:SI 1 "register_operand" "=S")
16205         (plus:SI (match_dup 3)
16206                  (const_int 1)))]
16207   "!TARGET_64BIT"
16208   "movsb"
16209   [(set_attr "type" "str")
16210    (set_attr "memory" "both")
16211    (set_attr "mode" "QI")])
16212
16213 (define_insn "*strmovqi_rex_1"
16214   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
16215         (mem:QI (match_operand:DI 3 "register_operand" "1")))
16216    (set (match_operand:DI 0 "register_operand" "=D")
16217         (plus:DI (match_dup 2)
16218                  (const_int 1)))
16219    (set (match_operand:DI 1 "register_operand" "=S")
16220         (plus:DI (match_dup 3)
16221                  (const_int 1)))]
16222   "TARGET_64BIT"
16223   "movsb"
16224   [(set_attr "type" "str")
16225    (set_attr "memory" "both")
16226    (set_attr "prefix_rex" "0")
16227    (set_attr "mode" "QI")])
16228
16229 (define_expand "rep_mov"
16230   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
16231               (set (match_operand 0 "register_operand" "")
16232                    (match_operand 5 "" ""))
16233               (set (match_operand 2 "register_operand" "")
16234                    (match_operand 6 "" ""))
16235               (set (match_operand 1 "memory_operand" "")
16236                    (match_operand 3 "memory_operand" ""))
16237               (use (match_dup 4))])]
16238   ""
16239   "ix86_current_function_needs_cld = 1;")
16240
16241 (define_insn "*rep_movdi_rex64"
16242   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16243    (set (match_operand:DI 0 "register_operand" "=D")
16244         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
16245                             (const_int 3))
16246                  (match_operand:DI 3 "register_operand" "0")))
16247    (set (match_operand:DI 1 "register_operand" "=S")
16248         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
16249                  (match_operand:DI 4 "register_operand" "1")))
16250    (set (mem:BLK (match_dup 3))
16251         (mem:BLK (match_dup 4)))
16252    (use (match_dup 5))]
16253   "TARGET_64BIT"
16254   "rep movsq"
16255   [(set_attr "type" "str")
16256    (set_attr "prefix_rep" "1")
16257    (set_attr "memory" "both")
16258    (set_attr "mode" "DI")])
16259
16260 (define_insn "*rep_movsi"
16261   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
16262    (set (match_operand:SI 0 "register_operand" "=D")
16263         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
16264                             (const_int 2))
16265                  (match_operand:SI 3 "register_operand" "0")))
16266    (set (match_operand:SI 1 "register_operand" "=S")
16267         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
16268                  (match_operand:SI 4 "register_operand" "1")))
16269    (set (mem:BLK (match_dup 3))
16270         (mem:BLK (match_dup 4)))
16271    (use (match_dup 5))]
16272   "!TARGET_64BIT"
16273   "rep movs{l|d}"
16274   [(set_attr "type" "str")
16275    (set_attr "prefix_rep" "1")
16276    (set_attr "memory" "both")
16277    (set_attr "mode" "SI")])
16278
16279 (define_insn "*rep_movsi_rex64"
16280   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16281    (set (match_operand:DI 0 "register_operand" "=D")
16282         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
16283                             (const_int 2))
16284                  (match_operand:DI 3 "register_operand" "0")))
16285    (set (match_operand:DI 1 "register_operand" "=S")
16286         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
16287                  (match_operand:DI 4 "register_operand" "1")))
16288    (set (mem:BLK (match_dup 3))
16289         (mem:BLK (match_dup 4)))
16290    (use (match_dup 5))]
16291   "TARGET_64BIT"
16292   "rep movs{l|d}"
16293   [(set_attr "type" "str")
16294    (set_attr "prefix_rep" "1")
16295    (set_attr "memory" "both")
16296    (set_attr "mode" "SI")])
16297
16298 (define_insn "*rep_movqi"
16299   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
16300    (set (match_operand:SI 0 "register_operand" "=D")
16301         (plus:SI (match_operand:SI 3 "register_operand" "0")
16302                  (match_operand:SI 5 "register_operand" "2")))
16303    (set (match_operand:SI 1 "register_operand" "=S")
16304         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
16305    (set (mem:BLK (match_dup 3))
16306         (mem:BLK (match_dup 4)))
16307    (use (match_dup 5))]
16308   "!TARGET_64BIT"
16309   "rep movsb"
16310   [(set_attr "type" "str")
16311    (set_attr "prefix_rep" "1")
16312    (set_attr "memory" "both")
16313    (set_attr "mode" "SI")])
16314
16315 (define_insn "*rep_movqi_rex64"
16316   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16317    (set (match_operand:DI 0 "register_operand" "=D")
16318         (plus:DI (match_operand:DI 3 "register_operand" "0")
16319                  (match_operand:DI 5 "register_operand" "2")))
16320    (set (match_operand:DI 1 "register_operand" "=S")
16321         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
16322    (set (mem:BLK (match_dup 3))
16323         (mem:BLK (match_dup 4)))
16324    (use (match_dup 5))]
16325   "TARGET_64BIT"
16326   "rep movsb"
16327   [(set_attr "type" "str")
16328    (set_attr "prefix_rep" "1")
16329    (set_attr "memory" "both")
16330    (set_attr "mode" "SI")])
16331
16332 (define_expand "setmemsi"
16333    [(use (match_operand:BLK 0 "memory_operand" ""))
16334     (use (match_operand:SI 1 "nonmemory_operand" ""))
16335     (use (match_operand 2 "const_int_operand" ""))
16336     (use (match_operand 3 "const_int_operand" ""))
16337     (use (match_operand:SI 4 "const_int_operand" ""))
16338     (use (match_operand:SI 5 "const_int_operand" ""))]
16339   ""
16340 {
16341  if (ix86_expand_setmem (operands[0], operands[1],
16342                          operands[2], operands[3],
16343                          operands[4], operands[5]))
16344    DONE;
16345  else
16346    FAIL;
16347 })
16348
16349 (define_expand "setmemdi"
16350    [(use (match_operand:BLK 0 "memory_operand" ""))
16351     (use (match_operand:DI 1 "nonmemory_operand" ""))
16352     (use (match_operand 2 "const_int_operand" ""))
16353     (use (match_operand 3 "const_int_operand" ""))
16354     (use (match_operand 4 "const_int_operand" ""))
16355     (use (match_operand 5 "const_int_operand" ""))]
16356   "TARGET_64BIT"
16357 {
16358  if (ix86_expand_setmem (operands[0], operands[1],
16359                          operands[2], operands[3],
16360                          operands[4], operands[5]))
16361    DONE;
16362  else
16363    FAIL;
16364 })
16365
16366 ;; Most CPUs don't like single string operations
16367 ;; Handle this case here to simplify previous expander.
16368
16369 (define_expand "strset"
16370   [(set (match_operand 1 "memory_operand" "")
16371         (match_operand 2 "register_operand" ""))
16372    (parallel [(set (match_operand 0 "register_operand" "")
16373                    (match_dup 3))
16374               (clobber (reg:CC FLAGS_REG))])]
16375   ""
16376 {
16377   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
16378     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
16379
16380   /* If .md ever supports :P for Pmode, this can be directly
16381      in the pattern above.  */
16382   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
16383                               GEN_INT (GET_MODE_SIZE (GET_MODE
16384                                                       (operands[2]))));
16385   if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
16386     {
16387       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
16388                                       operands[3]));
16389       DONE;
16390     }
16391 })
16392
16393 (define_expand "strset_singleop"
16394   [(parallel [(set (match_operand 1 "memory_operand" "")
16395                    (match_operand 2 "register_operand" ""))
16396               (set (match_operand 0 "register_operand" "")
16397                    (match_operand 3 "" ""))])]
16398   ""
16399   "ix86_current_function_needs_cld = 1;")
16400
16401 (define_insn "*strsetdi_rex_1"
16402   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
16403         (match_operand:DI 2 "register_operand" "a"))
16404    (set (match_operand:DI 0 "register_operand" "=D")
16405         (plus:DI (match_dup 1)
16406                  (const_int 8)))]
16407   "TARGET_64BIT"
16408   "stosq"
16409   [(set_attr "type" "str")
16410    (set_attr "memory" "store")
16411    (set_attr "mode" "DI")])
16412
16413 (define_insn "*strsetsi_1"
16414   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
16415         (match_operand:SI 2 "register_operand" "a"))
16416    (set (match_operand:SI 0 "register_operand" "=D")
16417         (plus:SI (match_dup 1)
16418                  (const_int 4)))]
16419   "!TARGET_64BIT"
16420   "stos{l|d}"
16421   [(set_attr "type" "str")
16422    (set_attr "memory" "store")
16423    (set_attr "mode" "SI")])
16424
16425 (define_insn "*strsetsi_rex_1"
16426   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
16427         (match_operand:SI 2 "register_operand" "a"))
16428    (set (match_operand:DI 0 "register_operand" "=D")
16429         (plus:DI (match_dup 1)
16430                  (const_int 4)))]
16431   "TARGET_64BIT"
16432   "stos{l|d}"
16433   [(set_attr "type" "str")
16434    (set_attr "memory" "store")
16435    (set_attr "mode" "SI")])
16436
16437 (define_insn "*strsethi_1"
16438   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
16439         (match_operand:HI 2 "register_operand" "a"))
16440    (set (match_operand:SI 0 "register_operand" "=D")
16441         (plus:SI (match_dup 1)
16442                  (const_int 2)))]
16443   "!TARGET_64BIT"
16444   "stosw"
16445   [(set_attr "type" "str")
16446    (set_attr "memory" "store")
16447    (set_attr "mode" "HI")])
16448
16449 (define_insn "*strsethi_rex_1"
16450   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
16451         (match_operand:HI 2 "register_operand" "a"))
16452    (set (match_operand:DI 0 "register_operand" "=D")
16453         (plus:DI (match_dup 1)
16454                  (const_int 2)))]
16455   "TARGET_64BIT"
16456   "stosw"
16457   [(set_attr "type" "str")
16458    (set_attr "memory" "store")
16459    (set_attr "mode" "HI")])
16460
16461 (define_insn "*strsetqi_1"
16462   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
16463         (match_operand:QI 2 "register_operand" "a"))
16464    (set (match_operand:SI 0 "register_operand" "=D")
16465         (plus:SI (match_dup 1)
16466                  (const_int 1)))]
16467   "!TARGET_64BIT"
16468   "stosb"
16469   [(set_attr "type" "str")
16470    (set_attr "memory" "store")
16471    (set_attr "mode" "QI")])
16472
16473 (define_insn "*strsetqi_rex_1"
16474   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
16475         (match_operand:QI 2 "register_operand" "a"))
16476    (set (match_operand:DI 0 "register_operand" "=D")
16477         (plus:DI (match_dup 1)
16478                  (const_int 1)))]
16479   "TARGET_64BIT"
16480   "stosb"
16481   [(set_attr "type" "str")
16482    (set_attr "memory" "store")
16483    (set_attr "prefix_rex" "0")
16484    (set_attr "mode" "QI")])
16485
16486 (define_expand "rep_stos"
16487   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
16488               (set (match_operand 0 "register_operand" "")
16489                    (match_operand 4 "" ""))
16490               (set (match_operand 2 "memory_operand" "") (const_int 0))
16491               (use (match_operand 3 "register_operand" ""))
16492               (use (match_dup 1))])]
16493   ""
16494   "ix86_current_function_needs_cld = 1;")
16495
16496 (define_insn "*rep_stosdi_rex64"
16497   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16498    (set (match_operand:DI 0 "register_operand" "=D")
16499         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
16500                             (const_int 3))
16501                  (match_operand:DI 3 "register_operand" "0")))
16502    (set (mem:BLK (match_dup 3))
16503         (const_int 0))
16504    (use (match_operand:DI 2 "register_operand" "a"))
16505    (use (match_dup 4))]
16506   "TARGET_64BIT"
16507   "rep stosq"
16508   [(set_attr "type" "str")
16509    (set_attr "prefix_rep" "1")
16510    (set_attr "memory" "store")
16511    (set_attr "mode" "DI")])
16512
16513 (define_insn "*rep_stossi"
16514   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
16515    (set (match_operand:SI 0 "register_operand" "=D")
16516         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
16517                             (const_int 2))
16518                  (match_operand:SI 3 "register_operand" "0")))
16519    (set (mem:BLK (match_dup 3))
16520         (const_int 0))
16521    (use (match_operand:SI 2 "register_operand" "a"))
16522    (use (match_dup 4))]
16523   "!TARGET_64BIT"
16524   "rep stos{l|d}"
16525   [(set_attr "type" "str")
16526    (set_attr "prefix_rep" "1")
16527    (set_attr "memory" "store")
16528    (set_attr "mode" "SI")])
16529
16530 (define_insn "*rep_stossi_rex64"
16531   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16532    (set (match_operand:DI 0 "register_operand" "=D")
16533         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
16534                             (const_int 2))
16535                  (match_operand:DI 3 "register_operand" "0")))
16536    (set (mem:BLK (match_dup 3))
16537         (const_int 0))
16538    (use (match_operand:SI 2 "register_operand" "a"))
16539    (use (match_dup 4))]
16540   "TARGET_64BIT"
16541   "rep stos{l|d}"
16542   [(set_attr "type" "str")
16543    (set_attr "prefix_rep" "1")
16544    (set_attr "memory" "store")
16545    (set_attr "mode" "SI")])
16546
16547 (define_insn "*rep_stosqi"
16548   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
16549    (set (match_operand:SI 0 "register_operand" "=D")
16550         (plus:SI (match_operand:SI 3 "register_operand" "0")
16551                  (match_operand:SI 4 "register_operand" "1")))
16552    (set (mem:BLK (match_dup 3))
16553         (const_int 0))
16554    (use (match_operand:QI 2 "register_operand" "a"))
16555    (use (match_dup 4))]
16556   "!TARGET_64BIT"
16557   "rep stosb"
16558   [(set_attr "type" "str")
16559    (set_attr "prefix_rep" "1")
16560    (set_attr "memory" "store")
16561    (set_attr "mode" "QI")])
16562
16563 (define_insn "*rep_stosqi_rex64"
16564   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16565    (set (match_operand:DI 0 "register_operand" "=D")
16566         (plus:DI (match_operand:DI 3 "register_operand" "0")
16567                  (match_operand:DI 4 "register_operand" "1")))
16568    (set (mem:BLK (match_dup 3))
16569         (const_int 0))
16570    (use (match_operand:QI 2 "register_operand" "a"))
16571    (use (match_dup 4))]
16572   "TARGET_64BIT"
16573   "rep stosb"
16574   [(set_attr "type" "str")
16575    (set_attr "prefix_rep" "1")
16576    (set_attr "memory" "store")
16577    (set_attr "prefix_rex" "0")
16578    (set_attr "mode" "QI")])
16579
16580 (define_expand "cmpstrnsi"
16581   [(set (match_operand:SI 0 "register_operand" "")
16582         (compare:SI (match_operand:BLK 1 "general_operand" "")
16583                     (match_operand:BLK 2 "general_operand" "")))
16584    (use (match_operand 3 "general_operand" ""))
16585    (use (match_operand 4 "immediate_operand" ""))]
16586   ""
16587 {
16588   rtx addr1, addr2, out, outlow, count, countreg, align;
16589
16590   if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16591     FAIL;
16592
16593   /* Can't use this if the user has appropriated esi or edi.  */
16594   if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
16595     FAIL;
16596
16597   out = operands[0];
16598   if (!REG_P (out))
16599     out = gen_reg_rtx (SImode);
16600
16601   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
16602   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
16603   if (addr1 != XEXP (operands[1], 0))
16604     operands[1] = replace_equiv_address_nv (operands[1], addr1);
16605   if (addr2 != XEXP (operands[2], 0))
16606     operands[2] = replace_equiv_address_nv (operands[2], addr2);
16607
16608   count = operands[3];
16609   countreg = ix86_zero_extend_to_Pmode (count);
16610
16611   /* %%% Iff we are testing strict equality, we can use known alignment
16612      to good advantage.  This may be possible with combine, particularly
16613      once cc0 is dead.  */
16614   align = operands[4];
16615
16616   if (CONST_INT_P (count))
16617     {
16618       if (INTVAL (count) == 0)
16619         {
16620           emit_move_insn (operands[0], const0_rtx);
16621           DONE;
16622         }
16623       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16624                                      operands[1], operands[2]));
16625     }
16626   else
16627     {
16628       rtx (*cmp_insn)(rtx, rtx);
16629
16630       if (TARGET_64BIT)
16631         cmp_insn = gen_cmpdi_1;
16632       else
16633         cmp_insn = gen_cmpsi_1;
16634       emit_insn (cmp_insn (countreg, countreg));
16635       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16636                                   operands[1], operands[2]));
16637     }
16638
16639   outlow = gen_lowpart (QImode, out);
16640   emit_insn (gen_cmpintqi (outlow));
16641   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16642
16643   if (operands[0] != out)
16644     emit_move_insn (operands[0], out);
16645
16646   DONE;
16647 })
16648
16649 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16650
16651 (define_expand "cmpintqi"
16652   [(set (match_dup 1)
16653         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16654    (set (match_dup 2)
16655         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16656    (parallel [(set (match_operand:QI 0 "register_operand" "")
16657                    (minus:QI (match_dup 1)
16658                              (match_dup 2)))
16659               (clobber (reg:CC FLAGS_REG))])]
16660   ""
16661   "operands[1] = gen_reg_rtx (QImode);
16662    operands[2] = gen_reg_rtx (QImode);")
16663
16664 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
16665 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
16666
16667 (define_expand "cmpstrnqi_nz_1"
16668   [(parallel [(set (reg:CC FLAGS_REG)
16669                    (compare:CC (match_operand 4 "memory_operand" "")
16670                                (match_operand 5 "memory_operand" "")))
16671               (use (match_operand 2 "register_operand" ""))
16672               (use (match_operand:SI 3 "immediate_operand" ""))
16673               (clobber (match_operand 0 "register_operand" ""))
16674               (clobber (match_operand 1 "register_operand" ""))
16675               (clobber (match_dup 2))])]
16676   ""
16677   "ix86_current_function_needs_cld = 1;")
16678
16679 (define_insn "*cmpstrnqi_nz_1"
16680   [(set (reg:CC FLAGS_REG)
16681         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
16682                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
16683    (use (match_operand:SI 6 "register_operand" "2"))
16684    (use (match_operand:SI 3 "immediate_operand" "i"))
16685    (clobber (match_operand:SI 0 "register_operand" "=S"))
16686    (clobber (match_operand:SI 1 "register_operand" "=D"))
16687    (clobber (match_operand:SI 2 "register_operand" "=c"))]
16688   "!TARGET_64BIT"
16689   "repz cmpsb"
16690   [(set_attr "type" "str")
16691    (set_attr "mode" "QI")
16692    (set_attr "prefix_rep" "1")])
16693
16694 (define_insn "*cmpstrnqi_nz_rex_1"
16695   [(set (reg:CC FLAGS_REG)
16696         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
16697                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
16698    (use (match_operand:DI 6 "register_operand" "2"))
16699    (use (match_operand:SI 3 "immediate_operand" "i"))
16700    (clobber (match_operand:DI 0 "register_operand" "=S"))
16701    (clobber (match_operand:DI 1 "register_operand" "=D"))
16702    (clobber (match_operand:DI 2 "register_operand" "=c"))]
16703   "TARGET_64BIT"
16704   "repz cmpsb"
16705   [(set_attr "type" "str")
16706    (set_attr "mode" "QI")
16707    (set_attr "prefix_rex" "0")
16708    (set_attr "prefix_rep" "1")])
16709
16710 ;; The same, but the count is not known to not be zero.
16711
16712 (define_expand "cmpstrnqi_1"
16713   [(parallel [(set (reg:CC FLAGS_REG)
16714                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
16715                                      (const_int 0))
16716                   (compare:CC (match_operand 4 "memory_operand" "")
16717                               (match_operand 5 "memory_operand" ""))
16718                   (const_int 0)))
16719               (use (match_operand:SI 3 "immediate_operand" ""))
16720               (use (reg:CC FLAGS_REG))
16721               (clobber (match_operand 0 "register_operand" ""))
16722               (clobber (match_operand 1 "register_operand" ""))
16723               (clobber (match_dup 2))])]
16724   ""
16725   "ix86_current_function_needs_cld = 1;")
16726
16727 (define_insn "*cmpstrnqi_1"
16728   [(set (reg:CC FLAGS_REG)
16729         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
16730                              (const_int 0))
16731           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
16732                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
16733           (const_int 0)))
16734    (use (match_operand:SI 3 "immediate_operand" "i"))
16735    (use (reg:CC FLAGS_REG))
16736    (clobber (match_operand:SI 0 "register_operand" "=S"))
16737    (clobber (match_operand:SI 1 "register_operand" "=D"))
16738    (clobber (match_operand:SI 2 "register_operand" "=c"))]
16739   "!TARGET_64BIT"
16740   "repz cmpsb"
16741   [(set_attr "type" "str")
16742    (set_attr "mode" "QI")
16743    (set_attr "prefix_rep" "1")])
16744
16745 (define_insn "*cmpstrnqi_rex_1"
16746   [(set (reg:CC FLAGS_REG)
16747         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
16748                              (const_int 0))
16749           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
16750                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
16751           (const_int 0)))
16752    (use (match_operand:SI 3 "immediate_operand" "i"))
16753    (use (reg:CC FLAGS_REG))
16754    (clobber (match_operand:DI 0 "register_operand" "=S"))
16755    (clobber (match_operand:DI 1 "register_operand" "=D"))
16756    (clobber (match_operand:DI 2 "register_operand" "=c"))]
16757   "TARGET_64BIT"
16758   "repz cmpsb"
16759   [(set_attr "type" "str")
16760    (set_attr "mode" "QI")
16761    (set_attr "prefix_rex" "0")
16762    (set_attr "prefix_rep" "1")])
16763
16764 (define_expand "strlensi"
16765   [(set (match_operand:SI 0 "register_operand" "")
16766         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
16767                     (match_operand:QI 2 "immediate_operand" "")
16768                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
16769   ""
16770 {
16771  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16772    DONE;
16773  else
16774    FAIL;
16775 })
16776
16777 (define_expand "strlendi"
16778   [(set (match_operand:DI 0 "register_operand" "")
16779         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
16780                     (match_operand:QI 2 "immediate_operand" "")
16781                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
16782   ""
16783 {
16784  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16785    DONE;
16786  else
16787    FAIL;
16788 })
16789
16790 (define_expand "strlenqi_1"
16791   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
16792               (clobber (match_operand 1 "register_operand" ""))
16793               (clobber (reg:CC FLAGS_REG))])]
16794   ""
16795   "ix86_current_function_needs_cld = 1;")
16796
16797 (define_insn "*strlenqi_1"
16798   [(set (match_operand:SI 0 "register_operand" "=&c")
16799         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
16800                     (match_operand:QI 2 "register_operand" "a")
16801                     (match_operand:SI 3 "immediate_operand" "i")
16802                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
16803    (clobber (match_operand:SI 1 "register_operand" "=D"))
16804    (clobber (reg:CC FLAGS_REG))]
16805   "!TARGET_64BIT"
16806   "repnz scasb"
16807   [(set_attr "type" "str")
16808    (set_attr "mode" "QI")
16809    (set_attr "prefix_rep" "1")])
16810
16811 (define_insn "*strlenqi_rex_1"
16812   [(set (match_operand:DI 0 "register_operand" "=&c")
16813         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
16814                     (match_operand:QI 2 "register_operand" "a")
16815                     (match_operand:DI 3 "immediate_operand" "i")
16816                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
16817    (clobber (match_operand:DI 1 "register_operand" "=D"))
16818    (clobber (reg:CC FLAGS_REG))]
16819   "TARGET_64BIT"
16820   "repnz scasb"
16821   [(set_attr "type" "str")
16822    (set_attr "mode" "QI")
16823    (set_attr "prefix_rex" "0")
16824    (set_attr "prefix_rep" "1")])
16825
16826 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
16827 ;; handled in combine, but it is not currently up to the task.
16828 ;; When used for their truth value, the cmpstrn* expanders generate
16829 ;; code like this:
16830 ;;
16831 ;;   repz cmpsb
16832 ;;   seta       %al
16833 ;;   setb       %dl
16834 ;;   cmpb       %al, %dl
16835 ;;   jcc        label
16836 ;;
16837 ;; The intermediate three instructions are unnecessary.
16838
16839 ;; This one handles cmpstrn*_nz_1...
16840 (define_peephole2
16841   [(parallel[
16842      (set (reg:CC FLAGS_REG)
16843           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16844                       (mem:BLK (match_operand 5 "register_operand" ""))))
16845      (use (match_operand 6 "register_operand" ""))
16846      (use (match_operand:SI 3 "immediate_operand" ""))
16847      (clobber (match_operand 0 "register_operand" ""))
16848      (clobber (match_operand 1 "register_operand" ""))
16849      (clobber (match_operand 2 "register_operand" ""))])
16850    (set (match_operand:QI 7 "register_operand" "")
16851         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16852    (set (match_operand:QI 8 "register_operand" "")
16853         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16854    (set (reg FLAGS_REG)
16855         (compare (match_dup 7) (match_dup 8)))
16856   ]
16857   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16858   [(parallel[
16859      (set (reg:CC FLAGS_REG)
16860           (compare:CC (mem:BLK (match_dup 4))
16861                       (mem:BLK (match_dup 5))))
16862      (use (match_dup 6))
16863      (use (match_dup 3))
16864      (clobber (match_dup 0))
16865      (clobber (match_dup 1))
16866      (clobber (match_dup 2))])]
16867   "")
16868
16869 ;; ...and this one handles cmpstrn*_1.
16870 (define_peephole2
16871   [(parallel[
16872      (set (reg:CC FLAGS_REG)
16873           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
16874                                (const_int 0))
16875             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16876                         (mem:BLK (match_operand 5 "register_operand" "")))
16877             (const_int 0)))
16878      (use (match_operand:SI 3 "immediate_operand" ""))
16879      (use (reg:CC FLAGS_REG))
16880      (clobber (match_operand 0 "register_operand" ""))
16881      (clobber (match_operand 1 "register_operand" ""))
16882      (clobber (match_operand 2 "register_operand" ""))])
16883    (set (match_operand:QI 7 "register_operand" "")
16884         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16885    (set (match_operand:QI 8 "register_operand" "")
16886         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16887    (set (reg FLAGS_REG)
16888         (compare (match_dup 7) (match_dup 8)))
16889   ]
16890   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16891   [(parallel[
16892      (set (reg:CC FLAGS_REG)
16893           (if_then_else:CC (ne (match_dup 6)
16894                                (const_int 0))
16895             (compare:CC (mem:BLK (match_dup 4))
16896                         (mem:BLK (match_dup 5)))
16897             (const_int 0)))
16898      (use (match_dup 3))
16899      (use (reg:CC FLAGS_REG))
16900      (clobber (match_dup 0))
16901      (clobber (match_dup 1))
16902      (clobber (match_dup 2))])]
16903   "")
16904
16905
16906 \f
16907 ;; Conditional move instructions.
16908
16909 (define_expand "mov<mode>cc"
16910   [(set (match_operand:SWIM 0 "register_operand" "")
16911         (if_then_else:SWIM (match_operand 1 "comparison_operator" "")
16912                            (match_operand:SWIM 2 "general_operand" "")
16913                            (match_operand:SWIM 3 "general_operand" "")))]
16914   ""
16915   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16916
16917 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16918 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16919 ;; So just document what we're doing explicitly.
16920
16921 (define_expand "x86_mov<mode>cc_0_m1"
16922   [(parallel
16923     [(set (match_operand:SWI48 0 "register_operand" "")
16924           (if_then_else:SWI48
16925             (match_operator:SWI48 2 "ix86_carry_flag_operator"
16926              [(match_operand 1 "flags_reg_operand" "")
16927               (const_int 0)])
16928             (const_int -1)
16929             (const_int 0)))
16930      (clobber (reg:CC FLAGS_REG))])]
16931   ""
16932   "")
16933
16934 (define_insn "*x86_mov<mode>cc_0_m1"
16935   [(set (match_operand:SWI48 0 "register_operand" "=r")
16936         (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16937                              [(reg FLAGS_REG) (const_int 0)])
16938           (const_int -1)
16939           (const_int 0)))
16940    (clobber (reg:CC FLAGS_REG))]
16941   ""
16942   "sbb{<imodesuffix>}\t%0, %0"
16943   ; Since we don't have the proper number of operands for an alu insn,
16944   ; fill in all the blanks.
16945   [(set_attr "type" "alu")
16946    (set_attr "use_carry" "1")
16947    (set_attr "pent_pair" "pu")
16948    (set_attr "memory" "none")
16949    (set_attr "imm_disp" "false")
16950    (set_attr "mode" "<MODE>")
16951    (set_attr "length_immediate" "0")])
16952
16953 (define_insn "*x86_mov<mode>cc_0_m1_se"
16954   [(set (match_operand:SWI48 0 "register_operand" "=r")
16955         (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16956                              [(reg FLAGS_REG) (const_int 0)])
16957                             (const_int 1)
16958                             (const_int 0)))
16959    (clobber (reg:CC FLAGS_REG))]
16960   ""
16961   "sbb{<imodesuffix>}\t%0, %0"
16962   [(set_attr "type" "alu")
16963    (set_attr "use_carry" "1")
16964    (set_attr "pent_pair" "pu")
16965    (set_attr "memory" "none")
16966    (set_attr "imm_disp" "false")
16967    (set_attr "mode" "<MODE>")
16968    (set_attr "length_immediate" "0")])
16969
16970 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16971   [(set (match_operand:SWI48 0 "register_operand" "=r")
16972         (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16973                     [(reg FLAGS_REG) (const_int 0)])))]
16974   ""
16975   "sbb{<imodesuffix>}\t%0, %0"
16976   [(set_attr "type" "alu")
16977    (set_attr "use_carry" "1")
16978    (set_attr "pent_pair" "pu")
16979    (set_attr "memory" "none")
16980    (set_attr "imm_disp" "false")
16981    (set_attr "mode" "<MODE>")
16982    (set_attr "length_immediate" "0")])
16983
16984 (define_insn "*mov<mode>cc_noc"
16985   [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16986         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16987                                [(reg FLAGS_REG) (const_int 0)])
16988           (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16989           (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16990   "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16991   "@
16992    cmov%O2%C1\t{%2, %0|%0, %2}
16993    cmov%O2%c1\t{%3, %0|%0, %3}"
16994   [(set_attr "type" "icmov")
16995    (set_attr "mode" "<MODE>")])
16996
16997 (define_insn_and_split "*movqicc_noc"
16998   [(set (match_operand:QI 0 "register_operand" "=r,r")
16999         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
17000                            [(match_operand 4 "flags_reg_operand" "")
17001                             (const_int 0)])
17002                       (match_operand:QI 2 "register_operand" "r,0")
17003                       (match_operand:QI 3 "register_operand" "0,r")))]
17004   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
17005   "#"
17006   "&& reload_completed"
17007   [(set (match_dup 0)
17008         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17009                       (match_dup 2)
17010                       (match_dup 3)))]
17011   "operands[0] = gen_lowpart (SImode, operands[0]);
17012    operands[2] = gen_lowpart (SImode, operands[2]);
17013    operands[3] = gen_lowpart (SImode, operands[3]);"
17014   [(set_attr "type" "icmov")
17015    (set_attr "mode" "SI")])
17016
17017 (define_expand "mov<mode>cc"
17018   [(set (match_operand:X87MODEF 0 "register_operand" "")
17019         (if_then_else:X87MODEF
17020           (match_operand 1 "ix86_fp_comparison_operator" "")
17021           (match_operand:X87MODEF 2 "register_operand" "")
17022           (match_operand:X87MODEF 3 "register_operand" "")))]
17023   "(TARGET_80387 && TARGET_CMOVE)
17024    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
17025   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
17026
17027 (define_insn "*movsfcc_1_387"
17028   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
17029         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
17030                                 [(reg FLAGS_REG) (const_int 0)])
17031                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
17032                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
17033   "TARGET_80387 && TARGET_CMOVE
17034    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17035   "@
17036    fcmov%F1\t{%2, %0|%0, %2}
17037    fcmov%f1\t{%3, %0|%0, %3}
17038    cmov%O2%C1\t{%2, %0|%0, %2}
17039    cmov%O2%c1\t{%3, %0|%0, %3}"
17040   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17041    (set_attr "mode" "SF,SF,SI,SI")])
17042
17043 (define_insn "*movdfcc_1"
17044   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
17045         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17046                                 [(reg FLAGS_REG) (const_int 0)])
17047                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
17048                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
17049   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
17050    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17051   "@
17052    fcmov%F1\t{%2, %0|%0, %2}
17053    fcmov%f1\t{%3, %0|%0, %3}
17054    #
17055    #"
17056   [(set_attr "type" "fcmov,fcmov,multi,multi")
17057    (set_attr "mode" "DF")])
17058
17059 (define_insn "*movdfcc_1_rex64"
17060   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
17061         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17062                                 [(reg FLAGS_REG) (const_int 0)])
17063                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
17064                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
17065   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
17066    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17067   "@
17068    fcmov%F1\t{%2, %0|%0, %2}
17069    fcmov%f1\t{%3, %0|%0, %3}
17070    cmov%O2%C1\t{%2, %0|%0, %2}
17071    cmov%O2%c1\t{%3, %0|%0, %3}"
17072   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17073    (set_attr "mode" "DF")])
17074
17075 (define_split
17076   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
17077         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17078                                 [(match_operand 4 "flags_reg_operand" "")
17079                                  (const_int 0)])
17080                       (match_operand:DF 2 "nonimmediate_operand" "")
17081                       (match_operand:DF 3 "nonimmediate_operand" "")))]
17082   "!TARGET_64BIT && reload_completed"
17083   [(set (match_dup 2)
17084         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17085                       (match_dup 5)
17086                       (match_dup 6)))
17087    (set (match_dup 3)
17088         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17089                       (match_dup 7)
17090                       (match_dup 8)))]
17091   "split_di (&operands[2], 2, &operands[5], &operands[7]);
17092    split_di (&operands[0], 1, &operands[2], &operands[3]);")
17093
17094 (define_insn "*movxfcc_1"
17095   [(set (match_operand:XF 0 "register_operand" "=f,f")
17096         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
17097                                 [(reg FLAGS_REG) (const_int 0)])
17098                       (match_operand:XF 2 "register_operand" "f,0")
17099                       (match_operand:XF 3 "register_operand" "0,f")))]
17100   "TARGET_80387 && TARGET_CMOVE"
17101   "@
17102    fcmov%F1\t{%2, %0|%0, %2}
17103    fcmov%f1\t{%3, %0|%0, %3}"
17104   [(set_attr "type" "fcmov")
17105    (set_attr "mode" "XF")])
17106
17107 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
17108 ;; the scalar versions to have only XMM registers as operands.
17109
17110 ;; XOP conditional move
17111 (define_insn "*xop_pcmov_<mode>"
17112   [(set (match_operand:MODEF 0 "register_operand" "=x")
17113         (if_then_else:MODEF
17114           (match_operand:MODEF 1 "register_operand" "x")
17115           (match_operand:MODEF 2 "register_operand" "x")
17116           (match_operand:MODEF 3 "register_operand" "x")))]
17117   "TARGET_XOP"
17118   "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
17119   [(set_attr "type" "sse4arg")])
17120
17121 ;; These versions of the min/max patterns are intentionally ignorant of
17122 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
17123 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
17124 ;; are undefined in this condition, we're certain this is correct.
17125
17126 (define_insn "*avx_<code><mode>3"
17127   [(set (match_operand:MODEF 0 "register_operand" "=x")
17128         (smaxmin:MODEF
17129           (match_operand:MODEF 1 "nonimmediate_operand" "%x")
17130           (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
17131   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
17132   "v<maxminfprefix>s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
17133   [(set_attr "type" "sseadd")
17134    (set_attr "prefix" "vex")
17135    (set_attr "mode" "<MODE>")])
17136
17137 (define_insn "<code><mode>3"
17138   [(set (match_operand:MODEF 0 "register_operand" "=x")
17139         (smaxmin:MODEF
17140           (match_operand:MODEF 1 "nonimmediate_operand" "%0")
17141           (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
17142   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
17143   "<maxminfprefix>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
17144   [(set_attr "type" "sseadd")
17145    (set_attr "mode" "<MODE>")])
17146
17147 ;; These versions of the min/max patterns implement exactly the operations
17148 ;;   min = (op1 < op2 ? op1 : op2)
17149 ;;   max = (!(op1 < op2) ? op1 : op2)
17150 ;; Their operands are not commutative, and thus they may be used in the
17151 ;; presence of -0.0 and NaN.
17152
17153 (define_insn "*avx_ieee_smin<mode>3"
17154   [(set (match_operand:MODEF 0 "register_operand" "=x")
17155         (unspec:MODEF
17156           [(match_operand:MODEF 1 "register_operand" "x")
17157            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
17158          UNSPEC_IEEE_MIN))]
17159   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
17160   "vmins<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
17161   [(set_attr "type" "sseadd")
17162    (set_attr "prefix" "vex")
17163    (set_attr "mode" "<MODE>")])
17164
17165 (define_insn "*ieee_smin<mode>3"
17166   [(set (match_operand:MODEF 0 "register_operand" "=x")
17167         (unspec:MODEF
17168           [(match_operand:MODEF 1 "register_operand" "0")
17169            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
17170          UNSPEC_IEEE_MIN))]
17171   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
17172   "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
17173   [(set_attr "type" "sseadd")
17174    (set_attr "mode" "<MODE>")])
17175
17176 (define_insn "*avx_ieee_smax<mode>3"
17177   [(set (match_operand:MODEF 0 "register_operand" "=x")
17178         (unspec:MODEF
17179           [(match_operand:MODEF 1 "register_operand" "0")
17180            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
17181          UNSPEC_IEEE_MAX))]
17182   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
17183   "vmaxs<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
17184   [(set_attr "type" "sseadd")
17185    (set_attr "prefix" "vex")
17186    (set_attr "mode" "<MODE>")])
17187
17188 (define_insn "*ieee_smax<mode>3"
17189   [(set (match_operand:MODEF 0 "register_operand" "=x")
17190         (unspec:MODEF
17191           [(match_operand:MODEF 1 "register_operand" "0")
17192            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
17193          UNSPEC_IEEE_MAX))]
17194   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
17195   "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
17196   [(set_attr "type" "sseadd")
17197    (set_attr "mode" "<MODE>")])
17198
17199 ;; Make two stack loads independent:
17200 ;;   fld aa              fld aa
17201 ;;   fld %st(0)     ->   fld bb
17202 ;;   fmul bb             fmul %st(1), %st
17203 ;;
17204 ;; Actually we only match the last two instructions for simplicity.
17205 (define_peephole2
17206   [(set (match_operand 0 "fp_register_operand" "")
17207         (match_operand 1 "fp_register_operand" ""))
17208    (set (match_dup 0)
17209         (match_operator 2 "binary_fp_operator"
17210            [(match_dup 0)
17211             (match_operand 3 "memory_operand" "")]))]
17212   "REGNO (operands[0]) != REGNO (operands[1])"
17213   [(set (match_dup 0) (match_dup 3))
17214    (set (match_dup 0) (match_dup 4))]
17215
17216   ;; The % modifier is not operational anymore in peephole2's, so we have to
17217   ;; swap the operands manually in the case of addition and multiplication.
17218   "if (COMMUTATIVE_ARITH_P (operands[2]))
17219      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
17220                                  operands[0], operands[1]);
17221    else
17222      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
17223                                  operands[1], operands[0]);")
17224
17225 ;; Conditional addition patterns
17226 (define_expand "add<mode>cc"
17227   [(match_operand:SWI 0 "register_operand" "")
17228    (match_operand 1 "comparison_operator" "")
17229    (match_operand:SWI 2 "register_operand" "")
17230    (match_operand:SWI 3 "const_int_operand" "")]
17231   ""
17232   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
17233
17234 \f
17235 ;; Misc patterns (?)
17236
17237 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
17238 ;; Otherwise there will be nothing to keep
17239 ;;
17240 ;; [(set (reg ebp) (reg esp))]
17241 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
17242 ;;  (clobber (eflags)]
17243 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
17244 ;;
17245 ;; in proper program order.
17246 (define_insn "pro_epilogue_adjust_stack_1"
17247   [(set (match_operand:SI 0 "register_operand" "=r,r")
17248         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
17249                  (match_operand:SI 2 "immediate_operand" "i,i")))
17250    (clobber (reg:CC FLAGS_REG))
17251    (clobber (mem:BLK (scratch)))]
17252   "!TARGET_64BIT"
17253 {
17254   switch (get_attr_type (insn))
17255     {
17256     case TYPE_IMOV:
17257       return "mov{l}\t{%1, %0|%0, %1}";
17258
17259     case TYPE_ALU:
17260       if (CONST_INT_P (operands[2])
17261           && (INTVAL (operands[2]) == 128
17262               || (INTVAL (operands[2]) < 0
17263                   && INTVAL (operands[2]) != -128)))
17264         {
17265           operands[2] = GEN_INT (-INTVAL (operands[2]));
17266           return "sub{l}\t{%2, %0|%0, %2}";
17267         }
17268       return "add{l}\t{%2, %0|%0, %2}";
17269
17270     case TYPE_LEA:
17271       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
17272       return "lea{l}\t{%a2, %0|%0, %a2}";
17273
17274     default:
17275       gcc_unreachable ();
17276     }
17277 }
17278   [(set (attr "type")
17279         (cond [(and (eq_attr "alternative" "0") 
17280                     (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
17281                  (const_string "alu")
17282                (match_operand:SI 2 "const0_operand" "")
17283                  (const_string "imov")
17284               ]
17285               (const_string "lea")))
17286    (set (attr "length_immediate")
17287         (cond [(eq_attr "type" "imov")
17288                  (const_string "0")
17289                (and (eq_attr "type" "alu")
17290                     (match_operand 2 "const128_operand" ""))
17291                  (const_string "1")
17292               ]
17293               (const_string "*")))
17294    (set_attr "mode" "SI")])
17295
17296 (define_insn "pro_epilogue_adjust_stack_rex64"
17297   [(set (match_operand:DI 0 "register_operand" "=r,r")
17298         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
17299                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
17300    (clobber (reg:CC FLAGS_REG))
17301    (clobber (mem:BLK (scratch)))]
17302   "TARGET_64BIT"
17303 {
17304   switch (get_attr_type (insn))
17305     {
17306     case TYPE_IMOV:
17307       return "mov{q}\t{%1, %0|%0, %1}";
17308
17309     case TYPE_ALU:
17310       if (CONST_INT_P (operands[2])
17311           /* Avoid overflows.  */
17312           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
17313           && (INTVAL (operands[2]) == 128
17314               || (INTVAL (operands[2]) < 0
17315                   && INTVAL (operands[2]) != -128)))
17316         {
17317           operands[2] = GEN_INT (-INTVAL (operands[2]));
17318           return "sub{q}\t{%2, %0|%0, %2}";
17319         }
17320       return "add{q}\t{%2, %0|%0, %2}";
17321
17322     case TYPE_LEA:
17323       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
17324       return "lea{q}\t{%a2, %0|%0, %a2}";
17325
17326     default:
17327       gcc_unreachable ();
17328     }
17329 }
17330   [(set (attr "type")
17331         (cond [(and (eq_attr "alternative" "0")
17332                     (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
17333                  (const_string "alu")
17334                (match_operand:DI 2 "const0_operand" "")
17335                  (const_string "imov")
17336               ]
17337               (const_string "lea")))
17338    (set (attr "length_immediate")
17339         (cond [(eq_attr "type" "imov")
17340                  (const_string "0")
17341                (and (eq_attr "type" "alu")
17342                     (match_operand 2 "const128_operand" ""))
17343                  (const_string "1")
17344               ]
17345               (const_string "*")))
17346    (set_attr "mode" "DI")])
17347
17348 (define_insn "pro_epilogue_adjust_stack_rex64_2"
17349   [(set (match_operand:DI 0 "register_operand" "=r,r")
17350         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
17351                  (match_operand:DI 3 "immediate_operand" "i,i")))
17352    (use (match_operand:DI 2 "register_operand" "r,r"))
17353    (clobber (reg:CC FLAGS_REG))
17354    (clobber (mem:BLK (scratch)))]
17355   "TARGET_64BIT"
17356 {
17357   switch (get_attr_type (insn))
17358     {
17359     case TYPE_ALU:
17360       return "add{q}\t{%2, %0|%0, %2}";
17361
17362     case TYPE_LEA:
17363       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
17364       return "lea{q}\t{%a2, %0|%0, %a2}";
17365
17366     default:
17367       gcc_unreachable ();
17368     }
17369 }
17370   [(set_attr "type" "alu,lea")
17371    (set_attr "mode" "DI")])
17372
17373 (define_insn "allocate_stack_worker_32"
17374   [(set (match_operand:SI 0 "register_operand" "=a")
17375         (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")]
17376                             UNSPECV_STACK_PROBE))
17377    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 1)))
17378    (clobber (reg:CC FLAGS_REG))]
17379   "!TARGET_64BIT && TARGET_STACK_PROBE"
17380   "call\t___chkstk"
17381   [(set_attr "type" "multi")
17382    (set_attr "length" "5")])
17383
17384 (define_insn "allocate_stack_worker_64"
17385   [(set (match_operand:DI 0 "register_operand" "=a")
17386         (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "0")]
17387                             UNSPECV_STACK_PROBE))
17388    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 1)))
17389    (clobber (reg:DI R10_REG))
17390    (clobber (reg:DI R11_REG))
17391    (clobber (reg:CC FLAGS_REG))]
17392   "TARGET_64BIT && TARGET_STACK_PROBE"
17393   "call\t___chkstk"
17394   [(set_attr "type" "multi")
17395    (set_attr "length" "5")])
17396
17397 (define_expand "allocate_stack"
17398   [(match_operand 0 "register_operand" "")
17399    (match_operand 1 "general_operand" "")]
17400   "TARGET_STACK_PROBE"
17401 {
17402   rtx x;
17403
17404 #ifndef CHECK_STACK_LIMIT
17405 #define CHECK_STACK_LIMIT 0
17406 #endif
17407
17408   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
17409       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
17410     {
17411       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
17412                                stack_pointer_rtx, 0, OPTAB_DIRECT);
17413       if (x != stack_pointer_rtx)
17414         emit_move_insn (stack_pointer_rtx, x);
17415     }
17416   else
17417     {
17418       x = copy_to_mode_reg (Pmode, operands[1]);
17419       if (TARGET_64BIT)
17420         x = gen_allocate_stack_worker_64 (x, x);
17421       else
17422         x = gen_allocate_stack_worker_32 (x, x);
17423       emit_insn (x);
17424     }
17425
17426   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
17427   DONE;
17428 })
17429
17430 ;; Use IOR for stack probes, this is shorter.
17431 (define_expand "probe_stack"
17432   [(match_operand 0 "memory_operand" "")]
17433   ""
17434 {
17435   if (GET_MODE (operands[0]) == DImode)
17436     emit_insn (gen_iordi3 (operands[0], operands[0], const0_rtx));
17437   else
17438     emit_insn (gen_iorsi3 (operands[0], operands[0], const0_rtx));
17439   DONE;
17440 })
17441
17442 (define_expand "builtin_setjmp_receiver"
17443   [(label_ref (match_operand 0 "" ""))]
17444   "!TARGET_64BIT && flag_pic"
17445 {
17446 #if TARGET_MACHO
17447   if (TARGET_MACHO)
17448     {
17449       rtx xops[3];
17450       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
17451       rtx label_rtx = gen_label_rtx ();
17452       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
17453       xops[0] = xops[1] = picreg;
17454       xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
17455       ix86_expand_binary_operator (MINUS, SImode, xops);
17456     }
17457   else
17458 #endif
17459     emit_insn (gen_set_got (pic_offset_table_rtx));
17460   DONE;
17461 })
17462 \f
17463 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
17464
17465 (define_split
17466   [(set (match_operand 0 "register_operand" "")
17467         (match_operator 3 "promotable_binary_operator"
17468            [(match_operand 1 "register_operand" "")
17469             (match_operand 2 "aligned_operand" "")]))
17470    (clobber (reg:CC FLAGS_REG))]
17471   "! TARGET_PARTIAL_REG_STALL && reload_completed
17472    && ((GET_MODE (operands[0]) == HImode
17473         && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
17474             /* ??? next two lines just !satisfies_constraint_K (...) */
17475             || !CONST_INT_P (operands[2])
17476             || satisfies_constraint_K (operands[2])))
17477        || (GET_MODE (operands[0]) == QImode
17478            && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
17479   [(parallel [(set (match_dup 0)
17480                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17481               (clobber (reg:CC FLAGS_REG))])]
17482   "operands[0] = gen_lowpart (SImode, operands[0]);
17483    operands[1] = gen_lowpart (SImode, operands[1]);
17484    if (GET_CODE (operands[3]) != ASHIFT)
17485      operands[2] = gen_lowpart (SImode, operands[2]);
17486    PUT_MODE (operands[3], SImode);")
17487
17488 ; Promote the QImode tests, as i386 has encoding of the AND
17489 ; instruction with 32-bit sign-extended immediate and thus the
17490 ; instruction size is unchanged, except in the %eax case for
17491 ; which it is increased by one byte, hence the ! optimize_size.
17492 (define_split
17493   [(set (match_operand 0 "flags_reg_operand" "")
17494         (match_operator 2 "compare_operator"
17495           [(and (match_operand 3 "aligned_operand" "")
17496                 (match_operand 4 "const_int_operand" ""))
17497            (const_int 0)]))
17498    (set (match_operand 1 "register_operand" "")
17499         (and (match_dup 3) (match_dup 4)))]
17500   "! TARGET_PARTIAL_REG_STALL && reload_completed
17501    && optimize_insn_for_speed_p ()
17502    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
17503        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
17504    /* Ensure that the operand will remain sign-extended immediate.  */
17505    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
17506   [(parallel [(set (match_dup 0)
17507                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
17508                                     (const_int 0)]))
17509               (set (match_dup 1)
17510                    (and:SI (match_dup 3) (match_dup 4)))])]
17511 {
17512   operands[4]
17513     = gen_int_mode (INTVAL (operands[4])
17514                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
17515   operands[1] = gen_lowpart (SImode, operands[1]);
17516   operands[3] = gen_lowpart (SImode, operands[3]);
17517 })
17518
17519 ; Don't promote the QImode tests, as i386 doesn't have encoding of
17520 ; the TEST instruction with 32-bit sign-extended immediate and thus
17521 ; the instruction size would at least double, which is not what we
17522 ; want even with ! optimize_size.
17523 (define_split
17524   [(set (match_operand 0 "flags_reg_operand" "")
17525         (match_operator 1 "compare_operator"
17526           [(and (match_operand:HI 2 "aligned_operand" "")
17527                 (match_operand:HI 3 "const_int_operand" ""))
17528            (const_int 0)]))]
17529   "! TARGET_PARTIAL_REG_STALL && reload_completed
17530    && ! TARGET_FAST_PREFIX
17531    && optimize_insn_for_speed_p ()
17532    /* Ensure that the operand will remain sign-extended immediate.  */
17533    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
17534   [(set (match_dup 0)
17535         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17536                          (const_int 0)]))]
17537 {
17538   operands[3]
17539     = gen_int_mode (INTVAL (operands[3])
17540                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
17541   operands[2] = gen_lowpart (SImode, operands[2]);
17542 })
17543
17544 (define_split
17545   [(set (match_operand 0 "register_operand" "")
17546         (neg (match_operand 1 "register_operand" "")))
17547    (clobber (reg:CC FLAGS_REG))]
17548   "! TARGET_PARTIAL_REG_STALL && reload_completed
17549    && (GET_MODE (operands[0]) == HImode
17550        || (GET_MODE (operands[0]) == QImode
17551            && (TARGET_PROMOTE_QImode
17552                || optimize_insn_for_size_p ())))"
17553   [(parallel [(set (match_dup 0)
17554                    (neg:SI (match_dup 1)))
17555               (clobber (reg:CC FLAGS_REG))])]
17556   "operands[0] = gen_lowpart (SImode, operands[0]);
17557    operands[1] = gen_lowpart (SImode, operands[1]);")
17558
17559 (define_split
17560   [(set (match_operand 0 "register_operand" "")
17561         (not (match_operand 1 "register_operand" "")))]
17562   "! TARGET_PARTIAL_REG_STALL && reload_completed
17563    && (GET_MODE (operands[0]) == HImode
17564        || (GET_MODE (operands[0]) == QImode
17565            && (TARGET_PROMOTE_QImode
17566                || optimize_insn_for_size_p ())))"
17567   [(set (match_dup 0)
17568         (not:SI (match_dup 1)))]
17569   "operands[0] = gen_lowpart (SImode, operands[0]);
17570    operands[1] = gen_lowpart (SImode, operands[1]);")
17571
17572 (define_split
17573   [(set (match_operand 0 "register_operand" "")
17574         (if_then_else (match_operator 1 "comparison_operator"
17575                                 [(reg FLAGS_REG) (const_int 0)])
17576                       (match_operand 2 "register_operand" "")
17577                       (match_operand 3 "register_operand" "")))]
17578   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
17579    && (GET_MODE (operands[0]) == HImode
17580        || (GET_MODE (operands[0]) == QImode
17581            && (TARGET_PROMOTE_QImode
17582                || optimize_insn_for_size_p ())))"
17583   [(set (match_dup 0)
17584         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
17585   "operands[0] = gen_lowpart (SImode, operands[0]);
17586    operands[2] = gen_lowpart (SImode, operands[2]);
17587    operands[3] = gen_lowpart (SImode, operands[3]);")
17588
17589 \f
17590 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
17591 ;; transform a complex memory operation into two memory to register operations.
17592
17593 ;; Don't push memory operands
17594 (define_peephole2
17595   [(set (match_operand:SI 0 "push_operand" "")
17596         (match_operand:SI 1 "memory_operand" ""))
17597    (match_scratch:SI 2 "r")]
17598   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
17599    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17600   [(set (match_dup 2) (match_dup 1))
17601    (set (match_dup 0) (match_dup 2))]
17602   "")
17603
17604 (define_peephole2
17605   [(set (match_operand:DI 0 "push_operand" "")
17606         (match_operand:DI 1 "memory_operand" ""))
17607    (match_scratch:DI 2 "r")]
17608   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
17609    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17610   [(set (match_dup 2) (match_dup 1))
17611    (set (match_dup 0) (match_dup 2))]
17612   "")
17613
17614 ;; We need to handle SFmode only, because DFmode and XFmode is split to
17615 ;; SImode pushes.
17616 (define_peephole2
17617   [(set (match_operand:SF 0 "push_operand" "")
17618         (match_operand:SF 1 "memory_operand" ""))
17619    (match_scratch:SF 2 "r")]
17620   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
17621    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17622   [(set (match_dup 2) (match_dup 1))
17623    (set (match_dup 0) (match_dup 2))]
17624   "")
17625
17626 (define_peephole2
17627   [(set (match_operand:HI 0 "push_operand" "")
17628         (match_operand:HI 1 "memory_operand" ""))
17629    (match_scratch:HI 2 "r")]
17630   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
17631    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17632   [(set (match_dup 2) (match_dup 1))
17633    (set (match_dup 0) (match_dup 2))]
17634   "")
17635
17636 (define_peephole2
17637   [(set (match_operand:QI 0 "push_operand" "")
17638         (match_operand:QI 1 "memory_operand" ""))
17639    (match_scratch:QI 2 "q")]
17640   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
17641    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17642   [(set (match_dup 2) (match_dup 1))
17643    (set (match_dup 0) (match_dup 2))]
17644   "")
17645
17646 ;; Don't move an immediate directly to memory when the instruction
17647 ;; gets too big.
17648 (define_peephole2
17649   [(match_scratch:SI 1 "r")
17650    (set (match_operand:SI 0 "memory_operand" "")
17651         (const_int 0))]
17652   "optimize_insn_for_speed_p ()
17653    && ! TARGET_USE_MOV0
17654    && TARGET_SPLIT_LONG_MOVES
17655    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
17656    && peep2_regno_dead_p (0, FLAGS_REG)"
17657   [(parallel [(set (match_dup 1) (const_int 0))
17658               (clobber (reg:CC FLAGS_REG))])
17659    (set (match_dup 0) (match_dup 1))]
17660   "")
17661
17662 (define_peephole2
17663   [(match_scratch:HI 1 "r")
17664    (set (match_operand:HI 0 "memory_operand" "")
17665         (const_int 0))]
17666   "optimize_insn_for_speed_p ()
17667    && ! TARGET_USE_MOV0
17668    && TARGET_SPLIT_LONG_MOVES
17669    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
17670    && peep2_regno_dead_p (0, FLAGS_REG)"
17671   [(parallel [(set (match_dup 2) (const_int 0))
17672               (clobber (reg:CC FLAGS_REG))])
17673    (set (match_dup 0) (match_dup 1))]
17674   "operands[2] = gen_lowpart (SImode, operands[1]);")
17675
17676 (define_peephole2
17677   [(match_scratch:QI 1 "q")
17678    (set (match_operand:QI 0 "memory_operand" "")
17679         (const_int 0))]
17680   "optimize_insn_for_speed_p ()
17681    && ! TARGET_USE_MOV0
17682    && TARGET_SPLIT_LONG_MOVES
17683    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
17684    && peep2_regno_dead_p (0, FLAGS_REG)"
17685   [(parallel [(set (match_dup 2) (const_int 0))
17686               (clobber (reg:CC FLAGS_REG))])
17687    (set (match_dup 0) (match_dup 1))]
17688   "operands[2] = gen_lowpart (SImode, operands[1]);")
17689
17690 (define_peephole2
17691   [(match_scratch:SI 2 "r")
17692    (set (match_operand:SI 0 "memory_operand" "")
17693         (match_operand:SI 1 "immediate_operand" ""))]
17694   "optimize_insn_for_speed_p ()
17695    && TARGET_SPLIT_LONG_MOVES
17696    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
17697   [(set (match_dup 2) (match_dup 1))
17698    (set (match_dup 0) (match_dup 2))]
17699   "")
17700
17701 (define_peephole2
17702   [(match_scratch:HI 2 "r")
17703    (set (match_operand:HI 0 "memory_operand" "")
17704         (match_operand:HI 1 "immediate_operand" ""))]
17705   "optimize_insn_for_speed_p ()
17706    && TARGET_SPLIT_LONG_MOVES
17707    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
17708   [(set (match_dup 2) (match_dup 1))
17709    (set (match_dup 0) (match_dup 2))]
17710   "")
17711
17712 (define_peephole2
17713   [(match_scratch:QI 2 "q")
17714    (set (match_operand:QI 0 "memory_operand" "")
17715         (match_operand:QI 1 "immediate_operand" ""))]
17716   "optimize_insn_for_speed_p ()
17717    && TARGET_SPLIT_LONG_MOVES
17718    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
17719   [(set (match_dup 2) (match_dup 1))
17720    (set (match_dup 0) (match_dup 2))]
17721   "")
17722
17723 ;; Don't compare memory with zero, load and use a test instead.
17724 (define_peephole2
17725   [(set (match_operand 0 "flags_reg_operand" "")
17726         (match_operator 1 "compare_operator"
17727           [(match_operand:SI 2 "memory_operand" "")
17728            (const_int 0)]))
17729    (match_scratch:SI 3 "r")]
17730   "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
17731   [(set (match_dup 3) (match_dup 2))
17732    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
17733   "")
17734
17735 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
17736 ;; Don't split NOTs with a displacement operand, because resulting XOR
17737 ;; will not be pairable anyway.
17738 ;;
17739 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
17740 ;; represented using a modRM byte.  The XOR replacement is long decoded,
17741 ;; so this split helps here as well.
17742 ;;
17743 ;; Note: Can't do this as a regular split because we can't get proper
17744 ;; lifetime information then.
17745
17746 (define_peephole2
17747   [(set (match_operand:SI 0 "nonimmediate_operand" "")
17748         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
17749   "optimize_insn_for_speed_p ()
17750    && ((TARGET_NOT_UNPAIRABLE
17751         && (!MEM_P (operands[0])
17752             || !memory_displacement_operand (operands[0], SImode)))
17753        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
17754    && peep2_regno_dead_p (0, FLAGS_REG)"
17755   [(parallel [(set (match_dup 0)
17756                    (xor:SI (match_dup 1) (const_int -1)))
17757               (clobber (reg:CC FLAGS_REG))])]
17758   "")
17759
17760 (define_peephole2
17761   [(set (match_operand:HI 0 "nonimmediate_operand" "")
17762         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
17763   "optimize_insn_for_speed_p ()
17764    && ((TARGET_NOT_UNPAIRABLE
17765         && (!MEM_P (operands[0])
17766             || !memory_displacement_operand (operands[0], HImode)))
17767        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
17768    && peep2_regno_dead_p (0, FLAGS_REG)"
17769   [(parallel [(set (match_dup 0)
17770                    (xor:HI (match_dup 1) (const_int -1)))
17771               (clobber (reg:CC FLAGS_REG))])]
17772   "")
17773
17774 (define_peephole2
17775   [(set (match_operand:QI 0 "nonimmediate_operand" "")
17776         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
17777   "optimize_insn_for_speed_p ()
17778    && ((TARGET_NOT_UNPAIRABLE
17779         && (!MEM_P (operands[0])
17780             || !memory_displacement_operand (operands[0], QImode)))
17781        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
17782    && peep2_regno_dead_p (0, FLAGS_REG)"
17783   [(parallel [(set (match_dup 0)
17784                    (xor:QI (match_dup 1) (const_int -1)))
17785               (clobber (reg:CC FLAGS_REG))])]
17786   "")
17787
17788 ;; Non pairable "test imm, reg" instructions can be translated to
17789 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
17790 ;; byte opcode instead of two, have a short form for byte operands),
17791 ;; so do it for other CPUs as well.  Given that the value was dead,
17792 ;; this should not create any new dependencies.  Pass on the sub-word
17793 ;; versions if we're concerned about partial register stalls.
17794
17795 (define_peephole2
17796   [(set (match_operand 0 "flags_reg_operand" "")
17797         (match_operator 1 "compare_operator"
17798           [(and:SI (match_operand:SI 2 "register_operand" "")
17799                    (match_operand:SI 3 "immediate_operand" ""))
17800            (const_int 0)]))]
17801   "ix86_match_ccmode (insn, CCNOmode)
17802    && (true_regnum (operands[2]) != AX_REG
17803        || satisfies_constraint_K (operands[3]))
17804    && peep2_reg_dead_p (1, operands[2])"
17805   [(parallel
17806      [(set (match_dup 0)
17807            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17808                             (const_int 0)]))
17809       (set (match_dup 2)
17810            (and:SI (match_dup 2) (match_dup 3)))])]
17811   "")
17812
17813 ;; We don't need to handle HImode case, because it will be promoted to SImode
17814 ;; on ! TARGET_PARTIAL_REG_STALL
17815
17816 (define_peephole2
17817   [(set (match_operand 0 "flags_reg_operand" "")
17818         (match_operator 1 "compare_operator"
17819           [(and:QI (match_operand:QI 2 "register_operand" "")
17820                    (match_operand:QI 3 "immediate_operand" ""))
17821            (const_int 0)]))]
17822   "! TARGET_PARTIAL_REG_STALL
17823    && ix86_match_ccmode (insn, CCNOmode)
17824    && true_regnum (operands[2]) != AX_REG
17825    && peep2_reg_dead_p (1, operands[2])"
17826   [(parallel
17827      [(set (match_dup 0)
17828            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17829                             (const_int 0)]))
17830       (set (match_dup 2)
17831            (and:QI (match_dup 2) (match_dup 3)))])]
17832   "")
17833
17834 (define_peephole2
17835   [(set (match_operand 0 "flags_reg_operand" "")
17836         (match_operator 1 "compare_operator"
17837           [(and:SI
17838              (zero_extract:SI
17839                (match_operand 2 "ext_register_operand" "")
17840                (const_int 8)
17841                (const_int 8))
17842              (match_operand 3 "const_int_operand" ""))
17843            (const_int 0)]))]
17844   "! TARGET_PARTIAL_REG_STALL
17845    && ix86_match_ccmode (insn, CCNOmode)
17846    && true_regnum (operands[2]) != AX_REG
17847    && peep2_reg_dead_p (1, operands[2])"
17848   [(parallel [(set (match_dup 0)
17849                    (match_op_dup 1
17850                      [(and:SI
17851                         (zero_extract:SI
17852                           (match_dup 2)
17853                           (const_int 8)
17854                           (const_int 8))
17855                         (match_dup 3))
17856                       (const_int 0)]))
17857               (set (zero_extract:SI (match_dup 2)
17858                                     (const_int 8)
17859                                     (const_int 8))
17860                    (and:SI
17861                      (zero_extract:SI
17862                        (match_dup 2)
17863                        (const_int 8)
17864                        (const_int 8))
17865                      (match_dup 3)))])]
17866   "")
17867
17868 ;; Don't do logical operations with memory inputs.
17869 (define_peephole2
17870   [(match_scratch:SI 2 "r")
17871    (parallel [(set (match_operand:SI 0 "register_operand" "")
17872                    (match_operator:SI 3 "arith_or_logical_operator"
17873                      [(match_dup 0)
17874                       (match_operand:SI 1 "memory_operand" "")]))
17875               (clobber (reg:CC FLAGS_REG))])]
17876   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
17877   [(set (match_dup 2) (match_dup 1))
17878    (parallel [(set (match_dup 0)
17879                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17880               (clobber (reg:CC FLAGS_REG))])]
17881   "")
17882
17883 (define_peephole2
17884   [(match_scratch:SI 2 "r")
17885    (parallel [(set (match_operand:SI 0 "register_operand" "")
17886                    (match_operator:SI 3 "arith_or_logical_operator"
17887                      [(match_operand:SI 1 "memory_operand" "")
17888                       (match_dup 0)]))
17889               (clobber (reg:CC FLAGS_REG))])]
17890   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
17891   [(set (match_dup 2) (match_dup 1))
17892    (parallel [(set (match_dup 0)
17893                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17894               (clobber (reg:CC FLAGS_REG))])]
17895   "")
17896
17897 ;; Prefer Load+RegOp to Mov+MemOp.  Watch out for cases when the memory address
17898 ;; refers to the destination of the load!
17899
17900 (define_peephole2
17901   [(set (match_operand:SI 0 "register_operand" "")
17902         (match_operand:SI 1 "register_operand" ""))
17903    (parallel [(set (match_dup 0)
17904                    (match_operator:SI 3 "commutative_operator"
17905                      [(match_dup 0)
17906                       (match_operand:SI 2 "memory_operand" "")]))
17907               (clobber (reg:CC FLAGS_REG))])]
17908   "REGNO (operands[0]) != REGNO (operands[1])
17909    && GENERAL_REGNO_P (REGNO (operands[0]))
17910    && GENERAL_REGNO_P (REGNO (operands[1]))"
17911   [(set (match_dup 0) (match_dup 4))
17912    (parallel [(set (match_dup 0)
17913                    (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17914               (clobber (reg:CC FLAGS_REG))])]
17915   "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17916
17917 (define_peephole2
17918   [(set (match_operand 0 "register_operand" "")
17919         (match_operand 1 "register_operand" ""))
17920    (set (match_dup 0)
17921                    (match_operator 3 "commutative_operator"
17922                      [(match_dup 0)
17923                       (match_operand 2 "memory_operand" "")]))]
17924   "REGNO (operands[0]) != REGNO (operands[1])
17925    && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1])) 
17926        || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17927   [(set (match_dup 0) (match_dup 2))
17928    (set (match_dup 0)
17929         (match_op_dup 3 [(match_dup 0) (match_dup 1)]))]
17930   "")
17931
17932 ; Don't do logical operations with memory outputs
17933 ;
17934 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17935 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
17936 ; the same decoder scheduling characteristics as the original.
17937
17938 (define_peephole2
17939   [(match_scratch:SI 2 "r")
17940    (parallel [(set (match_operand:SI 0 "memory_operand" "")
17941                    (match_operator:SI 3 "arith_or_logical_operator"
17942                      [(match_dup 0)
17943                       (match_operand:SI 1 "nonmemory_operand" "")]))
17944               (clobber (reg:CC FLAGS_REG))])]
17945   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
17946    /* Do not split stack checking probes.  */
17947    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17948   [(set (match_dup 2) (match_dup 0))
17949    (parallel [(set (match_dup 2)
17950                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17951               (clobber (reg:CC FLAGS_REG))])
17952    (set (match_dup 0) (match_dup 2))]
17953   "")
17954
17955 (define_peephole2
17956   [(match_scratch:SI 2 "r")
17957    (parallel [(set (match_operand:SI 0 "memory_operand" "")
17958                    (match_operator:SI 3 "arith_or_logical_operator"
17959                      [(match_operand:SI 1 "nonmemory_operand" "")
17960                       (match_dup 0)]))
17961               (clobber (reg:CC FLAGS_REG))])]
17962   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
17963    /* Do not split stack checking probes.  */
17964    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17965   [(set (match_dup 2) (match_dup 0))
17966    (parallel [(set (match_dup 2)
17967                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17968               (clobber (reg:CC FLAGS_REG))])
17969    (set (match_dup 0) (match_dup 2))]
17970   "")
17971
17972 ;; Attempt to always use XOR for zeroing registers.
17973 (define_peephole2
17974   [(set (match_operand 0 "register_operand" "")
17975         (match_operand 1 "const0_operand" ""))]
17976   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17977    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17978    && GENERAL_REG_P (operands[0])
17979    && peep2_regno_dead_p (0, FLAGS_REG)"
17980   [(parallel [(set (match_dup 0) (const_int 0))
17981               (clobber (reg:CC FLAGS_REG))])]
17982 {
17983   operands[0] = gen_lowpart (word_mode, operands[0]);
17984 })
17985
17986 (define_peephole2
17987   [(set (strict_low_part (match_operand 0 "register_operand" ""))
17988         (const_int 0))]
17989   "(GET_MODE (operands[0]) == QImode
17990     || GET_MODE (operands[0]) == HImode)
17991    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17992    && peep2_regno_dead_p (0, FLAGS_REG)"
17993   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17994               (clobber (reg:CC FLAGS_REG))])])
17995
17996 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
17997 (define_peephole2
17998   [(set (match_operand 0 "register_operand" "")
17999         (const_int -1))]
18000   "(GET_MODE (operands[0]) == HImode
18001     || GET_MODE (operands[0]) == SImode
18002     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
18003    && (optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
18004    && peep2_regno_dead_p (0, FLAGS_REG)"
18005   [(parallel [(set (match_dup 0) (const_int -1))
18006               (clobber (reg:CC FLAGS_REG))])]
18007   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
18008                               operands[0]);")
18009
18010 ;; Attempt to convert simple leas to adds. These can be created by
18011 ;; move expanders.
18012 (define_peephole2
18013   [(set (match_operand:SI 0 "register_operand" "")
18014         (plus:SI (match_dup 0)
18015                  (match_operand:SI 1 "nonmemory_operand" "")))]
18016   "peep2_regno_dead_p (0, FLAGS_REG)"
18017   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
18018               (clobber (reg:CC FLAGS_REG))])]
18019   "")
18020
18021 (define_peephole2
18022   [(set (match_operand:SI 0 "register_operand" "")
18023         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
18024                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
18025   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
18026   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
18027               (clobber (reg:CC FLAGS_REG))])]
18028   "operands[2] = gen_lowpart (SImode, operands[2]);")
18029
18030 (define_peephole2
18031   [(set (match_operand:DI 0 "register_operand" "")
18032         (plus:DI (match_dup 0)
18033                  (match_operand:DI 1 "x86_64_general_operand" "")))]
18034   "peep2_regno_dead_p (0, FLAGS_REG)"
18035   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
18036               (clobber (reg:CC FLAGS_REG))])]
18037   "")
18038
18039 (define_peephole2
18040   [(set (match_operand:SI 0 "register_operand" "")
18041         (mult:SI (match_dup 0)
18042                  (match_operand:SI 1 "const_int_operand" "")))]
18043   "exact_log2 (INTVAL (operands[1])) >= 0
18044    && peep2_regno_dead_p (0, FLAGS_REG)"
18045   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
18046               (clobber (reg:CC FLAGS_REG))])]
18047   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
18048
18049 (define_peephole2
18050   [(set (match_operand:DI 0 "register_operand" "")
18051         (mult:DI (match_dup 0)
18052                  (match_operand:DI 1 "const_int_operand" "")))]
18053   "exact_log2 (INTVAL (operands[1])) >= 0
18054    && peep2_regno_dead_p (0, FLAGS_REG)"
18055   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
18056               (clobber (reg:CC FLAGS_REG))])]
18057   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
18058
18059 (define_peephole2
18060   [(set (match_operand:SI 0 "register_operand" "")
18061         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
18062                    (match_operand:DI 2 "const_int_operand" "")) 0))]
18063   "exact_log2 (INTVAL (operands[2])) >= 0
18064    && REGNO (operands[0]) == REGNO (operands[1])
18065    && peep2_regno_dead_p (0, FLAGS_REG)"
18066   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
18067               (clobber (reg:CC FLAGS_REG))])]
18068   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
18069
18070 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
18071 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
18072 ;; many CPUs it is also faster, since special hardware to avoid esp
18073 ;; dependencies is present.
18074
18075 ;; While some of these conversions may be done using splitters, we use peepholes
18076 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
18077
18078 ;; Convert prologue esp subtractions to push.
18079 ;; We need register to push.  In order to keep verify_flow_info happy we have
18080 ;; two choices
18081 ;; - use scratch and clobber it in order to avoid dependencies
18082 ;; - use already live register
18083 ;; We can't use the second way right now, since there is no reliable way how to
18084 ;; verify that given register is live.  First choice will also most likely in
18085 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
18086 ;; call clobbered registers are dead.  We may want to use base pointer as an
18087 ;; alternative when no register is available later.
18088
18089 (define_peephole2
18090   [(match_scratch:SI 0 "r")
18091    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
18092               (clobber (reg:CC FLAGS_REG))
18093               (clobber (mem:BLK (scratch)))])]
18094   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
18095   [(clobber (match_dup 0))
18096    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
18097               (clobber (mem:BLK (scratch)))])])
18098
18099 (define_peephole2
18100   [(match_scratch:SI 0 "r")
18101    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
18102               (clobber (reg:CC FLAGS_REG))
18103               (clobber (mem:BLK (scratch)))])]
18104   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
18105   [(clobber (match_dup 0))
18106    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
18107    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
18108               (clobber (mem:BLK (scratch)))])])
18109
18110 ;; Convert esp subtractions to push.
18111 (define_peephole2
18112   [(match_scratch:SI 0 "r")
18113    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
18114               (clobber (reg:CC FLAGS_REG))])]
18115   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
18116   [(clobber (match_dup 0))
18117    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
18118
18119 (define_peephole2
18120   [(match_scratch:SI 0 "r")
18121    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
18122               (clobber (reg:CC FLAGS_REG))])]
18123   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
18124   [(clobber (match_dup 0))
18125    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
18126    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
18127
18128 ;; Convert epilogue deallocator to pop.
18129 (define_peephole2
18130   [(match_scratch:SI 0 "r")
18131    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
18132               (clobber (reg:CC FLAGS_REG))
18133               (clobber (mem:BLK (scratch)))])]
18134   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
18135   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18136               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
18137               (clobber (mem:BLK (scratch)))])]
18138   "")
18139
18140 ;; Two pops case is tricky, since pop causes dependency on destination register.
18141 ;; We use two registers if available.
18142 (define_peephole2
18143   [(match_scratch:SI 0 "r")
18144    (match_scratch:SI 1 "r")
18145    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
18146               (clobber (reg:CC FLAGS_REG))
18147               (clobber (mem:BLK (scratch)))])]
18148   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
18149   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18150               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
18151               (clobber (mem:BLK (scratch)))])
18152    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
18153               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
18154   "")
18155
18156 (define_peephole2
18157   [(match_scratch:SI 0 "r")
18158    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
18159               (clobber (reg:CC FLAGS_REG))
18160               (clobber (mem:BLK (scratch)))])]
18161   "optimize_insn_for_size_p ()"
18162   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18163               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
18164               (clobber (mem:BLK (scratch)))])
18165    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18166               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
18167   "")
18168
18169 ;; Convert esp additions to pop.
18170 (define_peephole2
18171   [(match_scratch:SI 0 "r")
18172    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
18173               (clobber (reg:CC FLAGS_REG))])]
18174   ""
18175   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18176               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
18177   "")
18178
18179 ;; Two pops case is tricky, since pop causes dependency on destination register.
18180 ;; We use two registers if available.
18181 (define_peephole2
18182   [(match_scratch:SI 0 "r")
18183    (match_scratch:SI 1 "r")
18184    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
18185               (clobber (reg:CC FLAGS_REG))])]
18186   ""
18187   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18188               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
18189    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
18190               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
18191   "")
18192
18193 (define_peephole2
18194   [(match_scratch:SI 0 "r")
18195    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
18196               (clobber (reg:CC FLAGS_REG))])]
18197   "optimize_insn_for_size_p ()"
18198   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18199               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
18200    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18201               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
18202   "")
18203 \f
18204 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
18205 ;; required and register dies.  Similarly for 128 to -128.
18206 (define_peephole2
18207   [(set (match_operand 0 "flags_reg_operand" "")
18208         (match_operator 1 "compare_operator"
18209           [(match_operand 2 "register_operand" "")
18210            (match_operand 3 "const_int_operand" "")]))]
18211   "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
18212      && incdec_operand (operands[3], GET_MODE (operands[3])))
18213     || (!TARGET_FUSE_CMP_AND_BRANCH
18214         && INTVAL (operands[3]) == 128))
18215    && ix86_match_ccmode (insn, CCGCmode)
18216    && peep2_reg_dead_p (1, operands[2])"
18217   [(parallel [(set (match_dup 0)
18218                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
18219               (clobber (match_dup 2))])]
18220   "")
18221 \f
18222 (define_peephole2
18223   [(match_scratch:DI 0 "r")
18224    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
18225               (clobber (reg:CC FLAGS_REG))
18226               (clobber (mem:BLK (scratch)))])]
18227   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
18228   [(clobber (match_dup 0))
18229    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
18230               (clobber (mem:BLK (scratch)))])])
18231
18232 (define_peephole2
18233   [(match_scratch:DI 0 "r")
18234    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
18235               (clobber (reg:CC FLAGS_REG))
18236               (clobber (mem:BLK (scratch)))])]
18237   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
18238   [(clobber (match_dup 0))
18239    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
18240    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
18241               (clobber (mem:BLK (scratch)))])])
18242
18243 ;; Convert esp subtractions to push.
18244 (define_peephole2
18245   [(match_scratch:DI 0 "r")
18246    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
18247               (clobber (reg:CC FLAGS_REG))])]
18248   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
18249   [(clobber (match_dup 0))
18250    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
18251
18252 (define_peephole2
18253   [(match_scratch:DI 0 "r")
18254    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
18255               (clobber (reg:CC FLAGS_REG))])]
18256   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
18257   [(clobber (match_dup 0))
18258    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
18259    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
18260
18261 ;; Convert epilogue deallocator to pop.
18262 (define_peephole2
18263   [(match_scratch:DI 0 "r")
18264    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
18265               (clobber (reg:CC FLAGS_REG))
18266               (clobber (mem:BLK (scratch)))])]
18267   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
18268   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18269               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
18270               (clobber (mem:BLK (scratch)))])]
18271   "")
18272
18273 ;; Two pops case is tricky, since pop causes dependency on destination register.
18274 ;; We use two registers if available.
18275 (define_peephole2
18276   [(match_scratch:DI 0 "r")
18277    (match_scratch:DI 1 "r")
18278    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
18279               (clobber (reg:CC FLAGS_REG))
18280               (clobber (mem:BLK (scratch)))])]
18281   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
18282   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18283               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
18284               (clobber (mem:BLK (scratch)))])
18285    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
18286               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
18287   "")
18288
18289 (define_peephole2
18290   [(match_scratch:DI 0 "r")
18291    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
18292               (clobber (reg:CC FLAGS_REG))
18293               (clobber (mem:BLK (scratch)))])]
18294   "optimize_insn_for_size_p ()"
18295   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18296               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
18297               (clobber (mem:BLK (scratch)))])
18298    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18299               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
18300   "")
18301
18302 ;; Convert esp additions to pop.
18303 (define_peephole2
18304   [(match_scratch:DI 0 "r")
18305    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
18306               (clobber (reg:CC FLAGS_REG))])]
18307   ""
18308   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18309               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
18310   "")
18311
18312 ;; Two pops case is tricky, since pop causes dependency on destination register.
18313 ;; We use two registers if available.
18314 (define_peephole2
18315   [(match_scratch:DI 0 "r")
18316    (match_scratch:DI 1 "r")
18317    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
18318               (clobber (reg:CC FLAGS_REG))])]
18319   ""
18320   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18321               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
18322    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
18323               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
18324   "")
18325
18326 (define_peephole2
18327   [(match_scratch:DI 0 "r")
18328    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
18329               (clobber (reg:CC FLAGS_REG))])]
18330   "optimize_insn_for_size_p ()"
18331   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18332               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
18333    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18334               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
18335   "")
18336 \f
18337 ;; Convert imul by three, five and nine into lea
18338 (define_peephole2
18339   [(parallel
18340     [(set (match_operand:SI 0 "register_operand" "")
18341           (mult:SI (match_operand:SI 1 "register_operand" "")
18342                    (match_operand:SI 2 "const_int_operand" "")))
18343      (clobber (reg:CC FLAGS_REG))])]
18344   "INTVAL (operands[2]) == 3
18345    || INTVAL (operands[2]) == 5
18346    || INTVAL (operands[2]) == 9"
18347   [(set (match_dup 0)
18348         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
18349                  (match_dup 1)))]
18350   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
18351
18352 (define_peephole2
18353   [(parallel
18354     [(set (match_operand:SI 0 "register_operand" "")
18355           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
18356                    (match_operand:SI 2 "const_int_operand" "")))
18357      (clobber (reg:CC FLAGS_REG))])]
18358   "optimize_insn_for_speed_p ()
18359    && (INTVAL (operands[2]) == 3
18360        || INTVAL (operands[2]) == 5
18361        || INTVAL (operands[2]) == 9)"
18362   [(set (match_dup 0) (match_dup 1))
18363    (set (match_dup 0)
18364         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
18365                  (match_dup 0)))]
18366   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
18367
18368 (define_peephole2
18369   [(parallel
18370     [(set (match_operand:DI 0 "register_operand" "")
18371           (mult:DI (match_operand:DI 1 "register_operand" "")
18372                    (match_operand:DI 2 "const_int_operand" "")))
18373      (clobber (reg:CC FLAGS_REG))])]
18374   "TARGET_64BIT
18375    && (INTVAL (operands[2]) == 3
18376        || INTVAL (operands[2]) == 5
18377        || INTVAL (operands[2]) == 9)"
18378   [(set (match_dup 0)
18379         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
18380                  (match_dup 1)))]
18381   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
18382
18383 (define_peephole2
18384   [(parallel
18385     [(set (match_operand:DI 0 "register_operand" "")
18386           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
18387                    (match_operand:DI 2 "const_int_operand" "")))
18388      (clobber (reg:CC FLAGS_REG))])]
18389   "TARGET_64BIT
18390    && optimize_insn_for_speed_p ()
18391    && (INTVAL (operands[2]) == 3
18392        || INTVAL (operands[2]) == 5
18393        || INTVAL (operands[2]) == 9)"
18394   [(set (match_dup 0) (match_dup 1))
18395    (set (match_dup 0)
18396         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
18397                  (match_dup 0)))]
18398   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
18399
18400 ;; Imul $32bit_imm, mem, reg is vector decoded, while
18401 ;; imul $32bit_imm, reg, reg is direct decoded.
18402 (define_peephole2
18403   [(match_scratch:DI 3 "r")
18404    (parallel [(set (match_operand:DI 0 "register_operand" "")
18405                    (mult:DI (match_operand:DI 1 "memory_operand" "")
18406                             (match_operand:DI 2 "immediate_operand" "")))
18407               (clobber (reg:CC FLAGS_REG))])]
18408   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
18409    && !satisfies_constraint_K (operands[2])"
18410   [(set (match_dup 3) (match_dup 1))
18411    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
18412               (clobber (reg:CC FLAGS_REG))])]
18413 "")
18414
18415 (define_peephole2
18416   [(match_scratch:SI 3 "r")
18417    (parallel [(set (match_operand:SI 0 "register_operand" "")
18418                    (mult:SI (match_operand:SI 1 "memory_operand" "")
18419                             (match_operand:SI 2 "immediate_operand" "")))
18420               (clobber (reg:CC FLAGS_REG))])]
18421   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
18422    && !satisfies_constraint_K (operands[2])"
18423   [(set (match_dup 3) (match_dup 1))
18424    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
18425               (clobber (reg:CC FLAGS_REG))])]
18426 "")
18427
18428 (define_peephole2
18429   [(match_scratch:SI 3 "r")
18430    (parallel [(set (match_operand:DI 0 "register_operand" "")
18431                    (zero_extend:DI
18432                      (mult:SI (match_operand:SI 1 "memory_operand" "")
18433                               (match_operand:SI 2 "immediate_operand" ""))))
18434               (clobber (reg:CC FLAGS_REG))])]
18435   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
18436    && !satisfies_constraint_K (operands[2])"
18437   [(set (match_dup 3) (match_dup 1))
18438    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
18439               (clobber (reg:CC FLAGS_REG))])]
18440 "")
18441
18442 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
18443 ;; Convert it into imul reg, reg
18444 ;; It would be better to force assembler to encode instruction using long
18445 ;; immediate, but there is apparently no way to do so.
18446 (define_peephole2
18447   [(parallel [(set (match_operand:DI 0 "register_operand" "")
18448                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
18449                             (match_operand:DI 2 "const_int_operand" "")))
18450               (clobber (reg:CC FLAGS_REG))])
18451    (match_scratch:DI 3 "r")]
18452   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
18453    && satisfies_constraint_K (operands[2])"
18454   [(set (match_dup 3) (match_dup 2))
18455    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
18456               (clobber (reg:CC FLAGS_REG))])]
18457 {
18458   if (!rtx_equal_p (operands[0], operands[1]))
18459     emit_move_insn (operands[0], operands[1]);
18460 })
18461
18462 (define_peephole2
18463   [(parallel [(set (match_operand:SI 0 "register_operand" "")
18464                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
18465                             (match_operand:SI 2 "const_int_operand" "")))
18466               (clobber (reg:CC FLAGS_REG))])
18467    (match_scratch:SI 3 "r")]
18468   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
18469    && satisfies_constraint_K (operands[2])"
18470   [(set (match_dup 3) (match_dup 2))
18471    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
18472               (clobber (reg:CC FLAGS_REG))])]
18473 {
18474   if (!rtx_equal_p (operands[0], operands[1]))
18475     emit_move_insn (operands[0], operands[1]);
18476 })
18477
18478 (define_peephole2
18479   [(parallel [(set (match_operand:HI 0 "register_operand" "")
18480                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
18481                             (match_operand:HI 2 "immediate_operand" "")))
18482               (clobber (reg:CC FLAGS_REG))])
18483    (match_scratch:HI 3 "r")]
18484   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()"
18485   [(set (match_dup 3) (match_dup 2))
18486    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
18487               (clobber (reg:CC FLAGS_REG))])]
18488 {
18489   if (!rtx_equal_p (operands[0], operands[1]))
18490     emit_move_insn (operands[0], operands[1]);
18491 })
18492
18493 ;; After splitting up read-modify operations, array accesses with memory
18494 ;; operands might end up in form:
18495 ;;  sall    $2, %eax
18496 ;;  movl    4(%esp), %edx
18497 ;;  addl    %edx, %eax
18498 ;; instead of pre-splitting:
18499 ;;  sall    $2, %eax
18500 ;;  addl    4(%esp), %eax
18501 ;; Turn it into:
18502 ;;  movl    4(%esp), %edx
18503 ;;  leal    (%edx,%eax,4), %eax
18504
18505 (define_peephole2
18506   [(parallel [(set (match_operand 0 "register_operand" "")
18507                    (ashift (match_operand 1 "register_operand" "")
18508                            (match_operand 2 "const_int_operand" "")))
18509                (clobber (reg:CC FLAGS_REG))])
18510    (set (match_operand 3 "register_operand")
18511         (match_operand 4 "x86_64_general_operand" ""))
18512    (parallel [(set (match_operand 5 "register_operand" "")
18513                    (plus (match_operand 6 "register_operand" "")
18514                          (match_operand 7 "register_operand" "")))
18515                    (clobber (reg:CC FLAGS_REG))])]
18516   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
18517    /* Validate MODE for lea.  */
18518    && ((!TARGET_PARTIAL_REG_STALL
18519         && (GET_MODE (operands[0]) == QImode
18520             || GET_MODE (operands[0]) == HImode))
18521        || GET_MODE (operands[0]) == SImode
18522        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
18523    /* We reorder load and the shift.  */
18524    && !rtx_equal_p (operands[1], operands[3])
18525    && !reg_overlap_mentioned_p (operands[0], operands[4])
18526    /* Last PLUS must consist of operand 0 and 3.  */
18527    && !rtx_equal_p (operands[0], operands[3])
18528    && (rtx_equal_p (operands[3], operands[6])
18529        || rtx_equal_p (operands[3], operands[7]))
18530    && (rtx_equal_p (operands[0], operands[6])
18531        || rtx_equal_p (operands[0], operands[7]))
18532    /* The intermediate operand 0 must die or be same as output.  */
18533    && (rtx_equal_p (operands[0], operands[5])
18534        || peep2_reg_dead_p (3, operands[0]))"
18535   [(set (match_dup 3) (match_dup 4))
18536    (set (match_dup 0) (match_dup 1))]
18537 {
18538   enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
18539   int scale = 1 << INTVAL (operands[2]);
18540   rtx index = gen_lowpart (Pmode, operands[1]);
18541   rtx base = gen_lowpart (Pmode, operands[3]);
18542   rtx dest = gen_lowpart (mode, operands[5]);
18543
18544   operands[1] = gen_rtx_PLUS (Pmode, base,
18545                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
18546   if (mode != Pmode)
18547     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
18548   operands[0] = dest;
18549 })
18550 \f
18551 ;; Call-value patterns last so that the wildcard operand does not
18552 ;; disrupt insn-recog's switch tables.
18553
18554 (define_insn "*call_value_pop_0"
18555   [(set (match_operand 0 "" "")
18556         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
18557               (match_operand:SI 2 "" "")))
18558    (set (reg:SI SP_REG)
18559         (plus:SI (reg:SI SP_REG)
18560                  (match_operand:SI 3 "immediate_operand" "")))]
18561   "!TARGET_64BIT"
18562 {
18563   if (SIBLING_CALL_P (insn))
18564     return "jmp\t%P1";
18565   else
18566     return "call\t%P1";
18567 }
18568   [(set_attr "type" "callv")])
18569
18570 (define_insn "*call_value_pop_1"
18571   [(set (match_operand 0 "" "")
18572         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
18573               (match_operand:SI 2 "" "")))
18574    (set (reg:SI SP_REG)
18575         (plus:SI (reg:SI SP_REG)
18576                  (match_operand:SI 3 "immediate_operand" "i")))]
18577   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
18578 {
18579   if (constant_call_address_operand (operands[1], Pmode))
18580     return "call\t%P1";
18581   return "call\t%A1";
18582 }
18583   [(set_attr "type" "callv")])
18584
18585 (define_insn "*sibcall_value_pop_1"
18586   [(set (match_operand 0 "" "")
18587         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
18588               (match_operand:SI 2 "" "")))
18589    (set (reg:SI SP_REG)
18590         (plus:SI (reg:SI SP_REG)
18591                  (match_operand:SI 3 "immediate_operand" "i,i")))]
18592   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
18593   "@
18594    jmp\t%P1
18595    jmp\t%A1"
18596   [(set_attr "type" "callv")])
18597
18598 (define_insn "*call_value_0"
18599   [(set (match_operand 0 "" "")
18600         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
18601               (match_operand:SI 2 "" "")))]
18602   "!TARGET_64BIT"
18603 {
18604   if (SIBLING_CALL_P (insn))
18605     return "jmp\t%P1";
18606   else
18607     return "call\t%P1";
18608 }
18609   [(set_attr "type" "callv")])
18610
18611 (define_insn "*call_value_0_rex64"
18612   [(set (match_operand 0 "" "")
18613         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
18614               (match_operand:DI 2 "const_int_operand" "")))]
18615   "TARGET_64BIT"
18616 {
18617   if (SIBLING_CALL_P (insn))
18618     return "jmp\t%P1";
18619   else
18620     return "call\t%P1";
18621 }
18622   [(set_attr "type" "callv")])
18623
18624 (define_insn "*call_value_0_rex64_ms_sysv"
18625   [(set (match_operand 0 "" "")
18626         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
18627               (match_operand:DI 2 "const_int_operand" "")))
18628    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
18629    (clobber (reg:TI XMM6_REG))
18630    (clobber (reg:TI XMM7_REG))
18631    (clobber (reg:TI XMM8_REG))
18632    (clobber (reg:TI XMM9_REG))
18633    (clobber (reg:TI XMM10_REG))
18634    (clobber (reg:TI XMM11_REG))
18635    (clobber (reg:TI XMM12_REG))
18636    (clobber (reg:TI XMM13_REG))
18637    (clobber (reg:TI XMM14_REG))
18638    (clobber (reg:TI XMM15_REG))
18639    (clobber (reg:DI SI_REG))
18640    (clobber (reg:DI DI_REG))]
18641   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
18642 {
18643   if (SIBLING_CALL_P (insn))
18644     return "jmp\t%P1";
18645   else
18646     return "call\t%P1";
18647 }
18648   [(set_attr "type" "callv")])
18649
18650 (define_insn "*call_value_1"
18651   [(set (match_operand 0 "" "")
18652         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
18653               (match_operand:SI 2 "" "")))]
18654   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
18655 {
18656   if (constant_call_address_operand (operands[1], Pmode))
18657     return "call\t%P1";
18658   return "call\t%A1";
18659 }
18660   [(set_attr "type" "callv")])
18661
18662 (define_insn "*sibcall_value_1"
18663   [(set (match_operand 0 "" "")
18664         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
18665               (match_operand:SI 2 "" "")))]
18666   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
18667   "@
18668    jmp\t%P1
18669    jmp\t%A1"
18670   [(set_attr "type" "callv")])
18671
18672 (define_insn "*call_value_1_rex64"
18673   [(set (match_operand 0 "" "")
18674         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
18675               (match_operand:DI 2 "" "")))]
18676   "TARGET_64BIT && !SIBLING_CALL_P (insn)
18677    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
18678 {
18679   if (constant_call_address_operand (operands[1], Pmode))
18680     return "call\t%P1";
18681   return "call\t%A1";
18682 }
18683   [(set_attr "type" "callv")])
18684
18685 (define_insn "*call_value_1_rex64_ms_sysv"
18686   [(set (match_operand 0 "" "")
18687         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
18688               (match_operand:DI 2 "" "")))
18689    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
18690    (clobber (reg:TI XMM6_REG))
18691    (clobber (reg:TI XMM7_REG))
18692    (clobber (reg:TI XMM8_REG))
18693    (clobber (reg:TI XMM9_REG))
18694    (clobber (reg:TI XMM10_REG))
18695    (clobber (reg:TI XMM11_REG))
18696    (clobber (reg:TI XMM12_REG))
18697    (clobber (reg:TI XMM13_REG))
18698    (clobber (reg:TI XMM14_REG))
18699    (clobber (reg:TI XMM15_REG))
18700    (clobber (reg:DI SI_REG))
18701    (clobber (reg:DI DI_REG))]
18702   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
18703 {
18704   if (constant_call_address_operand (operands[1], Pmode))
18705     return "call\t%P1";
18706   return "call\t%A1";
18707 }
18708   [(set_attr "type" "callv")])
18709
18710 (define_insn "*call_value_1_rex64_large"
18711   [(set (match_operand 0 "" "")
18712         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
18713               (match_operand:DI 2 "" "")))]
18714   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
18715   "call\t%A1"
18716   [(set_attr "type" "callv")])
18717
18718 (define_insn "*sibcall_value_1_rex64"
18719   [(set (match_operand 0 "" "")
18720         (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
18721               (match_operand:DI 2 "" "")))]
18722   "TARGET_64BIT && SIBLING_CALL_P (insn)"
18723   "@
18724    jmp\t%P1
18725    jmp\t%A1"
18726   [(set_attr "type" "callv")])
18727 \f
18728 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
18729 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
18730 ;; caught for use by garbage collectors and the like.  Using an insn that
18731 ;; maps to SIGILL makes it more likely the program will rightfully die.
18732 ;; Keeping with tradition, "6" is in honor of #UD.
18733 (define_insn "trap"
18734   [(trap_if (const_int 1) (const_int 6))]
18735   ""
18736   { return ASM_SHORT "0x0b0f"; }
18737   [(set_attr "length" "2")])
18738
18739 (define_expand "sse_prologue_save"
18740   [(parallel [(set (match_operand:BLK 0 "" "")
18741                    (unspec:BLK [(reg:DI XMM0_REG)
18742                                 (reg:DI XMM1_REG)
18743                                 (reg:DI XMM2_REG)
18744                                 (reg:DI XMM3_REG)
18745                                 (reg:DI XMM4_REG)
18746                                 (reg:DI XMM5_REG)
18747                                 (reg:DI XMM6_REG)
18748                                 (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE))
18749               (use (match_operand:DI 1 "register_operand" ""))
18750               (use (match_operand:DI 2 "immediate_operand" ""))
18751               (use (label_ref:DI (match_operand 3 "" "")))])]
18752   "TARGET_64BIT"
18753   "")
18754
18755 (define_insn "*sse_prologue_save_insn"
18756   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
18757                           (match_operand:DI 4 "const_int_operand" "n")))
18758         (unspec:BLK [(reg:DI XMM0_REG)
18759                      (reg:DI XMM1_REG)
18760                      (reg:DI XMM2_REG)
18761                      (reg:DI XMM3_REG)
18762                      (reg:DI XMM4_REG)
18763                      (reg:DI XMM5_REG)
18764                      (reg:DI XMM6_REG)
18765                      (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE))
18766    (use (match_operand:DI 1 "register_operand" "r"))
18767    (use (match_operand:DI 2 "const_int_operand" "i"))
18768    (use (label_ref:DI (match_operand 3 "" "X")))]
18769   "TARGET_64BIT
18770    && INTVAL (operands[4]) + X86_64_SSE_REGPARM_MAX * 16 - 16 < 128
18771    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
18772 {
18773   int i;
18774   operands[0] = gen_rtx_MEM (Pmode,
18775                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
18776   /* VEX instruction with a REX prefix will #UD.  */
18777   if (TARGET_AVX && GET_CODE (XEXP (operands[0], 0)) != PLUS)
18778     gcc_unreachable ();
18779
18780   output_asm_insn ("jmp\t%A1", operands);
18781   for (i = X86_64_SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
18782     {
18783       operands[4] = adjust_address (operands[0], DImode, i*16);
18784       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
18785       PUT_MODE (operands[4], TImode);
18786       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
18787         output_asm_insn ("rex", operands);
18788       output_asm_insn ("%vmovaps\t{%5, %4|%4, %5}", operands);
18789     }
18790   (*targetm.asm_out.internal_label) (asm_out_file, "L",
18791                                      CODE_LABEL_NUMBER (operands[3]));
18792   return "";
18793 }
18794   [(set_attr "type" "other")
18795    (set_attr "length_immediate" "0")
18796    (set_attr "length_address" "0")
18797    (set (attr "length")
18798      (if_then_else
18799        (eq (symbol_ref "TARGET_AVX") (const_int 0))
18800        (const_string "34")
18801        (const_string "42")))
18802    (set_attr "memory" "store")
18803    (set_attr "modrm" "0")
18804    (set_attr "prefix" "maybe_vex")
18805    (set_attr "mode" "DI")])
18806
18807 (define_expand "prefetch"
18808   [(prefetch (match_operand 0 "address_operand" "")
18809              (match_operand:SI 1 "const_int_operand" "")
18810              (match_operand:SI 2 "const_int_operand" ""))]
18811   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
18812 {
18813   int rw = INTVAL (operands[1]);
18814   int locality = INTVAL (operands[2]);
18815
18816   gcc_assert (rw == 0 || rw == 1);
18817   gcc_assert (locality >= 0 && locality <= 3);
18818   gcc_assert (GET_MODE (operands[0]) == Pmode
18819               || GET_MODE (operands[0]) == VOIDmode);
18820
18821   /* Use 3dNOW prefetch in case we are asking for write prefetch not
18822      supported by SSE counterpart or the SSE prefetch is not available
18823      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
18824      of locality.  */
18825   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
18826     operands[2] = GEN_INT (3);
18827   else
18828     operands[1] = const0_rtx;
18829 })
18830
18831 (define_insn "*prefetch_sse"
18832   [(prefetch (match_operand:SI 0 "address_operand" "p")
18833              (const_int 0)
18834              (match_operand:SI 1 "const_int_operand" ""))]
18835   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
18836 {
18837   static const char * const patterns[4] = {
18838    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
18839   };
18840
18841   int locality = INTVAL (operands[1]);
18842   gcc_assert (locality >= 0 && locality <= 3);
18843
18844   return patterns[locality];
18845 }
18846   [(set_attr "type" "sse")
18847    (set_attr "atom_sse_attr" "prefetch")
18848    (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
18849    (set_attr "memory" "none")])
18850
18851 (define_insn "*prefetch_sse_rex"
18852   [(prefetch (match_operand:DI 0 "address_operand" "p")
18853              (const_int 0)
18854              (match_operand:SI 1 "const_int_operand" ""))]
18855   "TARGET_PREFETCH_SSE && TARGET_64BIT"
18856 {
18857   static const char * const patterns[4] = {
18858    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
18859   };
18860
18861   int locality = INTVAL (operands[1]);
18862   gcc_assert (locality >= 0 && locality <= 3);
18863
18864   return patterns[locality];
18865 }
18866   [(set_attr "type" "sse")
18867    (set_attr "atom_sse_attr" "prefetch")
18868    (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
18869    (set_attr "memory" "none")])
18870
18871 (define_insn "*prefetch_3dnow"
18872   [(prefetch (match_operand:SI 0 "address_operand" "p")
18873              (match_operand:SI 1 "const_int_operand" "n")
18874              (const_int 3))]
18875   "TARGET_3DNOW && !TARGET_64BIT"
18876 {
18877   if (INTVAL (operands[1]) == 0)
18878     return "prefetch\t%a0";
18879   else
18880     return "prefetchw\t%a0";
18881 }
18882   [(set_attr "type" "mmx")
18883    (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
18884    (set_attr "memory" "none")])
18885
18886 (define_insn "*prefetch_3dnow_rex"
18887   [(prefetch (match_operand:DI 0 "address_operand" "p")
18888              (match_operand:SI 1 "const_int_operand" "n")
18889              (const_int 3))]
18890   "TARGET_3DNOW && TARGET_64BIT"
18891 {
18892   if (INTVAL (operands[1]) == 0)
18893     return "prefetch\t%a0";
18894   else
18895     return "prefetchw\t%a0";
18896 }
18897   [(set_attr "type" "mmx")
18898    (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
18899    (set_attr "memory" "none")])
18900
18901 (define_expand "stack_protect_set"
18902   [(match_operand 0 "memory_operand" "")
18903    (match_operand 1 "memory_operand" "")]
18904   ""
18905 {
18906 #ifdef TARGET_THREAD_SSP_OFFSET
18907   if (TARGET_64BIT)
18908     emit_insn (gen_stack_tls_protect_set_di (operands[0],
18909                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
18910   else
18911     emit_insn (gen_stack_tls_protect_set_si (operands[0],
18912                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
18913 #else
18914   if (TARGET_64BIT)
18915     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
18916   else
18917     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
18918 #endif
18919   DONE;
18920 })
18921
18922 (define_insn "stack_protect_set_si"
18923   [(set (match_operand:SI 0 "memory_operand" "=m")
18924         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
18925    (set (match_scratch:SI 2 "=&r") (const_int 0))
18926    (clobber (reg:CC FLAGS_REG))]
18927   ""
18928   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
18929   [(set_attr "type" "multi")])
18930
18931 (define_insn "stack_protect_set_di"
18932   [(set (match_operand:DI 0 "memory_operand" "=m")
18933         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
18934    (set (match_scratch:DI 2 "=&r") (const_int 0))
18935    (clobber (reg:CC FLAGS_REG))]
18936   "TARGET_64BIT"
18937   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
18938   [(set_attr "type" "multi")])
18939
18940 (define_insn "stack_tls_protect_set_si"
18941   [(set (match_operand:SI 0 "memory_operand" "=m")
18942         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
18943    (set (match_scratch:SI 2 "=&r") (const_int 0))
18944    (clobber (reg:CC FLAGS_REG))]
18945   ""
18946   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
18947   [(set_attr "type" "multi")])
18948
18949 (define_insn "stack_tls_protect_set_di"
18950   [(set (match_operand:DI 0 "memory_operand" "=m")
18951         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
18952    (set (match_scratch:DI 2 "=&r") (const_int 0))
18953    (clobber (reg:CC FLAGS_REG))]
18954   "TARGET_64BIT"
18955   {
18956      /* The kernel uses a different segment register for performance reasons; a
18957         system call would not have to trash the userspace segment register,
18958         which would be expensive */
18959      if (ix86_cmodel != CM_KERNEL)
18960         return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
18961      else
18962         return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
18963   }
18964   [(set_attr "type" "multi")])
18965
18966 (define_expand "stack_protect_test"
18967   [(match_operand 0 "memory_operand" "")
18968    (match_operand 1 "memory_operand" "")
18969    (match_operand 2 "" "")]
18970   ""
18971 {
18972   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
18973
18974 #ifdef TARGET_THREAD_SSP_OFFSET
18975   if (TARGET_64BIT)
18976     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
18977                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
18978   else
18979     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
18980                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
18981 #else
18982   if (TARGET_64BIT)
18983     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
18984   else
18985     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
18986 #endif
18987
18988   emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
18989                                   flags, const0_rtx, operands[2]));
18990   DONE;
18991 })
18992
18993 (define_insn "stack_protect_test_si"
18994   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
18995         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
18996                      (match_operand:SI 2 "memory_operand" "m")]
18997                     UNSPEC_SP_TEST))
18998    (clobber (match_scratch:SI 3 "=&r"))]
18999   ""
19000   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
19001   [(set_attr "type" "multi")])
19002
19003 (define_insn "stack_protect_test_di"
19004   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
19005         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
19006                      (match_operand:DI 2 "memory_operand" "m")]
19007                     UNSPEC_SP_TEST))
19008    (clobber (match_scratch:DI 3 "=&r"))]
19009   "TARGET_64BIT"
19010   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
19011   [(set_attr "type" "multi")])
19012
19013 (define_insn "stack_tls_protect_test_si"
19014   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
19015         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
19016                      (match_operand:SI 2 "const_int_operand" "i")]
19017                     UNSPEC_SP_TLS_TEST))
19018    (clobber (match_scratch:SI 3 "=r"))]
19019   ""
19020   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
19021   [(set_attr "type" "multi")])
19022
19023 (define_insn "stack_tls_protect_test_di"
19024   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
19025         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
19026                      (match_operand:DI 2 "const_int_operand" "i")]
19027                     UNSPEC_SP_TLS_TEST))
19028    (clobber (match_scratch:DI 3 "=r"))]
19029   "TARGET_64BIT"
19030   {
19031      /* The kernel uses a different segment register for performance reasons; a
19032         system call would not have to trash the userspace segment register,
19033         which would be expensive */
19034      if (ix86_cmodel != CM_KERNEL)
19035         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
19036      else
19037         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
19038   }
19039   [(set_attr "type" "multi")])
19040
19041 (define_insn "sse4_2_crc32<mode>"
19042   [(set (match_operand:SI 0 "register_operand" "=r")
19043         (unspec:SI
19044           [(match_operand:SI 1 "register_operand" "0")
19045            (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
19046           UNSPEC_CRC32))]
19047   "TARGET_SSE4_2 || TARGET_CRC32"
19048   "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
19049   [(set_attr "type" "sselog1")
19050    (set_attr "prefix_rep" "1")
19051    (set_attr "prefix_extra" "1")
19052    (set (attr "prefix_data16")
19053      (if_then_else (match_operand:HI 2 "" "")
19054        (const_string "1")
19055        (const_string "*")))
19056    (set (attr "prefix_rex")
19057      (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
19058        (const_string "1")
19059        (const_string "*")))
19060    (set_attr "mode" "SI")])
19061
19062 (define_insn "sse4_2_crc32di"
19063   [(set (match_operand:DI 0 "register_operand" "=r")
19064         (unspec:DI
19065           [(match_operand:DI 1 "register_operand" "0")
19066            (match_operand:DI 2 "nonimmediate_operand" "rm")]
19067           UNSPEC_CRC32))]
19068   "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
19069   "crc32{q}\t{%2, %0|%0, %2}"
19070   [(set_attr "type" "sselog1")
19071    (set_attr "prefix_rep" "1")
19072    (set_attr "prefix_extra" "1")
19073    (set_attr "mode" "DI")])
19074
19075 (define_expand "rdpmc"
19076   [(match_operand:DI 0 "register_operand" "")
19077    (match_operand:SI 1 "register_operand" "")]
19078   ""
19079 {
19080   rtx reg = gen_reg_rtx (DImode);
19081   rtx si;
19082
19083   /* Force operand 1 into ECX.  */
19084   rtx ecx = gen_rtx_REG (SImode, CX_REG);
19085   emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
19086   si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
19087                                 UNSPECV_RDPMC);
19088
19089   if (TARGET_64BIT)
19090     {
19091       rtvec vec = rtvec_alloc (2);
19092       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
19093       rtx upper = gen_reg_rtx (DImode);
19094       rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
19095                                         gen_rtvec (1, const0_rtx),
19096                                         UNSPECV_RDPMC);
19097       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
19098       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
19099       emit_insn (load);
19100       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
19101                                    NULL, 1, OPTAB_DIRECT);
19102       reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
19103                                  OPTAB_DIRECT);
19104     }
19105   else
19106     emit_insn (gen_rtx_SET (VOIDmode, reg, si));
19107   emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
19108   DONE;
19109 })
19110
19111 (define_insn "*rdpmc"
19112   [(set (match_operand:DI 0 "register_operand" "=A")
19113         (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
19114                             UNSPECV_RDPMC))]
19115   "!TARGET_64BIT"
19116   "rdpmc"
19117   [(set_attr "type" "other")
19118    (set_attr "length" "2")])
19119
19120 (define_insn "*rdpmc_rex64"
19121   [(set (match_operand:DI 0 "register_operand" "=a")
19122         (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
19123                             UNSPECV_RDPMC))
19124   (set (match_operand:DI 1 "register_operand" "=d")
19125        (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
19126   "TARGET_64BIT"
19127   "rdpmc"
19128   [(set_attr "type" "other")
19129    (set_attr "length" "2")])
19130
19131 (define_expand "rdtsc"
19132   [(set (match_operand:DI 0 "register_operand" "")
19133         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
19134   ""
19135 {
19136   if (TARGET_64BIT)
19137     {
19138       rtvec vec = rtvec_alloc (2);
19139       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
19140       rtx upper = gen_reg_rtx (DImode);
19141       rtx lower = gen_reg_rtx (DImode);
19142       rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
19143                                          gen_rtvec (1, const0_rtx),
19144                                          UNSPECV_RDTSC);
19145       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
19146       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
19147       emit_insn (load);
19148       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
19149                                    NULL, 1, OPTAB_DIRECT);
19150       lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
19151                                    OPTAB_DIRECT);
19152       emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
19153       DONE;
19154     }
19155 })
19156
19157 (define_insn "*rdtsc"
19158   [(set (match_operand:DI 0 "register_operand" "=A")
19159         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
19160   "!TARGET_64BIT"
19161   "rdtsc"
19162   [(set_attr "type" "other")
19163    (set_attr "length" "2")])
19164
19165 (define_insn "*rdtsc_rex64"
19166   [(set (match_operand:DI 0 "register_operand" "=a")
19167         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
19168    (set (match_operand:DI 1 "register_operand" "=d")
19169         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
19170   "TARGET_64BIT"
19171   "rdtsc"
19172   [(set_attr "type" "other")
19173    (set_attr "length" "2")])
19174
19175 (define_expand "rdtscp"
19176   [(match_operand:DI 0 "register_operand" "")
19177    (match_operand:SI 1 "memory_operand" "")]
19178   ""
19179 {
19180   rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
19181                                     gen_rtvec (1, const0_rtx),
19182                                     UNSPECV_RDTSCP);
19183   rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
19184                                     gen_rtvec (1, const0_rtx),
19185                                     UNSPECV_RDTSCP);
19186   rtx reg = gen_reg_rtx (DImode);
19187   rtx tmp = gen_reg_rtx (SImode);
19188
19189   if (TARGET_64BIT)
19190     {
19191       rtvec vec = rtvec_alloc (3);
19192       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
19193       rtx upper = gen_reg_rtx (DImode);
19194       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
19195       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
19196       RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
19197       emit_insn (load);
19198       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
19199                                    NULL, 1, OPTAB_DIRECT);
19200       reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
19201                                  OPTAB_DIRECT);
19202     }
19203   else
19204     {
19205       rtvec vec = rtvec_alloc (2);
19206       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
19207       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
19208       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
19209       emit_insn (load);
19210     }
19211   emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
19212   emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
19213   DONE;
19214 })
19215
19216 (define_insn "*rdtscp"
19217   [(set (match_operand:DI 0 "register_operand" "=A")
19218         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
19219    (set (match_operand:SI 1 "register_operand" "=c")
19220         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
19221   "!TARGET_64BIT"
19222   "rdtscp"
19223   [(set_attr "type" "other")
19224    (set_attr "length" "3")])
19225
19226 (define_insn "*rdtscp_rex64"
19227   [(set (match_operand:DI 0 "register_operand" "=a")
19228         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
19229    (set (match_operand:DI 1 "register_operand" "=d")
19230         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
19231    (set (match_operand:SI 2 "register_operand" "=c")
19232         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
19233   "TARGET_64BIT"
19234   "rdtscp"
19235   [(set_attr "type" "other")
19236    (set_attr "length" "3")])
19237
19238 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19239 ;;
19240 ;; LWP instructions
19241 ;;
19242 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19243
19244 (define_expand "lwp_llwpcb"
19245   [(unspec_volatile [(match_operand 0 "register_operand" "r")]
19246                     UNSPECV_LLWP_INTRINSIC)]
19247   "TARGET_LWP"
19248   "")
19249
19250 (define_insn "*lwp_llwpcb<mode>1"
19251   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
19252                     UNSPECV_LLWP_INTRINSIC)]
19253   "TARGET_LWP"
19254   "llwpcb\t%0"
19255   [(set_attr "type" "lwp")
19256    (set_attr "mode" "<MODE>")
19257    (set_attr "length" "5")])
19258
19259 (define_expand "lwp_slwpcb"
19260   [(set (match_operand 0 "register_operand" "=r")
19261         (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
19262   "TARGET_LWP"
19263   {
19264     if (TARGET_64BIT)
19265       emit_insn (gen_lwp_slwpcbdi (operands[0]));
19266     else
19267       emit_insn (gen_lwp_slwpcbsi (operands[0]));
19268     DONE;
19269   })
19270
19271 (define_insn "lwp_slwpcb<mode>"
19272   [(set (match_operand:P 0 "register_operand" "=r")
19273         (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
19274   "TARGET_LWP"
19275   "slwpcb\t%0"
19276   [(set_attr "type" "lwp")
19277    (set_attr "mode" "<MODE>")
19278    (set_attr "length" "5")])
19279
19280 (define_expand "lwp_lwpval<mode>3"
19281   [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
19282                      (match_operand:SI 2 "nonimmediate_operand" "rm")
19283                      (match_operand:SI 3 "const_int_operand" "i")]
19284                     UNSPECV_LWPVAL_INTRINSIC)]
19285   "TARGET_LWP"
19286   "/* Avoid unused variable warning.  */
19287    (void) operand0;")
19288
19289 (define_insn "*lwp_lwpval<mode>3_1"
19290   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
19291                      (match_operand:SI 1 "nonimmediate_operand" "rm")
19292                      (match_operand:SI 2 "const_int_operand" "i")]
19293                     UNSPECV_LWPVAL_INTRINSIC)]
19294   "TARGET_LWP"
19295   "lwpval\t{%2, %1, %0|%0, %1, %2}"
19296   [(set_attr "type" "lwp")
19297    (set_attr "mode" "<MODE>")
19298    (set (attr "length")
19299         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
19300
19301 (define_expand "lwp_lwpins<mode>3"
19302   [(set (reg:CCC FLAGS_REG)
19303         (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
19304                               (match_operand:SI 2 "nonimmediate_operand" "rm")
19305                               (match_operand:SI 3 "const_int_operand" "i")]
19306                              UNSPECV_LWPINS_INTRINSIC))
19307    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
19308         (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
19309   "TARGET_LWP"
19310   "")
19311
19312 (define_insn "*lwp_lwpins<mode>3_1"
19313   [(set (reg:CCC FLAGS_REG)
19314         (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
19315                               (match_operand:SI 1 "nonimmediate_operand" "rm")
19316                               (match_operand:SI 2 "const_int_operand" "i")]
19317                              UNSPECV_LWPINS_INTRINSIC))]
19318   "TARGET_LWP"
19319   "lwpins\t{%2, %1, %0|%0, %1, %2}"
19320   [(set_attr "type" "lwp")
19321    (set_attr "mode" "<MODE>")
19322    (set (attr "length")
19323         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
19324
19325 (include "mmx.md")
19326 (include "sse.md")
19327 (include "sync.md")