OSDN Git Service

PR target/43707
[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 abs neg operators
728 (define_code_iterator absneg [abs neg])
729
730 ;; Base name for x87 insn mnemonic.
731 (define_code_attr absnegprefix [(abs "abs") (neg "chs")])
732
733 ;; Used in signed and unsigned widening multiplications.
734 (define_code_iterator any_extend [sign_extend zero_extend])
735
736 ;; Various insn prefixes for signed and unsigned operations.
737 (define_code_attr u [(sign_extend "") (zero_extend "u")
738                      (div "") (udiv "u")])
739 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
740
741 ;; Used in signed and unsigned divisions.
742 (define_code_iterator any_div [div udiv])
743
744 ;; Instruction prefix for signed and unsigned operations.
745 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")
746                              (div "i") (udiv "")])
747
748 ;; All single word integer modes.
749 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
750
751 ;; Single word integer modes without DImode.
752 (define_mode_iterator SWI124 [QI HI SI])
753
754 ;; Single word integer modes without QImode.
755 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
756
757 ;; Single word integer modes without QImode and HImode.
758 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
759
760 ;; All math-dependant single and double word integer modes.
761 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
762                              (HI "TARGET_HIMODE_MATH")
763                              SI DI (TI "TARGET_64BIT")])
764
765 ;; Math-dependant single word integer modes.
766 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
767                             (HI "TARGET_HIMODE_MATH")
768                             SI (DI "TARGET_64BIT")])
769
770 ;; Math-dependant single word integer modes without QImode.
771 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
772                                SI (DI "TARGET_64BIT")])
773
774 ;; Double word integer modes.
775 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
776                            (TI "TARGET_64BIT")])
777
778 ;; Double word integer modes as mode attribute.
779 (define_mode_attr DWI [(SI "DI") (DI "TI")])
780 (define_mode_attr dwi [(SI "di") (DI "ti")])
781
782 ;; Half mode for double word integer modes.
783 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
784                             (DI "TARGET_64BIT")])
785
786 ;; Instruction suffix for integer modes.
787 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
788
789 ;; Register class for integer modes.
790 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
791
792 ;; Immediate operand constraint for integer modes.
793 (define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")])
794
795 ;; General operand constraint for word modes.
796 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "g") (DI "rme")])
797
798 ;; Immediate operand constraint for double integer modes.
799 (define_mode_attr di [(SI "iF") (DI "e")])
800
801 ;; Immediate operand constraint for shifts.
802 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
803
804 ;; General operand predicate for integer modes.
805 (define_mode_attr general_operand
806         [(QI "general_operand")
807          (HI "general_operand")
808          (SI "general_operand")
809          (DI "x86_64_general_operand")
810          (TI "x86_64_general_operand")])
811
812 ;; General sign/zero extend operand predicate for integer modes.
813 (define_mode_attr general_szext_operand
814         [(QI "general_operand")
815          (HI "general_operand")
816          (SI "general_operand")
817          (DI "x86_64_szext_general_operand")])
818
819 ;; Operand predicate for shifts.
820 (define_mode_attr shift_operand
821         [(QI "nonimmediate_operand")
822          (HI "nonimmediate_operand")
823          (SI "nonimmediate_operand")
824          (DI "shiftdi_operand")
825          (TI "register_operand")])
826
827 ;; Operand predicate for shift argument.
828 (define_mode_attr shift_immediate_operand
829         [(QI "const_1_to_31_operand")
830          (HI "const_1_to_31_operand")
831          (SI "const_1_to_31_operand")
832          (DI "const_1_to_63_operand")])
833
834 ;; Input operand predicate for arithmetic left shifts.
835 (define_mode_attr ashl_input_operand
836         [(QI "nonimmediate_operand")
837          (HI "nonimmediate_operand")
838          (SI "nonimmediate_operand")
839          (DI "ashldi_input_operand")
840          (TI "reg_or_pm1_operand")])
841
842 ;; SSE and x87 SFmode and DFmode floating point modes
843 (define_mode_iterator MODEF [SF DF])
844
845 ;; All x87 floating point modes
846 (define_mode_iterator X87MODEF [SF DF XF])
847
848 ;; All integer modes handled by x87 fisttp operator.
849 (define_mode_iterator X87MODEI [HI SI DI])
850
851 ;; All integer modes handled by integer x87 operators.
852 (define_mode_iterator X87MODEI12 [HI SI])
853
854 ;; All integer modes handled by SSE cvtts?2si* operators.
855 (define_mode_iterator SSEMODEI24 [SI DI])
856
857 ;; SSE asm suffix for floating point modes
858 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
859
860 ;; SSE vector mode corresponding to a scalar mode
861 (define_mode_attr ssevecmode
862   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
863
864 ;; Instruction suffix for REX 64bit operators.
865 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
866
867 ;; This mode iterator allows :P to be used for patterns that operate on
868 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
869 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
870 \f
871 ;; Scheduling descriptions
872
873 (include "pentium.md")
874 (include "ppro.md")
875 (include "k6.md")
876 (include "athlon.md")
877 (include "geode.md")
878 (include "atom.md")
879
880 \f
881 ;; Operand and operator predicates and constraints
882
883 (include "predicates.md")
884 (include "constraints.md")
885
886 \f
887 ;; Compare and branch/compare and store instructions.
888
889 (define_expand "cbranch<mode>4"
890   [(set (reg:CC FLAGS_REG)
891         (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
892                     (match_operand:SDWIM 2 "<general_operand>" "")))
893    (set (pc) (if_then_else
894                (match_operator 0 "comparison_operator"
895                 [(reg:CC FLAGS_REG) (const_int 0)])
896                (label_ref (match_operand 3 "" ""))
897                (pc)))]
898   ""
899 {
900   if (MEM_P (operands[1]) && MEM_P (operands[2]))
901     operands[1] = force_reg (<MODE>mode, operands[1]);
902   ix86_compare_op0 = operands[1];
903   ix86_compare_op1 = operands[2];
904   ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
905   DONE;
906 })
907
908 (define_expand "cstore<mode>4"
909   [(set (reg:CC FLAGS_REG)
910         (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
911                     (match_operand:SWIM 3 "<general_operand>" "")))
912    (set (match_operand:QI 0 "register_operand" "")
913         (match_operator 1 "comparison_operator"
914           [(reg:CC FLAGS_REG) (const_int 0)]))]
915   ""
916 {
917   if (MEM_P (operands[2]) && MEM_P (operands[3]))
918     operands[2] = force_reg (<MODE>mode, operands[2]);
919   ix86_compare_op0 = operands[2];
920   ix86_compare_op1 = operands[3];
921   ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
922   DONE;
923 })
924
925 (define_expand "cmp<mode>_1"
926   [(set (reg:CC FLAGS_REG)
927         (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
928                     (match_operand:SWI48 1 "<general_operand>" "")))]
929   ""
930   "")
931
932 (define_insn "*cmp<mode>_ccno_1"
933   [(set (reg FLAGS_REG)
934         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
935                  (match_operand:SWI 1 "const0_operand" "")))]
936   "ix86_match_ccmode (insn, CCNOmode)"
937   "@
938    test{<imodesuffix>}\t%0, %0
939    cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
940   [(set_attr "type" "test,icmp")
941    (set_attr "length_immediate" "0,1")
942    (set_attr "mode" "<MODE>")])
943
944 (define_insn "*cmp<mode>_1"
945   [(set (reg FLAGS_REG)
946         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
947                  (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
948   "ix86_match_ccmode (insn, CCmode)"
949   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
950   [(set_attr "type" "icmp")
951    (set_attr "mode" "<MODE>")])
952
953 (define_insn "*cmp<mode>_minus_1"
954   [(set (reg FLAGS_REG)
955         (compare
956           (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
957                      (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
958           (const_int 0)))]
959   "ix86_match_ccmode (insn, CCGOCmode)"
960   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
961   [(set_attr "type" "icmp")
962    (set_attr "mode" "<MODE>")])
963
964 (define_insn "*cmpqi_ext_1"
965   [(set (reg FLAGS_REG)
966         (compare
967           (match_operand:QI 0 "general_operand" "Qm")
968           (subreg:QI
969             (zero_extract:SI
970               (match_operand 1 "ext_register_operand" "Q")
971               (const_int 8)
972               (const_int 8)) 0)))]
973   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
974   "cmp{b}\t{%h1, %0|%0, %h1}"
975   [(set_attr "type" "icmp")
976    (set_attr "mode" "QI")])
977
978 (define_insn "*cmpqi_ext_1_rex64"
979   [(set (reg FLAGS_REG)
980         (compare
981           (match_operand:QI 0 "register_operand" "Q")
982           (subreg:QI
983             (zero_extract:SI
984               (match_operand 1 "ext_register_operand" "Q")
985               (const_int 8)
986               (const_int 8)) 0)))]
987   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
988   "cmp{b}\t{%h1, %0|%0, %h1}"
989   [(set_attr "type" "icmp")
990    (set_attr "mode" "QI")])
991
992 (define_insn "*cmpqi_ext_2"
993   [(set (reg FLAGS_REG)
994         (compare
995           (subreg:QI
996             (zero_extract:SI
997               (match_operand 0 "ext_register_operand" "Q")
998               (const_int 8)
999               (const_int 8)) 0)
1000           (match_operand:QI 1 "const0_operand" "")))]
1001   "ix86_match_ccmode (insn, CCNOmode)"
1002   "test{b}\t%h0, %h0"
1003   [(set_attr "type" "test")
1004    (set_attr "length_immediate" "0")
1005    (set_attr "mode" "QI")])
1006
1007 (define_expand "cmpqi_ext_3"
1008   [(set (reg:CC FLAGS_REG)
1009         (compare:CC
1010           (subreg:QI
1011             (zero_extract:SI
1012               (match_operand 0 "ext_register_operand" "")
1013               (const_int 8)
1014               (const_int 8)) 0)
1015           (match_operand:QI 1 "immediate_operand" "")))]
1016   ""
1017   "")
1018
1019 (define_insn "*cmpqi_ext_3_insn"
1020   [(set (reg FLAGS_REG)
1021         (compare
1022           (subreg:QI
1023             (zero_extract:SI
1024               (match_operand 0 "ext_register_operand" "Q")
1025               (const_int 8)
1026               (const_int 8)) 0)
1027           (match_operand:QI 1 "general_operand" "Qmn")))]
1028   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1029   "cmp{b}\t{%1, %h0|%h0, %1}"
1030   [(set_attr "type" "icmp")
1031    (set_attr "modrm" "1")
1032    (set_attr "mode" "QI")])
1033
1034 (define_insn "*cmpqi_ext_3_insn_rex64"
1035   [(set (reg FLAGS_REG)
1036         (compare
1037           (subreg:QI
1038             (zero_extract:SI
1039               (match_operand 0 "ext_register_operand" "Q")
1040               (const_int 8)
1041               (const_int 8)) 0)
1042           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1043   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1044   "cmp{b}\t{%1, %h0|%h0, %1}"
1045   [(set_attr "type" "icmp")
1046    (set_attr "modrm" "1")
1047    (set_attr "mode" "QI")])
1048
1049 (define_insn "*cmpqi_ext_4"
1050   [(set (reg FLAGS_REG)
1051         (compare
1052           (subreg:QI
1053             (zero_extract:SI
1054               (match_operand 0 "ext_register_operand" "Q")
1055               (const_int 8)
1056               (const_int 8)) 0)
1057           (subreg:QI
1058             (zero_extract:SI
1059               (match_operand 1 "ext_register_operand" "Q")
1060               (const_int 8)
1061               (const_int 8)) 0)))]
1062   "ix86_match_ccmode (insn, CCmode)"
1063   "cmp{b}\t{%h1, %h0|%h0, %h1}"
1064   [(set_attr "type" "icmp")
1065    (set_attr "mode" "QI")])
1066
1067 ;; These implement float point compares.
1068 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1069 ;; which would allow mix and match FP modes on the compares.  Which is what
1070 ;; the old patterns did, but with many more of them.
1071
1072 (define_expand "cbranchxf4"
1073   [(set (reg:CC FLAGS_REG)
1074         (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1075                     (match_operand:XF 2 "nonmemory_operand" "")))
1076    (set (pc) (if_then_else
1077               (match_operator 0 "ix86_fp_comparison_operator"
1078                [(reg:CC FLAGS_REG)
1079                 (const_int 0)])
1080               (label_ref (match_operand 3 "" ""))
1081               (pc)))]
1082   "TARGET_80387"
1083 {
1084   ix86_compare_op0 = operands[1];
1085   ix86_compare_op1 = operands[2];
1086   ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1087   DONE;
1088 })
1089
1090 (define_expand "cstorexf4"
1091   [(set (reg:CC FLAGS_REG)
1092         (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1093                     (match_operand:XF 3 "nonmemory_operand" "")))
1094    (set (match_operand:QI 0 "register_operand" "")
1095               (match_operator 1 "ix86_fp_comparison_operator"
1096                [(reg:CC FLAGS_REG)
1097                 (const_int 0)]))]
1098   "TARGET_80387"
1099 {
1100   ix86_compare_op0 = operands[2];
1101   ix86_compare_op1 = operands[3];
1102   ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1103   DONE;
1104 })
1105
1106 (define_expand "cbranch<mode>4"
1107   [(set (reg:CC FLAGS_REG)
1108         (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1109                     (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1110    (set (pc) (if_then_else
1111               (match_operator 0 "ix86_fp_comparison_operator"
1112                [(reg:CC FLAGS_REG)
1113                 (const_int 0)])
1114               (label_ref (match_operand 3 "" ""))
1115               (pc)))]
1116   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1117 {
1118   ix86_compare_op0 = operands[1];
1119   ix86_compare_op1 = operands[2];
1120   ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1121   DONE;
1122 })
1123
1124 (define_expand "cstore<mode>4"
1125   [(set (reg:CC FLAGS_REG)
1126         (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1127                     (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1128    (set (match_operand:QI 0 "register_operand" "")
1129               (match_operator 1 "ix86_fp_comparison_operator"
1130                [(reg:CC FLAGS_REG)
1131                 (const_int 0)]))]
1132   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1133 {
1134   ix86_compare_op0 = operands[2];
1135   ix86_compare_op1 = operands[3];
1136   ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1137   DONE;
1138 })
1139
1140 (define_expand "cbranchcc4"
1141   [(set (pc) (if_then_else
1142               (match_operator 0 "comparison_operator"
1143                [(match_operand 1 "flags_reg_operand" "")
1144                 (match_operand 2 "const0_operand" "")])
1145               (label_ref (match_operand 3 "" ""))
1146               (pc)))]
1147   ""
1148 {
1149   ix86_compare_op0 = operands[1];
1150   ix86_compare_op1 = operands[2];
1151   ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1152   DONE;
1153 })
1154
1155 (define_expand "cstorecc4"
1156   [(set (match_operand:QI 0 "register_operand" "")
1157               (match_operator 1 "comparison_operator"
1158                [(match_operand 2 "flags_reg_operand" "")
1159                 (match_operand 3 "const0_operand" "")]))]
1160   ""
1161 {
1162   ix86_compare_op0 = operands[2];
1163   ix86_compare_op1 = operands[3];
1164   ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1165   DONE;
1166 })
1167
1168
1169 ;; FP compares, step 1:
1170 ;; Set the FP condition codes.
1171 ;;
1172 ;; CCFPmode     compare with exceptions
1173 ;; CCFPUmode    compare with no exceptions
1174
1175 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1176 ;; used to manage the reg stack popping would not be preserved.
1177
1178 (define_insn "*cmpfp_0"
1179   [(set (match_operand:HI 0 "register_operand" "=a")
1180         (unspec:HI
1181           [(compare:CCFP
1182              (match_operand 1 "register_operand" "f")
1183              (match_operand 2 "const0_operand" ""))]
1184         UNSPEC_FNSTSW))]
1185   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1186    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1187   "* return output_fp_compare (insn, operands, 0, 0);"
1188   [(set_attr "type" "multi")
1189    (set_attr "unit" "i387")
1190    (set (attr "mode")
1191      (cond [(match_operand:SF 1 "" "")
1192               (const_string "SF")
1193             (match_operand:DF 1 "" "")
1194               (const_string "DF")
1195            ]
1196            (const_string "XF")))])
1197
1198 (define_insn_and_split "*cmpfp_0_cc"
1199   [(set (reg:CCFP FLAGS_REG)
1200         (compare:CCFP
1201           (match_operand 1 "register_operand" "f")
1202           (match_operand 2 "const0_operand" "")))
1203    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1204   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1205    && TARGET_SAHF && !TARGET_CMOVE
1206    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1207   "#"
1208   "&& reload_completed"
1209   [(set (match_dup 0)
1210         (unspec:HI
1211           [(compare:CCFP (match_dup 1)(match_dup 2))]
1212         UNSPEC_FNSTSW))
1213    (set (reg:CC FLAGS_REG)
1214         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1215   ""
1216   [(set_attr "type" "multi")
1217    (set_attr "unit" "i387")
1218    (set (attr "mode")
1219      (cond [(match_operand:SF 1 "" "")
1220               (const_string "SF")
1221             (match_operand:DF 1 "" "")
1222               (const_string "DF")
1223            ]
1224            (const_string "XF")))])
1225
1226 (define_insn "*cmpfp_xf"
1227   [(set (match_operand:HI 0 "register_operand" "=a")
1228         (unspec:HI
1229           [(compare:CCFP
1230              (match_operand:XF 1 "register_operand" "f")
1231              (match_operand:XF 2 "register_operand" "f"))]
1232           UNSPEC_FNSTSW))]
1233   "TARGET_80387"
1234   "* return output_fp_compare (insn, operands, 0, 0);"
1235   [(set_attr "type" "multi")
1236    (set_attr "unit" "i387")
1237    (set_attr "mode" "XF")])
1238
1239 (define_insn_and_split "*cmpfp_xf_cc"
1240   [(set (reg:CCFP FLAGS_REG)
1241         (compare:CCFP
1242           (match_operand:XF 1 "register_operand" "f")
1243           (match_operand:XF 2 "register_operand" "f")))
1244    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1245   "TARGET_80387
1246    && TARGET_SAHF && !TARGET_CMOVE"
1247   "#"
1248   "&& reload_completed"
1249   [(set (match_dup 0)
1250         (unspec:HI
1251           [(compare:CCFP (match_dup 1)(match_dup 2))]
1252         UNSPEC_FNSTSW))
1253    (set (reg:CC FLAGS_REG)
1254         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1255   ""
1256   [(set_attr "type" "multi")
1257    (set_attr "unit" "i387")
1258    (set_attr "mode" "XF")])
1259
1260 (define_insn "*cmpfp_<mode>"
1261   [(set (match_operand:HI 0 "register_operand" "=a")
1262         (unspec:HI
1263           [(compare:CCFP
1264              (match_operand:MODEF 1 "register_operand" "f")
1265              (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1266           UNSPEC_FNSTSW))]
1267   "TARGET_80387"
1268   "* return output_fp_compare (insn, operands, 0, 0);"
1269   [(set_attr "type" "multi")
1270    (set_attr "unit" "i387")
1271    (set_attr "mode" "<MODE>")])
1272
1273 (define_insn_and_split "*cmpfp_<mode>_cc"
1274   [(set (reg:CCFP FLAGS_REG)
1275         (compare:CCFP
1276           (match_operand:MODEF 1 "register_operand" "f")
1277           (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1278    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1279   "TARGET_80387
1280    && TARGET_SAHF && !TARGET_CMOVE"
1281   "#"
1282   "&& reload_completed"
1283   [(set (match_dup 0)
1284         (unspec:HI
1285           [(compare:CCFP (match_dup 1)(match_dup 2))]
1286         UNSPEC_FNSTSW))
1287    (set (reg:CC FLAGS_REG)
1288         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1289   ""
1290   [(set_attr "type" "multi")
1291    (set_attr "unit" "i387")
1292    (set_attr "mode" "<MODE>")])
1293
1294 (define_insn "*cmpfp_u"
1295   [(set (match_operand:HI 0 "register_operand" "=a")
1296         (unspec:HI
1297           [(compare:CCFPU
1298              (match_operand 1 "register_operand" "f")
1299              (match_operand 2 "register_operand" "f"))]
1300           UNSPEC_FNSTSW))]
1301   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1302    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1303   "* return output_fp_compare (insn, operands, 0, 1);"
1304   [(set_attr "type" "multi")
1305    (set_attr "unit" "i387")
1306    (set (attr "mode")
1307      (cond [(match_operand:SF 1 "" "")
1308               (const_string "SF")
1309             (match_operand:DF 1 "" "")
1310               (const_string "DF")
1311            ]
1312            (const_string "XF")))])
1313
1314 (define_insn_and_split "*cmpfp_u_cc"
1315   [(set (reg:CCFPU FLAGS_REG)
1316         (compare:CCFPU
1317           (match_operand 1 "register_operand" "f")
1318           (match_operand 2 "register_operand" "f")))
1319    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1320   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1321    && TARGET_SAHF && !TARGET_CMOVE
1322    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1323   "#"
1324   "&& reload_completed"
1325   [(set (match_dup 0)
1326         (unspec:HI
1327           [(compare:CCFPU (match_dup 1)(match_dup 2))]
1328         UNSPEC_FNSTSW))
1329    (set (reg:CC FLAGS_REG)
1330         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1331   ""
1332   [(set_attr "type" "multi")
1333    (set_attr "unit" "i387")
1334    (set (attr "mode")
1335      (cond [(match_operand:SF 1 "" "")
1336               (const_string "SF")
1337             (match_operand:DF 1 "" "")
1338               (const_string "DF")
1339            ]
1340            (const_string "XF")))])
1341
1342 (define_insn "*cmpfp_<mode>"
1343   [(set (match_operand:HI 0 "register_operand" "=a")
1344         (unspec:HI
1345           [(compare:CCFP
1346              (match_operand 1 "register_operand" "f")
1347              (match_operator 3 "float_operator"
1348                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1349           UNSPEC_FNSTSW))]
1350   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1351    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1352    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1353   "* return output_fp_compare (insn, operands, 0, 0);"
1354   [(set_attr "type" "multi")
1355    (set_attr "unit" "i387")
1356    (set_attr "fp_int_src" "true")
1357    (set_attr "mode" "<MODE>")])
1358
1359 (define_insn_and_split "*cmpfp_<mode>_cc"
1360   [(set (reg:CCFP FLAGS_REG)
1361         (compare:CCFP
1362           (match_operand 1 "register_operand" "f")
1363           (match_operator 3 "float_operator"
1364             [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1365    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1366   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1367    && TARGET_SAHF && !TARGET_CMOVE
1368    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1369    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1370   "#"
1371   "&& reload_completed"
1372   [(set (match_dup 0)
1373         (unspec:HI
1374           [(compare:CCFP
1375              (match_dup 1)
1376              (match_op_dup 3 [(match_dup 2)]))]
1377         UNSPEC_FNSTSW))
1378    (set (reg:CC FLAGS_REG)
1379         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1380   ""
1381   [(set_attr "type" "multi")
1382    (set_attr "unit" "i387")
1383    (set_attr "fp_int_src" "true")
1384    (set_attr "mode" "<MODE>")])
1385
1386 ;; FP compares, step 2
1387 ;; Move the fpsw to ax.
1388
1389 (define_insn "x86_fnstsw_1"
1390   [(set (match_operand:HI 0 "register_operand" "=a")
1391         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1392   "TARGET_80387"
1393   "fnstsw\t%0"
1394   [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1395    (set_attr "mode" "SI")
1396    (set_attr "unit" "i387")])
1397
1398 ;; FP compares, step 3
1399 ;; Get ax into flags, general case.
1400
1401 (define_insn "x86_sahf_1"
1402   [(set (reg:CC FLAGS_REG)
1403         (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1404                    UNSPEC_SAHF))]
1405   "TARGET_SAHF"
1406 {
1407 #ifdef HAVE_AS_IX86_SAHF
1408   return "sahf";
1409 #else
1410   return ASM_BYTE "0x9e";
1411 #endif
1412 }
1413   [(set_attr "length" "1")
1414    (set_attr "athlon_decode" "vector")
1415    (set_attr "amdfam10_decode" "direct")
1416    (set_attr "mode" "SI")])
1417
1418 ;; Pentium Pro can do steps 1 through 3 in one go.
1419 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1420 (define_insn "*cmpfp_i_mixed"
1421   [(set (reg:CCFP FLAGS_REG)
1422         (compare:CCFP (match_operand 0 "register_operand" "f,x")
1423                       (match_operand 1 "nonimmediate_operand" "f,xm")))]
1424   "TARGET_MIX_SSE_I387
1425    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1426    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1427   "* return output_fp_compare (insn, operands, 1, 0);"
1428   [(set_attr "type" "fcmp,ssecomi")
1429    (set_attr "prefix" "orig,maybe_vex")
1430    (set (attr "mode")
1431      (if_then_else (match_operand:SF 1 "" "")
1432         (const_string "SF")
1433         (const_string "DF")))
1434    (set (attr "prefix_rep")
1435         (if_then_else (eq_attr "type" "ssecomi")
1436                       (const_string "0")
1437                       (const_string "*")))
1438    (set (attr "prefix_data16")
1439         (cond [(eq_attr "type" "fcmp")
1440                  (const_string "*")
1441                (eq_attr "mode" "DF")
1442                  (const_string "1")
1443               ]
1444               (const_string "0")))
1445    (set_attr "athlon_decode" "vector")
1446    (set_attr "amdfam10_decode" "direct")])
1447
1448 (define_insn "*cmpfp_i_sse"
1449   [(set (reg:CCFP FLAGS_REG)
1450         (compare:CCFP (match_operand 0 "register_operand" "x")
1451                       (match_operand 1 "nonimmediate_operand" "xm")))]
1452   "TARGET_SSE_MATH
1453    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1454    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1455   "* return output_fp_compare (insn, operands, 1, 0);"
1456   [(set_attr "type" "ssecomi")
1457    (set_attr "prefix" "maybe_vex")
1458    (set (attr "mode")
1459      (if_then_else (match_operand:SF 1 "" "")
1460         (const_string "SF")
1461         (const_string "DF")))
1462    (set_attr "prefix_rep" "0")
1463    (set (attr "prefix_data16")
1464         (if_then_else (eq_attr "mode" "DF")
1465                       (const_string "1")
1466                       (const_string "0")))
1467    (set_attr "athlon_decode" "vector")
1468    (set_attr "amdfam10_decode" "direct")])
1469
1470 (define_insn "*cmpfp_i_i387"
1471   [(set (reg:CCFP FLAGS_REG)
1472         (compare:CCFP (match_operand 0 "register_operand" "f")
1473                       (match_operand 1 "register_operand" "f")))]
1474   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1475    && TARGET_CMOVE
1476    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1477    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1478   "* return output_fp_compare (insn, operands, 1, 0);"
1479   [(set_attr "type" "fcmp")
1480    (set (attr "mode")
1481      (cond [(match_operand:SF 1 "" "")
1482               (const_string "SF")
1483             (match_operand:DF 1 "" "")
1484               (const_string "DF")
1485            ]
1486            (const_string "XF")))
1487    (set_attr "athlon_decode" "vector")
1488    (set_attr "amdfam10_decode" "direct")])
1489
1490 (define_insn "*cmpfp_iu_mixed"
1491   [(set (reg:CCFPU FLAGS_REG)
1492         (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1493                        (match_operand 1 "nonimmediate_operand" "f,xm")))]
1494   "TARGET_MIX_SSE_I387
1495    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1496    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1497   "* return output_fp_compare (insn, operands, 1, 1);"
1498   [(set_attr "type" "fcmp,ssecomi")
1499    (set_attr "prefix" "orig,maybe_vex")
1500    (set (attr "mode")
1501      (if_then_else (match_operand:SF 1 "" "")
1502         (const_string "SF")
1503         (const_string "DF")))
1504    (set (attr "prefix_rep")
1505         (if_then_else (eq_attr "type" "ssecomi")
1506                       (const_string "0")
1507                       (const_string "*")))
1508    (set (attr "prefix_data16")
1509         (cond [(eq_attr "type" "fcmp")
1510                  (const_string "*")
1511                (eq_attr "mode" "DF")
1512                  (const_string "1")
1513               ]
1514               (const_string "0")))
1515    (set_attr "athlon_decode" "vector")
1516    (set_attr "amdfam10_decode" "direct")])
1517
1518 (define_insn "*cmpfp_iu_sse"
1519   [(set (reg:CCFPU FLAGS_REG)
1520         (compare:CCFPU (match_operand 0 "register_operand" "x")
1521                        (match_operand 1 "nonimmediate_operand" "xm")))]
1522   "TARGET_SSE_MATH
1523    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1524    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1525   "* return output_fp_compare (insn, operands, 1, 1);"
1526   [(set_attr "type" "ssecomi")
1527    (set_attr "prefix" "maybe_vex")
1528    (set (attr "mode")
1529      (if_then_else (match_operand:SF 1 "" "")
1530         (const_string "SF")
1531         (const_string "DF")))
1532    (set_attr "prefix_rep" "0")
1533    (set (attr "prefix_data16")
1534         (if_then_else (eq_attr "mode" "DF")
1535                       (const_string "1")
1536                       (const_string "0")))
1537    (set_attr "athlon_decode" "vector")
1538    (set_attr "amdfam10_decode" "direct")])
1539
1540 (define_insn "*cmpfp_iu_387"
1541   [(set (reg:CCFPU FLAGS_REG)
1542         (compare:CCFPU (match_operand 0 "register_operand" "f")
1543                        (match_operand 1 "register_operand" "f")))]
1544   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1545    && TARGET_CMOVE
1546    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1547    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1548   "* return output_fp_compare (insn, operands, 1, 1);"
1549   [(set_attr "type" "fcmp")
1550    (set (attr "mode")
1551      (cond [(match_operand:SF 1 "" "")
1552               (const_string "SF")
1553             (match_operand:DF 1 "" "")
1554               (const_string "DF")
1555            ]
1556            (const_string "XF")))
1557    (set_attr "athlon_decode" "vector")
1558    (set_attr "amdfam10_decode" "direct")])
1559 \f
1560 ;; Move instructions.
1561
1562 ;; General case of fullword move.
1563
1564 (define_expand "movsi"
1565   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1566         (match_operand:SI 1 "general_operand" ""))]
1567   ""
1568   "ix86_expand_move (SImode, operands); DONE;")
1569
1570 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1571 ;; general_operand.
1572 ;;
1573 ;; %%% We don't use a post-inc memory reference because x86 is not a
1574 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1575 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1576 ;; targets without our curiosities, and it is just as easy to represent
1577 ;; this differently.
1578
1579 (define_insn "*pushsi2"
1580   [(set (match_operand:SI 0 "push_operand" "=<")
1581         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1582   "!TARGET_64BIT"
1583   "push{l}\t%1"
1584   [(set_attr "type" "push")
1585    (set_attr "mode" "SI")])
1586
1587 ;; For 64BIT abi we always round up to 8 bytes.
1588 (define_insn "*pushsi2_rex64"
1589   [(set (match_operand:SI 0 "push_operand" "=X")
1590         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1591   "TARGET_64BIT"
1592   "push{q}\t%q1"
1593   [(set_attr "type" "push")
1594    (set_attr "mode" "SI")])
1595
1596 (define_insn "*pushsi2_prologue"
1597   [(set (match_operand:SI 0 "push_operand" "=<")
1598         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1599    (clobber (mem:BLK (scratch)))]
1600   "!TARGET_64BIT"
1601   "push{l}\t%1"
1602   [(set_attr "type" "push")
1603    (set_attr "mode" "SI")])
1604
1605 (define_insn "*popsi1_epilogue"
1606   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1607         (mem:SI (reg:SI SP_REG)))
1608    (set (reg:SI SP_REG)
1609         (plus:SI (reg:SI SP_REG) (const_int 4)))
1610    (clobber (mem:BLK (scratch)))]
1611   "!TARGET_64BIT"
1612   "pop{l}\t%0"
1613   [(set_attr "type" "pop")
1614    (set_attr "mode" "SI")])
1615
1616 (define_insn "popsi1"
1617   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1618         (mem:SI (reg:SI SP_REG)))
1619    (set (reg:SI SP_REG)
1620         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1621   "!TARGET_64BIT"
1622   "pop{l}\t%0"
1623   [(set_attr "type" "pop")
1624    (set_attr "mode" "SI")])
1625
1626 (define_insn "*movsi_xor"
1627   [(set (match_operand:SI 0 "register_operand" "=r")
1628         (match_operand:SI 1 "const0_operand" ""))
1629    (clobber (reg:CC FLAGS_REG))]
1630   "reload_completed"
1631   "xor{l}\t%0, %0"
1632   [(set_attr "type" "alu1")
1633    (set_attr "mode" "SI")
1634    (set_attr "length_immediate" "0")])
1635
1636 (define_insn "*movsi_or"
1637   [(set (match_operand:SI 0 "register_operand" "=r")
1638         (match_operand:SI 1 "immediate_operand" "i"))
1639    (clobber (reg:CC FLAGS_REG))]
1640   "reload_completed
1641    && operands[1] == constm1_rtx"
1642 {
1643   operands[1] = constm1_rtx;
1644   return "or{l}\t{%1, %0|%0, %1}";
1645 }
1646   [(set_attr "type" "alu1")
1647    (set_attr "mode" "SI")
1648    (set_attr "length_immediate" "1")])
1649
1650 (define_insn "*movsi_1"
1651   [(set (match_operand:SI 0 "nonimmediate_operand"
1652                         "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1653         (match_operand:SI 1 "general_operand"
1654                         "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r   ,m "))]
1655   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1656 {
1657   switch (get_attr_type (insn))
1658     {
1659     case TYPE_SSELOG1:
1660       if (get_attr_mode (insn) == MODE_TI)
1661         return "%vpxor\t%0, %d0";
1662       return "%vxorps\t%0, %d0";
1663
1664     case TYPE_SSEMOV:
1665       switch (get_attr_mode (insn))
1666         {
1667         case MODE_TI:
1668           return "%vmovdqa\t{%1, %0|%0, %1}";
1669         case MODE_V4SF:
1670           return "%vmovaps\t{%1, %0|%0, %1}";
1671         case MODE_SI:
1672           return "%vmovd\t{%1, %0|%0, %1}";
1673         case MODE_SF:
1674           return "%vmovss\t{%1, %0|%0, %1}";
1675         default:
1676           gcc_unreachable ();
1677         }
1678
1679     case TYPE_MMX:
1680       return "pxor\t%0, %0";
1681
1682     case TYPE_MMXMOV:
1683       if (get_attr_mode (insn) == MODE_DI)
1684         return "movq\t{%1, %0|%0, %1}";
1685       return "movd\t{%1, %0|%0, %1}";
1686
1687     case TYPE_LEA:
1688       return "lea{l}\t{%1, %0|%0, %1}";
1689
1690     default:
1691       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1692       return "mov{l}\t{%1, %0|%0, %1}";
1693     }
1694 }
1695   [(set (attr "type")
1696      (cond [(eq_attr "alternative" "2")
1697               (const_string "mmx")
1698             (eq_attr "alternative" "3,4,5")
1699               (const_string "mmxmov")
1700             (eq_attr "alternative" "6")
1701               (const_string "sselog1")
1702             (eq_attr "alternative" "7,8,9,10,11")
1703               (const_string "ssemov")
1704             (match_operand:DI 1 "pic_32bit_operand" "")
1705               (const_string "lea")
1706            ]
1707            (const_string "imov")))
1708    (set (attr "prefix")
1709      (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
1710        (const_string "orig")
1711        (const_string "maybe_vex")))
1712    (set (attr "prefix_data16")
1713      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
1714        (const_string "1")
1715        (const_string "*")))
1716    (set (attr "mode")
1717      (cond [(eq_attr "alternative" "2,3")
1718               (const_string "DI")
1719             (eq_attr "alternative" "6,7")
1720               (if_then_else
1721                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1722                 (const_string "V4SF")
1723                 (const_string "TI"))
1724             (and (eq_attr "alternative" "8,9,10,11")
1725                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1726               (const_string "SF")
1727            ]
1728            (const_string "SI")))])
1729
1730 ;; Stores and loads of ax to arbitrary constant address.
1731 ;; We fake an second form of instruction to force reload to load address
1732 ;; into register when rax is not available
1733 (define_insn "*movabssi_1_rex64"
1734   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1735         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1736   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1737   "@
1738    movabs{l}\t{%1, %P0|%P0, %1}
1739    mov{l}\t{%1, %a0|%a0, %1}"
1740   [(set_attr "type" "imov")
1741    (set_attr "modrm" "0,*")
1742    (set_attr "length_address" "8,0")
1743    (set_attr "length_immediate" "0,*")
1744    (set_attr "memory" "store")
1745    (set_attr "mode" "SI")])
1746
1747 (define_insn "*movabssi_2_rex64"
1748   [(set (match_operand:SI 0 "register_operand" "=a,r")
1749         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1750   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1751   "@
1752    movabs{l}\t{%P1, %0|%0, %P1}
1753    mov{l}\t{%a1, %0|%0, %a1}"
1754   [(set_attr "type" "imov")
1755    (set_attr "modrm" "0,*")
1756    (set_attr "length_address" "8,0")
1757    (set_attr "length_immediate" "0")
1758    (set_attr "memory" "load")
1759    (set_attr "mode" "SI")])
1760
1761 (define_insn "*swapsi"
1762   [(set (match_operand:SI 0 "register_operand" "+r")
1763         (match_operand:SI 1 "register_operand" "+r"))
1764    (set (match_dup 1)
1765         (match_dup 0))]
1766   ""
1767   "xchg{l}\t%1, %0"
1768   [(set_attr "type" "imov")
1769    (set_attr "mode" "SI")
1770    (set_attr "pent_pair" "np")
1771    (set_attr "athlon_decode" "vector")
1772    (set_attr "amdfam10_decode" "double")])
1773
1774 (define_expand "movhi"
1775   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1776         (match_operand:HI 1 "general_operand" ""))]
1777   ""
1778   "ix86_expand_move (HImode, operands); DONE;")
1779
1780 (define_insn "*pushhi2"
1781   [(set (match_operand:HI 0 "push_operand" "=X")
1782         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1783   "!TARGET_64BIT"
1784   "push{l}\t%k1"
1785   [(set_attr "type" "push")
1786    (set_attr "mode" "SI")])
1787
1788 ;; For 64BIT abi we always round up to 8 bytes.
1789 (define_insn "*pushhi2_rex64"
1790   [(set (match_operand:HI 0 "push_operand" "=X")
1791         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1792   "TARGET_64BIT"
1793   "push{q}\t%q1"
1794   [(set_attr "type" "push")
1795    (set_attr "mode" "DI")])
1796
1797 (define_insn "*movhi_1"
1798   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1799         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1800   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1801 {
1802   switch (get_attr_type (insn))
1803     {
1804     case TYPE_IMOVX:
1805       /* movzwl is faster than movw on p2 due to partial word stalls,
1806          though not as fast as an aligned movl.  */
1807       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1808     default:
1809       if (get_attr_mode (insn) == MODE_SI)
1810         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1811       else
1812         return "mov{w}\t{%1, %0|%0, %1}";
1813     }
1814 }
1815   [(set (attr "type")
1816      (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
1817               (const_string "imov")
1818             (and (eq_attr "alternative" "0")
1819                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1820                           (const_int 0))
1821                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1822                           (const_int 0))))
1823               (const_string "imov")
1824             (and (eq_attr "alternative" "1,2")
1825                  (match_operand:HI 1 "aligned_operand" ""))
1826               (const_string "imov")
1827             (and (ne (symbol_ref "TARGET_MOVX")
1828                      (const_int 0))
1829                  (eq_attr "alternative" "0,2"))
1830               (const_string "imovx")
1831            ]
1832            (const_string "imov")))
1833     (set (attr "mode")
1834       (cond [(eq_attr "type" "imovx")
1835                (const_string "SI")
1836              (and (eq_attr "alternative" "1,2")
1837                   (match_operand:HI 1 "aligned_operand" ""))
1838                (const_string "SI")
1839              (and (eq_attr "alternative" "0")
1840                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1841                            (const_int 0))
1842                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1843                            (const_int 0))))
1844                (const_string "SI")
1845             ]
1846             (const_string "HI")))])
1847
1848 ;; Stores and loads of ax to arbitrary constant address.
1849 ;; We fake an second form of instruction to force reload to load address
1850 ;; into register when rax is not available
1851 (define_insn "*movabshi_1_rex64"
1852   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1853         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1854   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1855   "@
1856    movabs{w}\t{%1, %P0|%P0, %1}
1857    mov{w}\t{%1, %a0|%a0, %1}"
1858   [(set_attr "type" "imov")
1859    (set_attr "modrm" "0,*")
1860    (set_attr "length_address" "8,0")
1861    (set_attr "length_immediate" "0,*")
1862    (set_attr "memory" "store")
1863    (set_attr "mode" "HI")])
1864
1865 (define_insn "*movabshi_2_rex64"
1866   [(set (match_operand:HI 0 "register_operand" "=a,r")
1867         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1868   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1869   "@
1870    movabs{w}\t{%P1, %0|%0, %P1}
1871    mov{w}\t{%a1, %0|%0, %a1}"
1872   [(set_attr "type" "imov")
1873    (set_attr "modrm" "0,*")
1874    (set_attr "length_address" "8,0")
1875    (set_attr "length_immediate" "0")
1876    (set_attr "memory" "load")
1877    (set_attr "mode" "HI")])
1878
1879 (define_insn "*swaphi_1"
1880   [(set (match_operand:HI 0 "register_operand" "+r")
1881         (match_operand:HI 1 "register_operand" "+r"))
1882    (set (match_dup 1)
1883         (match_dup 0))]
1884   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
1885   "xchg{l}\t%k1, %k0"
1886   [(set_attr "type" "imov")
1887    (set_attr "mode" "SI")
1888    (set_attr "pent_pair" "np")
1889    (set_attr "athlon_decode" "vector")
1890    (set_attr "amdfam10_decode" "double")])
1891
1892 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1893 (define_insn "*swaphi_2"
1894   [(set (match_operand:HI 0 "register_operand" "+r")
1895         (match_operand:HI 1 "register_operand" "+r"))
1896    (set (match_dup 1)
1897         (match_dup 0))]
1898   "TARGET_PARTIAL_REG_STALL"
1899   "xchg{w}\t%1, %0"
1900   [(set_attr "type" "imov")
1901    (set_attr "mode" "HI")
1902    (set_attr "pent_pair" "np")
1903    (set_attr "athlon_decode" "vector")])
1904
1905 (define_expand "movstricthi"
1906   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1907         (match_operand:HI 1 "general_operand" ""))]
1908   ""
1909 {
1910   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
1911     FAIL;
1912   /* Don't generate memory->memory moves, go through a register */
1913   if (MEM_P (operands[0]) && MEM_P (operands[1]))
1914     operands[1] = force_reg (HImode, operands[1]);
1915 })
1916
1917 (define_insn "*movstricthi_1"
1918   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1919         (match_operand:HI 1 "general_operand" "rn,m"))]
1920   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
1921    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1922   "mov{w}\t{%1, %0|%0, %1}"
1923   [(set_attr "type" "imov")
1924    (set_attr "mode" "HI")])
1925
1926 (define_insn "*movstricthi_xor"
1927   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1928         (match_operand:HI 1 "const0_operand" ""))
1929    (clobber (reg:CC FLAGS_REG))]
1930   "reload_completed"
1931   "xor{w}\t%0, %0"
1932   [(set_attr "type" "alu1")
1933    (set_attr "mode" "HI")
1934    (set_attr "length_immediate" "0")])
1935
1936 (define_expand "movqi"
1937   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1938         (match_operand:QI 1 "general_operand" ""))]
1939   ""
1940   "ix86_expand_move (QImode, operands); DONE;")
1941
1942 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1943 ;; "push a byte".  But actually we use pushl, which has the effect
1944 ;; of rounding the amount pushed up to a word.
1945
1946 (define_insn "*pushqi2"
1947   [(set (match_operand:QI 0 "push_operand" "=X")
1948         (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1949   "!TARGET_64BIT"
1950   "push{l}\t%k1"
1951   [(set_attr "type" "push")
1952    (set_attr "mode" "SI")])
1953
1954 ;; For 64BIT abi we always round up to 8 bytes.
1955 (define_insn "*pushqi2_rex64"
1956   [(set (match_operand:QI 0 "push_operand" "=X")
1957         (match_operand:QI 1 "nonmemory_no_elim_operand" "qn"))]
1958   "TARGET_64BIT"
1959   "push{q}\t%q1"
1960   [(set_attr "type" "push")
1961    (set_attr "mode" "DI")])
1962
1963 ;; Situation is quite tricky about when to choose full sized (SImode) move
1964 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1965 ;; partial register dependency machines (such as AMD Athlon), where QImode
1966 ;; moves issue extra dependency and for partial register stalls machines
1967 ;; that don't use QImode patterns (and QImode move cause stall on the next
1968 ;; instruction).
1969 ;;
1970 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1971 ;; register stall machines with, where we use QImode instructions, since
1972 ;; partial register stall can be caused there.  Then we use movzx.
1973 (define_insn "*movqi_1"
1974   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1975         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1976   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1977 {
1978   switch (get_attr_type (insn))
1979     {
1980     case TYPE_IMOVX:
1981       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
1982       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1983     default:
1984       if (get_attr_mode (insn) == MODE_SI)
1985         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1986       else
1987         return "mov{b}\t{%1, %0|%0, %1}";
1988     }
1989 }
1990   [(set (attr "type")
1991      (cond [(and (eq_attr "alternative" "5")
1992                  (not (match_operand:QI 1 "aligned_operand" "")))
1993               (const_string "imovx")
1994             (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
1995               (const_string "imov")
1996             (and (eq_attr "alternative" "3")
1997                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1998                           (const_int 0))
1999                       (eq (symbol_ref "TARGET_QIMODE_MATH")
2000                           (const_int 0))))
2001               (const_string "imov")
2002             (eq_attr "alternative" "3,5")
2003               (const_string "imovx")
2004             (and (ne (symbol_ref "TARGET_MOVX")
2005                      (const_int 0))
2006                  (eq_attr "alternative" "2"))
2007               (const_string "imovx")
2008            ]
2009            (const_string "imov")))
2010    (set (attr "mode")
2011       (cond [(eq_attr "alternative" "3,4,5")
2012                (const_string "SI")
2013              (eq_attr "alternative" "6")
2014                (const_string "QI")
2015              (eq_attr "type" "imovx")
2016                (const_string "SI")
2017              (and (eq_attr "type" "imov")
2018                   (and (eq_attr "alternative" "0,1")
2019                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
2020                                 (const_int 0))
2021                             (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2022                                      (const_int 0))
2023                                  (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2024                                      (const_int 0))))))
2025                (const_string "SI")
2026              ;; Avoid partial register stalls when not using QImode arithmetic
2027              (and (eq_attr "type" "imov")
2028                   (and (eq_attr "alternative" "0,1")
2029                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
2030                                 (const_int 0))
2031                             (eq (symbol_ref "TARGET_QIMODE_MATH")
2032                                 (const_int 0)))))
2033                (const_string "SI")
2034            ]
2035            (const_string "QI")))])
2036
2037 (define_insn "*swapqi_1"
2038   [(set (match_operand:QI 0 "register_operand" "+r")
2039         (match_operand:QI 1 "register_operand" "+r"))
2040    (set (match_dup 1)
2041         (match_dup 0))]
2042   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2043   "xchg{l}\t%k1, %k0"
2044   [(set_attr "type" "imov")
2045    (set_attr "mode" "SI")
2046    (set_attr "pent_pair" "np")
2047    (set_attr "athlon_decode" "vector")
2048    (set_attr "amdfam10_decode" "vector")])
2049
2050 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
2051 (define_insn "*swapqi_2"
2052   [(set (match_operand:QI 0 "register_operand" "+q")
2053         (match_operand:QI 1 "register_operand" "+q"))
2054    (set (match_dup 1)
2055         (match_dup 0))]
2056   "TARGET_PARTIAL_REG_STALL"
2057   "xchg{b}\t%1, %0"
2058   [(set_attr "type" "imov")
2059    (set_attr "mode" "QI")
2060    (set_attr "pent_pair" "np")
2061    (set_attr "athlon_decode" "vector")])
2062
2063 (define_expand "movstrictqi"
2064   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
2065         (match_operand:QI 1 "general_operand" ""))]
2066   ""
2067 {
2068   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2069     FAIL;
2070   /* Don't generate memory->memory moves, go through a register.  */
2071   if (MEM_P (operands[0]) && MEM_P (operands[1]))
2072     operands[1] = force_reg (QImode, operands[1]);
2073 })
2074
2075 (define_insn "*movstrictqi_1"
2076   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
2077         (match_operand:QI 1 "general_operand" "*qn,m"))]
2078   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2079    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2080   "mov{b}\t{%1, %0|%0, %1}"
2081   [(set_attr "type" "imov")
2082    (set_attr "mode" "QI")])
2083
2084 (define_insn "*movstrictqi_xor"
2085   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
2086         (match_operand:QI 1 "const0_operand" ""))
2087    (clobber (reg:CC FLAGS_REG))]
2088   "reload_completed"
2089   "xor{b}\t%0, %0"
2090   [(set_attr "type" "alu1")
2091    (set_attr "mode" "QI")
2092    (set_attr "length_immediate" "0")])
2093
2094 (define_insn "*movsi_extv_1"
2095   [(set (match_operand:SI 0 "register_operand" "=R")
2096         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
2097                          (const_int 8)
2098                          (const_int 8)))]
2099   ""
2100   "movs{bl|x}\t{%h1, %0|%0, %h1}"
2101   [(set_attr "type" "imovx")
2102    (set_attr "mode" "SI")])
2103
2104 (define_insn "*movhi_extv_1"
2105   [(set (match_operand:HI 0 "register_operand" "=R")
2106         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
2107                          (const_int 8)
2108                          (const_int 8)))]
2109   ""
2110   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2111   [(set_attr "type" "imovx")
2112    (set_attr "mode" "SI")])
2113
2114 (define_insn "*movqi_extv_1"
2115   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2116         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2117                          (const_int 8)
2118                          (const_int 8)))]
2119   "!TARGET_64BIT"
2120 {
2121   switch (get_attr_type (insn))
2122     {
2123     case TYPE_IMOVX:
2124       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2125     default:
2126       return "mov{b}\t{%h1, %0|%0, %h1}";
2127     }
2128 }
2129   [(set (attr "type")
2130      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2131                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2132                              (ne (symbol_ref "TARGET_MOVX")
2133                                  (const_int 0))))
2134         (const_string "imovx")
2135         (const_string "imov")))
2136    (set (attr "mode")
2137      (if_then_else (eq_attr "type" "imovx")
2138         (const_string "SI")
2139         (const_string "QI")))])
2140
2141 (define_insn "*movqi_extv_1_rex64"
2142   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2143         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2144                          (const_int 8)
2145                          (const_int 8)))]
2146   "TARGET_64BIT"
2147 {
2148   switch (get_attr_type (insn))
2149     {
2150     case TYPE_IMOVX:
2151       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2152     default:
2153       return "mov{b}\t{%h1, %0|%0, %h1}";
2154     }
2155 }
2156   [(set (attr "type")
2157      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2158                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2159                              (ne (symbol_ref "TARGET_MOVX")
2160                                  (const_int 0))))
2161         (const_string "imovx")
2162         (const_string "imov")))
2163    (set (attr "mode")
2164      (if_then_else (eq_attr "type" "imovx")
2165         (const_string "SI")
2166         (const_string "QI")))])
2167
2168 ;; Stores and loads of ax to arbitrary constant address.
2169 ;; We fake an second form of instruction to force reload to load address
2170 ;; into register when rax is not available
2171 (define_insn "*movabsqi_1_rex64"
2172   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2173         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
2174   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2175   "@
2176    movabs{b}\t{%1, %P0|%P0, %1}
2177    mov{b}\t{%1, %a0|%a0, %1}"
2178   [(set_attr "type" "imov")
2179    (set_attr "modrm" "0,*")
2180    (set_attr "length_address" "8,0")
2181    (set_attr "length_immediate" "0,*")
2182    (set_attr "memory" "store")
2183    (set_attr "mode" "QI")])
2184
2185 (define_insn "*movabsqi_2_rex64"
2186   [(set (match_operand:QI 0 "register_operand" "=a,r")
2187         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2188   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2189   "@
2190    movabs{b}\t{%P1, %0|%0, %P1}
2191    mov{b}\t{%a1, %0|%0, %a1}"
2192   [(set_attr "type" "imov")
2193    (set_attr "modrm" "0,*")
2194    (set_attr "length_address" "8,0")
2195    (set_attr "length_immediate" "0")
2196    (set_attr "memory" "load")
2197    (set_attr "mode" "QI")])
2198
2199 (define_insn "*movdi_extzv_1"
2200   [(set (match_operand:DI 0 "register_operand" "=R")
2201         (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
2202                          (const_int 8)
2203                          (const_int 8)))]
2204   "TARGET_64BIT"
2205   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2206   [(set_attr "type" "imovx")
2207    (set_attr "mode" "SI")])
2208
2209 (define_insn "*movsi_extzv_1"
2210   [(set (match_operand:SI 0 "register_operand" "=R")
2211         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
2212                          (const_int 8)
2213                          (const_int 8)))]
2214   ""
2215   "movz{bl|x}\t{%h1, %0|%0, %h1}"
2216   [(set_attr "type" "imovx")
2217    (set_attr "mode" "SI")])
2218
2219 (define_insn "*movqi_extzv_2"
2220   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2221         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2222                                     (const_int 8)
2223                                     (const_int 8)) 0))]
2224   "!TARGET_64BIT"
2225 {
2226   switch (get_attr_type (insn))
2227     {
2228     case TYPE_IMOVX:
2229       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2230     default:
2231       return "mov{b}\t{%h1, %0|%0, %h1}";
2232     }
2233 }
2234   [(set (attr "type")
2235      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2236                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2237                              (ne (symbol_ref "TARGET_MOVX")
2238                                  (const_int 0))))
2239         (const_string "imovx")
2240         (const_string "imov")))
2241    (set (attr "mode")
2242      (if_then_else (eq_attr "type" "imovx")
2243         (const_string "SI")
2244         (const_string "QI")))])
2245
2246 (define_insn "*movqi_extzv_2_rex64"
2247   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2248         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2249                                     (const_int 8)
2250                                     (const_int 8)) 0))]
2251   "TARGET_64BIT"
2252 {
2253   switch (get_attr_type (insn))
2254     {
2255     case TYPE_IMOVX:
2256       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2257     default:
2258       return "mov{b}\t{%h1, %0|%0, %h1}";
2259     }
2260 }
2261   [(set (attr "type")
2262      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2263                         (ne (symbol_ref "TARGET_MOVX")
2264                             (const_int 0)))
2265         (const_string "imovx")
2266         (const_string "imov")))
2267    (set (attr "mode")
2268      (if_then_else (eq_attr "type" "imovx")
2269         (const_string "SI")
2270         (const_string "QI")))])
2271
2272 (define_insn "movsi_insv_1"
2273   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2274                          (const_int 8)
2275                          (const_int 8))
2276         (match_operand:SI 1 "general_operand" "Qmn"))]
2277   "!TARGET_64BIT"
2278   "mov{b}\t{%b1, %h0|%h0, %b1}"
2279   [(set_attr "type" "imov")
2280    (set_attr "mode" "QI")])
2281
2282 (define_insn "*movsi_insv_1_rex64"
2283   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2284                          (const_int 8)
2285                          (const_int 8))
2286         (match_operand:SI 1 "nonmemory_operand" "Qn"))]
2287   "TARGET_64BIT"
2288   "mov{b}\t{%b1, %h0|%h0, %b1}"
2289   [(set_attr "type" "imov")
2290    (set_attr "mode" "QI")])
2291
2292 (define_insn "movdi_insv_1_rex64"
2293   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
2294                          (const_int 8)
2295                          (const_int 8))
2296         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
2297   "TARGET_64BIT"
2298   "mov{b}\t{%b1, %h0|%h0, %b1}"
2299   [(set_attr "type" "imov")
2300    (set_attr "mode" "QI")])
2301
2302 (define_insn "*movqi_insv_2"
2303   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2304                          (const_int 8)
2305                          (const_int 8))
2306         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2307                      (const_int 8)))]
2308   ""
2309   "mov{b}\t{%h1, %h0|%h0, %h1}"
2310   [(set_attr "type" "imov")
2311    (set_attr "mode" "QI")])
2312
2313 (define_expand "movdi"
2314   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2315         (match_operand:DI 1 "general_operand" ""))]
2316   ""
2317   "ix86_expand_move (DImode, operands); DONE;")
2318
2319 (define_insn "*pushdi"
2320   [(set (match_operand:DI 0 "push_operand" "=<")
2321         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
2322   "!TARGET_64BIT"
2323   "#")
2324
2325 (define_insn "*pushdi2_rex64"
2326   [(set (match_operand:DI 0 "push_operand" "=<,!<")
2327         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
2328   "TARGET_64BIT"
2329   "@
2330    push{q}\t%1
2331    #"
2332   [(set_attr "type" "push,multi")
2333    (set_attr "mode" "DI")])
2334
2335 ;; Convert impossible pushes of immediate to existing instructions.
2336 ;; First try to get scratch register and go through it.  In case this
2337 ;; fails, push sign extended lower part first and then overwrite
2338 ;; upper part by 32bit move.
2339 (define_peephole2
2340   [(match_scratch:DI 2 "r")
2341    (set (match_operand:DI 0 "push_operand" "")
2342         (match_operand:DI 1 "immediate_operand" ""))]
2343   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2344    && !x86_64_immediate_operand (operands[1], DImode)"
2345   [(set (match_dup 2) (match_dup 1))
2346    (set (match_dup 0) (match_dup 2))]
2347   "")
2348
2349 ;; We need to define this as both peepholer and splitter for case
2350 ;; peephole2 pass is not run.
2351 ;; "&& 1" is needed to keep it from matching the previous pattern.
2352 (define_peephole2
2353   [(set (match_operand:DI 0 "push_operand" "")
2354         (match_operand:DI 1 "immediate_operand" ""))]
2355   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2356    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2357   [(set (match_dup 0) (match_dup 1))
2358    (set (match_dup 2) (match_dup 3))]
2359   "split_di (&operands[1], 1, &operands[2], &operands[3]);
2360    operands[1] = gen_lowpart (DImode, operands[2]);
2361    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2362                                                     GEN_INT (4)));
2363   ")
2364
2365 (define_split
2366   [(set (match_operand:DI 0 "push_operand" "")
2367         (match_operand:DI 1 "immediate_operand" ""))]
2368   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2369                     ? epilogue_completed : reload_completed)
2370    && !symbolic_operand (operands[1], DImode)
2371    && !x86_64_immediate_operand (operands[1], DImode)"
2372   [(set (match_dup 0) (match_dup 1))
2373    (set (match_dup 2) (match_dup 3))]
2374   "split_di (&operands[1], 1, &operands[2], &operands[3]);
2375    operands[1] = gen_lowpart (DImode, operands[2]);
2376    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2377                                                     GEN_INT (4)));
2378   ")
2379
2380 (define_insn "*pushdi2_prologue_rex64"
2381   [(set (match_operand:DI 0 "push_operand" "=<")
2382         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
2383    (clobber (mem:BLK (scratch)))]
2384   "TARGET_64BIT"
2385   "push{q}\t%1"
2386   [(set_attr "type" "push")
2387    (set_attr "mode" "DI")])
2388
2389 (define_insn "*popdi1_epilogue_rex64"
2390   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2391         (mem:DI (reg:DI SP_REG)))
2392    (set (reg:DI SP_REG)
2393         (plus:DI (reg:DI SP_REG) (const_int 8)))
2394    (clobber (mem:BLK (scratch)))]
2395   "TARGET_64BIT"
2396   "pop{q}\t%0"
2397   [(set_attr "type" "pop")
2398    (set_attr "mode" "DI")])
2399
2400 (define_insn "popdi1"
2401   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2402         (mem:DI (reg:DI SP_REG)))
2403    (set (reg:DI SP_REG)
2404         (plus:DI (reg:DI SP_REG) (const_int 8)))]
2405   "TARGET_64BIT"
2406   "pop{q}\t%0"
2407   [(set_attr "type" "pop")
2408    (set_attr "mode" "DI")])
2409
2410 (define_insn "*movdi_xor_rex64"
2411   [(set (match_operand:DI 0 "register_operand" "=r")
2412         (match_operand:DI 1 "const0_operand" ""))
2413    (clobber (reg:CC FLAGS_REG))]
2414   "TARGET_64BIT
2415    && reload_completed"
2416   "xor{l}\t%k0, %k0";
2417   [(set_attr "type" "alu1")
2418    (set_attr "mode" "SI")
2419    (set_attr "length_immediate" "0")])
2420
2421 (define_insn "*movdi_or_rex64"
2422   [(set (match_operand:DI 0 "register_operand" "=r")
2423         (match_operand:DI 1 "const_int_operand" "i"))
2424    (clobber (reg:CC FLAGS_REG))]
2425   "TARGET_64BIT
2426    && reload_completed
2427    && operands[1] == constm1_rtx"
2428 {
2429   operands[1] = constm1_rtx;
2430   return "or{q}\t{%1, %0|%0, %1}";
2431 }
2432   [(set_attr "type" "alu1")
2433    (set_attr "mode" "DI")
2434    (set_attr "length_immediate" "1")])
2435
2436 (define_insn "*movdi_2"
2437   [(set (match_operand:DI 0 "nonimmediate_operand"
2438                         "=r  ,o  ,*y,m*y,*y,*Y2,m  ,*Y2,*Y2,*x,m ,*x,*x")
2439         (match_operand:DI 1 "general_operand"
2440                         "riFo,riF,C ,*y ,m ,C  ,*Y2,*Y2,m  ,C ,*x,*x,m "))]
2441   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2442   "@
2443    #
2444    #
2445    pxor\t%0, %0
2446    movq\t{%1, %0|%0, %1}
2447    movq\t{%1, %0|%0, %1}
2448    %vpxor\t%0, %d0
2449    %vmovq\t{%1, %0|%0, %1}
2450    %vmovdqa\t{%1, %0|%0, %1}
2451    %vmovq\t{%1, %0|%0, %1}
2452    xorps\t%0, %0
2453    movlps\t{%1, %0|%0, %1}
2454    movaps\t{%1, %0|%0, %1}
2455    movlps\t{%1, %0|%0, %1}"
2456   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2457    (set (attr "prefix")
2458      (if_then_else (eq_attr "alternative" "5,6,7,8")
2459        (const_string "vex")
2460        (const_string "orig")))
2461    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2462
2463 (define_split
2464   [(set (match_operand:DI 0 "push_operand" "")
2465         (match_operand:DI 1 "general_operand" ""))]
2466   "!TARGET_64BIT && reload_completed
2467    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2468   [(const_int 0)]
2469   "ix86_split_long_move (operands); DONE;")
2470
2471 ;; %%% This multiword shite has got to go.
2472 (define_split
2473   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2474         (match_operand:DI 1 "general_operand" ""))]
2475   "!TARGET_64BIT && reload_completed
2476    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2477    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2478   [(const_int 0)]
2479   "ix86_split_long_move (operands); DONE;")
2480
2481 (define_insn "*movdi_1_rex64"
2482   [(set (match_operand:DI 0 "nonimmediate_operand"
2483           "=r,r  ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2484         (match_operand:DI 1 "general_operand"
2485           "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r   ,m  ,C ,*x,*Yi,*x,r  ,m ,*Ym,*x"))]
2486   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2487 {
2488   switch (get_attr_type (insn))
2489     {
2490     case TYPE_SSECVT:
2491       if (SSE_REG_P (operands[0]))
2492         return "movq2dq\t{%1, %0|%0, %1}";
2493       else
2494         return "movdq2q\t{%1, %0|%0, %1}";
2495
2496     case TYPE_SSEMOV:
2497       if (TARGET_AVX)
2498         {
2499           if (get_attr_mode (insn) == MODE_TI)
2500             return "vmovdqa\t{%1, %0|%0, %1}";
2501           else
2502             return "vmovq\t{%1, %0|%0, %1}";
2503         }
2504
2505       if (get_attr_mode (insn) == MODE_TI)
2506         return "movdqa\t{%1, %0|%0, %1}";
2507       /* FALLTHRU */
2508
2509     case TYPE_MMXMOV:
2510       /* Moves from and into integer register is done using movd
2511          opcode with REX prefix.  */
2512       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2513         return "movd\t{%1, %0|%0, %1}";
2514       return "movq\t{%1, %0|%0, %1}";
2515
2516     case TYPE_SSELOG1:
2517       return "%vpxor\t%0, %d0";
2518
2519     case TYPE_MMX:
2520       return "pxor\t%0, %0";
2521
2522     case TYPE_MULTI:
2523       return "#";
2524
2525     case TYPE_LEA:
2526       return "lea{q}\t{%a1, %0|%0, %a1}";
2527
2528     default:
2529       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2530       if (get_attr_mode (insn) == MODE_SI)
2531         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2532       else if (which_alternative == 2)
2533         return "movabs{q}\t{%1, %0|%0, %1}";
2534       else
2535         return "mov{q}\t{%1, %0|%0, %1}";
2536     }
2537 }
2538   [(set (attr "type")
2539      (cond [(eq_attr "alternative" "5")
2540               (const_string "mmx")
2541             (eq_attr "alternative" "6,7,8,9,10")
2542               (const_string "mmxmov")
2543             (eq_attr "alternative" "11")
2544               (const_string "sselog1")
2545             (eq_attr "alternative" "12,13,14,15,16")
2546               (const_string "ssemov")
2547             (eq_attr "alternative" "17,18")
2548               (const_string "ssecvt")
2549             (eq_attr "alternative" "4")
2550               (const_string "multi")
2551             (match_operand:DI 1 "pic_32bit_operand" "")
2552               (const_string "lea")
2553            ]
2554            (const_string "imov")))
2555    (set (attr "modrm")
2556      (if_then_else
2557        (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2558          (const_string "0")
2559          (const_string "*")))
2560    (set (attr "length_immediate")
2561      (if_then_else
2562        (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2563          (const_string "8")
2564          (const_string "*")))
2565    (set_attr "prefix_rex" "*,*,*,*,*,*,*,1,*,1,*,*,*,*,*,*,*,*,*")
2566    (set_attr "prefix_data16" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,1,*,*,*")
2567    (set (attr "prefix")
2568      (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
2569        (const_string "maybe_vex")
2570        (const_string "orig")))
2571    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2572
2573 ;; Stores and loads of ax to arbitrary constant address.
2574 ;; We fake an second form of instruction to force reload to load address
2575 ;; into register when rax is not available
2576 (define_insn "*movabsdi_1_rex64"
2577   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2578         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2579   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2580   "@
2581    movabs{q}\t{%1, %P0|%P0, %1}
2582    mov{q}\t{%1, %a0|%a0, %1}"
2583   [(set_attr "type" "imov")
2584    (set_attr "modrm" "0,*")
2585    (set_attr "length_address" "8,0")
2586    (set_attr "length_immediate" "0,*")
2587    (set_attr "memory" "store")
2588    (set_attr "mode" "DI")])
2589
2590 (define_insn "*movabsdi_2_rex64"
2591   [(set (match_operand:DI 0 "register_operand" "=a,r")
2592         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2593   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2594   "@
2595    movabs{q}\t{%P1, %0|%0, %P1}
2596    mov{q}\t{%a1, %0|%0, %a1}"
2597   [(set_attr "type" "imov")
2598    (set_attr "modrm" "0,*")
2599    (set_attr "length_address" "8,0")
2600    (set_attr "length_immediate" "0")
2601    (set_attr "memory" "load")
2602    (set_attr "mode" "DI")])
2603
2604 ;; Convert impossible stores of immediate to existing instructions.
2605 ;; First try to get scratch register and go through it.  In case this
2606 ;; fails, move by 32bit parts.
2607 (define_peephole2
2608   [(match_scratch:DI 2 "r")
2609    (set (match_operand:DI 0 "memory_operand" "")
2610         (match_operand:DI 1 "immediate_operand" ""))]
2611   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2612    && !x86_64_immediate_operand (operands[1], DImode)"
2613   [(set (match_dup 2) (match_dup 1))
2614    (set (match_dup 0) (match_dup 2))]
2615   "")
2616
2617 ;; We need to define this as both peepholer and splitter for case
2618 ;; peephole2 pass is not run.
2619 ;; "&& 1" is needed to keep it from matching the previous pattern.
2620 (define_peephole2
2621   [(set (match_operand:DI 0 "memory_operand" "")
2622         (match_operand:DI 1 "immediate_operand" ""))]
2623   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2624    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2625   [(set (match_dup 2) (match_dup 3))
2626    (set (match_dup 4) (match_dup 5))]
2627   "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2628
2629 (define_split
2630   [(set (match_operand:DI 0 "memory_operand" "")
2631         (match_operand:DI 1 "immediate_operand" ""))]
2632   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2633                     ? epilogue_completed : reload_completed)
2634    && !symbolic_operand (operands[1], DImode)
2635    && !x86_64_immediate_operand (operands[1], DImode)"
2636   [(set (match_dup 2) (match_dup 3))
2637    (set (match_dup 4) (match_dup 5))]
2638   "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2639
2640 (define_insn "*swapdi_rex64"
2641   [(set (match_operand:DI 0 "register_operand" "+r")
2642         (match_operand:DI 1 "register_operand" "+r"))
2643    (set (match_dup 1)
2644         (match_dup 0))]
2645   "TARGET_64BIT"
2646   "xchg{q}\t%1, %0"
2647   [(set_attr "type" "imov")
2648    (set_attr "mode" "DI")
2649    (set_attr "pent_pair" "np")
2650    (set_attr "athlon_decode" "vector")
2651    (set_attr "amdfam10_decode" "double")])
2652
2653 (define_expand "movoi"
2654   [(set (match_operand:OI 0 "nonimmediate_operand" "")
2655         (match_operand:OI 1 "general_operand" ""))]
2656   "TARGET_AVX"
2657   "ix86_expand_move (OImode, operands); DONE;")
2658
2659 (define_insn "*movoi_internal"
2660   [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
2661         (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
2662   "TARGET_AVX
2663    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2664 {
2665   switch (which_alternative)
2666     {
2667     case 0:
2668       return "vxorps\t%0, %0, %0";
2669     case 1:
2670     case 2:
2671       if (misaligned_operand (operands[0], OImode)
2672           || misaligned_operand (operands[1], OImode))
2673         return "vmovdqu\t{%1, %0|%0, %1}";
2674       else
2675         return "vmovdqa\t{%1, %0|%0, %1}";
2676     default:
2677       gcc_unreachable ();
2678     }
2679 }
2680   [(set_attr "type" "sselog1,ssemov,ssemov")
2681    (set_attr "prefix" "vex")
2682    (set_attr "mode" "OI")])
2683
2684 (define_expand "movti"
2685   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2686         (match_operand:TI 1 "nonimmediate_operand" ""))]
2687   "TARGET_SSE || TARGET_64BIT"
2688 {
2689   if (TARGET_64BIT)
2690     ix86_expand_move (TImode, operands);
2691   else if (push_operand (operands[0], TImode))
2692     ix86_expand_push (TImode, operands[1]);
2693   else
2694     ix86_expand_vector_move (TImode, operands);
2695   DONE;
2696 })
2697
2698 (define_insn "*movti_internal"
2699   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2700         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2701   "TARGET_SSE && !TARGET_64BIT
2702    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2703 {
2704   switch (which_alternative)
2705     {
2706     case 0:
2707       if (get_attr_mode (insn) == MODE_V4SF)
2708         return "%vxorps\t%0, %d0";
2709       else
2710         return "%vpxor\t%0, %d0";
2711     case 1:
2712     case 2:
2713       /* TDmode values are passed as TImode on the stack.  Moving them
2714          to stack may result in unaligned memory access.  */
2715       if (misaligned_operand (operands[0], TImode)
2716           || misaligned_operand (operands[1], TImode))
2717         {
2718           if (get_attr_mode (insn) == MODE_V4SF)
2719             return "%vmovups\t{%1, %0|%0, %1}";
2720          else
2721            return "%vmovdqu\t{%1, %0|%0, %1}";
2722         }
2723       else
2724         {
2725           if (get_attr_mode (insn) == MODE_V4SF)
2726             return "%vmovaps\t{%1, %0|%0, %1}";
2727          else
2728            return "%vmovdqa\t{%1, %0|%0, %1}";
2729         }
2730     default:
2731       gcc_unreachable ();
2732     }
2733 }
2734   [(set_attr "type" "sselog1,ssemov,ssemov")
2735    (set_attr "prefix" "maybe_vex")
2736    (set (attr "mode")
2737         (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2738                     (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0)))
2739                  (const_string "V4SF")
2740                (and (eq_attr "alternative" "2")
2741                     (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2742                         (const_int 0)))
2743                  (const_string "V4SF")]
2744               (const_string "TI")))])
2745
2746 (define_insn "*movti_rex64"
2747   [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
2748         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2749   "TARGET_64BIT
2750    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2751 {
2752   switch (which_alternative)
2753     {
2754     case 0:
2755     case 1:
2756       return "#";
2757     case 2:
2758       if (get_attr_mode (insn) == MODE_V4SF)
2759         return "%vxorps\t%0, %d0";
2760       else
2761         return "%vpxor\t%0, %d0";
2762     case 3:
2763     case 4:
2764       /* TDmode values are passed as TImode on the stack.  Moving them
2765          to stack may result in unaligned memory access.  */
2766       if (misaligned_operand (operands[0], TImode)
2767           || misaligned_operand (operands[1], TImode))
2768         {
2769           if (get_attr_mode (insn) == MODE_V4SF)
2770             return "%vmovups\t{%1, %0|%0, %1}";
2771          else
2772            return "%vmovdqu\t{%1, %0|%0, %1}";
2773         }
2774       else
2775         {
2776           if (get_attr_mode (insn) == MODE_V4SF)
2777             return "%vmovaps\t{%1, %0|%0, %1}";
2778          else
2779            return "%vmovdqa\t{%1, %0|%0, %1}";
2780         }
2781     default:
2782       gcc_unreachable ();
2783     }
2784 }
2785   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2786    (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
2787    (set (attr "mode")
2788         (cond [(eq_attr "alternative" "2,3")
2789                  (if_then_else
2790                    (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2791                        (const_int 0))
2792                    (const_string "V4SF")
2793                    (const_string "TI"))
2794                (eq_attr "alternative" "4")
2795                  (if_then_else
2796                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2797                             (const_int 0))
2798                         (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2799                             (const_int 0)))
2800                    (const_string "V4SF")
2801                    (const_string "TI"))]
2802                (const_string "DI")))])
2803
2804 (define_split
2805   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2806         (match_operand:TI 1 "general_operand" ""))]
2807   "reload_completed && !SSE_REG_P (operands[0])
2808    && !SSE_REG_P (operands[1])"
2809   [(const_int 0)]
2810   "ix86_split_long_move (operands); DONE;")
2811
2812 ;; This expands to what emit_move_complex would generate if we didn't
2813 ;; have a movti pattern.  Having this avoids problems with reload on
2814 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2815 ;; to have around all the time.
2816 (define_expand "movcdi"
2817   [(set (match_operand:CDI 0 "nonimmediate_operand" "")
2818         (match_operand:CDI 1 "general_operand" ""))]
2819   ""
2820 {
2821   if (push_operand (operands[0], CDImode))
2822     emit_move_complex_push (CDImode, operands[0], operands[1]);
2823   else
2824     emit_move_complex_parts (operands[0], operands[1]);
2825   DONE;
2826 })
2827
2828 (define_expand "movsf"
2829   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2830         (match_operand:SF 1 "general_operand" ""))]
2831   ""
2832   "ix86_expand_move (SFmode, operands); DONE;")
2833
2834 (define_insn "*pushsf"
2835   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2836         (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2837   "!TARGET_64BIT"
2838 {
2839   /* Anything else should be already split before reg-stack.  */
2840   gcc_assert (which_alternative == 1);
2841   return "push{l}\t%1";
2842 }
2843   [(set_attr "type" "multi,push,multi")
2844    (set_attr "unit" "i387,*,*")
2845    (set_attr "mode" "SF,SI,SF")])
2846
2847 (define_insn "*pushsf_rex64"
2848   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2849         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2850   "TARGET_64BIT"
2851 {
2852   /* Anything else should be already split before reg-stack.  */
2853   gcc_assert (which_alternative == 1);
2854   return "push{q}\t%q1";
2855 }
2856   [(set_attr "type" "multi,push,multi")
2857    (set_attr "unit" "i387,*,*")
2858    (set_attr "mode" "SF,DI,SF")])
2859
2860 (define_split
2861   [(set (match_operand:SF 0 "push_operand" "")
2862         (match_operand:SF 1 "memory_operand" ""))]
2863   "reload_completed
2864    && MEM_P (operands[1])
2865    && (operands[2] = find_constant_src (insn))"
2866   [(set (match_dup 0)
2867         (match_dup 2))])
2868
2869 ;; %%% Kill this when call knows how to work this out.
2870 (define_split
2871   [(set (match_operand:SF 0 "push_operand" "")
2872         (match_operand:SF 1 "any_fp_register_operand" ""))]
2873   "!TARGET_64BIT"
2874   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2875    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2876
2877 (define_split
2878   [(set (match_operand:SF 0 "push_operand" "")
2879         (match_operand:SF 1 "any_fp_register_operand" ""))]
2880   "TARGET_64BIT"
2881   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2882    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2883
2884 (define_insn "*movsf_1"
2885   [(set (match_operand:SF 0 "nonimmediate_operand"
2886           "=f,m,f,r  ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
2887         (match_operand:SF 1 "general_operand"
2888           "fm,f,G,rmF,Fr,C,x,xm,x,m  ,*y,*y ,r  ,Yi,r   ,*Ym"))]
2889   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2890    && (reload_in_progress || reload_completed
2891        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2892        || (!TARGET_SSE_MATH && optimize_function_for_size_p (cfun)
2893            && standard_80387_constant_p (operands[1]))
2894        || GET_CODE (operands[1]) != CONST_DOUBLE
2895        || memory_operand (operands[0], SFmode))"
2896 {
2897   switch (which_alternative)
2898     {
2899     case 0:
2900     case 1:
2901       return output_387_reg_move (insn, operands);
2902
2903     case 2:
2904       return standard_80387_constant_opcode (operands[1]);
2905
2906     case 3:
2907     case 4:
2908       return "mov{l}\t{%1, %0|%0, %1}";
2909     case 5:
2910       if (get_attr_mode (insn) == MODE_TI)
2911         return "%vpxor\t%0, %d0";
2912       else
2913         return "%vxorps\t%0, %d0";
2914     case 6:
2915       if (get_attr_mode (insn) == MODE_V4SF)
2916         return "%vmovaps\t{%1, %0|%0, %1}";
2917       else
2918         return "%vmovss\t{%1, %d0|%d0, %1}";
2919     case 7:
2920       if (TARGET_AVX)
2921         return REG_P (operands[1]) ? "vmovss\t{%1, %0, %0|%0, %0, %1}"
2922                                    : "vmovss\t{%1, %0|%0, %1}";
2923       else
2924         return "movss\t{%1, %0|%0, %1}";
2925     case 8:
2926       return "%vmovss\t{%1, %0|%0, %1}";
2927
2928     case 9: case 10: case 14: case 15:
2929       return "movd\t{%1, %0|%0, %1}";
2930     case 12: case 13:
2931       return "%vmovd\t{%1, %0|%0, %1}";
2932
2933     case 11:
2934       return "movq\t{%1, %0|%0, %1}";
2935
2936     default:
2937       gcc_unreachable ();
2938     }
2939 }
2940   [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2941    (set (attr "prefix")
2942      (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
2943        (const_string "maybe_vex")
2944        (const_string "orig")))
2945    (set (attr "mode")
2946         (cond [(eq_attr "alternative" "3,4,9,10")
2947                  (const_string "SI")
2948                (eq_attr "alternative" "5")
2949                  (if_then_else
2950                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2951                                  (const_int 0))
2952                              (ne (symbol_ref "TARGET_SSE2")
2953                                  (const_int 0)))
2954                         (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2955                             (const_int 0)))
2956                    (const_string "TI")
2957                    (const_string "V4SF"))
2958                /* For architectures resolving dependencies on
2959                   whole SSE registers use APS move to break dependency
2960                   chains, otherwise use short move to avoid extra work.
2961
2962                   Do the same for architectures resolving dependencies on
2963                   the parts.  While in DF mode it is better to always handle
2964                   just register parts, the SF mode is different due to lack
2965                   of instructions to load just part of the register.  It is
2966                   better to maintain the whole registers in single format
2967                   to avoid problems on using packed logical operations.  */
2968                (eq_attr "alternative" "6")
2969                  (if_then_else
2970                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2971                             (const_int 0))
2972                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2973                             (const_int 0)))
2974                    (const_string "V4SF")
2975                    (const_string "SF"))
2976                (eq_attr "alternative" "11")
2977                  (const_string "DI")]
2978                (const_string "SF")))])
2979
2980 (define_insn "*swapsf"
2981   [(set (match_operand:SF 0 "fp_register_operand" "+f")
2982         (match_operand:SF 1 "fp_register_operand" "+f"))
2983    (set (match_dup 1)
2984         (match_dup 0))]
2985   "reload_completed || TARGET_80387"
2986 {
2987   if (STACK_TOP_P (operands[0]))
2988     return "fxch\t%1";
2989   else
2990     return "fxch\t%0";
2991 }
2992   [(set_attr "type" "fxch")
2993    (set_attr "mode" "SF")])
2994
2995 (define_expand "movdf"
2996   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2997         (match_operand:DF 1 "general_operand" ""))]
2998   ""
2999   "ix86_expand_move (DFmode, operands); DONE;")
3000
3001 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3002 ;; Size of pushdf using integer instructions is 2+2*memory operand size
3003 ;; On the average, pushdf using integers can be still shorter.  Allow this
3004 ;; pattern for optimize_size too.
3005
3006 (define_insn "*pushdf_nointeger"
3007   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
3008         (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
3009   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
3010 {
3011   /* This insn should be already split before reg-stack.  */
3012   gcc_unreachable ();
3013 }
3014   [(set_attr "type" "multi")
3015    (set_attr "unit" "i387,*,*,*")
3016    (set_attr "mode" "DF,SI,SI,DF")])
3017
3018 (define_insn "*pushdf_integer"
3019   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
3020         (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
3021   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
3022 {
3023   /* This insn should be already split before reg-stack.  */
3024   gcc_unreachable ();
3025 }
3026   [(set_attr "type" "multi")
3027    (set_attr "unit" "i387,*,*")
3028    (set_attr "mode" "DF,SI,DF")])
3029
3030 ;; %%% Kill this when call knows how to work this out.
3031 (define_split
3032   [(set (match_operand:DF 0 "push_operand" "")
3033         (match_operand:DF 1 "any_fp_register_operand" ""))]
3034   "reload_completed"
3035   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3036    (set (mem:DF (reg:P SP_REG)) (match_dup 1))]
3037   "")
3038
3039 (define_split
3040   [(set (match_operand:DF 0 "push_operand" "")
3041         (match_operand:DF 1 "general_operand" ""))]
3042   "reload_completed"
3043   [(const_int 0)]
3044   "ix86_split_long_move (operands); DONE;")
3045
3046 ;; Moving is usually shorter when only FP registers are used. This separate
3047 ;; movdf pattern avoids the use of integer registers for FP operations
3048 ;; when optimizing for size.
3049
3050 (define_insn "*movdf_nointeger"
3051   [(set (match_operand:DF 0 "nonimmediate_operand"
3052                         "=f,m,f,*r  ,o  ,Y2*x,Y2*x,Y2*x ,m  ")
3053         (match_operand:DF 1 "general_operand"
3054                         "fm,f,G,*roF,*Fr,C   ,Y2*x,mY2*x,Y2*x"))]
3055   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3056    && ((optimize_function_for_size_p (cfun)
3057        || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
3058    && (reload_in_progress || reload_completed
3059        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3060        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3061            && optimize_function_for_size_p (cfun)
3062            && !memory_operand (operands[0], DFmode)
3063            && standard_80387_constant_p (operands[1]))
3064        || GET_CODE (operands[1]) != CONST_DOUBLE
3065        || ((optimize_function_for_size_p (cfun)
3066             || !TARGET_MEMORY_MISMATCH_STALL
3067             || reload_in_progress || reload_completed)
3068            && memory_operand (operands[0], DFmode)))"
3069 {
3070   switch (which_alternative)
3071     {
3072     case 0:
3073     case 1:
3074       return output_387_reg_move (insn, operands);
3075
3076     case 2:
3077       return standard_80387_constant_opcode (operands[1]);
3078
3079     case 3:
3080     case 4:
3081       return "#";
3082     case 5:
3083       switch (get_attr_mode (insn))
3084         {
3085         case MODE_V4SF:
3086           return "%vxorps\t%0, %d0";
3087         case MODE_V2DF:
3088           return "%vxorpd\t%0, %d0";
3089         case MODE_TI:
3090           return "%vpxor\t%0, %d0";
3091         default:
3092           gcc_unreachable ();
3093         }
3094     case 6:
3095     case 7:
3096     case 8:
3097       switch (get_attr_mode (insn))
3098         {
3099         case MODE_V4SF:
3100           return "%vmovaps\t{%1, %0|%0, %1}";
3101         case MODE_V2DF:
3102           return "%vmovapd\t{%1, %0|%0, %1}";
3103         case MODE_TI:
3104           return "%vmovdqa\t{%1, %0|%0, %1}";
3105         case MODE_DI:
3106           return "%vmovq\t{%1, %0|%0, %1}";
3107         case MODE_DF:
3108           if (TARGET_AVX)
3109             {
3110               if (REG_P (operands[0]) && REG_P (operands[1]))
3111                 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3112               else
3113                 return "vmovsd\t{%1, %0|%0, %1}";
3114             }
3115           else
3116             return "movsd\t{%1, %0|%0, %1}";
3117         case MODE_V1DF:
3118           if (TARGET_AVX)
3119             {
3120               if (REG_P (operands[0]))
3121                 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
3122               else
3123                 return "vmovlpd\t{%1, %0|%0, %1}";
3124             }
3125           else
3126             return "movlpd\t{%1, %0|%0, %1}";
3127         case MODE_V2SF:
3128           if (TARGET_AVX)
3129             {
3130               if (REG_P (operands[0]))
3131                 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
3132               else
3133                 return "vmovlps\t{%1, %0|%0, %1}";
3134             }
3135           else
3136             return "movlps\t{%1, %0|%0, %1}";
3137         default:
3138           gcc_unreachable ();
3139         }
3140
3141     default:
3142       gcc_unreachable ();
3143     }
3144 }
3145   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3146    (set (attr "prefix")
3147      (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3148        (const_string "orig")
3149        (const_string "maybe_vex")))
3150    (set (attr "prefix_data16")
3151      (if_then_else (eq_attr "mode" "V1DF")
3152        (const_string "1")
3153        (const_string "*")))
3154    (set (attr "mode")
3155         (cond [(eq_attr "alternative" "0,1,2")
3156                  (const_string "DF")
3157                (eq_attr "alternative" "3,4")
3158                  (const_string "SI")
3159
3160                /* For SSE1, we have many fewer alternatives.  */
3161                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3162                  (cond [(eq_attr "alternative" "5,6")
3163                           (const_string "V4SF")
3164                        ]
3165                    (const_string "V2SF"))
3166
3167                /* xorps is one byte shorter.  */
3168                (eq_attr "alternative" "5")
3169                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3170                             (const_int 0))
3171                           (const_string "V4SF")
3172                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3173                             (const_int 0))
3174                           (const_string "TI")
3175                        ]
3176                        (const_string "V2DF"))
3177
3178                /* For architectures resolving dependencies on
3179                   whole SSE registers use APD move to break dependency
3180                   chains, otherwise use short move to avoid extra work.
3181
3182                   movaps encodes one byte shorter.  */
3183                (eq_attr "alternative" "6")
3184                  (cond
3185                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3186                         (const_int 0))
3187                       (const_string "V4SF")
3188                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3189                         (const_int 0))
3190                       (const_string "V2DF")
3191                    ]
3192                    (const_string "DF"))
3193                /* For architectures resolving dependencies on register
3194                   parts we may avoid extra work to zero out upper part
3195                   of register.  */
3196                (eq_attr "alternative" "7")
3197                  (if_then_else
3198                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3199                        (const_int 0))
3200                    (const_string "V1DF")
3201                    (const_string "DF"))
3202               ]
3203               (const_string "DF")))])
3204
3205 (define_insn "*movdf_integer_rex64"
3206   [(set (match_operand:DF 0 "nonimmediate_operand"
3207                 "=f,m,f,r  ,m ,Y2*x,Y2*x,Y2*x,m   ,Yi,r ")
3208         (match_operand:DF 1 "general_operand"
3209                 "fm,f,G,rmF,Fr,C   ,Y2*x,m   ,Y2*x,r ,Yi"))]
3210   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3211    && (reload_in_progress || reload_completed
3212        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3213        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3214            && optimize_function_for_size_p (cfun)
3215            && standard_80387_constant_p (operands[1]))
3216        || GET_CODE (operands[1]) != CONST_DOUBLE
3217        || memory_operand (operands[0], DFmode))"
3218 {
3219   switch (which_alternative)
3220     {
3221     case 0:
3222     case 1:
3223       return output_387_reg_move (insn, operands);
3224
3225     case 2:
3226       return standard_80387_constant_opcode (operands[1]);
3227
3228     case 3:
3229     case 4:
3230       return "#";
3231
3232     case 5:
3233       switch (get_attr_mode (insn))
3234         {
3235         case MODE_V4SF:
3236           return "%vxorps\t%0, %d0";
3237         case MODE_V2DF:
3238           return "%vxorpd\t%0, %d0";
3239         case MODE_TI:
3240           return "%vpxor\t%0, %d0";
3241         default:
3242           gcc_unreachable ();
3243         }
3244     case 6:
3245     case 7:
3246     case 8:
3247       switch (get_attr_mode (insn))
3248         {
3249         case MODE_V4SF:
3250           return "%vmovaps\t{%1, %0|%0, %1}";
3251         case MODE_V2DF:
3252           return "%vmovapd\t{%1, %0|%0, %1}";
3253         case MODE_TI:
3254           return "%vmovdqa\t{%1, %0|%0, %1}";
3255         case MODE_DI:
3256           return "%vmovq\t{%1, %0|%0, %1}";
3257         case MODE_DF:
3258           if (TARGET_AVX)
3259             {
3260               if (REG_P (operands[0]) && REG_P (operands[1]))
3261                 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3262               else
3263                 return "vmovsd\t{%1, %0|%0, %1}";
3264             }
3265           else
3266             return "movsd\t{%1, %0|%0, %1}";
3267         case MODE_V1DF:
3268           return "%vmovlpd\t{%1, %d0|%d0, %1}";
3269         case MODE_V2SF:
3270           return "%vmovlps\t{%1, %d0|%d0, %1}";
3271         default:
3272           gcc_unreachable ();
3273         }
3274
3275     case 9:
3276     case 10:
3277     return "%vmovd\t{%1, %0|%0, %1}";
3278
3279     default:
3280       gcc_unreachable();
3281     }
3282 }
3283   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
3284    (set (attr "prefix")
3285      (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3286        (const_string "orig")
3287        (const_string "maybe_vex")))
3288    (set (attr "prefix_data16")
3289      (if_then_else (eq_attr "mode" "V1DF")
3290        (const_string "1")
3291        (const_string "*")))
3292    (set (attr "mode")
3293         (cond [(eq_attr "alternative" "0,1,2")
3294                  (const_string "DF")
3295                (eq_attr "alternative" "3,4,9,10")
3296                  (const_string "DI")
3297
3298                /* For SSE1, we have many fewer alternatives.  */
3299                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3300                  (cond [(eq_attr "alternative" "5,6")
3301                           (const_string "V4SF")
3302                        ]
3303                    (const_string "V2SF"))
3304
3305                /* xorps is one byte shorter.  */
3306                (eq_attr "alternative" "5")
3307                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3308                             (const_int 0))
3309                           (const_string "V4SF")
3310                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3311                             (const_int 0))
3312                           (const_string "TI")
3313                        ]
3314                        (const_string "V2DF"))
3315
3316                /* For architectures resolving dependencies on
3317                   whole SSE registers use APD move to break dependency
3318                   chains, otherwise use short move to avoid extra work.
3319
3320                   movaps encodes one byte shorter.  */
3321                (eq_attr "alternative" "6")
3322                  (cond
3323                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3324                         (const_int 0))
3325                       (const_string "V4SF")
3326                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3327                         (const_int 0))
3328                       (const_string "V2DF")
3329                    ]
3330                    (const_string "DF"))
3331                /* For architectures resolving dependencies on register
3332                   parts we may avoid extra work to zero out upper part
3333                   of register.  */
3334                (eq_attr "alternative" "7")
3335                  (if_then_else
3336                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3337                        (const_int 0))
3338                    (const_string "V1DF")
3339                    (const_string "DF"))
3340               ]
3341               (const_string "DF")))])
3342
3343 (define_insn "*movdf_integer"
3344   [(set (match_operand:DF 0 "nonimmediate_operand"
3345                 "=f,m,f,r  ,o ,Y2*x,Y2*x,Y2*x,m   ")
3346         (match_operand:DF 1 "general_operand"
3347                 "fm,f,G,roF,Fr,C   ,Y2*x,m   ,Y2*x"))]
3348   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3349    && optimize_function_for_speed_p (cfun)
3350    && TARGET_INTEGER_DFMODE_MOVES
3351    && (reload_in_progress || reload_completed
3352        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3353        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3354            && optimize_function_for_size_p (cfun)
3355            && standard_80387_constant_p (operands[1]))
3356        || GET_CODE (operands[1]) != CONST_DOUBLE
3357        || memory_operand (operands[0], DFmode))"
3358 {
3359   switch (which_alternative)
3360     {
3361     case 0:
3362     case 1:
3363       return output_387_reg_move (insn, operands);
3364
3365     case 2:
3366       return standard_80387_constant_opcode (operands[1]);
3367
3368     case 3:
3369     case 4:
3370       return "#";
3371
3372     case 5:
3373       switch (get_attr_mode (insn))
3374         {
3375         case MODE_V4SF:
3376           return "xorps\t%0, %0";
3377         case MODE_V2DF:
3378           return "xorpd\t%0, %0";
3379         case MODE_TI:
3380           return "pxor\t%0, %0";
3381         default:
3382           gcc_unreachable ();
3383         }
3384     case 6:
3385     case 7:
3386     case 8:
3387       switch (get_attr_mode (insn))
3388         {
3389         case MODE_V4SF:
3390           return "movaps\t{%1, %0|%0, %1}";
3391         case MODE_V2DF:
3392           return "movapd\t{%1, %0|%0, %1}";
3393         case MODE_TI:
3394           return "movdqa\t{%1, %0|%0, %1}";
3395         case MODE_DI:
3396           return "movq\t{%1, %0|%0, %1}";
3397         case MODE_DF:
3398           return "movsd\t{%1, %0|%0, %1}";
3399         case MODE_V1DF:
3400           return "movlpd\t{%1, %0|%0, %1}";
3401         case MODE_V2SF:
3402           return "movlps\t{%1, %0|%0, %1}";
3403         default:
3404           gcc_unreachable ();
3405         }
3406
3407     default:
3408       gcc_unreachable();
3409     }
3410 }
3411   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3412    (set (attr "prefix_data16")
3413      (if_then_else (eq_attr "mode" "V1DF")
3414        (const_string "1")
3415        (const_string "*")))
3416    (set (attr "mode")
3417         (cond [(eq_attr "alternative" "0,1,2")
3418                  (const_string "DF")
3419                (eq_attr "alternative" "3,4")
3420                  (const_string "SI")
3421
3422                /* For SSE1, we have many fewer alternatives.  */
3423                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3424                  (cond [(eq_attr "alternative" "5,6")
3425                           (const_string "V4SF")
3426                        ]
3427                    (const_string "V2SF"))
3428
3429                /* xorps is one byte shorter.  */
3430                (eq_attr "alternative" "5")
3431                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3432                             (const_int 0))
3433                           (const_string "V4SF")
3434                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3435                             (const_int 0))
3436                           (const_string "TI")
3437                        ]
3438                        (const_string "V2DF"))
3439
3440                /* For architectures resolving dependencies on
3441                   whole SSE registers use APD move to break dependency
3442                   chains, otherwise use short move to avoid extra work.
3443
3444                   movaps encodes one byte shorter.  */
3445                (eq_attr "alternative" "6")
3446                  (cond
3447                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3448                         (const_int 0))
3449                       (const_string "V4SF")
3450                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3451                         (const_int 0))
3452                       (const_string "V2DF")
3453                    ]
3454                    (const_string "DF"))
3455                /* For architectures resolving dependencies on register
3456                   parts we may avoid extra work to zero out upper part
3457                   of register.  */
3458                (eq_attr "alternative" "7")
3459                  (if_then_else
3460                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3461                        (const_int 0))
3462                    (const_string "V1DF")
3463                    (const_string "DF"))
3464               ]
3465               (const_string "DF")))])
3466
3467 (define_split
3468   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3469         (match_operand:DF 1 "general_operand" ""))]
3470   "reload_completed
3471    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3472    && ! (ANY_FP_REG_P (operands[0]) ||
3473          (GET_CODE (operands[0]) == SUBREG
3474           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3475    && ! (ANY_FP_REG_P (operands[1]) ||
3476          (GET_CODE (operands[1]) == SUBREG
3477           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3478   [(const_int 0)]
3479   "ix86_split_long_move (operands); DONE;")
3480
3481 (define_insn "*swapdf"
3482   [(set (match_operand:DF 0 "fp_register_operand" "+f")
3483         (match_operand:DF 1 "fp_register_operand" "+f"))
3484    (set (match_dup 1)
3485         (match_dup 0))]
3486   "reload_completed || TARGET_80387"
3487 {
3488   if (STACK_TOP_P (operands[0]))
3489     return "fxch\t%1";
3490   else
3491     return "fxch\t%0";
3492 }
3493   [(set_attr "type" "fxch")
3494    (set_attr "mode" "DF")])
3495
3496 (define_expand "movxf"
3497   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3498         (match_operand:XF 1 "general_operand" ""))]
3499   ""
3500   "ix86_expand_move (XFmode, operands); DONE;")
3501
3502 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3503 ;; Size of pushdf using integer instructions is 3+3*memory operand size
3504 ;; Pushing using integer instructions is longer except for constants
3505 ;; and direct memory references.
3506 ;; (assuming that any given constant is pushed only once, but this ought to be
3507 ;;  handled elsewhere).
3508
3509 (define_insn "*pushxf_nointeger"
3510   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
3511         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
3512   "optimize_function_for_size_p (cfun)"
3513 {
3514   /* This insn should be already split before reg-stack.  */
3515   gcc_unreachable ();
3516 }
3517   [(set_attr "type" "multi")
3518    (set_attr "unit" "i387,*,*")
3519    (set_attr "mode" "XF,SI,SI")])
3520
3521 (define_insn "*pushxf_integer"
3522   [(set (match_operand:XF 0 "push_operand" "=<,<")
3523         (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
3524   "optimize_function_for_speed_p (cfun)"
3525 {
3526   /* This insn should be already split before reg-stack.  */
3527   gcc_unreachable ();
3528 }
3529   [(set_attr "type" "multi")
3530    (set_attr "unit" "i387,*")
3531    (set_attr "mode" "XF,SI")])
3532
3533 (define_split
3534   [(set (match_operand 0 "push_operand" "")
3535         (match_operand 1 "general_operand" ""))]
3536   "reload_completed
3537    && (GET_MODE (operands[0]) == XFmode
3538        || GET_MODE (operands[0]) == DFmode)
3539    && !ANY_FP_REG_P (operands[1])"
3540   [(const_int 0)]
3541   "ix86_split_long_move (operands); DONE;")
3542
3543 (define_split
3544   [(set (match_operand:XF 0 "push_operand" "")
3545         (match_operand:XF 1 "any_fp_register_operand" ""))]
3546   ""
3547   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3548    (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
3549   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3550
3551 ;; Do not use integer registers when optimizing for size
3552 (define_insn "*movxf_nointeger"
3553   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3554         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3555   "optimize_function_for_size_p (cfun)
3556    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3557    && (reload_in_progress || reload_completed
3558        || standard_80387_constant_p (operands[1])
3559        || GET_CODE (operands[1]) != CONST_DOUBLE
3560        || memory_operand (operands[0], XFmode))"
3561 {
3562   switch (which_alternative)
3563     {
3564     case 0:
3565     case 1:
3566       return output_387_reg_move (insn, operands);
3567
3568     case 2:
3569       return standard_80387_constant_opcode (operands[1]);
3570
3571     case 3: case 4:
3572       return "#";
3573     default:
3574       gcc_unreachable ();
3575     }
3576 }
3577   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3578    (set_attr "mode" "XF,XF,XF,SI,SI")])
3579
3580 (define_insn "*movxf_integer"
3581   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
3582         (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
3583   "optimize_function_for_speed_p (cfun)
3584    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3585    && (reload_in_progress || reload_completed
3586        || GET_CODE (operands[1]) != CONST_DOUBLE
3587        || memory_operand (operands[0], XFmode))"
3588 {
3589   switch (which_alternative)
3590     {
3591     case 0:
3592     case 1:
3593       return output_387_reg_move (insn, operands);
3594
3595     case 2:
3596       return standard_80387_constant_opcode (operands[1]);
3597
3598     case 3: case 4:
3599       return "#";
3600
3601     default:
3602       gcc_unreachable ();
3603     }
3604 }
3605   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3606    (set_attr "mode" "XF,XF,XF,SI,SI")])
3607
3608 (define_expand "movtf"
3609   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3610         (match_operand:TF 1 "nonimmediate_operand" ""))]
3611   "TARGET_SSE2"
3612 {
3613   ix86_expand_move (TFmode, operands);
3614   DONE;
3615 })
3616
3617 (define_insn "*movtf_internal"
3618   [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
3619         (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
3620   "TARGET_SSE2
3621    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3622 {
3623   switch (which_alternative)
3624     {
3625     case 0:
3626     case 1:
3627       if (get_attr_mode (insn) == MODE_V4SF)
3628         return "%vmovaps\t{%1, %0|%0, %1}";
3629       else
3630         return "%vmovdqa\t{%1, %0|%0, %1}";
3631     case 2:
3632       if (get_attr_mode (insn) == MODE_V4SF)
3633         return "%vxorps\t%0, %d0";
3634       else
3635         return "%vpxor\t%0, %d0";
3636     case 3:
3637     case 4:
3638         return "#";
3639     default:
3640       gcc_unreachable ();
3641     }
3642 }
3643   [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
3644    (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
3645    (set (attr "mode")
3646         (cond [(eq_attr "alternative" "0,2")
3647                  (if_then_else
3648                    (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3649                        (const_int 0))
3650                    (const_string "V4SF")
3651                    (const_string "TI"))
3652                (eq_attr "alternative" "1")
3653                  (if_then_else
3654                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3655                             (const_int 0))
3656                         (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3657                             (const_int 0)))
3658                    (const_string "V4SF")
3659                    (const_string "TI"))]
3660                (const_string "DI")))])
3661
3662 (define_insn "*pushtf_sse"
3663   [(set (match_operand:TF 0 "push_operand" "=<,<,<")
3664         (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
3665   "TARGET_SSE2"
3666 {
3667   /* This insn should be already split before reg-stack.  */
3668   gcc_unreachable ();
3669 }
3670   [(set_attr "type" "multi")
3671    (set_attr "unit" "sse,*,*")
3672    (set_attr "mode" "TF,SI,SI")])
3673
3674 (define_split
3675   [(set (match_operand:TF 0 "push_operand" "")
3676         (match_operand:TF 1 "general_operand" ""))]
3677   "TARGET_SSE2 && reload_completed
3678    && !SSE_REG_P (operands[1])"
3679   [(const_int 0)]
3680   "ix86_split_long_move (operands); DONE;")
3681
3682 (define_split
3683   [(set (match_operand:TF 0 "push_operand" "")
3684         (match_operand:TF 1 "any_fp_register_operand" ""))]
3685   "TARGET_SSE2"
3686   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3687    (set (mem:TF (reg:P SP_REG)) (match_dup 1))]
3688   "")
3689
3690 (define_split
3691   [(set (match_operand 0 "nonimmediate_operand" "")
3692         (match_operand 1 "general_operand" ""))]
3693   "reload_completed
3694    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3695    && GET_MODE (operands[0]) == XFmode
3696    && ! (ANY_FP_REG_P (operands[0]) ||
3697          (GET_CODE (operands[0]) == SUBREG
3698           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3699    && ! (ANY_FP_REG_P (operands[1]) ||
3700          (GET_CODE (operands[1]) == SUBREG
3701           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3702   [(const_int 0)]
3703   "ix86_split_long_move (operands); DONE;")
3704
3705 (define_split
3706   [(set (match_operand 0 "register_operand" "")
3707         (match_operand 1 "memory_operand" ""))]
3708   "reload_completed
3709    && MEM_P (operands[1])
3710    && (GET_MODE (operands[0]) == TFmode
3711        || GET_MODE (operands[0]) == XFmode
3712        || GET_MODE (operands[0]) == SFmode
3713        || GET_MODE (operands[0]) == DFmode)
3714    && (operands[2] = find_constant_src (insn))"
3715   [(set (match_dup 0) (match_dup 2))]
3716 {
3717   rtx c = operands[2];
3718   rtx r = operands[0];
3719
3720   if (GET_CODE (r) == SUBREG)
3721     r = SUBREG_REG (r);
3722
3723   if (SSE_REG_P (r))
3724     {
3725       if (!standard_sse_constant_p (c))
3726         FAIL;
3727     }
3728   else if (FP_REG_P (r))
3729     {
3730       if (!standard_80387_constant_p (c))
3731         FAIL;
3732     }
3733   else if (MMX_REG_P (r))
3734     FAIL;
3735 })
3736
3737 (define_split
3738   [(set (match_operand 0 "register_operand" "")
3739         (float_extend (match_operand 1 "memory_operand" "")))]
3740   "reload_completed
3741    && MEM_P (operands[1])
3742    && (GET_MODE (operands[0]) == TFmode
3743        || GET_MODE (operands[0]) == XFmode
3744        || GET_MODE (operands[0]) == SFmode
3745        || GET_MODE (operands[0]) == DFmode)
3746    && (operands[2] = find_constant_src (insn))"
3747   [(set (match_dup 0) (match_dup 2))]
3748 {
3749   rtx c = operands[2];
3750   rtx r = operands[0];
3751
3752   if (GET_CODE (r) == SUBREG)
3753     r = SUBREG_REG (r);
3754
3755   if (SSE_REG_P (r))
3756     {
3757       if (!standard_sse_constant_p (c))
3758         FAIL;
3759     }
3760   else if (FP_REG_P (r))
3761     {
3762       if (!standard_80387_constant_p (c))
3763         FAIL;
3764     }
3765   else if (MMX_REG_P (r))
3766     FAIL;
3767 })
3768
3769 (define_insn "swapxf"
3770   [(set (match_operand:XF 0 "register_operand" "+f")
3771         (match_operand:XF 1 "register_operand" "+f"))
3772    (set (match_dup 1)
3773         (match_dup 0))]
3774   "TARGET_80387"
3775 {
3776   if (STACK_TOP_P (operands[0]))
3777     return "fxch\t%1";
3778   else
3779     return "fxch\t%0";
3780 }
3781   [(set_attr "type" "fxch")
3782    (set_attr "mode" "XF")])
3783
3784 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3785 (define_split
3786   [(set (match_operand:X87MODEF 0 "register_operand" "")
3787         (match_operand:X87MODEF 1 "immediate_operand" ""))]
3788   "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3789    && (standard_80387_constant_p (operands[1]) == 8
3790        || standard_80387_constant_p (operands[1]) == 9)"
3791   [(set (match_dup 0)(match_dup 1))
3792    (set (match_dup 0)
3793         (neg:X87MODEF (match_dup 0)))]
3794 {
3795   REAL_VALUE_TYPE r;
3796
3797   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3798   if (real_isnegzero (&r))
3799     operands[1] = CONST0_RTX (<MODE>mode);
3800   else
3801     operands[1] = CONST1_RTX (<MODE>mode);
3802 })
3803
3804 (define_split
3805   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3806         (match_operand:TF 1 "general_operand" ""))]
3807   "reload_completed
3808    && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
3809   [(const_int 0)]
3810   "ix86_split_long_move (operands); DONE;")
3811 \f
3812 ;; Zero extension instructions
3813
3814 (define_expand "zero_extendhisi2"
3815   [(set (match_operand:SI 0 "register_operand" "")
3816      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3817   ""
3818 {
3819   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3820     {
3821       operands[1] = force_reg (HImode, operands[1]);
3822       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3823       DONE;
3824     }
3825 })
3826
3827 (define_insn "zero_extendhisi2_and"
3828   [(set (match_operand:SI 0 "register_operand" "=r")
3829      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3830    (clobber (reg:CC FLAGS_REG))]
3831   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3832   "#"
3833   [(set_attr "type" "alu1")
3834    (set_attr "mode" "SI")])
3835
3836 (define_split
3837   [(set (match_operand:SI 0 "register_operand" "")
3838         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3839    (clobber (reg:CC FLAGS_REG))]
3840   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND
3841    && optimize_function_for_speed_p (cfun)"
3842   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3843               (clobber (reg:CC FLAGS_REG))])]
3844   "")
3845
3846 (define_insn "*zero_extendhisi2_movzwl"
3847   [(set (match_operand:SI 0 "register_operand" "=r")
3848      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3849   "!TARGET_ZERO_EXTEND_WITH_AND
3850    || optimize_function_for_size_p (cfun)"
3851   "movz{wl|x}\t{%1, %0|%0, %1}"
3852   [(set_attr "type" "imovx")
3853    (set_attr "mode" "SI")])
3854
3855 (define_expand "zero_extendqihi2"
3856   [(parallel
3857     [(set (match_operand:HI 0 "register_operand" "")
3858        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3859      (clobber (reg:CC FLAGS_REG))])]
3860   ""
3861   "")
3862
3863 (define_insn "*zero_extendqihi2_and"
3864   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3865      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3866    (clobber (reg:CC FLAGS_REG))]
3867   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3868   "#"
3869   [(set_attr "type" "alu1")
3870    (set_attr "mode" "HI")])
3871
3872 (define_insn "*zero_extendqihi2_movzbw_and"
3873   [(set (match_operand:HI 0 "register_operand" "=r,r")
3874      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3875    (clobber (reg:CC FLAGS_REG))]
3876   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3877   "#"
3878   [(set_attr "type" "imovx,alu1")
3879    (set_attr "mode" "HI")])
3880
3881 ; zero extend to SImode here to avoid partial register stalls
3882 (define_insn "*zero_extendqihi2_movzbl"
3883   [(set (match_operand:HI 0 "register_operand" "=r")
3884      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3885   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3886    && reload_completed"
3887   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3888   [(set_attr "type" "imovx")
3889    (set_attr "mode" "SI")])
3890
3891 ;; For the movzbw case strip only the clobber
3892 (define_split
3893   [(set (match_operand:HI 0 "register_operand" "")
3894         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3895    (clobber (reg:CC FLAGS_REG))]
3896   "reload_completed
3897    && (!TARGET_ZERO_EXTEND_WITH_AND
3898        || optimize_function_for_size_p (cfun))
3899    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3900   [(set (match_operand:HI 0 "register_operand" "")
3901         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3902
3903 ;; When source and destination does not overlap, clear destination
3904 ;; first and then do the movb
3905 (define_split
3906   [(set (match_operand:HI 0 "register_operand" "")
3907         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3908    (clobber (reg:CC FLAGS_REG))]
3909   "reload_completed
3910    && ANY_QI_REG_P (operands[0])
3911    && (TARGET_ZERO_EXTEND_WITH_AND
3912        && optimize_function_for_speed_p (cfun))
3913    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3914   [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3915 {
3916   operands[2] = gen_lowpart (QImode, operands[0]);
3917   ix86_expand_clear (operands[0]);
3918 })
3919
3920 ;; Rest is handled by single and.
3921 (define_split
3922   [(set (match_operand:HI 0 "register_operand" "")
3923         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3924    (clobber (reg:CC FLAGS_REG))]
3925   "reload_completed
3926    && true_regnum (operands[0]) == true_regnum (operands[1])"
3927   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3928               (clobber (reg:CC FLAGS_REG))])]
3929   "")
3930
3931 (define_expand "zero_extendqisi2"
3932   [(parallel
3933     [(set (match_operand:SI 0 "register_operand" "")
3934        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3935      (clobber (reg:CC FLAGS_REG))])]
3936   ""
3937   "")
3938
3939 (define_insn "*zero_extendqisi2_and"
3940   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3941      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3942    (clobber (reg:CC FLAGS_REG))]
3943   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3944   "#"
3945   [(set_attr "type" "alu1")
3946    (set_attr "mode" "SI")])
3947
3948 (define_insn "*zero_extendqisi2_movzbl_and"
3949   [(set (match_operand:SI 0 "register_operand" "=r,r")
3950      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3951    (clobber (reg:CC FLAGS_REG))]
3952   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3953   "#"
3954   [(set_attr "type" "imovx,alu1")
3955    (set_attr "mode" "SI")])
3956
3957 (define_insn "*zero_extendqisi2_movzbl"
3958   [(set (match_operand:SI 0 "register_operand" "=r")
3959      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3960   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3961    && reload_completed"
3962   "movz{bl|x}\t{%1, %0|%0, %1}"
3963   [(set_attr "type" "imovx")
3964    (set_attr "mode" "SI")])
3965
3966 ;; For the movzbl case strip only the clobber
3967 (define_split
3968   [(set (match_operand:SI 0 "register_operand" "")
3969         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3970    (clobber (reg:CC FLAGS_REG))]
3971   "reload_completed
3972    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3973    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3974   [(set (match_dup 0)
3975         (zero_extend:SI (match_dup 1)))])
3976
3977 ;; When source and destination does not overlap, clear destination
3978 ;; first and then do the movb
3979 (define_split
3980   [(set (match_operand:SI 0 "register_operand" "")
3981         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3982    (clobber (reg:CC FLAGS_REG))]
3983   "reload_completed
3984    && ANY_QI_REG_P (operands[0])
3985    && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3986    && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3987    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3988   [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3989 {
3990   operands[2] = gen_lowpart (QImode, operands[0]);
3991   ix86_expand_clear (operands[0]);
3992 })
3993
3994 ;; Rest is handled by single and.
3995 (define_split
3996   [(set (match_operand:SI 0 "register_operand" "")
3997         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3998    (clobber (reg:CC FLAGS_REG))]
3999   "reload_completed
4000    && true_regnum (operands[0]) == true_regnum (operands[1])"
4001   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
4002               (clobber (reg:CC FLAGS_REG))])]
4003   "")
4004
4005 ;; %%% Kill me once multi-word ops are sane.
4006 (define_expand "zero_extendsidi2"
4007   [(set (match_operand:DI 0 "register_operand" "")
4008      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
4009   ""
4010 {
4011   if (!TARGET_64BIT)
4012     {
4013       emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
4014       DONE;
4015     }
4016 })
4017
4018 (define_insn "zero_extendsidi2_32"
4019   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
4020         (zero_extend:DI
4021          (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r   ,m  ,r   ,m")))
4022    (clobber (reg:CC FLAGS_REG))]
4023   "!TARGET_64BIT"
4024   "@
4025    #
4026    #
4027    #
4028    movd\t{%1, %0|%0, %1}
4029    movd\t{%1, %0|%0, %1}
4030    %vmovd\t{%1, %0|%0, %1}
4031    %vmovd\t{%1, %0|%0, %1}"
4032   [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
4033    (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
4034    (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
4035
4036 (define_insn "zero_extendsidi2_rex64"
4037   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
4038      (zero_extend:DI
4039        (match_operand:SI 1 "nonimmediate_operand"  "rm,0,r   ,m  ,r   ,m")))]
4040   "TARGET_64BIT"
4041   "@
4042    mov\t{%k1, %k0|%k0, %k1}
4043    #
4044    movd\t{%1, %0|%0, %1}
4045    movd\t{%1, %0|%0, %1}
4046    %vmovd\t{%1, %0|%0, %1}
4047    %vmovd\t{%1, %0|%0, %1}"
4048   [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
4049    (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
4050    (set_attr "prefix_0f" "0,*,*,*,*,*")
4051    (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
4052
4053 (define_split
4054   [(set (match_operand:DI 0 "memory_operand" "")
4055      (zero_extend:DI (match_dup 0)))]
4056   "TARGET_64BIT"
4057   [(set (match_dup 4) (const_int 0))]
4058   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4059
4060 (define_split
4061   [(set (match_operand:DI 0 "register_operand" "")
4062         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
4063    (clobber (reg:CC FLAGS_REG))]
4064   "!TARGET_64BIT && reload_completed
4065    && true_regnum (operands[0]) == true_regnum (operands[1])"
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 "nonimmediate_operand" "")
4071         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
4072    (clobber (reg:CC FLAGS_REG))]
4073   "!TARGET_64BIT && reload_completed
4074    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
4075   [(set (match_dup 3) (match_dup 1))
4076    (set (match_dup 4) (const_int 0))]
4077   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4078
4079 (define_insn "zero_extendhidi2"
4080   [(set (match_operand:DI 0 "register_operand" "=r")
4081      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
4082   "TARGET_64BIT"
4083   "movz{wl|x}\t{%1, %k0|%k0, %1}"
4084   [(set_attr "type" "imovx")
4085    (set_attr "mode" "SI")])
4086
4087 (define_insn "zero_extendqidi2"
4088   [(set (match_operand:DI 0 "register_operand" "=r")
4089      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
4090   "TARGET_64BIT"
4091   "movz{bl|x}\t{%1, %k0|%k0, %1}"
4092   [(set_attr "type" "imovx")
4093    (set_attr "mode" "SI")])
4094 \f
4095 ;; Sign extension instructions
4096
4097 (define_expand "extendsidi2"
4098   [(parallel [(set (match_operand:DI 0 "register_operand" "")
4099                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4100               (clobber (reg:CC FLAGS_REG))
4101               (clobber (match_scratch:SI 2 ""))])]
4102   ""
4103 {
4104   if (TARGET_64BIT)
4105     {
4106       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
4107       DONE;
4108     }
4109 })
4110
4111 (define_insn "*extendsidi2_1"
4112   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
4113         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
4114    (clobber (reg:CC FLAGS_REG))
4115    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
4116   "!TARGET_64BIT"
4117   "#")
4118
4119 (define_insn "extendsidi2_rex64"
4120   [(set (match_operand:DI 0 "register_operand" "=*a,r")
4121         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
4122   "TARGET_64BIT"
4123   "@
4124    {cltq|cdqe}
4125    movs{lq|x}\t{%1, %0|%0, %1}"
4126   [(set_attr "type" "imovx")
4127    (set_attr "mode" "DI")
4128    (set_attr "prefix_0f" "0")
4129    (set_attr "modrm" "0,1")])
4130
4131 (define_insn "extendhidi2"
4132   [(set (match_operand:DI 0 "register_operand" "=r")
4133         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
4134   "TARGET_64BIT"
4135   "movs{wq|x}\t{%1, %0|%0, %1}"
4136   [(set_attr "type" "imovx")
4137    (set_attr "mode" "DI")])
4138
4139 (define_insn "extendqidi2"
4140   [(set (match_operand:DI 0 "register_operand" "=r")
4141         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4142   "TARGET_64BIT"
4143   "movs{bq|x}\t{%1, %0|%0, %1}"
4144    [(set_attr "type" "imovx")
4145     (set_attr "mode" "DI")])
4146
4147 ;; Extend to memory case when source register does die.
4148 (define_split
4149   [(set (match_operand:DI 0 "memory_operand" "")
4150         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4151    (clobber (reg:CC FLAGS_REG))
4152    (clobber (match_operand:SI 2 "register_operand" ""))]
4153   "(reload_completed
4154     && dead_or_set_p (insn, operands[1])
4155     && !reg_mentioned_p (operands[1], operands[0]))"
4156   [(set (match_dup 3) (match_dup 1))
4157    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4158               (clobber (reg:CC FLAGS_REG))])
4159    (set (match_dup 4) (match_dup 1))]
4160   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4161
4162 ;; Extend to memory case when source register does not die.
4163 (define_split
4164   [(set (match_operand:DI 0 "memory_operand" "")
4165         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4166    (clobber (reg:CC FLAGS_REG))
4167    (clobber (match_operand:SI 2 "register_operand" ""))]
4168   "reload_completed"
4169   [(const_int 0)]
4170 {
4171   split_di (&operands[0], 1, &operands[3], &operands[4]);
4172
4173   emit_move_insn (operands[3], operands[1]);
4174
4175   /* Generate a cltd if possible and doing so it profitable.  */
4176   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4177       && true_regnum (operands[1]) == AX_REG
4178       && true_regnum (operands[2]) == DX_REG)
4179     {
4180       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
4181     }
4182   else
4183     {
4184       emit_move_insn (operands[2], operands[1]);
4185       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
4186     }
4187   emit_move_insn (operands[4], operands[2]);
4188   DONE;
4189 })
4190
4191 ;; Extend to register case.  Optimize case where source and destination
4192 ;; registers match and cases where we can use cltd.
4193 (define_split
4194   [(set (match_operand:DI 0 "register_operand" "")
4195         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4196    (clobber (reg:CC FLAGS_REG))
4197    (clobber (match_scratch:SI 2 ""))]
4198   "reload_completed"
4199   [(const_int 0)]
4200 {
4201   split_di (&operands[0], 1, &operands[3], &operands[4]);
4202
4203   if (true_regnum (operands[3]) != true_regnum (operands[1]))
4204     emit_move_insn (operands[3], operands[1]);
4205
4206   /* Generate a cltd if possible and doing so it profitable.  */
4207   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4208       && true_regnum (operands[3]) == AX_REG)
4209     {
4210       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
4211       DONE;
4212     }
4213
4214   if (true_regnum (operands[4]) != true_regnum (operands[1]))
4215     emit_move_insn (operands[4], operands[1]);
4216
4217   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
4218   DONE;
4219 })
4220
4221 (define_insn "extendhisi2"
4222   [(set (match_operand:SI 0 "register_operand" "=*a,r")
4223         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4224   ""
4225 {
4226   switch (get_attr_prefix_0f (insn))
4227     {
4228     case 0:
4229       return "{cwtl|cwde}";
4230     default:
4231       return "movs{wl|x}\t{%1, %0|%0, %1}";
4232     }
4233 }
4234   [(set_attr "type" "imovx")
4235    (set_attr "mode" "SI")
4236    (set (attr "prefix_0f")
4237      ;; movsx is short decodable while cwtl is vector decoded.
4238      (if_then_else (and (eq_attr "cpu" "!k6")
4239                         (eq_attr "alternative" "0"))
4240         (const_string "0")
4241         (const_string "1")))
4242    (set (attr "modrm")
4243      (if_then_else (eq_attr "prefix_0f" "0")
4244         (const_string "0")
4245         (const_string "1")))])
4246
4247 (define_insn "*extendhisi2_zext"
4248   [(set (match_operand:DI 0 "register_operand" "=*a,r")
4249         (zero_extend:DI
4250           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4251   "TARGET_64BIT"
4252 {
4253   switch (get_attr_prefix_0f (insn))
4254     {
4255     case 0:
4256       return "{cwtl|cwde}";
4257     default:
4258       return "movs{wl|x}\t{%1, %k0|%k0, %1}";
4259     }
4260 }
4261   [(set_attr "type" "imovx")
4262    (set_attr "mode" "SI")
4263    (set (attr "prefix_0f")
4264      ;; movsx is short decodable while cwtl is vector decoded.
4265      (if_then_else (and (eq_attr "cpu" "!k6")
4266                         (eq_attr "alternative" "0"))
4267         (const_string "0")
4268         (const_string "1")))
4269    (set (attr "modrm")
4270      (if_then_else (eq_attr "prefix_0f" "0")
4271         (const_string "0")
4272         (const_string "1")))])
4273
4274 (define_insn "extendqihi2"
4275   [(set (match_operand:HI 0 "register_operand" "=*a,r")
4276         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4277   ""
4278 {
4279   switch (get_attr_prefix_0f (insn))
4280     {
4281     case 0:
4282       return "{cbtw|cbw}";
4283     default:
4284       return "movs{bw|x}\t{%1, %0|%0, %1}";
4285     }
4286 }
4287   [(set_attr "type" "imovx")
4288    (set_attr "mode" "HI")
4289    (set (attr "prefix_0f")
4290      ;; movsx is short decodable while cwtl is vector decoded.
4291      (if_then_else (and (eq_attr "cpu" "!k6")
4292                         (eq_attr "alternative" "0"))
4293         (const_string "0")
4294         (const_string "1")))
4295    (set (attr "modrm")
4296      (if_then_else (eq_attr "prefix_0f" "0")
4297         (const_string "0")
4298         (const_string "1")))])
4299
4300 (define_insn "extendqisi2"
4301   [(set (match_operand:SI 0 "register_operand" "=r")
4302         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4303   ""
4304   "movs{bl|x}\t{%1, %0|%0, %1}"
4305    [(set_attr "type" "imovx")
4306     (set_attr "mode" "SI")])
4307
4308 (define_insn "*extendqisi2_zext"
4309   [(set (match_operand:DI 0 "register_operand" "=r")
4310         (zero_extend:DI
4311           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4312   "TARGET_64BIT"
4313   "movs{bl|x}\t{%1, %k0|%k0, %1}"
4314    [(set_attr "type" "imovx")
4315     (set_attr "mode" "SI")])
4316 \f
4317 ;; Conversions between float and double.
4318
4319 ;; These are all no-ops in the model used for the 80387.  So just
4320 ;; emit moves.
4321
4322 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4323 (define_insn "*dummy_extendsfdf2"
4324   [(set (match_operand:DF 0 "push_operand" "=<")
4325         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY2")))]
4326   "0"
4327   "#")
4328
4329 (define_split
4330   [(set (match_operand:DF 0 "push_operand" "")
4331         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
4332   ""
4333   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4334    (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4335
4336 (define_insn "*dummy_extendsfxf2"
4337   [(set (match_operand:XF 0 "push_operand" "=<")
4338         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
4339   "0"
4340   "#")
4341
4342 (define_split
4343   [(set (match_operand:XF 0 "push_operand" "")
4344         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
4345   ""
4346   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4347    (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4348   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4349
4350 (define_split
4351   [(set (match_operand:XF 0 "push_operand" "")
4352         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
4353   ""
4354   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4355    (set (mem:DF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4356   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4357
4358 (define_expand "extendsfdf2"
4359   [(set (match_operand:DF 0 "nonimmediate_operand" "")
4360         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
4361   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4362 {
4363   /* ??? Needed for compress_float_constant since all fp constants
4364      are LEGITIMATE_CONSTANT_P.  */
4365   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4366     {
4367       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4368           && standard_80387_constant_p (operands[1]) > 0)
4369         {
4370           operands[1] = simplify_const_unary_operation
4371             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4372           emit_move_insn_1 (operands[0], operands[1]);
4373           DONE;
4374         }
4375       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4376     }
4377 })
4378
4379 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4380    cvtss2sd:
4381       unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4382       cvtps2pd xmm2,xmm1
4383    We do the conversion post reload to avoid producing of 128bit spills
4384    that might lead to ICE on 32bit target.  The sequence unlikely combine
4385    anyway.  */
4386 (define_split
4387   [(set (match_operand:DF 0 "register_operand" "")
4388         (float_extend:DF
4389           (match_operand:SF 1 "nonimmediate_operand" "")))]
4390   "TARGET_USE_VECTOR_FP_CONVERTS
4391    && optimize_insn_for_speed_p ()
4392    && reload_completed && SSE_REG_P (operands[0])"
4393    [(set (match_dup 2)
4394          (float_extend:V2DF
4395            (vec_select:V2SF
4396              (match_dup 3)
4397              (parallel [(const_int 0) (const_int 1)]))))]
4398 {
4399   operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4400   operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4401   /* Use movss for loading from memory, unpcklps reg, reg for registers.
4402      Try to avoid move when unpacking can be done in source.  */
4403   if (REG_P (operands[1]))
4404     {
4405       /* If it is unsafe to overwrite upper half of source, we need
4406          to move to destination and unpack there.  */
4407       if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4408            || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4409           && true_regnum (operands[0]) != true_regnum (operands[1]))
4410         {
4411           rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4412           emit_move_insn (tmp, operands[1]);
4413         }
4414       else
4415         operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4416       emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4417                                              operands[3]));
4418     }
4419   else
4420     emit_insn (gen_vec_setv4sf_0 (operands[3],
4421                                   CONST0_RTX (V4SFmode), operands[1]));
4422 })
4423
4424 (define_insn "*extendsfdf2_mixed"
4425   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4426         (float_extend:DF
4427           (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4428   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4429 {
4430   switch (which_alternative)
4431     {
4432     case 0:
4433     case 1:
4434       return output_387_reg_move (insn, operands);
4435
4436     case 2:
4437       return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4438
4439     default:
4440       gcc_unreachable ();
4441     }
4442 }
4443   [(set_attr "type" "fmov,fmov,ssecvt")
4444    (set_attr "prefix" "orig,orig,maybe_vex")
4445    (set_attr "mode" "SF,XF,DF")])
4446
4447 (define_insn "*extendsfdf2_sse"
4448   [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4449         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4450   "TARGET_SSE2 && TARGET_SSE_MATH"
4451   "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4452   [(set_attr "type" "ssecvt")
4453    (set_attr "prefix" "maybe_vex")
4454    (set_attr "mode" "DF")])
4455
4456 (define_insn "*extendsfdf2_i387"
4457   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4458         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4459   "TARGET_80387"
4460   "* return output_387_reg_move (insn, operands);"
4461   [(set_attr "type" "fmov")
4462    (set_attr "mode" "SF,XF")])
4463
4464 (define_expand "extend<mode>xf2"
4465   [(set (match_operand:XF 0 "nonimmediate_operand" "")
4466         (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4467   "TARGET_80387"
4468 {
4469   /* ??? Needed for compress_float_constant since all fp constants
4470      are LEGITIMATE_CONSTANT_P.  */
4471   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4472     {
4473       if (standard_80387_constant_p (operands[1]) > 0)
4474         {
4475           operands[1] = simplify_const_unary_operation
4476             (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4477           emit_move_insn_1 (operands[0], operands[1]);
4478           DONE;
4479         }
4480       operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4481     }
4482 })
4483
4484 (define_insn "*extend<mode>xf2_i387"
4485   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4486         (float_extend:XF
4487           (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4488   "TARGET_80387"
4489   "* return output_387_reg_move (insn, operands);"
4490   [(set_attr "type" "fmov")
4491    (set_attr "mode" "<MODE>,XF")])
4492
4493 ;; %%% This seems bad bad news.
4494 ;; This cannot output into an f-reg because there is no way to be sure
4495 ;; of truncating in that case.  Otherwise this is just like a simple move
4496 ;; insn.  So we pretend we can output to a reg in order to get better
4497 ;; register preferencing, but we really use a stack slot.
4498
4499 ;; Conversion from DFmode to SFmode.
4500
4501 (define_expand "truncdfsf2"
4502   [(set (match_operand:SF 0 "nonimmediate_operand" "")
4503         (float_truncate:SF
4504           (match_operand:DF 1 "nonimmediate_operand" "")))]
4505   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4506 {
4507   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4508     ;
4509   else if (flag_unsafe_math_optimizations)
4510     ;
4511   else
4512     {
4513       enum ix86_stack_slot slot = (virtuals_instantiated
4514                                    ? SLOT_TEMP
4515                                    : SLOT_VIRTUAL);
4516       rtx temp = assign_386_stack_local (SFmode, slot);
4517       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4518       DONE;
4519     }
4520 })
4521
4522 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4523    cvtsd2ss:
4524       unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4525       cvtpd2ps xmm2,xmm1
4526    We do the conversion post reload to avoid producing of 128bit spills
4527    that might lead to ICE on 32bit target.  The sequence unlikely combine
4528    anyway.  */
4529 (define_split
4530   [(set (match_operand:SF 0 "register_operand" "")
4531         (float_truncate:SF
4532           (match_operand:DF 1 "nonimmediate_operand" "")))]
4533   "TARGET_USE_VECTOR_FP_CONVERTS
4534    && optimize_insn_for_speed_p ()
4535    && reload_completed && SSE_REG_P (operands[0])"
4536    [(set (match_dup 2)
4537          (vec_concat:V4SF
4538            (float_truncate:V2SF
4539              (match_dup 4))
4540            (match_dup 3)))]
4541 {
4542   operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4543   operands[3] = CONST0_RTX (V2SFmode);
4544   operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4545   /* Use movsd for loading from memory, unpcklpd for registers.
4546      Try to avoid move when unpacking can be done in source, or SSE3
4547      movddup is available.  */
4548   if (REG_P (operands[1]))
4549     {
4550       if (!TARGET_SSE3
4551           && true_regnum (operands[0]) != true_regnum (operands[1])
4552           && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4553               || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4554         {
4555           rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4556           emit_move_insn (tmp, operands[1]);
4557           operands[1] = tmp;
4558         }
4559       else if (!TARGET_SSE3)
4560         operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4561       emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4562     }
4563   else
4564     emit_insn (gen_sse2_loadlpd (operands[4],
4565                                  CONST0_RTX (V2DFmode), operands[1]));
4566 })
4567
4568 (define_expand "truncdfsf2_with_temp"
4569   [(parallel [(set (match_operand:SF 0 "" "")
4570                    (float_truncate:SF (match_operand:DF 1 "" "")))
4571               (clobber (match_operand:SF 2 "" ""))])]
4572   "")
4573
4574 (define_insn "*truncdfsf_fast_mixed"
4575   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm,x")
4576         (float_truncate:SF
4577           (match_operand:DF 1 "nonimmediate_operand" "f  ,xm")))]
4578   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4579 {
4580   switch (which_alternative)
4581     {
4582     case 0:
4583       return output_387_reg_move (insn, operands);
4584     case 1:
4585       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4586     default:
4587       gcc_unreachable ();
4588     }
4589 }
4590   [(set_attr "type" "fmov,ssecvt")
4591    (set_attr "prefix" "orig,maybe_vex")
4592    (set_attr "mode" "SF")])
4593
4594 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4595 ;; because nothing we do here is unsafe.
4596 (define_insn "*truncdfsf_fast_sse"
4597   [(set (match_operand:SF 0 "nonimmediate_operand"   "=x")
4598         (float_truncate:SF
4599           (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4600   "TARGET_SSE2 && TARGET_SSE_MATH"
4601   "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4602   [(set_attr "type" "ssecvt")
4603    (set_attr "prefix" "maybe_vex")
4604    (set_attr "mode" "SF")])
4605
4606 (define_insn "*truncdfsf_fast_i387"
4607   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
4608         (float_truncate:SF
4609           (match_operand:DF 1 "nonimmediate_operand" "f")))]
4610   "TARGET_80387 && flag_unsafe_math_optimizations"
4611   "* return output_387_reg_move (insn, operands);"
4612   [(set_attr "type" "fmov")
4613    (set_attr "mode" "SF")])
4614
4615 (define_insn "*truncdfsf_mixed"
4616   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,Y2 ,?f,?x,?*r")
4617         (float_truncate:SF
4618           (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4619    (clobber (match_operand:SF 2 "memory_operand"     "=X,X  ,m ,m ,m"))]
4620   "TARGET_MIX_SSE_I387"
4621 {
4622   switch (which_alternative)
4623     {
4624     case 0:
4625       return output_387_reg_move (insn, operands);
4626     case 1:
4627       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4628
4629     default:
4630       return "#";
4631     }
4632 }
4633   [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4634    (set_attr "unit" "*,*,i387,i387,i387")
4635    (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4636    (set_attr "mode" "SF")])
4637
4638 (define_insn "*truncdfsf_i387"
4639   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?f,?x,?*r")
4640         (float_truncate:SF
4641           (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4642    (clobber (match_operand:SF 2 "memory_operand"     "=X,m ,m ,m"))]
4643   "TARGET_80387"
4644 {
4645   switch (which_alternative)
4646     {
4647     case 0:
4648       return output_387_reg_move (insn, operands);
4649
4650     default:
4651       return "#";
4652     }
4653 }
4654   [(set_attr "type" "fmov,multi,multi,multi")
4655    (set_attr "unit" "*,i387,i387,i387")
4656    (set_attr "mode" "SF")])
4657
4658 (define_insn "*truncdfsf2_i387_1"
4659   [(set (match_operand:SF 0 "memory_operand" "=m")
4660         (float_truncate:SF
4661           (match_operand:DF 1 "register_operand" "f")))]
4662   "TARGET_80387
4663    && !(TARGET_SSE2 && TARGET_SSE_MATH)
4664    && !TARGET_MIX_SSE_I387"
4665   "* return output_387_reg_move (insn, operands);"
4666   [(set_attr "type" "fmov")
4667    (set_attr "mode" "SF")])
4668
4669 (define_split
4670   [(set (match_operand:SF 0 "register_operand" "")
4671         (float_truncate:SF
4672          (match_operand:DF 1 "fp_register_operand" "")))
4673    (clobber (match_operand 2 "" ""))]
4674   "reload_completed"
4675   [(set (match_dup 2) (match_dup 1))
4676    (set (match_dup 0) (match_dup 2))]
4677 {
4678   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4679 })
4680
4681 ;; Conversion from XFmode to {SF,DF}mode
4682
4683 (define_expand "truncxf<mode>2"
4684   [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4685                    (float_truncate:MODEF
4686                      (match_operand:XF 1 "register_operand" "")))
4687               (clobber (match_dup 2))])]
4688   "TARGET_80387"
4689 {
4690   if (flag_unsafe_math_optimizations)
4691     {
4692       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4693       emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4694       if (reg != operands[0])
4695         emit_move_insn (operands[0], reg);
4696       DONE;
4697     }
4698   else
4699     {
4700      enum ix86_stack_slot slot = (virtuals_instantiated
4701                                   ? SLOT_TEMP
4702                                   : SLOT_VIRTUAL);
4703       operands[2] = assign_386_stack_local (<MODE>mode, slot);
4704     }
4705 })
4706
4707 (define_insn "*truncxfsf2_mixed"
4708   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4709         (float_truncate:SF
4710           (match_operand:XF 1 "register_operand"   "f ,f ,f ,f")))
4711    (clobber (match_operand:SF 2 "memory_operand"   "=X,m ,m ,m"))]
4712   "TARGET_80387"
4713 {
4714   gcc_assert (!which_alternative);
4715   return output_387_reg_move (insn, operands);
4716 }
4717   [(set_attr "type" "fmov,multi,multi,multi")
4718    (set_attr "unit" "*,i387,i387,i387")
4719    (set_attr "mode" "SF")])
4720
4721 (define_insn "*truncxfdf2_mixed"
4722   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4723         (float_truncate:DF
4724           (match_operand:XF 1 "register_operand"   "f ,f ,f  ,f")))
4725    (clobber (match_operand:DF 2 "memory_operand"   "=X,m ,m  ,m"))]
4726   "TARGET_80387"
4727 {
4728   gcc_assert (!which_alternative);
4729   return output_387_reg_move (insn, operands);
4730 }
4731   [(set_attr "type" "fmov,multi,multi,multi")
4732    (set_attr "unit" "*,i387,i387,i387")
4733    (set_attr "mode" "DF")])
4734
4735 (define_insn "truncxf<mode>2_i387_noop"
4736   [(set (match_operand:MODEF 0 "register_operand" "=f")
4737         (float_truncate:MODEF
4738           (match_operand:XF 1 "register_operand" "f")))]
4739   "TARGET_80387 && flag_unsafe_math_optimizations"
4740   "* return output_387_reg_move (insn, operands);"
4741   [(set_attr "type" "fmov")
4742    (set_attr "mode" "<MODE>")])
4743
4744 (define_insn "*truncxf<mode>2_i387"
4745   [(set (match_operand:MODEF 0 "memory_operand" "=m")
4746         (float_truncate:MODEF
4747           (match_operand:XF 1 "register_operand" "f")))]
4748   "TARGET_80387"
4749   "* return output_387_reg_move (insn, operands);"
4750   [(set_attr "type" "fmov")
4751    (set_attr "mode" "<MODE>")])
4752
4753 (define_split
4754   [(set (match_operand:MODEF 0 "register_operand" "")
4755         (float_truncate:MODEF
4756           (match_operand:XF 1 "register_operand" "")))
4757    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4758   "TARGET_80387 && reload_completed"
4759   [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4760    (set (match_dup 0) (match_dup 2))]
4761   "")
4762
4763 (define_split
4764   [(set (match_operand:MODEF 0 "memory_operand" "")
4765         (float_truncate:MODEF
4766           (match_operand:XF 1 "register_operand" "")))
4767    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4768   "TARGET_80387"
4769   [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]
4770   "")
4771 \f
4772 ;; Signed conversion to DImode.
4773
4774 (define_expand "fix_truncxfdi2"
4775   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4776                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4777               (clobber (reg:CC FLAGS_REG))])]
4778   "TARGET_80387"
4779 {
4780   if (TARGET_FISTTP)
4781    {
4782      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4783      DONE;
4784    }
4785 })
4786
4787 (define_expand "fix_trunc<mode>di2"
4788   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4789                    (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4790               (clobber (reg:CC FLAGS_REG))])]
4791   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4792 {
4793   if (TARGET_FISTTP
4794       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4795    {
4796      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4797      DONE;
4798    }
4799   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4800    {
4801      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4802      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4803      if (out != operands[0])
4804         emit_move_insn (operands[0], out);
4805      DONE;
4806    }
4807 })
4808
4809 ;; Signed conversion to SImode.
4810
4811 (define_expand "fix_truncxfsi2"
4812   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4813                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4814               (clobber (reg:CC FLAGS_REG))])]
4815   "TARGET_80387"
4816 {
4817   if (TARGET_FISTTP)
4818    {
4819      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4820      DONE;
4821    }
4822 })
4823
4824 (define_expand "fix_trunc<mode>si2"
4825   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4826                    (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4827               (clobber (reg:CC FLAGS_REG))])]
4828   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4829 {
4830   if (TARGET_FISTTP
4831       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4832    {
4833      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4834      DONE;
4835    }
4836   if (SSE_FLOAT_MODE_P (<MODE>mode))
4837    {
4838      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4839      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4840      if (out != operands[0])
4841         emit_move_insn (operands[0], out);
4842      DONE;
4843    }
4844 })
4845
4846 ;; Signed conversion to HImode.
4847
4848 (define_expand "fix_trunc<mode>hi2"
4849   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4850                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4851               (clobber (reg:CC FLAGS_REG))])]
4852   "TARGET_80387
4853    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4854 {
4855   if (TARGET_FISTTP)
4856    {
4857      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4858      DONE;
4859    }
4860 })
4861
4862 ;; Unsigned conversion to SImode.
4863
4864 (define_expand "fixuns_trunc<mode>si2"
4865   [(parallel
4866     [(set (match_operand:SI 0 "register_operand" "")
4867           (unsigned_fix:SI
4868             (match_operand:MODEF 1 "nonimmediate_operand" "")))
4869      (use (match_dup 2))
4870      (clobber (match_scratch:<ssevecmode> 3 ""))
4871      (clobber (match_scratch:<ssevecmode> 4 ""))])]
4872   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4873 {
4874   enum machine_mode mode = <MODE>mode;
4875   enum machine_mode vecmode = <ssevecmode>mode;
4876   REAL_VALUE_TYPE TWO31r;
4877   rtx two31;
4878
4879   if (optimize_insn_for_size_p ())
4880     FAIL;
4881
4882   real_ldexp (&TWO31r, &dconst1, 31);
4883   two31 = const_double_from_real_value (TWO31r, mode);
4884   two31 = ix86_build_const_vector (mode, true, two31);
4885   operands[2] = force_reg (vecmode, two31);
4886 })
4887
4888 (define_insn_and_split "*fixuns_trunc<mode>_1"
4889   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4890         (unsigned_fix:SI
4891           (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4892    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
4893    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4894    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4895   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4896    && optimize_function_for_speed_p (cfun)"
4897   "#"
4898   "&& reload_completed"
4899   [(const_int 0)]
4900 {
4901   ix86_split_convert_uns_si_sse (operands);
4902   DONE;
4903 })
4904
4905 ;; Unsigned conversion to HImode.
4906 ;; Without these patterns, we'll try the unsigned SI conversion which
4907 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4908
4909 (define_expand "fixuns_trunc<mode>hi2"
4910   [(set (match_dup 2)
4911         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4912    (set (match_operand:HI 0 "nonimmediate_operand" "")
4913         (subreg:HI (match_dup 2) 0))]
4914   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4915   "operands[2] = gen_reg_rtx (SImode);")
4916
4917 ;; When SSE is available, it is always faster to use it!
4918 (define_insn "fix_trunc<mode>di_sse"
4919   [(set (match_operand:DI 0 "register_operand" "=r,r")
4920         (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4921   "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4922    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4923   "%vcvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4924   [(set_attr "type" "sseicvt")
4925    (set_attr "prefix" "maybe_vex")
4926    (set_attr "prefix_rex" "1")
4927    (set_attr "mode" "<MODE>")
4928    (set_attr "athlon_decode" "double,vector")
4929    (set_attr "amdfam10_decode" "double,double")])
4930
4931 (define_insn "fix_trunc<mode>si_sse"
4932   [(set (match_operand:SI 0 "register_operand" "=r,r")
4933         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4934   "SSE_FLOAT_MODE_P (<MODE>mode)
4935    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4936   "%vcvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4937   [(set_attr "type" "sseicvt")
4938    (set_attr "prefix" "maybe_vex")
4939    (set_attr "mode" "<MODE>")
4940    (set_attr "athlon_decode" "double,vector")
4941    (set_attr "amdfam10_decode" "double,double")])
4942
4943 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4944 (define_peephole2
4945   [(set (match_operand:MODEF 0 "register_operand" "")
4946         (match_operand:MODEF 1 "memory_operand" ""))
4947    (set (match_operand:SSEMODEI24 2 "register_operand" "")
4948         (fix:SSEMODEI24 (match_dup 0)))]
4949   "TARGET_SHORTEN_X87_SSE
4950    && peep2_reg_dead_p (2, operands[0])"
4951   [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4952   "")
4953
4954 ;; Avoid vector decoded forms of the instruction.
4955 (define_peephole2
4956   [(match_scratch:DF 2 "Y2")
4957    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4958         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4959   "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4960   [(set (match_dup 2) (match_dup 1))
4961    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4962   "")
4963
4964 (define_peephole2
4965   [(match_scratch:SF 2 "x")
4966    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4967         (fix:SSEMODEI24 (match_operand:SF 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_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4974   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4975         (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4976   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4977    && TARGET_FISTTP
4978    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4979          && (TARGET_64BIT || <MODE>mode != DImode))
4980         && TARGET_SSE_MATH)
4981    && can_create_pseudo_p ()"
4982   "#"
4983   "&& 1"
4984   [(const_int 0)]
4985 {
4986   if (memory_operand (operands[0], VOIDmode))
4987     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4988   else
4989     {
4990       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4991       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4992                                                             operands[1],
4993                                                             operands[2]));
4994     }
4995   DONE;
4996 }
4997   [(set_attr "type" "fisttp")
4998    (set_attr "mode" "<MODE>")])
4999
5000 (define_insn "fix_trunc<mode>_i387_fisttp"
5001   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
5002         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
5003    (clobber (match_scratch:XF 2 "=&1f"))]
5004   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5005    && TARGET_FISTTP
5006    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5007          && (TARGET_64BIT || <MODE>mode != DImode))
5008         && TARGET_SSE_MATH)"
5009   "* return output_fix_trunc (insn, operands, 1);"
5010   [(set_attr "type" "fisttp")
5011    (set_attr "mode" "<MODE>")])
5012
5013 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
5014   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
5015         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
5016    (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
5017    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
5018   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5019    && TARGET_FISTTP
5020    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5021         && (TARGET_64BIT || <MODE>mode != DImode))
5022         && TARGET_SSE_MATH)"
5023   "#"
5024   [(set_attr "type" "fisttp")
5025    (set_attr "mode" "<MODE>")])
5026
5027 (define_split
5028   [(set (match_operand:X87MODEI 0 "register_operand" "")
5029         (fix:X87MODEI (match_operand 1 "register_operand" "")))
5030    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
5031    (clobber (match_scratch 3 ""))]
5032   "reload_completed"
5033   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
5034               (clobber (match_dup 3))])
5035    (set (match_dup 0) (match_dup 2))]
5036   "")
5037
5038 (define_split
5039   [(set (match_operand:X87MODEI 0 "memory_operand" "")
5040         (fix:X87MODEI (match_operand 1 "register_operand" "")))
5041    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
5042    (clobber (match_scratch 3 ""))]
5043   "reload_completed"
5044   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
5045               (clobber (match_dup 3))])]
5046   "")
5047
5048 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
5049 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
5050 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
5051 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
5052 ;; function in i386.c.
5053 (define_insn_and_split "*fix_trunc<mode>_i387_1"
5054   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
5055         (fix:X87MODEI (match_operand 1 "register_operand" "")))
5056    (clobber (reg:CC FLAGS_REG))]
5057   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5058    && !TARGET_FISTTP
5059    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5060          && (TARGET_64BIT || <MODE>mode != DImode))
5061    && can_create_pseudo_p ()"
5062   "#"
5063   "&& 1"
5064   [(const_int 0)]
5065 {
5066   ix86_optimize_mode_switching[I387_TRUNC] = 1;
5067
5068   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
5069   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
5070   if (memory_operand (operands[0], VOIDmode))
5071     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
5072                                          operands[2], operands[3]));
5073   else
5074     {
5075       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
5076       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
5077                                                      operands[2], operands[3],
5078                                                      operands[4]));
5079     }
5080   DONE;
5081 }
5082   [(set_attr "type" "fistp")
5083    (set_attr "i387_cw" "trunc")
5084    (set_attr "mode" "<MODE>")])
5085
5086 (define_insn "fix_truncdi_i387"
5087   [(set (match_operand:DI 0 "memory_operand" "=m")
5088         (fix:DI (match_operand 1 "register_operand" "f")))
5089    (use (match_operand:HI 2 "memory_operand" "m"))
5090    (use (match_operand:HI 3 "memory_operand" "m"))
5091    (clobber (match_scratch:XF 4 "=&1f"))]
5092   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5093    && !TARGET_FISTTP
5094    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5095   "* return output_fix_trunc (insn, operands, 0);"
5096   [(set_attr "type" "fistp")
5097    (set_attr "i387_cw" "trunc")
5098    (set_attr "mode" "DI")])
5099
5100 (define_insn "fix_truncdi_i387_with_temp"
5101   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
5102         (fix:DI (match_operand 1 "register_operand" "f,f")))
5103    (use (match_operand:HI 2 "memory_operand" "m,m"))
5104    (use (match_operand:HI 3 "memory_operand" "m,m"))
5105    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
5106    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
5107   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5108    && !TARGET_FISTTP
5109    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5110   "#"
5111   [(set_attr "type" "fistp")
5112    (set_attr "i387_cw" "trunc")
5113    (set_attr "mode" "DI")])
5114
5115 (define_split
5116   [(set (match_operand:DI 0 "register_operand" "")
5117         (fix:DI (match_operand 1 "register_operand" "")))
5118    (use (match_operand:HI 2 "memory_operand" ""))
5119    (use (match_operand:HI 3 "memory_operand" ""))
5120    (clobber (match_operand:DI 4 "memory_operand" ""))
5121    (clobber (match_scratch 5 ""))]
5122   "reload_completed"
5123   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
5124               (use (match_dup 2))
5125               (use (match_dup 3))
5126               (clobber (match_dup 5))])
5127    (set (match_dup 0) (match_dup 4))]
5128   "")
5129
5130 (define_split
5131   [(set (match_operand:DI 0 "memory_operand" "")
5132         (fix:DI (match_operand 1 "register_operand" "")))
5133    (use (match_operand:HI 2 "memory_operand" ""))
5134    (use (match_operand:HI 3 "memory_operand" ""))
5135    (clobber (match_operand:DI 4 "memory_operand" ""))
5136    (clobber (match_scratch 5 ""))]
5137   "reload_completed"
5138   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
5139               (use (match_dup 2))
5140               (use (match_dup 3))
5141               (clobber (match_dup 5))])]
5142   "")
5143
5144 (define_insn "fix_trunc<mode>_i387"
5145   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
5146         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
5147    (use (match_operand:HI 2 "memory_operand" "m"))
5148    (use (match_operand:HI 3 "memory_operand" "m"))]
5149   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5150    && !TARGET_FISTTP
5151    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5152   "* return output_fix_trunc (insn, operands, 0);"
5153   [(set_attr "type" "fistp")
5154    (set_attr "i387_cw" "trunc")
5155    (set_attr "mode" "<MODE>")])
5156
5157 (define_insn "fix_trunc<mode>_i387_with_temp"
5158   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
5159         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
5160    (use (match_operand:HI 2 "memory_operand" "m,m"))
5161    (use (match_operand:HI 3 "memory_operand" "m,m"))
5162    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
5163   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5164    && !TARGET_FISTTP
5165    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5166   "#"
5167   [(set_attr "type" "fistp")
5168    (set_attr "i387_cw" "trunc")
5169    (set_attr "mode" "<MODE>")])
5170
5171 (define_split
5172   [(set (match_operand:X87MODEI12 0 "register_operand" "")
5173         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5174    (use (match_operand:HI 2 "memory_operand" ""))
5175    (use (match_operand:HI 3 "memory_operand" ""))
5176    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5177   "reload_completed"
5178   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
5179               (use (match_dup 2))
5180               (use (match_dup 3))])
5181    (set (match_dup 0) (match_dup 4))]
5182   "")
5183
5184 (define_split
5185   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
5186         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5187    (use (match_operand:HI 2 "memory_operand" ""))
5188    (use (match_operand:HI 3 "memory_operand" ""))
5189    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5190   "reload_completed"
5191   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
5192               (use (match_dup 2))
5193               (use (match_dup 3))])]
5194   "")
5195
5196 (define_insn "x86_fnstcw_1"
5197   [(set (match_operand:HI 0 "memory_operand" "=m")
5198         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
5199   "TARGET_80387"
5200   "fnstcw\t%0"
5201   [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5202    (set_attr "mode" "HI")
5203    (set_attr "unit" "i387")])
5204
5205 (define_insn "x86_fldcw_1"
5206   [(set (reg:HI FPCR_REG)
5207         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
5208   "TARGET_80387"
5209   "fldcw\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    (set_attr "athlon_decode" "vector")
5214    (set_attr "amdfam10_decode" "vector")])
5215 \f
5216 ;; Conversion between fixed point and floating point.
5217
5218 ;; Even though we only accept memory inputs, the backend _really_
5219 ;; wants to be able to do this between registers.
5220
5221 (define_expand "floathi<mode>2"
5222   [(set (match_operand:X87MODEF 0 "register_operand" "")
5223         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
5224   "TARGET_80387
5225    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5226        || TARGET_MIX_SSE_I387)"
5227   "")
5228
5229 ;; Pre-reload splitter to add memory clobber to the pattern.
5230 (define_insn_and_split "*floathi<mode>2_1"
5231   [(set (match_operand:X87MODEF 0 "register_operand" "")
5232         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
5233   "TARGET_80387
5234    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5235        || TARGET_MIX_SSE_I387)
5236    && can_create_pseudo_p ()"
5237   "#"
5238   "&& 1"
5239   [(parallel [(set (match_dup 0)
5240               (float:X87MODEF (match_dup 1)))
5241    (clobber (match_dup 2))])]
5242   "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
5243
5244 (define_insn "*floathi<mode>2_i387_with_temp"
5245   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5246         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
5247   (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
5248   "TARGET_80387
5249    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5250        || TARGET_MIX_SSE_I387)"
5251   "#"
5252   [(set_attr "type" "fmov,multi")
5253    (set_attr "mode" "<MODE>")
5254    (set_attr "unit" "*,i387")
5255    (set_attr "fp_int_src" "true")])
5256
5257 (define_insn "*floathi<mode>2_i387"
5258   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5259         (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
5260   "TARGET_80387
5261    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5262        || TARGET_MIX_SSE_I387)"
5263   "fild%Z1\t%1"
5264   [(set_attr "type" "fmov")
5265    (set_attr "mode" "<MODE>")
5266    (set_attr "fp_int_src" "true")])
5267
5268 (define_split
5269   [(set (match_operand:X87MODEF 0 "register_operand" "")
5270         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
5271    (clobber (match_operand:HI 2 "memory_operand" ""))]
5272   "TARGET_80387
5273    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5274        || TARGET_MIX_SSE_I387)
5275    && reload_completed"
5276   [(set (match_dup 2) (match_dup 1))
5277    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5278   "")
5279
5280 (define_split
5281   [(set (match_operand:X87MODEF 0 "register_operand" "")
5282         (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
5283    (clobber (match_operand:HI 2 "memory_operand" ""))]
5284    "TARGET_80387
5285     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5286         || TARGET_MIX_SSE_I387)
5287     && reload_completed"
5288   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5289   "")
5290
5291 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
5292   [(set (match_operand:X87MODEF 0 "register_operand" "")
5293         (float:X87MODEF
5294           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
5295   "TARGET_80387
5296    || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5297        && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
5298 {
5299   if (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5300         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5301       && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode))
5302     {
5303       rtx reg = gen_reg_rtx (XFmode);
5304       rtx insn;
5305
5306       emit_insn (gen_float<SSEMODEI24:mode>xf2 (reg, operands[1]));
5307
5308       if (<X87MODEF:MODE>mode == SFmode)
5309         insn = gen_truncxfsf2 (operands[0], reg);
5310       else if (<X87MODEF:MODE>mode == DFmode)
5311         insn = gen_truncxfdf2 (operands[0], reg);
5312       else
5313         gcc_unreachable ();
5314
5315       emit_insn (insn);
5316       DONE;
5317     }
5318 })
5319
5320 ;; Pre-reload splitter to add memory clobber to the pattern.
5321 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
5322   [(set (match_operand:X87MODEF 0 "register_operand" "")
5323         (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
5324   "((TARGET_80387
5325      && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5326      && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5327            && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5328          || TARGET_MIX_SSE_I387))
5329     || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5330         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
5331         && ((<SSEMODEI24:MODE>mode == SImode
5332              && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
5333              && optimize_function_for_speed_p (cfun)
5334              && flag_trapping_math)
5335             || !(TARGET_INTER_UNIT_CONVERSIONS
5336                  || optimize_function_for_size_p (cfun)))))
5337    && can_create_pseudo_p ()"
5338   "#"
5339   "&& 1"
5340   [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
5341               (clobber (match_dup 2))])]
5342 {
5343   operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
5344
5345   /* Avoid store forwarding (partial memory) stall penalty
5346      by passing DImode value through XMM registers.  */
5347   if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
5348       && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5349       && optimize_function_for_speed_p (cfun))
5350     {
5351       emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
5352                                                             operands[1],
5353                                                             operands[2]));
5354       DONE;
5355     }
5356 })
5357
5358 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
5359   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
5360         (float:MODEF
5361           (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
5362    (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
5363   "TARGET_SSE2 && TARGET_MIX_SSE_I387
5364    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5365   "#"
5366   [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
5367    (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
5368    (set_attr "unit" "*,i387,*,*,*")
5369    (set_attr "athlon_decode" "*,*,double,direct,double")
5370    (set_attr "amdfam10_decode" "*,*,vector,double,double")
5371    (set_attr "fp_int_src" "true")])
5372
5373 (define_insn "*floatsi<mode>2_vector_mixed"
5374   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5375         (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
5376   "TARGET_SSE2 && TARGET_MIX_SSE_I387
5377    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5378   "@
5379    fild%Z1\t%1
5380    #"
5381   [(set_attr "type" "fmov,sseicvt")
5382    (set_attr "mode" "<MODE>,<ssevecmode>")
5383    (set_attr "unit" "i387,*")
5384    (set_attr "athlon_decode" "*,direct")
5385    (set_attr "amdfam10_decode" "*,double")
5386    (set_attr "fp_int_src" "true")])
5387
5388 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
5389   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
5390         (float:MODEF
5391           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
5392   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
5393   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5394    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
5395   "#"
5396   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5397    (set_attr "mode" "<MODEF:MODE>")
5398    (set_attr "unit" "*,i387,*,*")
5399    (set_attr "athlon_decode" "*,*,double,direct")
5400    (set_attr "amdfam10_decode" "*,*,vector,double")
5401    (set_attr "fp_int_src" "true")])
5402
5403 (define_split
5404   [(set (match_operand:MODEF 0 "register_operand" "")
5405         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5406    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5407   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5408    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5409    && TARGET_INTER_UNIT_CONVERSIONS
5410    && reload_completed
5411    && (SSE_REG_P (operands[0])
5412        || (GET_CODE (operands[0]) == SUBREG
5413            && SSE_REG_P (operands[0])))"
5414   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5415   "")
5416
5417 (define_split
5418   [(set (match_operand:MODEF 0 "register_operand" "")
5419         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5420    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5421   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5422    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5423    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5424    && reload_completed
5425    && (SSE_REG_P (operands[0])
5426        || (GET_CODE (operands[0]) == SUBREG
5427            && SSE_REG_P (operands[0])))"
5428   [(set (match_dup 2) (match_dup 1))
5429    (set (match_dup 0) (float:MODEF (match_dup 2)))]
5430   "")
5431
5432 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5433   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5434         (float:MODEF
5435           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
5436   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5437    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5438    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5439   "@
5440    fild%Z1\t%1
5441    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
5442    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5443   [(set_attr "type" "fmov,sseicvt,sseicvt")
5444    (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5445    (set_attr "mode" "<MODEF:MODE>")
5446    (set (attr "prefix_rex")
5447      (if_then_else
5448        (and (eq_attr "prefix" "maybe_vex")
5449             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5450        (const_string "1")
5451        (const_string "*")))
5452    (set_attr "unit" "i387,*,*")
5453    (set_attr "athlon_decode" "*,double,direct")
5454    (set_attr "amdfam10_decode" "*,vector,double")
5455    (set_attr "fp_int_src" "true")])
5456
5457 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5458   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5459         (float:MODEF
5460           (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5461   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5462    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5463    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5464   "@
5465    fild%Z1\t%1
5466    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5467   [(set_attr "type" "fmov,sseicvt")
5468    (set_attr "prefix" "orig,maybe_vex")
5469    (set_attr "mode" "<MODEF:MODE>")
5470    (set (attr "prefix_rex")
5471      (if_then_else
5472        (and (eq_attr "prefix" "maybe_vex")
5473             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5474        (const_string "1")
5475        (const_string "*")))
5476    (set_attr "athlon_decode" "*,direct")
5477    (set_attr "amdfam10_decode" "*,double")
5478    (set_attr "fp_int_src" "true")])
5479
5480 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5481   [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5482         (float:MODEF
5483           (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5484    (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5485   "TARGET_SSE2 && TARGET_SSE_MATH
5486    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5487   "#"
5488   [(set_attr "type" "sseicvt")
5489    (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5490    (set_attr "athlon_decode" "double,direct,double")
5491    (set_attr "amdfam10_decode" "vector,double,double")
5492    (set_attr "fp_int_src" "true")])
5493
5494 (define_insn "*floatsi<mode>2_vector_sse"
5495   [(set (match_operand:MODEF 0 "register_operand" "=x")
5496         (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5497   "TARGET_SSE2 && TARGET_SSE_MATH
5498    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5499   "#"
5500   [(set_attr "type" "sseicvt")
5501    (set_attr "mode" "<MODE>")
5502    (set_attr "athlon_decode" "direct")
5503    (set_attr "amdfam10_decode" "double")
5504    (set_attr "fp_int_src" "true")])
5505
5506 (define_split
5507   [(set (match_operand:MODEF 0 "register_operand" "")
5508         (float:MODEF (match_operand:SI 1 "register_operand" "")))
5509    (clobber (match_operand:SI 2 "memory_operand" ""))]
5510   "TARGET_SSE2 && TARGET_SSE_MATH
5511    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5512    && reload_completed
5513    && (SSE_REG_P (operands[0])
5514        || (GET_CODE (operands[0]) == SUBREG
5515            && SSE_REG_P (operands[0])))"
5516   [(const_int 0)]
5517 {
5518   rtx op1 = operands[1];
5519
5520   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5521                                      <MODE>mode, 0);
5522   if (GET_CODE (op1) == SUBREG)
5523     op1 = SUBREG_REG (op1);
5524
5525   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5526     {
5527       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5528       emit_insn (gen_sse2_loadld (operands[4],
5529                                   CONST0_RTX (V4SImode), operands[1]));
5530     }
5531   /* We can ignore possible trapping value in the
5532      high part of SSE register for non-trapping math. */
5533   else if (SSE_REG_P (op1) && !flag_trapping_math)
5534     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5535   else
5536     {
5537       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5538       emit_move_insn (operands[2], operands[1]);
5539       emit_insn (gen_sse2_loadld (operands[4],
5540                                   CONST0_RTX (V4SImode), operands[2]));
5541     }
5542   emit_insn
5543     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5544   DONE;
5545 })
5546
5547 (define_split
5548   [(set (match_operand:MODEF 0 "register_operand" "")
5549         (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5550    (clobber (match_operand:SI 2 "memory_operand" ""))]
5551   "TARGET_SSE2 && TARGET_SSE_MATH
5552    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5553    && reload_completed
5554    && (SSE_REG_P (operands[0])
5555        || (GET_CODE (operands[0]) == SUBREG
5556            && SSE_REG_P (operands[0])))"
5557   [(const_int 0)]
5558 {
5559   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5560                                      <MODE>mode, 0);
5561   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5562
5563   emit_insn (gen_sse2_loadld (operands[4],
5564                               CONST0_RTX (V4SImode), operands[1]));
5565   emit_insn
5566     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5567   DONE;
5568 })
5569
5570 (define_split
5571   [(set (match_operand:MODEF 0 "register_operand" "")
5572         (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5573   "TARGET_SSE2 && TARGET_SSE_MATH
5574    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5575    && reload_completed
5576    && (SSE_REG_P (operands[0])
5577        || (GET_CODE (operands[0]) == SUBREG
5578            && SSE_REG_P (operands[0])))"
5579   [(const_int 0)]
5580 {
5581   rtx op1 = operands[1];
5582
5583   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5584                                      <MODE>mode, 0);
5585   if (GET_CODE (op1) == SUBREG)
5586     op1 = SUBREG_REG (op1);
5587
5588   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5589     {
5590       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5591       emit_insn (gen_sse2_loadld (operands[4],
5592                                   CONST0_RTX (V4SImode), operands[1]));
5593     }
5594   /* We can ignore possible trapping value in the
5595      high part of SSE register for non-trapping math. */
5596   else if (SSE_REG_P (op1) && !flag_trapping_math)
5597     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5598   else
5599     gcc_unreachable ();
5600   emit_insn
5601     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5602   DONE;
5603 })
5604
5605 (define_split
5606   [(set (match_operand:MODEF 0 "register_operand" "")
5607         (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5608   "TARGET_SSE2 && TARGET_SSE_MATH
5609    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5610    && reload_completed
5611    && (SSE_REG_P (operands[0])
5612        || (GET_CODE (operands[0]) == SUBREG
5613            && SSE_REG_P (operands[0])))"
5614   [(const_int 0)]
5615 {
5616   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5617                                      <MODE>mode, 0);
5618   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5619
5620   emit_insn (gen_sse2_loadld (operands[4],
5621                               CONST0_RTX (V4SImode), operands[1]));
5622   emit_insn
5623     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5624   DONE;
5625 })
5626
5627 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5628   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5629         (float:MODEF
5630           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5631   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5632   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5633    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5634   "#"
5635   [(set_attr "type" "sseicvt")
5636    (set_attr "mode" "<MODEF:MODE>")
5637    (set_attr "athlon_decode" "double,direct")
5638    (set_attr "amdfam10_decode" "vector,double")
5639    (set_attr "fp_int_src" "true")])
5640
5641 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5642   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5643         (float:MODEF
5644           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5645   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5646    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5647    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5648   "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5649   [(set_attr "type" "sseicvt")
5650    (set_attr "prefix" "maybe_vex")
5651    (set_attr "mode" "<MODEF:MODE>")
5652    (set (attr "prefix_rex")
5653      (if_then_else
5654        (and (eq_attr "prefix" "maybe_vex")
5655             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5656        (const_string "1")
5657        (const_string "*")))
5658    (set_attr "athlon_decode" "double,direct")
5659    (set_attr "amdfam10_decode" "vector,double")
5660    (set_attr "fp_int_src" "true")])
5661
5662 (define_split
5663   [(set (match_operand:MODEF 0 "register_operand" "")
5664         (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5665    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5666   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5667    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5668    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5669    && reload_completed
5670    && (SSE_REG_P (operands[0])
5671        || (GET_CODE (operands[0]) == SUBREG
5672            && SSE_REG_P (operands[0])))"
5673   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5674   "")
5675
5676 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5677   [(set (match_operand:MODEF 0 "register_operand" "=x")
5678         (float:MODEF
5679           (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5680   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5681    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5682    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5683   "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5684   [(set_attr "type" "sseicvt")
5685    (set_attr "prefix" "maybe_vex")
5686    (set_attr "mode" "<MODEF:MODE>")
5687    (set (attr "prefix_rex")
5688      (if_then_else
5689        (and (eq_attr "prefix" "maybe_vex")
5690             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5691        (const_string "1")
5692        (const_string "*")))
5693    (set_attr "athlon_decode" "direct")
5694    (set_attr "amdfam10_decode" "double")
5695    (set_attr "fp_int_src" "true")])
5696
5697 (define_split
5698   [(set (match_operand:MODEF 0 "register_operand" "")
5699         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5700    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5701   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5702    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5703    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5704    && reload_completed
5705    && (SSE_REG_P (operands[0])
5706        || (GET_CODE (operands[0]) == SUBREG
5707            && SSE_REG_P (operands[0])))"
5708   [(set (match_dup 2) (match_dup 1))
5709    (set (match_dup 0) (float:MODEF (match_dup 2)))]
5710   "")
5711
5712 (define_split
5713   [(set (match_operand:MODEF 0 "register_operand" "")
5714         (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5715    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5716   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5717    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5718    && reload_completed
5719    && (SSE_REG_P (operands[0])
5720        || (GET_CODE (operands[0]) == SUBREG
5721            && SSE_REG_P (operands[0])))"
5722   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5723   "")
5724
5725 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5726   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5727         (float:X87MODEF
5728           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5729   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5730   "TARGET_80387
5731    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5732   "@
5733    fild%Z1\t%1
5734    #"
5735   [(set_attr "type" "fmov,multi")
5736    (set_attr "mode" "<X87MODEF:MODE>")
5737    (set_attr "unit" "*,i387")
5738    (set_attr "fp_int_src" "true")])
5739
5740 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5741   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5742         (float:X87MODEF
5743           (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5744   "TARGET_80387
5745    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5746   "fild%Z1\t%1"
5747   [(set_attr "type" "fmov")
5748    (set_attr "mode" "<X87MODEF:MODE>")
5749    (set_attr "fp_int_src" "true")])
5750
5751 (define_split
5752   [(set (match_operand:X87MODEF 0 "register_operand" "")
5753         (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5754    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5755   "TARGET_80387
5756    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5757    && reload_completed
5758    && FP_REG_P (operands[0])"
5759   [(set (match_dup 2) (match_dup 1))
5760    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5761   "")
5762
5763 (define_split
5764   [(set (match_operand:X87MODEF 0 "register_operand" "")
5765         (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5766    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5767   "TARGET_80387
5768    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5769    && reload_completed
5770    && FP_REG_P (operands[0])"
5771   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5772   "")
5773
5774 ;; Avoid store forwarding (partial memory) stall penalty
5775 ;; by passing DImode value through XMM registers.  */
5776
5777 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5778   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5779         (float:X87MODEF
5780           (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5781    (clobber (match_scratch:V4SI 3 "=X,x"))
5782    (clobber (match_scratch:V4SI 4 "=X,x"))
5783    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5784   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5785    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5786    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5787   "#"
5788   [(set_attr "type" "multi")
5789    (set_attr "mode" "<X87MODEF:MODE>")
5790    (set_attr "unit" "i387")
5791    (set_attr "fp_int_src" "true")])
5792
5793 (define_split
5794   [(set (match_operand:X87MODEF 0 "register_operand" "")
5795         (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5796    (clobber (match_scratch:V4SI 3 ""))
5797    (clobber (match_scratch:V4SI 4 ""))
5798    (clobber (match_operand:DI 2 "memory_operand" ""))]
5799   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5800    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5801    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5802    && reload_completed
5803    && FP_REG_P (operands[0])"
5804   [(set (match_dup 2) (match_dup 3))
5805    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5806 {
5807   /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5808      Assemble the 64-bit DImode value in an xmm register.  */
5809   emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5810                               gen_rtx_SUBREG (SImode, operands[1], 0)));
5811   emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5812                               gen_rtx_SUBREG (SImode, operands[1], 4)));
5813   emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5814                                          operands[4]));
5815
5816   operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5817 })
5818
5819 (define_split
5820   [(set (match_operand:X87MODEF 0 "register_operand" "")
5821         (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5822    (clobber (match_scratch:V4SI 3 ""))
5823    (clobber (match_scratch:V4SI 4 ""))
5824    (clobber (match_operand:DI 2 "memory_operand" ""))]
5825   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5826    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5827    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5828    && reload_completed
5829    && FP_REG_P (operands[0])"
5830   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5831   "")
5832
5833 ;; Avoid store forwarding (partial memory) stall penalty by extending
5834 ;; SImode value to DImode through XMM register instead of pushing two
5835 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5836 ;; targets benefit from this optimization. Also note that fild
5837 ;; loads from memory only.
5838
5839 (define_insn "*floatunssi<mode>2_1"
5840   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5841         (unsigned_float:X87MODEF
5842           (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5843    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5844    (clobber (match_scratch:SI 3 "=X,x"))]
5845   "!TARGET_64BIT
5846    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5847    && TARGET_SSE"
5848   "#"
5849   [(set_attr "type" "multi")
5850    (set_attr "mode" "<MODE>")])
5851
5852 (define_split
5853   [(set (match_operand:X87MODEF 0 "register_operand" "")
5854         (unsigned_float:X87MODEF
5855           (match_operand:SI 1 "register_operand" "")))
5856    (clobber (match_operand:DI 2 "memory_operand" ""))
5857    (clobber (match_scratch:SI 3 ""))]
5858   "!TARGET_64BIT
5859    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5860    && TARGET_SSE
5861    && reload_completed"
5862   [(set (match_dup 2) (match_dup 1))
5863    (set (match_dup 0)
5864         (float:X87MODEF (match_dup 2)))]
5865   "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5866
5867 (define_split
5868   [(set (match_operand:X87MODEF 0 "register_operand" "")
5869         (unsigned_float:X87MODEF
5870           (match_operand:SI 1 "memory_operand" "")))
5871    (clobber (match_operand:DI 2 "memory_operand" ""))
5872    (clobber (match_scratch:SI 3 ""))]
5873   "!TARGET_64BIT
5874    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5875    && TARGET_SSE
5876    && reload_completed"
5877   [(set (match_dup 2) (match_dup 3))
5878    (set (match_dup 0)
5879         (float:X87MODEF (match_dup 2)))]
5880 {
5881   emit_move_insn (operands[3], operands[1]);
5882   operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5883 })
5884
5885 (define_expand "floatunssi<mode>2"
5886   [(parallel
5887      [(set (match_operand:X87MODEF 0 "register_operand" "")
5888            (unsigned_float:X87MODEF
5889              (match_operand:SI 1 "nonimmediate_operand" "")))
5890       (clobber (match_dup 2))
5891       (clobber (match_scratch:SI 3 ""))])]
5892   "!TARGET_64BIT
5893    && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5894         && TARGET_SSE)
5895        || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5896 {
5897   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5898     {
5899       ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5900       DONE;
5901     }
5902   else
5903     {
5904       enum ix86_stack_slot slot = (virtuals_instantiated
5905                                    ? SLOT_TEMP
5906                                    : SLOT_VIRTUAL);
5907       operands[2] = assign_386_stack_local (DImode, slot);
5908     }
5909 })
5910
5911 (define_expand "floatunsdisf2"
5912   [(use (match_operand:SF 0 "register_operand" ""))
5913    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5914   "TARGET_64BIT && TARGET_SSE_MATH"
5915   "x86_emit_floatuns (operands); DONE;")
5916
5917 (define_expand "floatunsdidf2"
5918   [(use (match_operand:DF 0 "register_operand" ""))
5919    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5920   "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5921    && TARGET_SSE2 && TARGET_SSE_MATH"
5922 {
5923   if (TARGET_64BIT)
5924     x86_emit_floatuns (operands);
5925   else
5926     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5927   DONE;
5928 })
5929 \f
5930 ;; Add instructions
5931
5932 (define_expand "add<mode>3"
5933   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5934         (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5935                     (match_operand:SDWIM 2 "<general_operand>" "")))]
5936   ""
5937   "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5938
5939 (define_insn_and_split "*add<dwi>3_doubleword"
5940   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5941         (plus:<DWI>
5942           (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5943           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5944    (clobber (reg:CC FLAGS_REG))]
5945   "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5946   "#"
5947   "reload_completed"
5948   [(parallel [(set (reg:CC FLAGS_REG)
5949                    (unspec:CC [(match_dup 1) (match_dup 2)]
5950                               UNSPEC_ADD_CARRY))
5951               (set (match_dup 0)
5952                    (plus:DWIH (match_dup 1) (match_dup 2)))])
5953    (parallel [(set (match_dup 3)
5954                    (plus:DWIH
5955                      (match_dup 4)
5956                      (plus:DWIH
5957                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5958                        (match_dup 5))))
5959               (clobber (reg:CC FLAGS_REG))])]
5960   "split_<dwi> (&operands[0], 3, &operands[0], &operands[3]);")
5961
5962 (define_insn "*add<mode>3_cc"
5963   [(set (reg:CC FLAGS_REG)
5964         (unspec:CC
5965           [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5966            (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5967           UNSPEC_ADD_CARRY))
5968    (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5969         (plus:SWI48 (match_dup 1) (match_dup 2)))]
5970   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5971   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5972   [(set_attr "type" "alu")
5973    (set_attr "mode" "<MODE>")])
5974
5975 (define_insn "addqi3_cc"
5976   [(set (reg:CC FLAGS_REG)
5977         (unspec:CC
5978           [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5979            (match_operand:QI 2 "general_operand" "qn,qm")]
5980           UNSPEC_ADD_CARRY))
5981    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5982         (plus:QI (match_dup 1) (match_dup 2)))]
5983   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5984   "add{b}\t{%2, %0|%0, %2}"
5985   [(set_attr "type" "alu")
5986    (set_attr "mode" "QI")])
5987
5988 (define_insn "*lea_1"
5989   [(set (match_operand:DWIH 0 "register_operand" "=r")
5990         (match_operand:DWIH 1 "no_seg_address_operand" "p"))]
5991   ""
5992   "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
5993   [(set_attr "type" "lea")
5994    (set_attr "mode" "<MODE>")])
5995
5996 (define_insn "*lea_2"
5997   [(set (match_operand:SI 0 "register_operand" "=r")
5998         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5999   "TARGET_64BIT"
6000   "lea{l}\t{%a1, %0|%0, %a1}"
6001   [(set_attr "type" "lea")
6002    (set_attr "mode" "SI")])
6003
6004 (define_insn "*lea_2_zext"
6005   [(set (match_operand:DI 0 "register_operand" "=r")
6006         (zero_extend:DI
6007           (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
6008   "TARGET_64BIT"
6009   "lea{l}\t{%a1, %k0|%k0, %a1}"
6010   [(set_attr "type" "lea")
6011    (set_attr "mode" "SI")])
6012
6013 (define_insn "*add<mode>_1"
6014   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
6015         (plus:SWI48
6016           (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
6017           (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,0,l<i>")))
6018    (clobber (reg:CC FLAGS_REG))]
6019   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6020 {
6021   switch (get_attr_type (insn))
6022     {
6023     case TYPE_LEA:
6024       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6025       return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
6026
6027     case TYPE_INCDEC:
6028       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6029       if (operands[2] == const1_rtx)
6030         return "inc{<imodesuffix>}\t%0";
6031       else
6032         {
6033           gcc_assert (operands[2] == constm1_rtx);
6034           return "dec{<imodesuffix>}\t%0";
6035         }
6036
6037     default:
6038       /* Use add as much as possible to replace lea for AGU optimization. */
6039       if (which_alternative == 2 && TARGET_OPT_AGU)
6040         return "add{<imodesuffix>}\t{%1, %0|%0, %1}";
6041         
6042       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6043       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6044         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6045
6046       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6047     }
6048 }
6049   [(set (attr "type")
6050      (cond [(and (eq_attr "alternative" "2") 
6051                  (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
6052               (const_string "lea")
6053             (eq_attr "alternative" "3")
6054               (const_string "lea")
6055             ; Current assemblers are broken and do not allow @GOTOFF in
6056             ; ought but a memory context.
6057             (match_operand:SWI48 2 "pic_symbolic_operand" "")
6058               (const_string "lea")
6059             (match_operand:SWI48 2 "incdec_operand" "")
6060               (const_string "incdec")
6061            ]
6062            (const_string "alu")))
6063    (set (attr "length_immediate")
6064       (if_then_else
6065         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6066         (const_string "1")
6067         (const_string "*")))
6068    (set_attr "mode" "<MODE>")])
6069
6070 ;; It may seem that nonimmediate operand is proper one for operand 1.
6071 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6072 ;; we take care in ix86_binary_operator_ok to not allow two memory
6073 ;; operands so proper swapping will be done in reload.  This allow
6074 ;; patterns constructed from addsi_1 to match.
6075
6076 (define_insn "*addsi_1_zext"
6077   [(set (match_operand:DI 0 "register_operand" "=r,r")
6078         (zero_extend:DI
6079           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6080                    (match_operand:SI 2 "general_operand" "g,li"))))
6081    (clobber (reg:CC FLAGS_REG))]
6082   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6083 {
6084   switch (get_attr_type (insn))
6085     {
6086     case TYPE_LEA:
6087       operands[2] = XEXP (SET_SRC (XVECEXP (PATTERN (insn), 0, 0)), 0);
6088       return "lea{l}\t{%a2, %k0|%k0, %a2}";
6089
6090     case TYPE_INCDEC:
6091       if (operands[2] == const1_rtx)
6092         return "inc{l}\t%k0";
6093       else
6094         {
6095           gcc_assert (operands[2] == constm1_rtx);
6096           return "dec{l}\t%k0";
6097         }
6098
6099     default:
6100       if (x86_maybe_negate_const_int (&operands[2], SImode))
6101         return "sub{l}\t{%2, %k0|%k0, %2}";
6102
6103       return "add{l}\t{%2, %k0|%k0, %2}";
6104     }
6105 }
6106   [(set (attr "type")
6107      (cond [(eq_attr "alternative" "1")
6108               (const_string "lea")
6109             ; Current assemblers are broken and do not allow @GOTOFF in
6110             ; ought but a memory context.
6111             (match_operand:SI 2 "pic_symbolic_operand" "")
6112               (const_string "lea")
6113             (match_operand:SI 2 "incdec_operand" "")
6114               (const_string "incdec")
6115            ]
6116            (const_string "alu")))
6117    (set (attr "length_immediate")
6118       (if_then_else
6119         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6120         (const_string "1")
6121         (const_string "*")))
6122    (set_attr "mode" "SI")])
6123
6124 (define_insn "*addhi_1"
6125   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6126         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6127                  (match_operand:HI 2 "general_operand" "rn,rm")))
6128    (clobber (reg:CC FLAGS_REG))]
6129   "TARGET_PARTIAL_REG_STALL
6130    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6131 {
6132   switch (get_attr_type (insn))
6133     {
6134     case TYPE_INCDEC:
6135       if (operands[2] == const1_rtx)
6136         return "inc{w}\t%0";
6137       else
6138         {
6139           gcc_assert (operands[2] == constm1_rtx);
6140           return "dec{w}\t%0";
6141         }
6142
6143     default:
6144       if (x86_maybe_negate_const_int (&operands[2], HImode))
6145         return "sub{w}\t{%2, %0|%0, %2}";
6146
6147       return "add{w}\t{%2, %0|%0, %2}";
6148     }
6149 }
6150   [(set (attr "type")
6151      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6152         (const_string "incdec")
6153         (const_string "alu")))
6154    (set (attr "length_immediate")
6155       (if_then_else
6156         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6157         (const_string "1")
6158         (const_string "*")))
6159    (set_attr "mode" "HI")])
6160
6161 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6162 ;; type optimizations enabled by define-splits.  This is not important
6163 ;; for PII, and in fact harmful because of partial register stalls.
6164
6165 (define_insn "*addhi_1_lea"
6166   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6167         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6168                  (match_operand:HI 2 "general_operand" "rn,rm,ln")))
6169    (clobber (reg:CC FLAGS_REG))]
6170   "!TARGET_PARTIAL_REG_STALL
6171    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6172 {
6173   switch (get_attr_type (insn))
6174     {
6175     case TYPE_LEA:
6176       return "#";
6177     case TYPE_INCDEC:
6178       if (operands[2] == const1_rtx)
6179         return "inc{w}\t%0";
6180       else
6181         {
6182           gcc_assert (operands[2] == constm1_rtx);
6183           return "dec{w}\t%0";
6184         }
6185
6186     default:
6187       if (x86_maybe_negate_const_int (&operands[2], HImode))
6188         return "sub{w}\t{%2, %0|%0, %2}";
6189
6190       return "add{w}\t{%2, %0|%0, %2}";
6191     }
6192 }
6193   [(set (attr "type")
6194      (if_then_else (eq_attr "alternative" "2")
6195         (const_string "lea")
6196         (if_then_else (match_operand:HI 2 "incdec_operand" "")
6197            (const_string "incdec")
6198            (const_string "alu"))))
6199    (set (attr "length_immediate")
6200       (if_then_else
6201         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6202         (const_string "1")
6203         (const_string "*")))
6204    (set_attr "mode" "HI,HI,SI")])
6205
6206 (define_insn "*addqi_1"
6207   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6208         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6209                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6210    (clobber (reg:CC FLAGS_REG))]
6211   "TARGET_PARTIAL_REG_STALL
6212    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6213 {
6214   int widen = (which_alternative == 2);
6215   switch (get_attr_type (insn))
6216     {
6217     case TYPE_INCDEC:
6218       if (operands[2] == const1_rtx)
6219         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6220       else
6221         {
6222           gcc_assert (operands[2] == constm1_rtx);
6223           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6224         }
6225
6226     default:
6227       if (x86_maybe_negate_const_int (&operands[2], QImode))
6228         {
6229           if (widen)
6230             return "sub{l}\t{%2, %k0|%k0, %2}";
6231           else
6232             return "sub{b}\t{%2, %0|%0, %2}";
6233         }
6234       if (widen)
6235         return "add{l}\t{%k2, %k0|%k0, %k2}";
6236       else
6237         return "add{b}\t{%2, %0|%0, %2}";
6238     }
6239 }
6240   [(set (attr "type")
6241      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6242         (const_string "incdec")
6243         (const_string "alu")))
6244    (set (attr "length_immediate")
6245       (if_then_else
6246         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6247         (const_string "1")
6248         (const_string "*")))
6249    (set_attr "mode" "QI,QI,SI")])
6250
6251 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6252 (define_insn "*addqi_1_lea"
6253   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6254         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6255                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6256    (clobber (reg:CC FLAGS_REG))]
6257   "!TARGET_PARTIAL_REG_STALL
6258    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6259 {
6260   int widen = (which_alternative == 2);
6261   switch (get_attr_type (insn))
6262     {
6263     case TYPE_LEA:
6264       return "#";
6265     case TYPE_INCDEC:
6266       if (operands[2] == const1_rtx)
6267         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6268       else
6269         {
6270           gcc_assert (operands[2] == constm1_rtx);
6271           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6272         }
6273
6274     default:
6275       if (x86_maybe_negate_const_int (&operands[2], QImode))
6276         {
6277           if (widen)
6278             return "sub{l}\t{%2, %k0|%k0, %2}";
6279           else
6280             return "sub{b}\t{%2, %0|%0, %2}";
6281         }
6282       if (widen)
6283         return "add{l}\t{%k2, %k0|%k0, %k2}";
6284       else
6285         return "add{b}\t{%2, %0|%0, %2}";
6286     }
6287 }
6288   [(set (attr "type")
6289      (if_then_else (eq_attr "alternative" "3")
6290         (const_string "lea")
6291         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6292            (const_string "incdec")
6293            (const_string "alu"))))
6294    (set (attr "length_immediate")
6295       (if_then_else
6296         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6297         (const_string "1")
6298         (const_string "*")))
6299    (set_attr "mode" "QI,QI,SI,SI")])
6300
6301 (define_insn "*addqi_1_slp"
6302   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6303         (plus:QI (match_dup 0)
6304                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6305    (clobber (reg:CC FLAGS_REG))]
6306   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6307    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6308 {
6309   switch (get_attr_type (insn))
6310     {
6311     case TYPE_INCDEC:
6312       if (operands[1] == const1_rtx)
6313         return "inc{b}\t%0";
6314       else
6315         {
6316           gcc_assert (operands[1] == constm1_rtx);
6317           return "dec{b}\t%0";
6318         }
6319
6320     default:
6321       if (x86_maybe_negate_const_int (&operands[1], QImode))
6322         return "sub{b}\t{%1, %0|%0, %1}";
6323
6324       return "add{b}\t{%1, %0|%0, %1}";
6325     }
6326 }
6327   [(set (attr "type")
6328      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6329         (const_string "incdec")
6330         (const_string "alu1")))
6331    (set (attr "memory")
6332      (if_then_else (match_operand 1 "memory_operand" "")
6333         (const_string "load")
6334         (const_string "none")))
6335    (set_attr "mode" "QI")])
6336
6337 (define_insn "*add<mode>_2"
6338   [(set (reg FLAGS_REG)
6339         (compare
6340           (plus:SWI48
6341             (match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
6342             (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>"))
6343           (const_int 0)))
6344    (set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm")
6345         (plus:SWI48 (match_dup 1) (match_dup 2)))]
6346   "ix86_match_ccmode (insn, CCGOCmode)
6347    && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
6348    /* Current assemblers are broken and do not allow @GOTOFF in
6349       ought but a memory context.  */
6350    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6351 {
6352   switch (get_attr_type (insn))
6353     {
6354     case TYPE_INCDEC:
6355       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6356       if (operands[2] == const1_rtx)
6357         return "inc{<imodesuffix>}\t%0";
6358       else
6359         {
6360           gcc_assert (operands[2] == constm1_rtx);
6361           return "dec{<imodesuffix>}\t%0";
6362         }
6363
6364     default:
6365       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6366       /* ???? In DImode, we ought to handle there the 32bit case too
6367          - do we need new constraint?  */
6368       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6369         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6370
6371       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6372     }
6373 }
6374   [(set (attr "type")
6375      (if_then_else (match_operand:SWI48 2 "incdec_operand" "")
6376         (const_string "incdec")
6377         (const_string "alu")))
6378    (set (attr "length_immediate")
6379       (if_then_else
6380         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6381         (const_string "1")
6382         (const_string "*")))
6383    (set_attr "mode" "<MODE>")])
6384
6385 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6386 (define_insn "*addsi_2_zext"
6387   [(set (reg FLAGS_REG)
6388         (compare
6389           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6390                    (match_operand:SI 2 "general_operand" "g"))
6391           (const_int 0)))
6392    (set (match_operand:DI 0 "register_operand" "=r")
6393         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6394   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6395    && ix86_binary_operator_ok (PLUS, SImode, operands)
6396    /* Current assemblers are broken and do not allow @GOTOFF in
6397       ought but a memory context.  */
6398    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6399 {
6400   switch (get_attr_type (insn))
6401     {
6402     case TYPE_INCDEC:
6403       if (operands[2] == const1_rtx)
6404         return "inc{l}\t%k0";
6405       else
6406         {
6407           gcc_assert (operands[2] == constm1_rtx);
6408           return "dec{l}\t%k0";
6409         }
6410
6411     default:
6412       if (x86_maybe_negate_const_int (&operands[2], SImode))
6413         return "sub{l}\t{%2, %k0|%k0, %2}";
6414
6415       return "add{l}\t{%2, %k0|%k0, %2}";
6416     }
6417 }
6418   [(set (attr "type")
6419      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6420         (const_string "incdec")
6421         (const_string "alu")))
6422    (set (attr "length_immediate")
6423       (if_then_else
6424         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6425         (const_string "1")
6426         (const_string "*")))
6427    (set_attr "mode" "SI")])
6428
6429 (define_insn "*addhi_2"
6430   [(set (reg FLAGS_REG)
6431         (compare
6432           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6433                    (match_operand:HI 2 "general_operand" "rmn,rn"))
6434           (const_int 0)))
6435    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6436         (plus:HI (match_dup 1) (match_dup 2)))]
6437   "ix86_match_ccmode (insn, CCGOCmode)
6438    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6439 {
6440   switch (get_attr_type (insn))
6441     {
6442     case TYPE_INCDEC:
6443       if (operands[2] == const1_rtx)
6444         return "inc{w}\t%0";
6445       else
6446         {
6447           gcc_assert (operands[2] == constm1_rtx);
6448           return "dec{w}\t%0";
6449         }
6450
6451     default:
6452       if (x86_maybe_negate_const_int (&operands[2], HImode))
6453         return "sub{w}\t{%2, %0|%0, %2}";
6454
6455       return "add{w}\t{%2, %0|%0, %2}";
6456     }
6457 }
6458   [(set (attr "type")
6459      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6460         (const_string "incdec")
6461         (const_string "alu")))
6462    (set (attr "length_immediate")
6463       (if_then_else
6464         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6465         (const_string "1")
6466         (const_string "*")))
6467    (set_attr "mode" "HI")])
6468
6469 (define_insn "*addqi_2"
6470   [(set (reg FLAGS_REG)
6471         (compare
6472           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6473                    (match_operand:QI 2 "general_operand" "qmn,qn"))
6474           (const_int 0)))
6475    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6476         (plus:QI (match_dup 1) (match_dup 2)))]
6477   "ix86_match_ccmode (insn, CCGOCmode)
6478    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6479 {
6480   switch (get_attr_type (insn))
6481     {
6482     case TYPE_INCDEC:
6483       if (operands[2] == const1_rtx)
6484         return "inc{b}\t%0";
6485       else
6486         {
6487           gcc_assert (operands[2] == constm1_rtx
6488                       || (CONST_INT_P (operands[2])
6489                           && INTVAL (operands[2]) == 255));
6490           return "dec{b}\t%0";
6491         }
6492
6493     default:
6494       if (x86_maybe_negate_const_int (&operands[2], QImode))
6495         return "sub{b}\t{%2, %0|%0, %2}";
6496
6497       return "add{b}\t{%2, %0|%0, %2}";
6498     }
6499 }
6500   [(set (attr "type")
6501      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6502         (const_string "incdec")
6503         (const_string "alu")))
6504    (set_attr "mode" "QI")])
6505
6506 (define_insn "*add<mode>_3"
6507   [(set (reg FLAGS_REG)
6508         (compare
6509           (neg:SWI48 (match_operand:SWI48 2 "<general_operand>" "<g>"))
6510           (match_operand:SWI48 1 "nonimmediate_operand" "%0")))
6511    (clobber (match_scratch:SWI48 0 "=r"))]
6512   "ix86_match_ccmode (insn, CCZmode)
6513    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6514    /* Current assemblers are broken and do not allow @GOTOFF in
6515       ought but a memory context.  */
6516    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6517 {
6518   switch (get_attr_type (insn))
6519     {
6520     case TYPE_INCDEC:
6521       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6522       if (operands[2] == const1_rtx)
6523         return "inc{<imodesuffix>}\t%0";
6524       else
6525         {
6526           gcc_assert (operands[2] == constm1_rtx);
6527           return "dec{<imodesuffix>}\t%0";
6528         }
6529
6530     default:
6531       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6532       /* ???? In DImode, we ought to handle there the 32bit case too
6533          - do we need new constraint?  */
6534       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6535         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6536
6537       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6538     }
6539 }
6540   [(set (attr "type")
6541      (if_then_else (match_operand:SWI48 2 "incdec_operand" "")
6542         (const_string "incdec")
6543         (const_string "alu")))
6544    (set (attr "length_immediate")
6545       (if_then_else
6546         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6547         (const_string "1")
6548         (const_string "*")))
6549    (set_attr "mode" "<MODE>")])
6550
6551 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6552 (define_insn "*addsi_3_zext"
6553   [(set (reg FLAGS_REG)
6554         (compare
6555           (neg:SI (match_operand:SI 2 "general_operand" "g"))
6556           (match_operand:SI 1 "nonimmediate_operand" "%0")))
6557    (set (match_operand:DI 0 "register_operand" "=r")
6558         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6559   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6560    && ix86_binary_operator_ok (PLUS, SImode, operands)
6561    /* Current assemblers are broken and do not allow @GOTOFF in
6562       ought but a memory context.  */
6563    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6564 {
6565   switch (get_attr_type (insn))
6566     {
6567     case TYPE_INCDEC:
6568       if (operands[2] == const1_rtx)
6569         return "inc{l}\t%k0";
6570       else
6571         {
6572           gcc_assert (operands[2] == constm1_rtx);
6573           return "dec{l}\t%k0";
6574         }
6575
6576     default:
6577       if (x86_maybe_negate_const_int (&operands[2], SImode))
6578         return "sub{l}\t{%2, %k0|%k0, %2}";
6579
6580       return "add{l}\t{%2, %k0|%k0, %2}";
6581     }
6582 }
6583   [(set (attr "type")
6584      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6585         (const_string "incdec")
6586         (const_string "alu")))
6587    (set (attr "length_immediate")
6588       (if_then_else
6589         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6590         (const_string "1")
6591         (const_string "*")))
6592    (set_attr "mode" "SI")])
6593
6594 (define_insn "*addhi_3"
6595   [(set (reg FLAGS_REG)
6596         (compare
6597           (neg:HI (match_operand:HI 2 "general_operand" "rmn"))
6598           (match_operand:HI 1 "nonimmediate_operand" "%0")))
6599    (clobber (match_scratch:HI 0 "=r"))]
6600   "ix86_match_ccmode (insn, CCZmode)
6601    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6602 {
6603   switch (get_attr_type (insn))
6604     {
6605     case TYPE_INCDEC:
6606       if (operands[2] == const1_rtx)
6607         return "inc{w}\t%0";
6608       else
6609         {
6610           gcc_assert (operands[2] == constm1_rtx);
6611           return "dec{w}\t%0";
6612         }
6613
6614     default:
6615       if (x86_maybe_negate_const_int (&operands[2], HImode))
6616         return "sub{w}\t{%2, %0|%0, %2}";
6617
6618       return "add{w}\t{%2, %0|%0, %2}";
6619     }
6620 }
6621   [(set (attr "type")
6622      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6623         (const_string "incdec")
6624         (const_string "alu")))
6625    (set (attr "length_immediate")
6626       (if_then_else
6627         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6628         (const_string "1")
6629         (const_string "*")))
6630    (set_attr "mode" "HI")])
6631
6632 (define_insn "*addqi_3"
6633   [(set (reg FLAGS_REG)
6634         (compare
6635           (neg:QI (match_operand:QI 2 "general_operand" "qmn"))
6636           (match_operand:QI 1 "nonimmediate_operand" "%0")))
6637    (clobber (match_scratch:QI 0 "=q"))]
6638   "ix86_match_ccmode (insn, CCZmode)
6639    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6640 {
6641   switch (get_attr_type (insn))
6642     {
6643     case TYPE_INCDEC:
6644       if (operands[2] == const1_rtx)
6645         return "inc{b}\t%0";
6646       else
6647         {
6648           gcc_assert (operands[2] == constm1_rtx
6649                       || (CONST_INT_P (operands[2])
6650                           && INTVAL (operands[2]) == 255));
6651           return "dec{b}\t%0";
6652         }
6653
6654     default:
6655       if (x86_maybe_negate_const_int (&operands[2], QImode))
6656         return "sub{b}\t{%2, %0|%0, %2}";
6657
6658       return "add{b}\t{%2, %0|%0, %2}";
6659     }
6660 }
6661   [(set (attr "type")
6662      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6663         (const_string "incdec")
6664         (const_string "alu")))
6665    (set_attr "mode" "QI")])
6666
6667 ; For comparisons against 1, -1 and 128, we may generate better code
6668 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6669 ; is matched then.  We can't accept general immediate, because for
6670 ; case of overflows,  the result is messed up.
6671 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6672 ; only for comparisons not depending on it.
6673
6674 (define_insn "*adddi_4"
6675   [(set (reg FLAGS_REG)
6676         (compare
6677           (match_operand:DI 1 "nonimmediate_operand" "0")
6678           (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6679    (clobber (match_scratch:DI 0 "=rm"))]
6680   "TARGET_64BIT
6681    && ix86_match_ccmode (insn, CCGCmode)"
6682 {
6683   switch (get_attr_type (insn))
6684     {
6685     case TYPE_INCDEC:
6686       if (operands[2] == constm1_rtx)
6687         return "inc{q}\t%0";
6688       else
6689         {
6690           gcc_assert (operands[2] == const1_rtx);
6691           return "dec{q}\t%0";
6692         }
6693
6694     default:
6695       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6696       if (x86_maybe_negate_const_int (&operands[2], DImode))
6697         return "add{q}\t{%2, %0|%0, %2}";
6698
6699       return "sub{q}\t{%2, %0|%0, %2}";
6700     }
6701 }
6702   [(set (attr "type")
6703      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6704         (const_string "incdec")
6705         (const_string "alu")))
6706    (set (attr "length_immediate")
6707       (if_then_else
6708         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6709         (const_string "1")
6710         (const_string "*")))
6711    (set_attr "mode" "DI")])
6712
6713 ; For comparisons against 1, -1 and 128, we may generate better code
6714 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6715 ; is matched then.  We can't accept general immediate, because for
6716 ; case of overflows,  the result is messed up.
6717 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6718 ; only for comparisons not depending on it.
6719
6720 (define_insn "*addsi_4"
6721   [(set (reg FLAGS_REG)
6722         (compare
6723           (match_operand:SI 1 "nonimmediate_operand" "0")
6724           (match_operand:SI 2 "const_int_operand" "n")))
6725    (clobber (match_scratch:SI 0 "=rm"))]
6726   "ix86_match_ccmode (insn, CCGCmode)"
6727 {
6728   switch (get_attr_type (insn))
6729     {
6730     case TYPE_INCDEC:
6731       if (operands[2] == constm1_rtx)
6732         return "inc{l}\t%0";
6733       else
6734         {
6735           gcc_assert (operands[2] == const1_rtx);
6736           return "dec{l}\t%0";
6737         }
6738
6739     default:
6740       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6741       if (x86_maybe_negate_const_int (&operands[2], SImode))
6742         return "add{l}\t{%2, %0|%0, %2}";
6743
6744       return "sub{l}\t{%2, %0|%0, %2}";
6745     }
6746 }
6747   [(set (attr "type")
6748      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6749         (const_string "incdec")
6750         (const_string "alu")))
6751    (set (attr "length_immediate")
6752       (if_then_else
6753         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6754         (const_string "1")
6755         (const_string "*")))
6756    (set_attr "mode" "SI")])
6757
6758 ; See comments above addsi_4 for details.
6759
6760 (define_insn "*addhi_4"
6761   [(set (reg FLAGS_REG)
6762         (compare
6763           (match_operand:HI 1 "nonimmediate_operand" "0")
6764           (match_operand:HI 2 "const_int_operand" "n")))
6765    (clobber (match_scratch:HI 0 "=rm"))]
6766   "ix86_match_ccmode (insn, CCGCmode)"
6767 {
6768   switch (get_attr_type (insn))
6769     {
6770     case TYPE_INCDEC:
6771       if (operands[2] == constm1_rtx)
6772         return "inc{w}\t%0";
6773       else
6774         {
6775           gcc_assert (operands[2] == const1_rtx);
6776           return "dec{w}\t%0";
6777         }
6778
6779     default:
6780       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6781       if (x86_maybe_negate_const_int (&operands[2], HImode))
6782         return "add{w}\t{%2, %0|%0, %2}";
6783
6784       return "sub{w}\t{%2, %0|%0, %2}";
6785     }
6786 }
6787   [(set (attr "type")
6788      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6789         (const_string "incdec")
6790         (const_string "alu")))
6791    (set (attr "length_immediate")
6792       (if_then_else
6793         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6794         (const_string "1")
6795         (const_string "*")))
6796    (set_attr "mode" "HI")])
6797
6798 ; See comments above addsi_4 for details.
6799
6800 (define_insn "*addqi_4"
6801   [(set (reg FLAGS_REG)
6802         (compare
6803           (match_operand:QI 1 "nonimmediate_operand" "0")
6804           (match_operand:QI 2 "const_int_operand" "n")))
6805    (clobber (match_scratch:QI 0 "=qm"))]
6806   "ix86_match_ccmode (insn, CCGCmode)"
6807 {
6808   switch (get_attr_type (insn))
6809     {
6810     case TYPE_INCDEC:
6811       if (operands[2] == constm1_rtx
6812           || (CONST_INT_P (operands[2])
6813               && INTVAL (operands[2]) == 255))
6814         return "inc{b}\t%0";
6815       else
6816         {
6817           gcc_assert (operands[2] == const1_rtx);
6818           return "dec{b}\t%0";
6819         }
6820
6821     default:
6822       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6823       if (x86_maybe_negate_const_int (&operands[2], QImode))
6824         return "add{b}\t{%2, %0|%0, %2}";
6825
6826       return "sub{b}\t{%2, %0|%0, %2}";
6827     }
6828 }
6829   [(set (attr "type")
6830      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6831         (const_string "incdec")
6832         (const_string "alu")))
6833    (set_attr "mode" "QI")])
6834
6835 (define_insn "*add<mode>_5"
6836   [(set (reg FLAGS_REG)
6837         (compare
6838           (plus:SWI48
6839             (match_operand:SWI48 1 "nonimmediate_operand" "%0")
6840             (match_operand:SWI48 2 "<general_operand>" "<g>"))
6841           (const_int 0)))
6842    (clobber (match_scratch:SWI48 0 "=r"))]
6843   "ix86_match_ccmode (insn, CCGOCmode)
6844    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6845    /* Current assemblers are broken and do not allow @GOTOFF in
6846       ought but a memory context.  */
6847    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6848 {
6849   switch (get_attr_type (insn))
6850     {
6851     case TYPE_INCDEC:
6852       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6853       if (operands[2] == const1_rtx)
6854         return "inc{<imodesuffix>}\t%0";
6855       else
6856         {
6857           gcc_assert (operands[2] == constm1_rtx);
6858           return "dec{<imodesuffix>}\t%0";
6859         }
6860
6861     default:
6862       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6863       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6864         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6865
6866       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6867     }
6868 }
6869   [(set (attr "type")
6870      (if_then_else (match_operand:SWI48 2 "incdec_operand" "")
6871         (const_string "incdec")
6872         (const_string "alu")))
6873    (set (attr "length_immediate")
6874       (if_then_else
6875         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6876         (const_string "1")
6877         (const_string "*")))
6878    (set_attr "mode" "<MODE>")])
6879
6880 (define_insn "*addhi_5"
6881   [(set (reg FLAGS_REG)
6882         (compare
6883           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6884                    (match_operand:HI 2 "general_operand" "rmn"))
6885           (const_int 0)))
6886    (clobber (match_scratch:HI 0 "=r"))]
6887   "ix86_match_ccmode (insn, CCGOCmode)
6888    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6889 {
6890   switch (get_attr_type (insn))
6891     {
6892     case TYPE_INCDEC:
6893       if (operands[2] == const1_rtx)
6894         return "inc{w}\t%0";
6895       else
6896         {
6897           gcc_assert (operands[2] == constm1_rtx);
6898           return "dec{w}\t%0";
6899         }
6900
6901     default:
6902       if (x86_maybe_negate_const_int (&operands[2], HImode))
6903         return "sub{w}\t{%2, %0|%0, %2}";
6904
6905       return "add{w}\t{%2, %0|%0, %2}";
6906     }
6907 }
6908   [(set (attr "type")
6909      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6910         (const_string "incdec")
6911         (const_string "alu")))
6912    (set (attr "length_immediate")
6913       (if_then_else
6914         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6915         (const_string "1")
6916         (const_string "*")))
6917    (set_attr "mode" "HI")])
6918
6919 (define_insn "*addqi_5"
6920   [(set (reg FLAGS_REG)
6921         (compare
6922           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6923                    (match_operand:QI 2 "general_operand" "qmn"))
6924           (const_int 0)))
6925    (clobber (match_scratch:QI 0 "=q"))]
6926   "ix86_match_ccmode (insn, CCGOCmode)
6927    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6928 {
6929   switch (get_attr_type (insn))
6930     {
6931     case TYPE_INCDEC:
6932       if (operands[2] == const1_rtx)
6933         return "inc{b}\t%0";
6934       else
6935         {
6936           gcc_assert (operands[2] == constm1_rtx
6937                       || (CONST_INT_P (operands[2])
6938                           && INTVAL (operands[2]) == 255));
6939           return "dec{b}\t%0";
6940         }
6941
6942     default:
6943       if (x86_maybe_negate_const_int (&operands[2], QImode))
6944         return "sub{b}\t{%2, %0|%0, %2}";
6945
6946       return "add{b}\t{%2, %0|%0, %2}";
6947     }
6948 }
6949   [(set (attr "type")
6950      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6951         (const_string "incdec")
6952         (const_string "alu")))
6953    (set_attr "mode" "QI")])
6954
6955 (define_insn "*addqi_ext_1_rex64"
6956   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6957                          (const_int 8)
6958                          (const_int 8))
6959         (plus:SI
6960           (zero_extract:SI
6961             (match_operand 1 "ext_register_operand" "0")
6962             (const_int 8)
6963             (const_int 8))
6964           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6965    (clobber (reg:CC FLAGS_REG))]
6966   "TARGET_64BIT"
6967 {
6968   switch (get_attr_type (insn))
6969     {
6970     case TYPE_INCDEC:
6971       if (operands[2] == const1_rtx)
6972         return "inc{b}\t%h0";
6973       else
6974         {
6975           gcc_assert (operands[2] == constm1_rtx
6976                       || (CONST_INT_P (operands[2])
6977                           && INTVAL (operands[2]) == 255));
6978           return "dec{b}\t%h0";
6979         }
6980
6981     default:
6982       return "add{b}\t{%2, %h0|%h0, %2}";
6983     }
6984 }
6985   [(set (attr "type")
6986      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6987         (const_string "incdec")
6988         (const_string "alu")))
6989    (set_attr "modrm" "1")
6990    (set_attr "mode" "QI")])
6991
6992 (define_insn "addqi_ext_1"
6993   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6994                          (const_int 8)
6995                          (const_int 8))
6996         (plus:SI
6997           (zero_extract:SI
6998             (match_operand 1 "ext_register_operand" "0")
6999             (const_int 8)
7000             (const_int 8))
7001           (match_operand:QI 2 "general_operand" "Qmn")))
7002    (clobber (reg:CC FLAGS_REG))]
7003   "!TARGET_64BIT"
7004 {
7005   switch (get_attr_type (insn))
7006     {
7007     case TYPE_INCDEC:
7008       if (operands[2] == const1_rtx)
7009         return "inc{b}\t%h0";
7010       else
7011         {
7012           gcc_assert (operands[2] == constm1_rtx
7013                       || (CONST_INT_P (operands[2])
7014                           && INTVAL (operands[2]) == 255));
7015           return "dec{b}\t%h0";
7016         }
7017
7018     default:
7019       return "add{b}\t{%2, %h0|%h0, %2}";
7020     }
7021 }
7022   [(set (attr "type")
7023      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7024         (const_string "incdec")
7025         (const_string "alu")))
7026    (set_attr "modrm" "1")
7027    (set_attr "mode" "QI")])
7028
7029 (define_insn "*addqi_ext_2"
7030   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7031                          (const_int 8)
7032                          (const_int 8))
7033         (plus:SI
7034           (zero_extract:SI
7035             (match_operand 1 "ext_register_operand" "%0")
7036             (const_int 8)
7037             (const_int 8))
7038           (zero_extract:SI
7039             (match_operand 2 "ext_register_operand" "Q")
7040             (const_int 8)
7041             (const_int 8))))
7042    (clobber (reg:CC FLAGS_REG))]
7043   ""
7044   "add{b}\t{%h2, %h0|%h0, %h2}"
7045   [(set_attr "type" "alu")
7046    (set_attr "mode" "QI")])
7047
7048 ;; The lea patterns for non-Pmodes needs to be matched by
7049 ;; several insns converted to real lea by splitters.
7050
7051 (define_insn_and_split "*lea_general_1"
7052   [(set (match_operand 0 "register_operand" "=r")
7053         (plus (plus (match_operand 1 "index_register_operand" "l")
7054                     (match_operand 2 "register_operand" "r"))
7055               (match_operand 3 "immediate_operand" "i")))]
7056   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
7057     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
7058    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7059    && GET_MODE (operands[0]) == GET_MODE (operands[1])
7060    && GET_MODE (operands[0]) == GET_MODE (operands[2])
7061    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
7062        || GET_MODE (operands[3]) == VOIDmode)"
7063   "#"
7064   "&& reload_completed"
7065   [(const_int 0)]
7066 {
7067   rtx pat;
7068   operands[0] = gen_lowpart (SImode, operands[0]);
7069   operands[1] = gen_lowpart (Pmode, operands[1]);
7070   operands[2] = gen_lowpart (Pmode, operands[2]);
7071   operands[3] = gen_lowpart (Pmode, operands[3]);
7072   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
7073                       operands[3]);
7074   if (Pmode != SImode)
7075     pat = gen_rtx_SUBREG (SImode, pat, 0);
7076   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7077   DONE;
7078 }
7079   [(set_attr "type" "lea")
7080    (set_attr "mode" "SI")])
7081
7082 (define_insn_and_split "*lea_general_1_zext"
7083   [(set (match_operand:DI 0 "register_operand" "=r")
7084         (zero_extend:DI
7085           (plus:SI (plus:SI
7086                      (match_operand:SI 1 "index_register_operand" "l")
7087                      (match_operand:SI 2 "register_operand" "r"))
7088                    (match_operand:SI 3 "immediate_operand" "i"))))]
7089   "TARGET_64BIT"
7090   "#"
7091   "&& reload_completed"
7092   [(set (match_dup 0)
7093         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
7094                                                      (match_dup 2))
7095                                             (match_dup 3)) 0)))]
7096 {
7097   operands[1] = gen_lowpart (Pmode, operands[1]);
7098   operands[2] = gen_lowpart (Pmode, operands[2]);
7099   operands[3] = gen_lowpart (Pmode, operands[3]);
7100 }
7101   [(set_attr "type" "lea")
7102    (set_attr "mode" "SI")])
7103
7104 (define_insn_and_split "*lea_general_2"
7105   [(set (match_operand 0 "register_operand" "=r")
7106         (plus (mult (match_operand 1 "index_register_operand" "l")
7107                     (match_operand 2 "const248_operand" "i"))
7108               (match_operand 3 "nonmemory_operand" "ri")))]
7109   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
7110     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
7111    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7112    && GET_MODE (operands[0]) == GET_MODE (operands[1])
7113    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
7114        || GET_MODE (operands[3]) == VOIDmode)"
7115   "#"
7116   "&& reload_completed"
7117   [(const_int 0)]
7118 {
7119   rtx pat;
7120   operands[0] = gen_lowpart (SImode, operands[0]);
7121   operands[1] = gen_lowpart (Pmode, operands[1]);
7122   operands[3] = gen_lowpart (Pmode, operands[3]);
7123   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
7124                       operands[3]);
7125   if (Pmode != SImode)
7126     pat = gen_rtx_SUBREG (SImode, pat, 0);
7127   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7128   DONE;
7129 }
7130   [(set_attr "type" "lea")
7131    (set_attr "mode" "SI")])
7132
7133 (define_insn_and_split "*lea_general_2_zext"
7134   [(set (match_operand:DI 0 "register_operand" "=r")
7135         (zero_extend:DI
7136           (plus:SI (mult:SI
7137                      (match_operand:SI 1 "index_register_operand" "l")
7138                      (match_operand:SI 2 "const248_operand" "n"))
7139                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
7140   "TARGET_64BIT"
7141   "#"
7142   "&& reload_completed"
7143   [(set (match_dup 0)
7144         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
7145                                                      (match_dup 2))
7146                                             (match_dup 3)) 0)))]
7147 {
7148   operands[1] = gen_lowpart (Pmode, operands[1]);
7149   operands[3] = gen_lowpart (Pmode, operands[3]);
7150 }
7151   [(set_attr "type" "lea")
7152    (set_attr "mode" "SI")])
7153
7154 (define_insn_and_split "*lea_general_3"
7155   [(set (match_operand 0 "register_operand" "=r")
7156         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
7157                           (match_operand 2 "const248_operand" "i"))
7158                     (match_operand 3 "register_operand" "r"))
7159               (match_operand 4 "immediate_operand" "i")))]
7160   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
7161     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
7162    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7163    && GET_MODE (operands[0]) == GET_MODE (operands[1])
7164    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
7165   "#"
7166   "&& reload_completed"
7167   [(const_int 0)]
7168 {
7169   rtx pat;
7170   operands[0] = gen_lowpart (SImode, operands[0]);
7171   operands[1] = gen_lowpart (Pmode, operands[1]);
7172   operands[3] = gen_lowpart (Pmode, operands[3]);
7173   operands[4] = gen_lowpart (Pmode, operands[4]);
7174   pat = gen_rtx_PLUS (Pmode,
7175                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
7176                                                          operands[2]),
7177                                     operands[3]),
7178                       operands[4]);
7179   if (Pmode != SImode)
7180     pat = gen_rtx_SUBREG (SImode, pat, 0);
7181   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7182   DONE;
7183 }
7184   [(set_attr "type" "lea")
7185    (set_attr "mode" "SI")])
7186
7187 (define_insn_and_split "*lea_general_3_zext"
7188   [(set (match_operand:DI 0 "register_operand" "=r")
7189         (zero_extend:DI
7190           (plus:SI (plus:SI
7191                      (mult:SI
7192                        (match_operand:SI 1 "index_register_operand" "l")
7193                        (match_operand:SI 2 "const248_operand" "n"))
7194                      (match_operand:SI 3 "register_operand" "r"))
7195                    (match_operand:SI 4 "immediate_operand" "i"))))]
7196   "TARGET_64BIT"
7197   "#"
7198   "&& reload_completed"
7199   [(set (match_dup 0)
7200         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
7201                                                               (match_dup 2))
7202                                                      (match_dup 3))
7203                                             (match_dup 4)) 0)))]
7204 {
7205   operands[1] = gen_lowpart (Pmode, operands[1]);
7206   operands[3] = gen_lowpart (Pmode, operands[3]);
7207   operands[4] = gen_lowpart (Pmode, operands[4]);
7208 }
7209   [(set_attr "type" "lea")
7210    (set_attr "mode" "SI")])
7211
7212 ;; Convert lea to the lea pattern to avoid flags dependency.
7213 (define_split
7214   [(set (match_operand:DI 0 "register_operand" "")
7215         (plus:DI (match_operand:DI 1 "register_operand" "")
7216                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
7217    (clobber (reg:CC FLAGS_REG))]
7218   "TARGET_64BIT && reload_completed 
7219    && ix86_lea_for_add_ok (PLUS, insn, operands)"
7220   [(set (match_dup 0)
7221         (plus:DI (match_dup 1)
7222                  (match_dup 2)))]
7223   "")
7224
7225 ;; Convert lea to the lea pattern to avoid flags dependency.
7226 (define_split
7227   [(set (match_operand 0 "register_operand" "")
7228         (plus (match_operand 1 "register_operand" "")
7229               (match_operand 2 "nonmemory_operand" "")))
7230    (clobber (reg:CC FLAGS_REG))]
7231   "reload_completed && ix86_lea_for_add_ok (PLUS, insn, operands)" 
7232   [(const_int 0)]
7233 {
7234   rtx pat;
7235   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
7236      may confuse gen_lowpart.  */
7237   if (GET_MODE (operands[0]) != Pmode)
7238     {
7239       operands[1] = gen_lowpart (Pmode, operands[1]);
7240       operands[2] = gen_lowpart (Pmode, operands[2]);
7241     }
7242   operands[0] = gen_lowpart (SImode, operands[0]);
7243   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
7244   if (Pmode != SImode)
7245     pat = gen_rtx_SUBREG (SImode, pat, 0);
7246   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7247   DONE;
7248 })
7249
7250 ;; Convert lea to the lea pattern to avoid flags dependency.
7251 (define_split
7252   [(set (match_operand:DI 0 "register_operand" "")
7253         (zero_extend:DI
7254           (plus:SI (match_operand:SI 1 "register_operand" "")
7255                    (match_operand:SI 2 "nonmemory_operand" ""))))
7256    (clobber (reg:CC FLAGS_REG))]
7257   "TARGET_64BIT && reload_completed
7258    && true_regnum (operands[0]) != true_regnum (operands[1])"
7259   [(set (match_dup 0)
7260         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
7261 {
7262   operands[1] = gen_lowpart (Pmode, operands[1]);
7263   operands[2] = gen_lowpart (Pmode, operands[2]);
7264 })
7265 \f
7266 ;; Subtract instructions
7267
7268 (define_expand "sub<mode>3"
7269   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
7270         (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
7271                      (match_operand:SDWIM 2 "<general_operand>" "")))]
7272   ""
7273   "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
7274
7275 (define_insn_and_split "*sub<dwi>3_doubleword"
7276   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
7277         (minus:<DWI>
7278           (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
7279           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
7280    (clobber (reg:CC FLAGS_REG))]
7281   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7282   "#"
7283   "reload_completed"
7284   [(parallel [(set (reg:CC FLAGS_REG)
7285                    (compare:CC (match_dup 1) (match_dup 2)))
7286               (set (match_dup 0)
7287                    (minus:DWIH (match_dup 1) (match_dup 2)))])
7288    (parallel [(set (match_dup 3)
7289                    (minus:DWIH
7290                      (match_dup 4)
7291                      (plus:DWIH
7292                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7293                        (match_dup 5))))
7294               (clobber (reg:CC FLAGS_REG))])]
7295   "split_<dwi> (&operands[0], 3, &operands[0], &operands[3]);")
7296
7297 (define_insn "*sub<mode>_1"
7298   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7299         (minus:SWI
7300           (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7301           (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
7302    (clobber (reg:CC FLAGS_REG))]
7303   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7304   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7305   [(set_attr "type" "alu")
7306    (set_attr "mode" "<MODE>")])
7307
7308 (define_insn "*subsi_1_zext"
7309   [(set (match_operand:DI 0 "register_operand" "=r")
7310         (zero_extend:DI
7311           (minus:SI (match_operand:SI 1 "register_operand" "0")
7312                     (match_operand:SI 2 "general_operand" "g"))))
7313    (clobber (reg:CC FLAGS_REG))]
7314   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7315   "sub{l}\t{%2, %k0|%k0, %2}"
7316   [(set_attr "type" "alu")
7317    (set_attr "mode" "SI")])
7318
7319 (define_insn "*subqi_1_slp"
7320   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7321         (minus:QI (match_dup 0)
7322                   (match_operand:QI 1 "general_operand" "qn,qm")))
7323    (clobber (reg:CC FLAGS_REG))]
7324   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7325    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7326   "sub{b}\t{%1, %0|%0, %1}"
7327   [(set_attr "type" "alu1")
7328    (set_attr "mode" "QI")])
7329
7330 (define_insn "*sub<mode>_2"
7331   [(set (reg FLAGS_REG)
7332         (compare
7333           (minus:SWI
7334             (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7335             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
7336           (const_int 0)))
7337    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7338         (minus:SWI (match_dup 1) (match_dup 2)))]
7339   "ix86_match_ccmode (insn, CCGOCmode)
7340    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7341   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7342   [(set_attr "type" "alu")
7343    (set_attr "mode" "<MODE>")])
7344
7345 (define_insn "*subsi_2_zext"
7346   [(set (reg FLAGS_REG)
7347         (compare
7348           (minus:SI (match_operand:SI 1 "register_operand" "0")
7349                     (match_operand:SI 2 "general_operand" "g"))
7350           (const_int 0)))
7351    (set (match_operand:DI 0 "register_operand" "=r")
7352         (zero_extend:DI
7353           (minus:SI (match_dup 1)
7354                     (match_dup 2))))]
7355   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7356    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7357   "sub{l}\t{%2, %k0|%k0, %2}"
7358   [(set_attr "type" "alu")
7359    (set_attr "mode" "SI")])
7360
7361 (define_insn "*sub<mode>_3"
7362   [(set (reg FLAGS_REG)
7363         (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7364                  (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
7365    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7366         (minus:SWI (match_dup 1) (match_dup 2)))]
7367   "ix86_match_ccmode (insn, CCmode)
7368    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7369   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7370   [(set_attr "type" "alu")
7371    (set_attr "mode" "<MODE>")])
7372
7373 (define_insn "*subsi_3_zext"
7374   [(set (reg FLAGS_REG)
7375         (compare (match_operand:SI 1 "register_operand" "0")
7376                  (match_operand:SI 2 "general_operand" "g")))
7377    (set (match_operand:DI 0 "register_operand" "=r")
7378         (zero_extend:DI
7379           (minus:SI (match_dup 1)
7380                     (match_dup 2))))]
7381   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7382    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7383   "sub{l}\t{%2, %1|%1, %2}"
7384   [(set_attr "type" "alu")
7385    (set_attr "mode" "SI")])
7386 \f
7387 ;; Add with carry and subtract with borrow
7388
7389 (define_expand "<plusminus_insn><mode>3_carry"
7390   [(parallel
7391     [(set (match_operand:SWI 0 "nonimmediate_operand" "")
7392           (plusminus:SWI
7393             (match_operand:SWI 1 "nonimmediate_operand" "")
7394             (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
7395                        [(match_operand 3 "flags_reg_operand" "")
7396                         (const_int 0)])
7397                       (match_operand:SWI 2 "<general_operand>" ""))))
7398      (clobber (reg:CC FLAGS_REG))])]
7399   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
7400   "")
7401
7402 (define_insn "*<plusminus_insn><mode>3_carry"
7403   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7404         (plusminus:SWI
7405           (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
7406           (plus:SWI
7407             (match_operator 3 "ix86_carry_flag_operator"
7408              [(reg FLAGS_REG) (const_int 0)])
7409             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
7410    (clobber (reg:CC FLAGS_REG))]
7411   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7412   "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
7413   [(set_attr "type" "alu")
7414    (set_attr "use_carry" "1")
7415    (set_attr "pent_pair" "pu")
7416    (set_attr "mode" "<MODE>")])
7417
7418 (define_insn "*addsi3_carry_zext"
7419   [(set (match_operand:DI 0 "register_operand" "=r")
7420         (zero_extend:DI
7421           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7422                    (plus:SI (match_operator 3 "ix86_carry_flag_operator"
7423                              [(reg FLAGS_REG) (const_int 0)])
7424                             (match_operand:SI 2 "general_operand" "g")))))
7425    (clobber (reg:CC FLAGS_REG))]
7426   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
7427   "adc{l}\t{%2, %k0|%k0, %2}"
7428   [(set_attr "type" "alu")
7429    (set_attr "use_carry" "1")
7430    (set_attr "pent_pair" "pu")
7431    (set_attr "mode" "SI")])
7432
7433 (define_insn "*subsi3_carry_zext"
7434   [(set (match_operand:DI 0 "register_operand" "=r")
7435         (zero_extend:DI
7436           (minus:SI (match_operand:SI 1 "register_operand" "0")
7437                     (plus:SI (match_operator 3 "ix86_carry_flag_operator"
7438                               [(reg FLAGS_REG) (const_int 0)])
7439                              (match_operand:SI 2 "general_operand" "g")))))
7440    (clobber (reg:CC FLAGS_REG))]
7441   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7442   "sbb{l}\t{%2, %k0|%k0, %2}"
7443   [(set_attr "type" "alu")
7444    (set_attr "pent_pair" "pu")
7445    (set_attr "mode" "SI")])
7446 \f
7447 ;; Overflow setting add and subtract instructions
7448
7449 (define_insn "*add<mode>3_cconly_overflow"
7450   [(set (reg:CCC FLAGS_REG)
7451         (compare:CCC
7452           (plus:SWI
7453             (match_operand:SWI 1 "nonimmediate_operand" "%0")
7454             (match_operand:SWI 2 "<general_operand>" "<r><i>m"))
7455           (match_dup 1)))
7456    (clobber (match_scratch:SWI 0 "=<r>"))]
7457   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7458   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7459   [(set_attr "type" "alu")
7460    (set_attr "mode" "<MODE>")])
7461
7462 (define_insn "*sub<mode>3_cconly_overflow"
7463   [(set (reg:CCC FLAGS_REG)
7464         (compare:CCC
7465           (minus:SWI
7466             (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
7467             (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
7468           (match_dup 0)))]
7469   ""
7470   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
7471   [(set_attr "type" "icmp")
7472    (set_attr "mode" "<MODE>")])
7473
7474 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
7475   [(set (reg:CCC FLAGS_REG)
7476         (compare:CCC
7477             (plusminus:SWI
7478                 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
7479                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
7480             (match_dup 1)))
7481    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7482         (plusminus:SWI (match_dup 1) (match_dup 2)))]
7483   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
7484   "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
7485   [(set_attr "type" "alu")
7486    (set_attr "mode" "<MODE>")])
7487
7488 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
7489   [(set (reg:CCC FLAGS_REG)
7490         (compare:CCC
7491           (plusminus:SI
7492             (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
7493             (match_operand:SI 2 "general_operand" "g"))
7494           (match_dup 1)))
7495    (set (match_operand:DI 0 "register_operand" "=r")
7496         (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
7497   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
7498   "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
7499   [(set_attr "type" "alu")
7500    (set_attr "mode" "SI")])
7501
7502 ;; The patterns that match these are at the end of this file.
7503
7504 (define_expand "<plusminus_insn>xf3"
7505   [(set (match_operand:XF 0 "register_operand" "")
7506         (plusminus:XF
7507           (match_operand:XF 1 "register_operand" "")
7508           (match_operand:XF 2 "register_operand" "")))]
7509   "TARGET_80387"
7510   "")
7511
7512 (define_expand "<plusminus_insn><mode>3"
7513   [(set (match_operand:MODEF 0 "register_operand" "")
7514         (plusminus:MODEF
7515           (match_operand:MODEF 1 "register_operand" "")
7516           (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7517   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7518     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7519   "")
7520 \f
7521 ;; Multiply instructions
7522
7523 (define_expand "mul<mode>3"
7524   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7525                    (mult:SWIM248
7526                      (match_operand:SWIM248 1 "register_operand" "")
7527                      (match_operand:SWIM248 2 "<general_operand>" "")))
7528               (clobber (reg:CC FLAGS_REG))])]
7529   ""
7530   "")
7531
7532 (define_expand "mulqi3"
7533   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7534                    (mult:QI
7535                      (match_operand:QI 1 "register_operand" "")
7536                      (match_operand:QI 2 "nonimmediate_operand" "")))
7537               (clobber (reg:CC FLAGS_REG))])]
7538   "TARGET_QIMODE_MATH"
7539   "")
7540
7541 ;; On AMDFAM10
7542 ;; IMUL reg32/64, reg32/64, imm8        Direct
7543 ;; IMUL reg32/64, mem32/64, imm8        VectorPath
7544 ;; IMUL reg32/64, reg32/64, imm32       Direct
7545 ;; IMUL reg32/64, mem32/64, imm32       VectorPath
7546 ;; IMUL reg32/64, reg32/64              Direct
7547 ;; IMUL reg32/64, mem32/64              Direct
7548
7549 (define_insn "*mul<mode>3_1"
7550   [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
7551         (mult:SWI48
7552           (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
7553           (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
7554    (clobber (reg:CC FLAGS_REG))]
7555   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7556   "@
7557    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7558    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7559    imul{<imodesuffix>}\t{%2, %0|%0, %2}"
7560   [(set_attr "type" "imul")
7561    (set_attr "prefix_0f" "0,0,1")
7562    (set (attr "athlon_decode")
7563         (cond [(eq_attr "cpu" "athlon")
7564                   (const_string "vector")
7565                (eq_attr "alternative" "1")
7566                   (const_string "vector")
7567                (and (eq_attr "alternative" "2")
7568                     (match_operand 1 "memory_operand" ""))
7569                   (const_string "vector")]
7570               (const_string "direct")))
7571    (set (attr "amdfam10_decode")
7572         (cond [(and (eq_attr "alternative" "0,1")
7573                     (match_operand 1 "memory_operand" ""))
7574                   (const_string "vector")]
7575               (const_string "direct")))
7576    (set_attr "mode" "<MODE>")])
7577
7578 (define_insn "*mulsi3_1_zext"
7579   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7580         (zero_extend:DI
7581           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7582                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
7583    (clobber (reg:CC FLAGS_REG))]
7584   "TARGET_64BIT
7585    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7586   "@
7587    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7588    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7589    imul{l}\t{%2, %k0|%k0, %2}"
7590   [(set_attr "type" "imul")
7591    (set_attr "prefix_0f" "0,0,1")
7592    (set (attr "athlon_decode")
7593         (cond [(eq_attr "cpu" "athlon")
7594                   (const_string "vector")
7595                (eq_attr "alternative" "1")
7596                   (const_string "vector")
7597                (and (eq_attr "alternative" "2")
7598                     (match_operand 1 "memory_operand" ""))
7599                   (const_string "vector")]
7600               (const_string "direct")))
7601    (set (attr "amdfam10_decode")
7602         (cond [(and (eq_attr "alternative" "0,1")
7603                     (match_operand 1 "memory_operand" ""))
7604                   (const_string "vector")]
7605               (const_string "direct")))
7606    (set_attr "mode" "SI")])
7607
7608 ;; On AMDFAM10
7609 ;; IMUL reg16, reg16, imm8      VectorPath
7610 ;; IMUL reg16, mem16, imm8      VectorPath
7611 ;; IMUL reg16, reg16, imm16     VectorPath
7612 ;; IMUL reg16, mem16, imm16     VectorPath
7613 ;; IMUL reg16, reg16            Direct
7614 ;; IMUL reg16, mem16            Direct
7615
7616 (define_insn "*mulhi3_1"
7617   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7618         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7619                  (match_operand:HI 2 "general_operand" "K,n,mr")))
7620    (clobber (reg:CC FLAGS_REG))]
7621   "TARGET_HIMODE_MATH
7622    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7623   "@
7624    imul{w}\t{%2, %1, %0|%0, %1, %2}
7625    imul{w}\t{%2, %1, %0|%0, %1, %2}
7626    imul{w}\t{%2, %0|%0, %2}"
7627   [(set_attr "type" "imul")
7628    (set_attr "prefix_0f" "0,0,1")
7629    (set (attr "athlon_decode")
7630         (cond [(eq_attr "cpu" "athlon")
7631                   (const_string "vector")
7632                (eq_attr "alternative" "1,2")
7633                   (const_string "vector")]
7634               (const_string "direct")))
7635    (set (attr "amdfam10_decode")
7636         (cond [(eq_attr "alternative" "0,1")
7637                   (const_string "vector")]
7638               (const_string "direct")))
7639    (set_attr "mode" "HI")])
7640
7641 ;;On AMDFAM10
7642 ;; MUL reg8     Direct
7643 ;; MUL mem8     Direct
7644
7645 (define_insn "*mulqi3_1"
7646   [(set (match_operand:QI 0 "register_operand" "=a")
7647         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7648                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7649    (clobber (reg:CC FLAGS_REG))]
7650   "TARGET_QIMODE_MATH
7651    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7652   "mul{b}\t%2"
7653   [(set_attr "type" "imul")
7654    (set_attr "length_immediate" "0")
7655    (set (attr "athlon_decode")
7656      (if_then_else (eq_attr "cpu" "athlon")
7657         (const_string "vector")
7658         (const_string "direct")))
7659    (set_attr "amdfam10_decode" "direct")
7660    (set_attr "mode" "QI")])
7661
7662 (define_expand "<u>mul<mode><dwi>3"
7663   [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
7664                    (mult:<DWI>
7665                      (any_extend:<DWI>
7666                        (match_operand:DWIH 1 "nonimmediate_operand" ""))
7667                      (any_extend:<DWI>
7668                        (match_operand:DWIH 2 "register_operand" ""))))
7669               (clobber (reg:CC FLAGS_REG))])]
7670   ""
7671   "")
7672
7673 (define_expand "<u>mulqihi3"
7674   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7675                    (mult:HI
7676                      (any_extend:HI
7677                        (match_operand:QI 1 "nonimmediate_operand" ""))
7678                      (any_extend:HI
7679                        (match_operand:QI 2 "register_operand" ""))))
7680               (clobber (reg:CC FLAGS_REG))])]
7681   "TARGET_QIMODE_MATH"
7682   "")
7683
7684 (define_insn "*<u>mul<mode><dwi>3_1"
7685   [(set (match_operand:<DWI> 0 "register_operand" "=A")
7686         (mult:<DWI>
7687           (any_extend:<DWI>
7688             (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
7689           (any_extend:<DWI>
7690             (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7691    (clobber (reg:CC FLAGS_REG))]
7692   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7693   "<sgnprefix>mul{<imodesuffix>}\t%2"
7694   [(set_attr "type" "imul")
7695    (set_attr "length_immediate" "0")
7696    (set (attr "athlon_decode")
7697      (if_then_else (eq_attr "cpu" "athlon")
7698         (const_string "vector")
7699         (const_string "double")))
7700    (set_attr "amdfam10_decode" "double")
7701    (set_attr "mode" "<MODE>")])
7702
7703 (define_insn "*<u>mulqihi3_1"
7704   [(set (match_operand:HI 0 "register_operand" "=a")
7705         (mult:HI
7706           (any_extend:HI
7707             (match_operand:QI 1 "nonimmediate_operand" "%0"))
7708           (any_extend:HI
7709             (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7710    (clobber (reg:CC FLAGS_REG))]
7711   "TARGET_QIMODE_MATH
7712    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7713   "<sgnprefix>mul{b}\t%2"
7714   [(set_attr "type" "imul")
7715    (set_attr "length_immediate" "0")
7716    (set (attr "athlon_decode")
7717      (if_then_else (eq_attr "cpu" "athlon")
7718         (const_string "vector")
7719         (const_string "direct")))
7720    (set_attr "amdfam10_decode" "direct")
7721    (set_attr "mode" "QI")])
7722
7723 (define_expand "<s>mul<mode>3_highpart"
7724   [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
7725                    (truncate:SWI48
7726                      (lshiftrt:<DWI>
7727                        (mult:<DWI>
7728                          (any_extend:<DWI>
7729                            (match_operand:SWI48 1 "nonimmediate_operand" ""))
7730                          (any_extend:<DWI>
7731                            (match_operand:SWI48 2 "register_operand" "")))
7732                        (match_dup 4))))
7733               (clobber (match_scratch:SWI48 3 ""))
7734               (clobber (reg:CC FLAGS_REG))])]
7735   ""
7736   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7737
7738 (define_insn "*<s>muldi3_highpart_1"
7739   [(set (match_operand:DI 0 "register_operand" "=d")
7740         (truncate:DI
7741           (lshiftrt:TI
7742             (mult:TI
7743               (any_extend:TI
7744                 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7745               (any_extend:TI
7746                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7747             (const_int 64))))
7748    (clobber (match_scratch:DI 3 "=1"))
7749    (clobber (reg:CC FLAGS_REG))]
7750   "TARGET_64BIT
7751    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7752   "<sgnprefix>mul{q}\t%2"
7753   [(set_attr "type" "imul")
7754    (set_attr "length_immediate" "0")
7755    (set (attr "athlon_decode")
7756      (if_then_else (eq_attr "cpu" "athlon")
7757         (const_string "vector")
7758         (const_string "double")))
7759    (set_attr "amdfam10_decode" "double")
7760    (set_attr "mode" "DI")])
7761
7762 (define_insn "*<s>mulsi3_highpart_1"
7763   [(set (match_operand:SI 0 "register_operand" "=d")
7764         (truncate:SI
7765           (lshiftrt:DI
7766             (mult:DI
7767               (any_extend:DI
7768                 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7769               (any_extend:DI
7770                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7771             (const_int 32))))
7772    (clobber (match_scratch:SI 3 "=1"))
7773    (clobber (reg:CC FLAGS_REG))]
7774   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7775   "<sgnprefix>mul{l}\t%2"
7776   [(set_attr "type" "imul")
7777    (set_attr "length_immediate" "0")
7778    (set (attr "athlon_decode")
7779      (if_then_else (eq_attr "cpu" "athlon")
7780         (const_string "vector")
7781         (const_string "double")))
7782    (set_attr "amdfam10_decode" "double")
7783    (set_attr "mode" "SI")])
7784
7785 (define_insn "*<s>mulsi3_highpart_zext"
7786   [(set (match_operand:DI 0 "register_operand" "=d")
7787         (zero_extend:DI (truncate:SI
7788           (lshiftrt:DI
7789             (mult:DI (any_extend:DI
7790                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7791                      (any_extend:DI
7792                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7793             (const_int 32)))))
7794    (clobber (match_scratch:SI 3 "=1"))
7795    (clobber (reg:CC FLAGS_REG))]
7796   "TARGET_64BIT
7797    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7798   "<sgnprefix>mul{l}\t%2"
7799   [(set_attr "type" "imul")
7800    (set_attr "length_immediate" "0")
7801    (set (attr "athlon_decode")
7802      (if_then_else (eq_attr "cpu" "athlon")
7803         (const_string "vector")
7804         (const_string "double")))
7805    (set_attr "amdfam10_decode" "double")
7806    (set_attr "mode" "SI")])
7807
7808 ;; The patterns that match these are at the end of this file.
7809
7810 (define_expand "mulxf3"
7811   [(set (match_operand:XF 0 "register_operand" "")
7812         (mult:XF (match_operand:XF 1 "register_operand" "")
7813                  (match_operand:XF 2 "register_operand" "")))]
7814   "TARGET_80387"
7815   "")
7816
7817 (define_expand "mul<mode>3"
7818   [(set (match_operand:MODEF 0 "register_operand" "")
7819         (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
7820                     (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7821   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7822     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7823   "")
7824 \f
7825 ;; Divide instructions
7826
7827 (define_insn "<u>divqi3"
7828   [(set (match_operand:QI 0 "register_operand" "=a")
7829         (any_div:QI
7830           (match_operand:HI 1 "register_operand" "0")
7831           (match_operand:QI 2 "nonimmediate_operand" "qm")))
7832    (clobber (reg:CC FLAGS_REG))]
7833   "TARGET_QIMODE_MATH"
7834   "<sgnprefix>div{b}\t%2"
7835   [(set_attr "type" "idiv")
7836    (set_attr "mode" "QI")])
7837
7838 ;; The patterns that match these are at the end of this file.
7839
7840 (define_expand "divxf3"
7841   [(set (match_operand:XF 0 "register_operand" "")
7842         (div:XF (match_operand:XF 1 "register_operand" "")
7843                 (match_operand:XF 2 "register_operand" "")))]
7844   "TARGET_80387"
7845   "")
7846
7847 (define_expand "divdf3"
7848   [(set (match_operand:DF 0 "register_operand" "")
7849         (div:DF (match_operand:DF 1 "register_operand" "")
7850                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7851    "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7852     || (TARGET_SSE2 && TARGET_SSE_MATH)"
7853    "")
7854
7855 (define_expand "divsf3"
7856   [(set (match_operand:SF 0 "register_operand" "")
7857         (div:SF (match_operand:SF 1 "register_operand" "")
7858                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7859   "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7860     || TARGET_SSE_MATH"
7861 {
7862   if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
7863       && flag_finite_math_only && !flag_trapping_math
7864       && flag_unsafe_math_optimizations)
7865     {
7866       ix86_emit_swdivsf (operands[0], operands[1],
7867                          operands[2], SFmode);
7868       DONE;
7869     }
7870 })
7871 \f
7872 ;; Divmod instructions.
7873
7874 (define_expand "divmod<mode>4"
7875   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7876                    (div:SWIM248
7877                      (match_operand:SWIM248 1 "register_operand" "")
7878                      (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7879               (set (match_operand:SWIM248 3 "register_operand" "")
7880                    (mod:SWIM248 (match_dup 1) (match_dup 2)))
7881               (clobber (reg:CC FLAGS_REG))])]
7882   ""
7883   "")
7884
7885 (define_insn_and_split "*divmod<mode>4"
7886   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7887         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7888                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7889    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7890         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7891    (clobber (reg:CC FLAGS_REG))]
7892   ""
7893   "#"
7894   "&& reload_completed"
7895   [(parallel [(set (match_dup 1)
7896                    (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7897               (clobber (reg:CC FLAGS_REG))])
7898    (parallel [(set (match_dup 0)
7899                    (div:SWIM248 (match_dup 2) (match_dup 3)))
7900               (set (match_dup 1)
7901                    (mod:SWIM248 (match_dup 2) (match_dup 3)))
7902               (use (match_dup 1))
7903               (clobber (reg:CC FLAGS_REG))])]
7904 {
7905   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - 1);
7906
7907   if (<MODE>mode != HImode
7908       && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7909     operands[4] = operands[2];
7910   else
7911     {
7912       /* Avoid use of cltd in favor of a mov+shift.  */
7913       emit_move_insn (operands[1], operands[2]);
7914       operands[4] = operands[1];
7915     }
7916 }
7917   [(set_attr "type" "multi")
7918    (set_attr "mode" "<MODE>")])
7919
7920 (define_insn "*divmod<mode>4_noext"
7921   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7922         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7923                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7924    (set (match_operand:SWIM248 1 "register_operand" "=d")
7925         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7926    (use (match_operand:SWIM248 4 "register_operand" "1"))
7927    (clobber (reg:CC FLAGS_REG))]
7928   ""
7929   "idiv{<imodesuffix>}\t%3"
7930   [(set_attr "type" "idiv")
7931    (set_attr "mode" "<MODE>")])
7932
7933 (define_expand "udivmod<mode>4"
7934   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7935                    (udiv:SWIM248
7936                      (match_operand:SWIM248 1 "register_operand" "")
7937                      (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7938               (set (match_operand:SWIM248 3 "register_operand" "")
7939                    (umod:SWIM248 (match_dup 1) (match_dup 2)))
7940               (clobber (reg:CC FLAGS_REG))])]
7941   ""
7942   "")
7943
7944 (define_insn_and_split "*udivmod<mode>4"
7945   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7946         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7947                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7948    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7949         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7950    (clobber (reg:CC FLAGS_REG))]
7951   ""
7952   "#"
7953   "&& reload_completed"
7954   [(set (match_dup 1) (const_int 0))
7955    (parallel [(set (match_dup 0)
7956                    (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7957               (set (match_dup 1)
7958                    (umod:SWIM248 (match_dup 2) (match_dup 3)))
7959               (use (match_dup 1))
7960               (clobber (reg:CC FLAGS_REG))])]
7961   ""
7962   [(set_attr "type" "multi")
7963    (set_attr "mode" "<MODE>")])
7964
7965 (define_insn "*udivmod<mode>4_noext"
7966   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7967         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7968                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7969    (set (match_operand:SWIM248 1 "register_operand" "=d")
7970         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7971    (use (match_operand:SWIM248 4 "register_operand" "1"))
7972    (clobber (reg:CC FLAGS_REG))]
7973   ""
7974   "div{<imodesuffix>}\t%3"
7975   [(set_attr "type" "idiv")
7976    (set_attr "mode" "<MODE>")])
7977
7978 ;; We cannot use div/idiv for double division, because it causes
7979 ;; "division by zero" on the overflow and that's not what we expect
7980 ;; from truncate.  Because true (non truncating) double division is
7981 ;; never generated, we can't create this insn anyway.
7982 ;
7983 ;(define_insn ""
7984 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7985 ;       (truncate:SI
7986 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7987 ;                  (zero_extend:DI
7988 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7989 ;   (set (match_operand:SI 3 "register_operand" "=d")
7990 ;       (truncate:SI
7991 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7992 ;   (clobber (reg:CC FLAGS_REG))]
7993 ;  ""
7994 ;  "div{l}\t{%2, %0|%0, %2}"
7995 ;  [(set_attr "type" "idiv")])
7996 \f
7997 ;;- Logical AND instructions
7998
7999 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8000 ;; Note that this excludes ah.
8001
8002 (define_expand "testsi_ccno_1"
8003   [(set (reg:CCNO FLAGS_REG)
8004         (compare:CCNO
8005           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8006                   (match_operand:SI 1 "nonmemory_operand" ""))
8007           (const_int 0)))]
8008   ""
8009   "")
8010
8011 (define_expand "testqi_ccz_1"
8012   [(set (reg:CCZ FLAGS_REG)
8013         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8014                              (match_operand:QI 1 "nonmemory_operand" ""))
8015                  (const_int 0)))]
8016   ""
8017   "")
8018
8019 (define_insn "*testdi_1"
8020   [(set (reg FLAGS_REG)
8021         (compare
8022          (and:DI
8023           (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8024           (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8025          (const_int 0)))]
8026   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8027    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8028   "@
8029    test{l}\t{%k1, %k0|%k0, %k1}
8030    test{l}\t{%k1, %k0|%k0, %k1}
8031    test{q}\t{%1, %0|%0, %1}
8032    test{q}\t{%1, %0|%0, %1}
8033    test{q}\t{%1, %0|%0, %1}"
8034   [(set_attr "type" "test")
8035    (set_attr "modrm" "0,1,0,1,1")
8036    (set_attr "mode" "SI,SI,DI,DI,DI")])
8037
8038 (define_insn "*testqi_1_maybe_si"
8039   [(set (reg FLAGS_REG)
8040         (compare
8041           (and:QI
8042             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8043             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8044           (const_int 0)))]
8045    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8046     && ix86_match_ccmode (insn,
8047                          CONST_INT_P (operands[1])
8048                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8049 {
8050   if (which_alternative == 3)
8051     {
8052       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8053         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8054       return "test{l}\t{%1, %k0|%k0, %1}";
8055     }
8056   return "test{b}\t{%1, %0|%0, %1}";
8057 }
8058   [(set_attr "type" "test")
8059    (set_attr "modrm" "0,1,1,1")
8060    (set_attr "mode" "QI,QI,QI,SI")
8061    (set_attr "pent_pair" "uv,np,uv,np")])
8062
8063 (define_insn "*test<mode>_1"
8064   [(set (reg FLAGS_REG)
8065         (compare
8066          (and:SWI124
8067           (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
8068           (match_operand:SWI124 1 "general_operand" "<i>,<i>,<r><i>"))
8069          (const_int 0)))]
8070   "ix86_match_ccmode (insn, CCNOmode)
8071    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8072   "test{<imodesuffix>}\t{%1, %0|%0, %1}"
8073   [(set_attr "type" "test")
8074    (set_attr "modrm" "0,1,1")
8075    (set_attr "mode" "<MODE>")
8076    (set_attr "pent_pair" "uv,np,uv")])
8077
8078 (define_expand "testqi_ext_ccno_0"
8079   [(set (reg:CCNO FLAGS_REG)
8080         (compare:CCNO
8081           (and:SI
8082             (zero_extract:SI
8083               (match_operand 0 "ext_register_operand" "")
8084               (const_int 8)
8085               (const_int 8))
8086             (match_operand 1 "const_int_operand" ""))
8087           (const_int 0)))]
8088   ""
8089   "")
8090
8091 (define_insn "*testqi_ext_0"
8092   [(set (reg FLAGS_REG)
8093         (compare
8094           (and:SI
8095             (zero_extract:SI
8096               (match_operand 0 "ext_register_operand" "Q")
8097               (const_int 8)
8098               (const_int 8))
8099             (match_operand 1 "const_int_operand" "n"))
8100           (const_int 0)))]
8101   "ix86_match_ccmode (insn, CCNOmode)"
8102   "test{b}\t{%1, %h0|%h0, %1}"
8103   [(set_attr "type" "test")
8104    (set_attr "mode" "QI")
8105    (set_attr "length_immediate" "1")
8106    (set_attr "modrm" "1")
8107    (set_attr "pent_pair" "np")])
8108
8109 (define_insn "*testqi_ext_1_rex64"
8110   [(set (reg FLAGS_REG)
8111         (compare
8112           (and:SI
8113             (zero_extract:SI
8114               (match_operand 0 "ext_register_operand" "Q")
8115               (const_int 8)
8116               (const_int 8))
8117             (zero_extend:SI
8118               (match_operand:QI 1 "register_operand" "Q")))
8119           (const_int 0)))]
8120   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8121   "test{b}\t{%1, %h0|%h0, %1}"
8122   [(set_attr "type" "test")
8123    (set_attr "mode" "QI")])
8124
8125 (define_insn "*testqi_ext_1"
8126   [(set (reg FLAGS_REG)
8127         (compare
8128           (and:SI
8129             (zero_extract:SI
8130               (match_operand 0 "ext_register_operand" "Q")
8131               (const_int 8)
8132               (const_int 8))
8133             (zero_extend:SI
8134               (match_operand:QI 1 "general_operand" "Qm")))
8135           (const_int 0)))]
8136   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8137   "test{b}\t{%1, %h0|%h0, %1}"
8138   [(set_attr "type" "test")
8139    (set_attr "mode" "QI")])
8140
8141 (define_insn "*testqi_ext_2"
8142   [(set (reg FLAGS_REG)
8143         (compare
8144           (and:SI
8145             (zero_extract:SI
8146               (match_operand 0 "ext_register_operand" "Q")
8147               (const_int 8)
8148               (const_int 8))
8149             (zero_extract:SI
8150               (match_operand 1 "ext_register_operand" "Q")
8151               (const_int 8)
8152               (const_int 8)))
8153           (const_int 0)))]
8154   "ix86_match_ccmode (insn, CCNOmode)"
8155   "test{b}\t{%h1, %h0|%h0, %h1}"
8156   [(set_attr "type" "test")
8157    (set_attr "mode" "QI")])
8158
8159 (define_insn "*testqi_ext_3_rex64"
8160   [(set (reg FLAGS_REG)
8161         (compare (zero_extract:DI
8162                    (match_operand 0 "nonimmediate_operand" "rm")
8163                    (match_operand:DI 1 "const_int_operand" "")
8164                    (match_operand:DI 2 "const_int_operand" ""))
8165                  (const_int 0)))]
8166   "TARGET_64BIT
8167    && ix86_match_ccmode (insn, CCNOmode)
8168    && INTVAL (operands[1]) > 0
8169    && INTVAL (operands[2]) >= 0
8170    /* Ensure that resulting mask is zero or sign extended operand.  */
8171    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8172        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8173            && INTVAL (operands[1]) > 32))
8174    && (GET_MODE (operands[0]) == SImode
8175        || GET_MODE (operands[0]) == DImode
8176        || GET_MODE (operands[0]) == HImode
8177        || GET_MODE (operands[0]) == QImode)"
8178   "#")
8179
8180 ;; Combine likes to form bit extractions for some tests.  Humor it.
8181 (define_insn "*testqi_ext_3"
8182   [(set (reg FLAGS_REG)
8183         (compare (zero_extract:SI
8184                    (match_operand 0 "nonimmediate_operand" "rm")
8185                    (match_operand:SI 1 "const_int_operand" "")
8186                    (match_operand:SI 2 "const_int_operand" ""))
8187                  (const_int 0)))]
8188   "ix86_match_ccmode (insn, CCNOmode)
8189    && INTVAL (operands[1]) > 0
8190    && INTVAL (operands[2]) >= 0
8191    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8192    && (GET_MODE (operands[0]) == SImode
8193        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8194        || GET_MODE (operands[0]) == HImode
8195        || GET_MODE (operands[0]) == QImode)"
8196   "#")
8197
8198 (define_split
8199   [(set (match_operand 0 "flags_reg_operand" "")
8200         (match_operator 1 "compare_operator"
8201           [(zero_extract
8202              (match_operand 2 "nonimmediate_operand" "")
8203              (match_operand 3 "const_int_operand" "")
8204              (match_operand 4 "const_int_operand" ""))
8205            (const_int 0)]))]
8206   "ix86_match_ccmode (insn, CCNOmode)"
8207   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8208 {
8209   rtx val = operands[2];
8210   HOST_WIDE_INT len = INTVAL (operands[3]);
8211   HOST_WIDE_INT pos = INTVAL (operands[4]);
8212   HOST_WIDE_INT mask;
8213   enum machine_mode mode, submode;
8214
8215   mode = GET_MODE (val);
8216   if (MEM_P (val))
8217     {
8218       /* ??? Combine likes to put non-volatile mem extractions in QImode
8219          no matter the size of the test.  So find a mode that works.  */
8220       if (! MEM_VOLATILE_P (val))
8221         {
8222           mode = smallest_mode_for_size (pos + len, MODE_INT);
8223           val = adjust_address (val, mode, 0);
8224         }
8225     }
8226   else if (GET_CODE (val) == SUBREG
8227            && (submode = GET_MODE (SUBREG_REG (val)),
8228                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8229            && pos + len <= GET_MODE_BITSIZE (submode)
8230            && GET_MODE_CLASS (submode) == MODE_INT)
8231     {
8232       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
8233       mode = submode;
8234       val = SUBREG_REG (val);
8235     }
8236   else if (mode == HImode && pos + len <= 8)
8237     {
8238       /* Small HImode tests can be converted to QImode.  */
8239       mode = QImode;
8240       val = gen_lowpart (QImode, val);
8241     }
8242
8243   if (len == HOST_BITS_PER_WIDE_INT)
8244     mask = -1;
8245   else
8246     mask = ((HOST_WIDE_INT)1 << len) - 1;
8247   mask <<= pos;
8248
8249   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8250 })
8251
8252 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8253 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8254 ;; this is relatively important trick.
8255 ;; Do the conversion only post-reload to avoid limiting of the register class
8256 ;; to QI regs.
8257 (define_split
8258   [(set (match_operand 0 "flags_reg_operand" "")
8259         (match_operator 1 "compare_operator"
8260           [(and (match_operand 2 "register_operand" "")
8261                 (match_operand 3 "const_int_operand" ""))
8262            (const_int 0)]))]
8263    "reload_completed
8264     && QI_REG_P (operands[2])
8265     && GET_MODE (operands[2]) != QImode
8266     && ((ix86_match_ccmode (insn, CCZmode)
8267          && !(INTVAL (operands[3]) & ~(255 << 8)))
8268         || (ix86_match_ccmode (insn, CCNOmode)
8269             && !(INTVAL (operands[3]) & ~(127 << 8))))"
8270   [(set (match_dup 0)
8271         (match_op_dup 1
8272           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8273                    (match_dup 3))
8274            (const_int 0)]))]
8275   "operands[2] = gen_lowpart (SImode, operands[2]);
8276    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8277
8278 (define_split
8279   [(set (match_operand 0 "flags_reg_operand" "")
8280         (match_operator 1 "compare_operator"
8281           [(and (match_operand 2 "nonimmediate_operand" "")
8282                 (match_operand 3 "const_int_operand" ""))
8283            (const_int 0)]))]
8284    "reload_completed
8285     && GET_MODE (operands[2]) != QImode
8286     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8287     && ((ix86_match_ccmode (insn, CCZmode)
8288          && !(INTVAL (operands[3]) & ~255))
8289         || (ix86_match_ccmode (insn, CCNOmode)
8290             && !(INTVAL (operands[3]) & ~127)))"
8291   [(set (match_dup 0)
8292         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8293                          (const_int 0)]))]
8294   "operands[2] = gen_lowpart (QImode, operands[2]);
8295    operands[3] = gen_lowpart (QImode, operands[3]);")
8296
8297 ;; %%% This used to optimize known byte-wide and operations to memory,
8298 ;; and sometimes to QImode registers.  If this is considered useful,
8299 ;; it should be done with splitters.
8300
8301 (define_expand "and<mode>3"
8302   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8303         (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8304                   (match_operand:SWIM 2 "<general_szext_operand>" "")))]
8305   ""
8306   "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
8307
8308 (define_insn "*anddi_1"
8309   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8310         (and:DI
8311          (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8312          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8313    (clobber (reg:CC FLAGS_REG))]
8314   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8315 {
8316   switch (get_attr_type (insn))
8317     {
8318     case TYPE_IMOVX:
8319       {
8320         enum machine_mode mode;
8321
8322         gcc_assert (CONST_INT_P (operands[2]));
8323         if (INTVAL (operands[2]) == 0xff)
8324           mode = QImode;
8325         else
8326           {
8327             gcc_assert (INTVAL (operands[2]) == 0xffff);
8328             mode = HImode;
8329           }
8330
8331         operands[1] = gen_lowpart (mode, operands[1]);
8332         if (mode == QImode)
8333           return "movz{bl|x}\t{%1, %k0|%k0, %1}";
8334         else
8335           return "movz{wl|x}\t{%1, %k0|%k0, %1}";
8336       }
8337
8338     default:
8339       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8340       if (get_attr_mode (insn) == MODE_SI)
8341         return "and{l}\t{%k2, %k0|%k0, %k2}";
8342       else
8343         return "and{q}\t{%2, %0|%0, %2}";
8344     }
8345 }
8346   [(set_attr "type" "alu,alu,alu,imovx")
8347    (set_attr "length_immediate" "*,*,*,0")
8348    (set (attr "prefix_rex")
8349      (if_then_else
8350        (and (eq_attr "type" "imovx")
8351             (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
8352                  (match_operand 1 "ext_QIreg_nomode_operand" "")))
8353        (const_string "1")
8354        (const_string "*")))
8355    (set_attr "mode" "SI,DI,DI,SI")])
8356
8357 (define_insn "*andsi_1"
8358   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8359         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8360                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8361    (clobber (reg:CC FLAGS_REG))]
8362   "ix86_binary_operator_ok (AND, SImode, operands)"
8363 {
8364   switch (get_attr_type (insn))
8365     {
8366     case TYPE_IMOVX:
8367       {
8368         enum machine_mode mode;
8369
8370         gcc_assert (CONST_INT_P (operands[2]));
8371         if (INTVAL (operands[2]) == 0xff)
8372           mode = QImode;
8373         else
8374           {
8375             gcc_assert (INTVAL (operands[2]) == 0xffff);
8376             mode = HImode;
8377           }
8378
8379         operands[1] = gen_lowpart (mode, operands[1]);
8380         if (mode == QImode)
8381           return "movz{bl|x}\t{%1, %0|%0, %1}";
8382         else
8383           return "movz{wl|x}\t{%1, %0|%0, %1}";
8384       }
8385
8386     default:
8387       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8388       return "and{l}\t{%2, %0|%0, %2}";
8389     }
8390 }
8391   [(set_attr "type" "alu,alu,imovx")
8392    (set (attr "prefix_rex")
8393      (if_then_else
8394        (and (eq_attr "type" "imovx")
8395             (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
8396                  (match_operand 1 "ext_QIreg_nomode_operand" "")))
8397        (const_string "1")
8398        (const_string "*")))
8399    (set_attr "length_immediate" "*,*,0")
8400    (set_attr "mode" "SI")])
8401
8402 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8403 (define_insn "*andsi_1_zext"
8404   [(set (match_operand:DI 0 "register_operand" "=r")
8405         (zero_extend:DI
8406           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8407                   (match_operand:SI 2 "general_operand" "g"))))
8408    (clobber (reg:CC FLAGS_REG))]
8409   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8410   "and{l}\t{%2, %k0|%k0, %2}"
8411   [(set_attr "type" "alu")
8412    (set_attr "mode" "SI")])
8413
8414 (define_insn "*andhi_1"
8415   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8416         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8417                 (match_operand:HI 2 "general_operand" "rn,rm,L")))
8418    (clobber (reg:CC FLAGS_REG))]
8419   "ix86_binary_operator_ok (AND, HImode, operands)"
8420 {
8421   switch (get_attr_type (insn))
8422     {
8423     case TYPE_IMOVX:
8424       gcc_assert (CONST_INT_P (operands[2]));
8425       gcc_assert (INTVAL (operands[2]) == 0xff);
8426       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8427
8428     default:
8429       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8430
8431       return "and{w}\t{%2, %0|%0, %2}";
8432     }
8433 }
8434   [(set_attr "type" "alu,alu,imovx")
8435    (set_attr "length_immediate" "*,*,0")
8436    (set (attr "prefix_rex")
8437      (if_then_else
8438        (and (eq_attr "type" "imovx")
8439             (match_operand 1 "ext_QIreg_nomode_operand" ""))
8440        (const_string "1")
8441        (const_string "*")))
8442    (set_attr "mode" "HI,HI,SI")])
8443
8444 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8445 (define_insn "*andqi_1"
8446   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8447         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8448                 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
8449    (clobber (reg:CC FLAGS_REG))]
8450   "ix86_binary_operator_ok (AND, QImode, operands)"
8451   "@
8452    and{b}\t{%2, %0|%0, %2}
8453    and{b}\t{%2, %0|%0, %2}
8454    and{l}\t{%k2, %k0|%k0, %k2}"
8455   [(set_attr "type" "alu")
8456    (set_attr "mode" "QI,QI,SI")])
8457
8458 (define_insn "*andqi_1_slp"
8459   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8460         (and:QI (match_dup 0)
8461                 (match_operand:QI 1 "general_operand" "qn,qmn")))
8462    (clobber (reg:CC FLAGS_REG))]
8463   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8464    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8465   "and{b}\t{%1, %0|%0, %1}"
8466   [(set_attr "type" "alu1")
8467    (set_attr "mode" "QI")])
8468
8469 (define_split
8470   [(set (match_operand 0 "register_operand" "")
8471         (and (match_dup 0)
8472              (const_int -65536)))
8473    (clobber (reg:CC FLAGS_REG))]
8474   "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
8475     || optimize_function_for_size_p (cfun)"
8476   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8477   "operands[1] = gen_lowpart (HImode, operands[0]);")
8478
8479 (define_split
8480   [(set (match_operand 0 "ext_register_operand" "")
8481         (and (match_dup 0)
8482              (const_int -256)))
8483    (clobber (reg:CC FLAGS_REG))]
8484   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8485    && reload_completed"
8486   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8487   "operands[1] = gen_lowpart (QImode, operands[0]);")
8488
8489 (define_split
8490   [(set (match_operand 0 "ext_register_operand" "")
8491         (and (match_dup 0)
8492              (const_int -65281)))
8493    (clobber (reg:CC FLAGS_REG))]
8494   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8495    && reload_completed"
8496   [(parallel [(set (zero_extract:SI (match_dup 0)
8497                                     (const_int 8)
8498                                     (const_int 8))
8499                    (xor:SI
8500                      (zero_extract:SI (match_dup 0)
8501                                       (const_int 8)
8502                                       (const_int 8))
8503                      (zero_extract:SI (match_dup 0)
8504                                       (const_int 8)
8505                                       (const_int 8))))
8506               (clobber (reg:CC FLAGS_REG))])]
8507   "operands[0] = gen_lowpart (SImode, operands[0]);")
8508
8509 (define_insn "*anddi_2"
8510   [(set (reg FLAGS_REG)
8511         (compare
8512          (and:DI
8513           (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8514           (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8515          (const_int 0)))
8516    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8517         (and:DI (match_dup 1) (match_dup 2)))]
8518   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8519    && ix86_binary_operator_ok (AND, DImode, operands)"
8520   "@
8521    and{l}\t{%k2, %k0|%k0, %k2}
8522    and{q}\t{%2, %0|%0, %2}
8523    and{q}\t{%2, %0|%0, %2}"
8524   [(set_attr "type" "alu")
8525    (set_attr "mode" "SI,DI,DI")])
8526
8527 (define_insn "*andqi_2_maybe_si"
8528   [(set (reg FLAGS_REG)
8529         (compare (and:QI
8530                   (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8531                   (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8532                  (const_int 0)))
8533    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8534         (and:QI (match_dup 1) (match_dup 2)))]
8535   "ix86_binary_operator_ok (AND, QImode, operands)
8536    && ix86_match_ccmode (insn,
8537                          CONST_INT_P (operands[2])
8538                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8539 {
8540   if (which_alternative == 2)
8541     {
8542       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8543         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8544       return "and{l}\t{%2, %k0|%k0, %2}";
8545     }
8546   return "and{b}\t{%2, %0|%0, %2}";
8547 }
8548   [(set_attr "type" "alu")
8549    (set_attr "mode" "QI,QI,SI")])
8550
8551 (define_insn "*and<mode>_2"
8552   [(set (reg FLAGS_REG)
8553         (compare (and:SWI124
8554                   (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8555                   (match_operand:SWI124 2 "general_operand" "<g>,<r><i>"))
8556                  (const_int 0)))
8557    (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8558         (and:SWI124 (match_dup 1) (match_dup 2)))]
8559   "ix86_match_ccmode (insn, CCNOmode)
8560    && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8561   "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8562   [(set_attr "type" "alu")
8563    (set_attr "mode" "<MODE>")])
8564
8565 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8566 (define_insn "*andsi_2_zext"
8567   [(set (reg FLAGS_REG)
8568         (compare (and:SI
8569                   (match_operand:SI 1 "nonimmediate_operand" "%0")
8570                   (match_operand:SI 2 "general_operand" "g"))
8571                  (const_int 0)))
8572    (set (match_operand:DI 0 "register_operand" "=r")
8573         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8574   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8575    && ix86_binary_operator_ok (AND, SImode, operands)"
8576   "and{l}\t{%2, %k0|%k0, %2}"
8577   [(set_attr "type" "alu")
8578    (set_attr "mode" "SI")])
8579
8580 (define_insn "*andqi_2_slp"
8581   [(set (reg FLAGS_REG)
8582         (compare (and:QI
8583                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8584                    (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8585                  (const_int 0)))
8586    (set (strict_low_part (match_dup 0))
8587         (and:QI (match_dup 0) (match_dup 1)))]
8588   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8589    && ix86_match_ccmode (insn, CCNOmode)
8590    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8591   "and{b}\t{%1, %0|%0, %1}"
8592   [(set_attr "type" "alu1")
8593    (set_attr "mode" "QI")])
8594
8595 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8596 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8597 ;; for a QImode operand, which of course failed.
8598 (define_insn "andqi_ext_0"
8599   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8600                          (const_int 8)
8601                          (const_int 8))
8602         (and:SI
8603           (zero_extract:SI
8604             (match_operand 1 "ext_register_operand" "0")
8605             (const_int 8)
8606             (const_int 8))
8607           (match_operand 2 "const_int_operand" "n")))
8608    (clobber (reg:CC FLAGS_REG))]
8609   ""
8610   "and{b}\t{%2, %h0|%h0, %2}"
8611   [(set_attr "type" "alu")
8612    (set_attr "length_immediate" "1")
8613    (set_attr "modrm" "1")
8614    (set_attr "mode" "QI")])
8615
8616 ;; Generated by peephole translating test to and.  This shows up
8617 ;; often in fp comparisons.
8618 (define_insn "*andqi_ext_0_cc"
8619   [(set (reg FLAGS_REG)
8620         (compare
8621           (and:SI
8622             (zero_extract:SI
8623               (match_operand 1 "ext_register_operand" "0")
8624               (const_int 8)
8625               (const_int 8))
8626             (match_operand 2 "const_int_operand" "n"))
8627           (const_int 0)))
8628    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8629                          (const_int 8)
8630                          (const_int 8))
8631         (and:SI
8632           (zero_extract:SI
8633             (match_dup 1)
8634             (const_int 8)
8635             (const_int 8))
8636           (match_dup 2)))]
8637   "ix86_match_ccmode (insn, CCNOmode)"
8638   "and{b}\t{%2, %h0|%h0, %2}"
8639   [(set_attr "type" "alu")
8640    (set_attr "length_immediate" "1")
8641    (set_attr "modrm" "1")
8642    (set_attr "mode" "QI")])
8643
8644 (define_insn "*andqi_ext_1_rex64"
8645   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8646                          (const_int 8)
8647                          (const_int 8))
8648         (and:SI
8649           (zero_extract:SI
8650             (match_operand 1 "ext_register_operand" "0")
8651             (const_int 8)
8652             (const_int 8))
8653           (zero_extend:SI
8654             (match_operand 2 "ext_register_operand" "Q"))))
8655    (clobber (reg:CC FLAGS_REG))]
8656   "TARGET_64BIT"
8657   "and{b}\t{%2, %h0|%h0, %2}"
8658   [(set_attr "type" "alu")
8659    (set_attr "length_immediate" "0")
8660    (set_attr "mode" "QI")])
8661
8662 (define_insn "*andqi_ext_1"
8663   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8664                          (const_int 8)
8665                          (const_int 8))
8666         (and:SI
8667           (zero_extract:SI
8668             (match_operand 1 "ext_register_operand" "0")
8669             (const_int 8)
8670             (const_int 8))
8671           (zero_extend:SI
8672             (match_operand:QI 2 "general_operand" "Qm"))))
8673    (clobber (reg:CC FLAGS_REG))]
8674   "!TARGET_64BIT"
8675   "and{b}\t{%2, %h0|%h0, %2}"
8676   [(set_attr "type" "alu")
8677    (set_attr "length_immediate" "0")
8678    (set_attr "mode" "QI")])
8679
8680 (define_insn "*andqi_ext_2"
8681   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8682                          (const_int 8)
8683                          (const_int 8))
8684         (and:SI
8685           (zero_extract:SI
8686             (match_operand 1 "ext_register_operand" "%0")
8687             (const_int 8)
8688             (const_int 8))
8689           (zero_extract:SI
8690             (match_operand 2 "ext_register_operand" "Q")
8691             (const_int 8)
8692             (const_int 8))))
8693    (clobber (reg:CC FLAGS_REG))]
8694   ""
8695   "and{b}\t{%h2, %h0|%h0, %h2}"
8696   [(set_attr "type" "alu")
8697    (set_attr "length_immediate" "0")
8698    (set_attr "mode" "QI")])
8699
8700 ;; Convert wide AND instructions with immediate operand to shorter QImode
8701 ;; equivalents when possible.
8702 ;; Don't do the splitting with memory operands, since it introduces risk
8703 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8704 ;; for size, but that can (should?) be handled by generic code instead.
8705 (define_split
8706   [(set (match_operand 0 "register_operand" "")
8707         (and (match_operand 1 "register_operand" "")
8708              (match_operand 2 "const_int_operand" "")))
8709    (clobber (reg:CC FLAGS_REG))]
8710    "reload_completed
8711     && QI_REG_P (operands[0])
8712     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8713     && !(~INTVAL (operands[2]) & ~(255 << 8))
8714     && GET_MODE (operands[0]) != QImode"
8715   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8716                    (and:SI (zero_extract:SI (match_dup 1)
8717                                             (const_int 8) (const_int 8))
8718                            (match_dup 2)))
8719               (clobber (reg:CC FLAGS_REG))])]
8720   "operands[0] = gen_lowpart (SImode, operands[0]);
8721    operands[1] = gen_lowpart (SImode, operands[1]);
8722    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8723
8724 ;; Since AND can be encoded with sign extended immediate, this is only
8725 ;; profitable when 7th bit is not set.
8726 (define_split
8727   [(set (match_operand 0 "register_operand" "")
8728         (and (match_operand 1 "general_operand" "")
8729              (match_operand 2 "const_int_operand" "")))
8730    (clobber (reg:CC FLAGS_REG))]
8731    "reload_completed
8732     && ANY_QI_REG_P (operands[0])
8733     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8734     && !(~INTVAL (operands[2]) & ~255)
8735     && !(INTVAL (operands[2]) & 128)
8736     && GET_MODE (operands[0]) != QImode"
8737   [(parallel [(set (strict_low_part (match_dup 0))
8738                    (and:QI (match_dup 1)
8739                            (match_dup 2)))
8740               (clobber (reg:CC FLAGS_REG))])]
8741   "operands[0] = gen_lowpart (QImode, operands[0]);
8742    operands[1] = gen_lowpart (QImode, operands[1]);
8743    operands[2] = gen_lowpart (QImode, operands[2]);")
8744 \f
8745 ;; Logical inclusive and exclusive OR instructions
8746
8747 ;; %%% This used to optimize known byte-wide and operations to memory.
8748 ;; If this is considered useful, it should be done with splitters.
8749
8750 (define_expand "<code><mode>3"
8751   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8752         (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8753                      (match_operand:SWIM 2 "<general_operand>" "")))]
8754   ""
8755   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8756
8757 (define_insn "*<code><mode>_1"
8758   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8759         (any_or:SWI248
8760          (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8761          (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8762    (clobber (reg:CC FLAGS_REG))]
8763   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8764   "<logicprefix>{<imodesuffix>}\t{%2, %0|%0, %2}"
8765   [(set_attr "type" "alu")
8766    (set_attr "mode" "<MODE>")])
8767
8768 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8769 (define_insn "*<code>qi_1"
8770   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8771         (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8772                    (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8773    (clobber (reg:CC FLAGS_REG))]
8774   "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8775   "@
8776    <logicprefix>{b}\t{%2, %0|%0, %2}
8777    <logicprefix>{b}\t{%2, %0|%0, %2}
8778    <logicprefix>{l}\t{%k2, %k0|%k0, %k2}"
8779   [(set_attr "type" "alu")
8780    (set_attr "mode" "QI,QI,SI")])
8781
8782 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8783 (define_insn "*<code>si_1_zext"
8784   [(set (match_operand:DI 0 "register_operand" "=r")
8785         (zero_extend:DI
8786          (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8787                     (match_operand:SI 2 "general_operand" "g"))))
8788    (clobber (reg:CC FLAGS_REG))]
8789   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8790   "<logicprefix>{l}\t{%2, %k0|%k0, %2}"
8791   [(set_attr "type" "alu")
8792    (set_attr "mode" "SI")])
8793
8794 (define_insn "*<code>si_1_zext_imm"
8795   [(set (match_operand:DI 0 "register_operand" "=r")
8796         (any_or:DI
8797          (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8798          (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8799    (clobber (reg:CC FLAGS_REG))]
8800   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8801   "<logicprefix>{l}\t{%2, %k0|%k0, %2}"
8802   [(set_attr "type" "alu")
8803    (set_attr "mode" "SI")])
8804
8805 (define_insn "*<code>qi_1_slp"
8806   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8807         (any_or:QI (match_dup 0)
8808                    (match_operand:QI 1 "general_operand" "qmn,qn")))
8809    (clobber (reg:CC FLAGS_REG))]
8810   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8811    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8812   "<logicprefix>{b}\t{%1, %0|%0, %1}"
8813   [(set_attr "type" "alu1")
8814    (set_attr "mode" "QI")])
8815
8816 (define_insn "*<code><mode>_2"
8817   [(set (reg FLAGS_REG)
8818         (compare (any_or:SWI
8819                   (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8820                   (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8821                  (const_int 0)))
8822    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8823         (any_or:SWI (match_dup 1) (match_dup 2)))]
8824   "ix86_match_ccmode (insn, CCNOmode)
8825    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8826   "<logicprefix>{<imodesuffix>}\t{%2, %0|%0, %2}"
8827   [(set_attr "type" "alu")
8828    (set_attr "mode" "<MODE>")])
8829
8830 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8831 ;; ??? Special case for immediate operand is missing - it is tricky.
8832 (define_insn "*<code>si_2_zext"
8833   [(set (reg FLAGS_REG)
8834         (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8835                             (match_operand:SI 2 "general_operand" "g"))
8836                  (const_int 0)))
8837    (set (match_operand:DI 0 "register_operand" "=r")
8838         (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8839   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8840    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8841   "<logicprefix>{l}\t{%2, %k0|%k0, %2}"
8842   [(set_attr "type" "alu")
8843    (set_attr "mode" "SI")])
8844
8845 (define_insn "*<code>si_2_zext_imm"
8846   [(set (reg FLAGS_REG)
8847         (compare (any_or:SI
8848                   (match_operand:SI 1 "nonimmediate_operand" "%0")
8849                   (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8850                  (const_int 0)))
8851    (set (match_operand:DI 0 "register_operand" "=r")
8852         (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8853   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8854    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8855   "<logicprefix>{l}\t{%2, %k0|%k0, %2}"
8856   [(set_attr "type" "alu")
8857    (set_attr "mode" "SI")])
8858
8859 (define_insn "*<code>qi_2_slp"
8860   [(set (reg FLAGS_REG)
8861         (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8862                             (match_operand:QI 1 "general_operand" "qmn,qn"))
8863                  (const_int 0)))
8864    (set (strict_low_part (match_dup 0))
8865         (any_or:QI (match_dup 0) (match_dup 1)))]
8866   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8867    && ix86_match_ccmode (insn, CCNOmode)
8868    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8869   "<logicprefix>{b}\t{%1, %0|%0, %1}"
8870   [(set_attr "type" "alu1")
8871    (set_attr "mode" "QI")])
8872
8873 (define_insn "*<code><mode>_3"
8874   [(set (reg FLAGS_REG)
8875         (compare (any_or:SWI
8876                   (match_operand:SWI 1 "nonimmediate_operand" "%0")
8877                   (match_operand:SWI 2 "<general_operand>" "<g>"))
8878                  (const_int 0)))
8879    (clobber (match_scratch:SWI 0 "=<r>"))]
8880   "ix86_match_ccmode (insn, CCNOmode)
8881    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8882   "<logicprefix>{<imodesuffix>}\t{%2, %0|%0, %2}"
8883   [(set_attr "type" "alu")
8884    (set_attr "mode" "<MODE>")])
8885
8886 (define_insn "*<code>qi_ext_0"
8887   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8888                          (const_int 8)
8889                          (const_int 8))
8890         (any_or:SI
8891           (zero_extract:SI
8892             (match_operand 1 "ext_register_operand" "0")
8893             (const_int 8)
8894             (const_int 8))
8895           (match_operand 2 "const_int_operand" "n")))
8896    (clobber (reg:CC FLAGS_REG))]
8897   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8898   "<logicprefix>{b}\t{%2, %h0|%h0, %2}"
8899   [(set_attr "type" "alu")
8900    (set_attr "length_immediate" "1")
8901    (set_attr "modrm" "1")
8902    (set_attr "mode" "QI")])
8903
8904 (define_insn "*<code>qi_ext_1_rex64"
8905   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8906                          (const_int 8)
8907                          (const_int 8))
8908         (any_or:SI
8909           (zero_extract:SI
8910             (match_operand 1 "ext_register_operand" "0")
8911             (const_int 8)
8912             (const_int 8))
8913           (zero_extend:SI
8914             (match_operand 2 "ext_register_operand" "Q"))))
8915    (clobber (reg:CC FLAGS_REG))]
8916   "TARGET_64BIT
8917    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8918   "<logicprefix>{b}\t{%2, %h0|%h0, %2}"
8919   [(set_attr "type" "alu")
8920    (set_attr "length_immediate" "0")
8921    (set_attr "mode" "QI")])
8922
8923 (define_insn "*<code>qi_ext_1"
8924   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8925                          (const_int 8)
8926                          (const_int 8))
8927         (any_or:SI
8928           (zero_extract:SI
8929             (match_operand 1 "ext_register_operand" "0")
8930             (const_int 8)
8931             (const_int 8))
8932           (zero_extend:SI
8933             (match_operand:QI 2 "general_operand" "Qm"))))
8934    (clobber (reg:CC FLAGS_REG))]
8935   "!TARGET_64BIT
8936    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8937   "<logicprefix>{b}\t{%2, %h0|%h0, %2}"
8938   [(set_attr "type" "alu")
8939    (set_attr "length_immediate" "0")
8940    (set_attr "mode" "QI")])
8941
8942 (define_insn "*<code>qi_ext_2"
8943   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8944                          (const_int 8)
8945                          (const_int 8))
8946         (any_or:SI
8947           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8948                            (const_int 8)
8949                            (const_int 8))
8950           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8951                            (const_int 8)
8952                            (const_int 8))))
8953    (clobber (reg:CC FLAGS_REG))]
8954   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8955   "<logicprefix>{b}\t{%h2, %h0|%h0, %h2}"
8956   [(set_attr "type" "alu")
8957    (set_attr "length_immediate" "0")
8958    (set_attr "mode" "QI")])
8959
8960 (define_split
8961   [(set (match_operand 0 "register_operand" "")
8962         (any_or (match_operand 1 "register_operand" "")
8963                 (match_operand 2 "const_int_operand" "")))
8964    (clobber (reg:CC FLAGS_REG))]
8965    "reload_completed
8966     && QI_REG_P (operands[0])
8967     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8968     && !(INTVAL (operands[2]) & ~(255 << 8))
8969     && GET_MODE (operands[0]) != QImode"
8970   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8971                    (any_or:SI (zero_extract:SI (match_dup 1)
8972                                                (const_int 8) (const_int 8))
8973                               (match_dup 2)))
8974               (clobber (reg:CC FLAGS_REG))])]
8975   "operands[0] = gen_lowpart (SImode, operands[0]);
8976    operands[1] = gen_lowpart (SImode, operands[1]);
8977    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8978
8979 ;; Since OR can be encoded with sign extended immediate, this is only
8980 ;; profitable when 7th bit is set.
8981 (define_split
8982   [(set (match_operand 0 "register_operand" "")
8983         (any_or (match_operand 1 "general_operand" "")
8984                 (match_operand 2 "const_int_operand" "")))
8985    (clobber (reg:CC FLAGS_REG))]
8986    "reload_completed
8987     && ANY_QI_REG_P (operands[0])
8988     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8989     && !(INTVAL (operands[2]) & ~255)
8990     && (INTVAL (operands[2]) & 128)
8991     && GET_MODE (operands[0]) != QImode"
8992   [(parallel [(set (strict_low_part (match_dup 0))
8993                    (any_or:QI (match_dup 1)
8994                               (match_dup 2)))
8995               (clobber (reg:CC FLAGS_REG))])]
8996   "operands[0] = gen_lowpart (QImode, operands[0]);
8997    operands[1] = gen_lowpart (QImode, operands[1]);
8998    operands[2] = gen_lowpart (QImode, operands[2]);")
8999
9000 (define_expand "xorqi_cc_ext_1"
9001   [(parallel [
9002      (set (reg:CCNO FLAGS_REG)
9003           (compare:CCNO
9004             (xor:SI
9005               (zero_extract:SI
9006                 (match_operand 1 "ext_register_operand" "")
9007                 (const_int 8)
9008                 (const_int 8))
9009               (match_operand:QI 2 "general_operand" ""))
9010             (const_int 0)))
9011      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9012                            (const_int 8)
9013                            (const_int 8))
9014           (xor:SI
9015             (zero_extract:SI
9016              (match_dup 1)
9017              (const_int 8)
9018              (const_int 8))
9019             (match_dup 2)))])]
9020   ""
9021   "")
9022
9023 (define_insn "*xorqi_cc_ext_1_rex64"
9024   [(set (reg FLAGS_REG)
9025         (compare
9026           (xor:SI
9027             (zero_extract:SI
9028               (match_operand 1 "ext_register_operand" "0")
9029               (const_int 8)
9030               (const_int 8))
9031             (match_operand:QI 2 "nonmemory_operand" "Qn"))
9032           (const_int 0)))
9033    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9034                          (const_int 8)
9035                          (const_int 8))
9036         (xor:SI
9037           (zero_extract:SI
9038            (match_dup 1)
9039            (const_int 8)
9040            (const_int 8))
9041           (match_dup 2)))]
9042   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9043   "xor{b}\t{%2, %h0|%h0, %2}"
9044   [(set_attr "type" "alu")
9045    (set_attr "modrm" "1")
9046    (set_attr "mode" "QI")])
9047
9048 (define_insn "*xorqi_cc_ext_1"
9049   [(set (reg FLAGS_REG)
9050         (compare
9051           (xor:SI
9052             (zero_extract:SI
9053               (match_operand 1 "ext_register_operand" "0")
9054               (const_int 8)
9055               (const_int 8))
9056             (match_operand:QI 2 "general_operand" "qmn"))
9057           (const_int 0)))
9058    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9059                          (const_int 8)
9060                          (const_int 8))
9061         (xor:SI
9062           (zero_extract:SI
9063            (match_dup 1)
9064            (const_int 8)
9065            (const_int 8))
9066           (match_dup 2)))]
9067   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9068   "xor{b}\t{%2, %h0|%h0, %2}"
9069   [(set_attr "type" "alu")
9070    (set_attr "modrm" "1")
9071    (set_attr "mode" "QI")])
9072 \f
9073 ;; Negation instructions
9074
9075 (define_expand "neg<mode>2"
9076   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
9077         (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
9078   ""
9079   "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
9080
9081 (define_insn_and_split "*neg<dwi>2_doubleword"
9082   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
9083         (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
9084    (clobber (reg:CC FLAGS_REG))]
9085   "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
9086   "#"
9087   "reload_completed"
9088   [(parallel
9089     [(set (reg:CCZ FLAGS_REG)
9090           (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
9091      (set (match_dup 0) (neg:DWIH (match_dup 1)))])
9092    (parallel
9093     [(set (match_dup 2)
9094           (plus:DWIH (match_dup 3)
9095                      (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
9096                                 (const_int 0))))
9097      (clobber (reg:CC FLAGS_REG))])
9098    (parallel
9099     [(set (match_dup 2)
9100           (neg:DWIH (match_dup 2)))
9101      (clobber (reg:CC FLAGS_REG))])]
9102   "split_<dwi> (&operands[0], 2, &operands[0], &operands[2]);")
9103
9104 (define_insn "*neg<mode>2_1"
9105   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9106         (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
9107    (clobber (reg:CC FLAGS_REG))]
9108   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9109   "neg{<imodesuffix>}\t%0"
9110   [(set_attr "type" "negnot")
9111    (set_attr "mode" "<MODE>")])
9112
9113 ;; Combine is quite creative about this pattern.
9114 (define_insn "*negsi2_1_zext"
9115   [(set (match_operand:DI 0 "register_operand" "=r")
9116         (lshiftrt:DI
9117           (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9118                              (const_int 32)))
9119         (const_int 32)))
9120    (clobber (reg:CC FLAGS_REG))]
9121   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9122   "neg{l}\t%k0"
9123   [(set_attr "type" "negnot")
9124    (set_attr "mode" "SI")])
9125
9126 ;; The problem with neg is that it does not perform (compare x 0),
9127 ;; it really performs (compare 0 x), which leaves us with the zero
9128 ;; flag being the only useful item.
9129
9130 (define_insn "*neg<mode>2_cmpz"
9131   [(set (reg:CCZ FLAGS_REG)
9132         (compare:CCZ
9133           (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9134                    (const_int 0)))
9135    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9136         (neg:SWI (match_dup 1)))]
9137   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9138   "neg{<imodesuffix>}\t%0"
9139   [(set_attr "type" "negnot")
9140    (set_attr "mode" "<MODE>")])
9141
9142 (define_insn "*negsi2_cmpz_zext"
9143   [(set (reg:CCZ FLAGS_REG)
9144         (compare:CCZ
9145           (lshiftrt:DI
9146             (neg:DI (ashift:DI
9147                       (match_operand:DI 1 "register_operand" "0")
9148                       (const_int 32)))
9149             (const_int 32))
9150           (const_int 0)))
9151    (set (match_operand:DI 0 "register_operand" "=r")
9152         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9153                                         (const_int 32)))
9154                      (const_int 32)))]
9155   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9156   "neg{l}\t%k0"
9157   [(set_attr "type" "negnot")
9158    (set_attr "mode" "SI")])
9159
9160 ;; Changing of sign for FP values is doable using integer unit too.
9161
9162 (define_expand "<code><mode>2"
9163   [(set (match_operand:X87MODEF 0 "register_operand" "")
9164         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
9165   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9166   "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
9167
9168 (define_insn "*absneg<mode>2_mixed"
9169   [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
9170         (match_operator:MODEF 3 "absneg_operator"
9171           [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
9172    (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
9173    (clobber (reg:CC FLAGS_REG))]
9174   "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
9175   "#")
9176
9177 (define_insn "*absneg<mode>2_sse"
9178   [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
9179         (match_operator:MODEF 3 "absneg_operator"
9180           [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
9181    (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
9182    (clobber (reg:CC FLAGS_REG))]
9183   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
9184   "#")
9185
9186 (define_insn "*absneg<mode>2_i387"
9187   [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
9188         (match_operator:X87MODEF 3 "absneg_operator"
9189           [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
9190    (use (match_operand 2 "" ""))
9191    (clobber (reg:CC FLAGS_REG))]
9192   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9193   "#")
9194
9195 (define_expand "<code>tf2"
9196   [(set (match_operand:TF 0 "register_operand" "")
9197         (absneg:TF (match_operand:TF 1 "register_operand" "")))]
9198   "TARGET_SSE2"
9199   "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
9200
9201 (define_insn "*absnegtf2_sse"
9202   [(set (match_operand:TF 0 "register_operand" "=x,x")
9203         (match_operator:TF 3 "absneg_operator"
9204           [(match_operand:TF 1 "register_operand" "0,x")]))
9205    (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
9206    (clobber (reg:CC FLAGS_REG))]
9207   "TARGET_SSE2"
9208   "#")
9209
9210 ;; Splitters for fp abs and neg.
9211
9212 (define_split
9213   [(set (match_operand 0 "fp_register_operand" "")
9214         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9215    (use (match_operand 2 "" ""))
9216    (clobber (reg:CC FLAGS_REG))]
9217   "reload_completed"
9218   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9219
9220 (define_split
9221   [(set (match_operand 0 "register_operand" "")
9222         (match_operator 3 "absneg_operator"
9223           [(match_operand 1 "register_operand" "")]))
9224    (use (match_operand 2 "nonimmediate_operand" ""))
9225    (clobber (reg:CC FLAGS_REG))]
9226   "reload_completed && SSE_REG_P (operands[0])"
9227   [(set (match_dup 0) (match_dup 3))]
9228 {
9229   enum machine_mode mode = GET_MODE (operands[0]);
9230   enum machine_mode vmode = GET_MODE (operands[2]);
9231   rtx tmp;
9232
9233   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9234   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9235   if (operands_match_p (operands[0], operands[2]))
9236     {
9237       tmp = operands[1];
9238       operands[1] = operands[2];
9239       operands[2] = tmp;
9240     }
9241   if (GET_CODE (operands[3]) == ABS)
9242     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9243   else
9244     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9245   operands[3] = tmp;
9246 })
9247
9248 (define_split
9249   [(set (match_operand:SF 0 "register_operand" "")
9250         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9251    (use (match_operand:V4SF 2 "" ""))
9252    (clobber (reg:CC FLAGS_REG))]
9253   "reload_completed"
9254   [(parallel [(set (match_dup 0) (match_dup 1))
9255               (clobber (reg:CC FLAGS_REG))])]
9256 {
9257   rtx tmp;
9258   operands[0] = gen_lowpart (SImode, operands[0]);
9259   if (GET_CODE (operands[1]) == ABS)
9260     {
9261       tmp = gen_int_mode (0x7fffffff, SImode);
9262       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9263     }
9264   else
9265     {
9266       tmp = gen_int_mode (0x80000000, SImode);
9267       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9268     }
9269   operands[1] = tmp;
9270 })
9271
9272 (define_split
9273   [(set (match_operand:DF 0 "register_operand" "")
9274         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9275    (use (match_operand 2 "" ""))
9276    (clobber (reg:CC FLAGS_REG))]
9277   "reload_completed"
9278   [(parallel [(set (match_dup 0) (match_dup 1))
9279               (clobber (reg:CC FLAGS_REG))])]
9280 {
9281   rtx tmp;
9282   if (TARGET_64BIT)
9283     {
9284       tmp = gen_lowpart (DImode, operands[0]);
9285       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9286       operands[0] = tmp;
9287
9288       if (GET_CODE (operands[1]) == ABS)
9289         tmp = const0_rtx;
9290       else
9291         tmp = gen_rtx_NOT (DImode, tmp);
9292     }
9293   else
9294     {
9295       operands[0] = gen_highpart (SImode, operands[0]);
9296       if (GET_CODE (operands[1]) == ABS)
9297         {
9298           tmp = gen_int_mode (0x7fffffff, SImode);
9299           tmp = gen_rtx_AND (SImode, operands[0], tmp);
9300         }
9301       else
9302         {
9303           tmp = gen_int_mode (0x80000000, SImode);
9304           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9305         }
9306     }
9307   operands[1] = tmp;
9308 })
9309
9310 (define_split
9311   [(set (match_operand:XF 0 "register_operand" "")
9312         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9313    (use (match_operand 2 "" ""))
9314    (clobber (reg:CC FLAGS_REG))]
9315   "reload_completed"
9316   [(parallel [(set (match_dup 0) (match_dup 1))
9317               (clobber (reg:CC FLAGS_REG))])]
9318 {
9319   rtx tmp;
9320   operands[0] = gen_rtx_REG (SImode,
9321                              true_regnum (operands[0])
9322                              + (TARGET_64BIT ? 1 : 2));
9323   if (GET_CODE (operands[1]) == ABS)
9324     {
9325       tmp = GEN_INT (0x7fff);
9326       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9327     }
9328   else
9329     {
9330       tmp = GEN_INT (0x8000);
9331       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9332     }
9333   operands[1] = tmp;
9334 })
9335
9336 ;; Conditionalize these after reload. If they match before reload, we
9337 ;; lose the clobber and ability to use integer instructions.
9338
9339 (define_insn "*<code><mode>2_1"
9340   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
9341         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
9342   "TARGET_80387
9343    && (reload_completed
9344        || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
9345   "f<absnegprefix>"
9346   [(set_attr "type" "fsgn")
9347    (set_attr "mode" "<MODE>")])
9348
9349 (define_insn "*<code>extendsfdf2"
9350   [(set (match_operand:DF 0 "register_operand" "=f")
9351         (absneg:DF (float_extend:DF
9352                      (match_operand:SF 1 "register_operand" "0"))))]
9353   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9354   "f<absnegprefix>"
9355   [(set_attr "type" "fsgn")
9356    (set_attr "mode" "DF")])
9357
9358 (define_insn "*<code>extendsfxf2"
9359   [(set (match_operand:XF 0 "register_operand" "=f")
9360         (absneg:XF (float_extend:XF
9361                      (match_operand:SF 1 "register_operand" "0"))))]
9362   "TARGET_80387"
9363   "f<absnegprefix>"
9364   [(set_attr "type" "fsgn")
9365    (set_attr "mode" "XF")])
9366
9367 (define_insn "*<code>extenddfxf2"
9368   [(set (match_operand:XF 0 "register_operand" "=f")
9369         (absneg:XF (float_extend:XF
9370                       (match_operand:DF 1 "register_operand" "0"))))]
9371   "TARGET_80387"
9372   "f<absnegprefix>"
9373   [(set_attr "type" "fsgn")
9374    (set_attr "mode" "XF")])
9375
9376 ;; Copysign instructions
9377
9378 (define_mode_iterator CSGNMODE [SF DF TF])
9379 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
9380
9381 (define_expand "copysign<mode>3"
9382   [(match_operand:CSGNMODE 0 "register_operand" "")
9383    (match_operand:CSGNMODE 1 "nonmemory_operand" "")
9384    (match_operand:CSGNMODE 2 "register_operand" "")]
9385   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9386    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
9387 {
9388   ix86_expand_copysign (operands);
9389   DONE;
9390 })
9391
9392 (define_insn_and_split "copysign<mode>3_const"
9393   [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
9394         (unspec:CSGNMODE
9395           [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
9396            (match_operand:CSGNMODE 2 "register_operand" "0")
9397            (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
9398           UNSPEC_COPYSIGN))]
9399   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9400    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
9401   "#"
9402   "&& reload_completed"
9403   [(const_int 0)]
9404 {
9405   ix86_split_copysign_const (operands);
9406   DONE;
9407 })
9408
9409 (define_insn "copysign<mode>3_var"
9410   [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
9411         (unspec:CSGNMODE
9412           [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
9413            (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
9414            (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
9415            (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
9416           UNSPEC_COPYSIGN))
9417    (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
9418   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9419    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
9420   "#")
9421
9422 (define_split
9423   [(set (match_operand:CSGNMODE 0 "register_operand" "")
9424         (unspec:CSGNMODE
9425           [(match_operand:CSGNMODE 2 "register_operand" "")
9426            (match_operand:CSGNMODE 3 "register_operand" "")
9427            (match_operand:<CSGNVMODE> 4 "" "")
9428            (match_operand:<CSGNVMODE> 5 "" "")]
9429           UNSPEC_COPYSIGN))
9430    (clobber (match_scratch:<CSGNVMODE> 1 ""))]
9431   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9432     || (TARGET_SSE2 && (<MODE>mode == TFmode)))
9433    && reload_completed"
9434   [(const_int 0)]
9435 {
9436   ix86_split_copysign_var (operands);
9437   DONE;
9438 })
9439 \f
9440 ;; One complement instructions
9441
9442 (define_expand "one_cmpl<mode>2"
9443   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
9444         (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
9445   ""
9446   "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
9447
9448 (define_insn "*one_cmpl<mode>2_1"
9449   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
9450         (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
9451   "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9452   "not{<imodesuffix>}\t%0"
9453   [(set_attr "type" "negnot")
9454    (set_attr "mode" "<MODE>")])
9455
9456 ;; %%% Potential partial reg stall on alternative 1.  What to do?
9457 (define_insn "*one_cmplqi2_1"
9458   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9459         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
9460   "ix86_unary_operator_ok (NOT, QImode, operands)"
9461   "@
9462    not{b}\t%0
9463    not{l}\t%k0"
9464   [(set_attr "type" "negnot")
9465    (set_attr "mode" "QI,SI")])
9466
9467 ;; ??? Currently never generated - xor is used instead.
9468 (define_insn "*one_cmplsi2_1_zext"
9469   [(set (match_operand:DI 0 "register_operand" "=r")
9470         (zero_extend:DI
9471           (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9472   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9473   "not{l}\t%k0"
9474   [(set_attr "type" "negnot")
9475    (set_attr "mode" "SI")])
9476
9477 (define_insn "*one_cmpl<mode>2_2"
9478   [(set (reg FLAGS_REG)
9479         (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9480                  (const_int 0)))
9481    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9482         (not:SWI (match_dup 1)))]
9483   "ix86_match_ccmode (insn, CCNOmode)
9484    && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9485   "#"
9486   [(set_attr "type" "alu1")
9487    (set_attr "mode" "<MODE>")])
9488
9489 (define_split
9490   [(set (match_operand 0 "flags_reg_operand" "")
9491         (match_operator 2 "compare_operator"
9492           [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
9493            (const_int 0)]))
9494    (set (match_operand:SWI 1 "nonimmediate_operand" "")
9495         (not:SWI (match_dup 3)))]
9496   "ix86_match_ccmode (insn, CCNOmode)"
9497   [(parallel [(set (match_dup 0)
9498                    (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9499                                     (const_int 0)]))
9500               (set (match_dup 1)
9501                    (xor:SWI (match_dup 3) (const_int -1)))])]
9502   "")
9503
9504 ;; ??? Currently never generated - xor is used instead.
9505 (define_insn "*one_cmplsi2_2_zext"
9506   [(set (reg FLAGS_REG)
9507         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9508                  (const_int 0)))
9509    (set (match_operand:DI 0 "register_operand" "=r")
9510         (zero_extend:DI (not:SI (match_dup 1))))]
9511   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9512    && ix86_unary_operator_ok (NOT, SImode, operands)"
9513   "#"
9514   [(set_attr "type" "alu1")
9515    (set_attr "mode" "SI")])
9516
9517 (define_split
9518   [(set (match_operand 0 "flags_reg_operand" "")
9519         (match_operator 2 "compare_operator"
9520           [(not:SI (match_operand:SI 3 "register_operand" ""))
9521            (const_int 0)]))
9522    (set (match_operand:DI 1 "register_operand" "")
9523         (zero_extend:DI (not:SI (match_dup 3))))]
9524   "ix86_match_ccmode (insn, CCNOmode)"
9525   [(parallel [(set (match_dup 0)
9526                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9527                                     (const_int 0)]))
9528               (set (match_dup 1)
9529                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
9530   "")
9531 \f
9532 ;; Arithmetic shift instructions
9533
9534 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9535 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
9536 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9537 ;; from the assembler input.
9538 ;;
9539 ;; This instruction shifts the target reg/mem as usual, but instead of
9540 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
9541 ;; is a left shift double, bits are taken from the high order bits of
9542 ;; reg, else if the insn is a shift right double, bits are taken from the
9543 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
9544 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9545 ;;
9546 ;; Since sh[lr]d does not change the `reg' operand, that is done
9547 ;; separately, making all shifts emit pairs of shift double and normal
9548 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
9549 ;; support a 63 bit shift, each shift where the count is in a reg expands
9550 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9551 ;;
9552 ;; If the shift count is a constant, we need never emit more than one
9553 ;; shift pair, instead using moves and sign extension for counts greater
9554 ;; than 31.
9555
9556 (define_expand "ashl<mode>3"
9557   [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9558         (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
9559                       (match_operand:QI 2 "nonmemory_operand" "")))]
9560   ""
9561   "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9562
9563 (define_insn "*ashl<mode>3_doubleword"
9564   [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9565         (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9566                     (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9567    (clobber (reg:CC FLAGS_REG))]
9568   ""
9569   "#"
9570   [(set_attr "type" "multi")])
9571
9572 (define_split
9573   [(set (match_operand:DWI 0 "register_operand" "")
9574         (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
9575                     (match_operand:QI 2 "nonmemory_operand" "")))
9576    (clobber (reg:CC FLAGS_REG))]
9577   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9578   [(const_int 0)]
9579   "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9580
9581 ;; By default we don't ask for a scratch register, because when DWImode
9582 ;; values are manipulated, registers are already at a premium.  But if
9583 ;; we have one handy, we won't turn it away.
9584
9585 (define_peephole2
9586   [(match_scratch:DWIH 3 "r")
9587    (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9588                    (ashift:<DWI>
9589                      (match_operand:<DWI> 1 "nonmemory_operand" "")
9590                      (match_operand:QI 2 "nonmemory_operand" "")))
9591               (clobber (reg:CC FLAGS_REG))])
9592    (match_dup 3)]
9593   "TARGET_CMOVE"
9594   [(const_int 0)]
9595   "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9596
9597 (define_insn "x86_64_shld"
9598   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9599         (ior:DI (ashift:DI (match_dup 0)
9600                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
9601                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9602                   (minus:QI (const_int 64) (match_dup 2)))))
9603    (clobber (reg:CC FLAGS_REG))]
9604   "TARGET_64BIT"
9605   "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9606   [(set_attr "type" "ishift")
9607    (set_attr "prefix_0f" "1")
9608    (set_attr "mode" "DI")
9609    (set_attr "athlon_decode" "vector")
9610    (set_attr "amdfam10_decode" "vector")])
9611
9612 (define_insn "x86_shld"
9613   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9614         (ior:SI (ashift:SI (match_dup 0)
9615                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
9616                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9617                   (minus:QI (const_int 32) (match_dup 2)))))
9618    (clobber (reg:CC FLAGS_REG))]
9619   ""
9620   "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9621   [(set_attr "type" "ishift")
9622    (set_attr "prefix_0f" "1")
9623    (set_attr "mode" "SI")
9624    (set_attr "pent_pair" "np")
9625    (set_attr "athlon_decode" "vector")
9626    (set_attr "amdfam10_decode" "vector")])
9627
9628 (define_expand "x86_shift<mode>_adj_1"
9629   [(set (reg:CCZ FLAGS_REG)
9630         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
9631                              (match_dup 4))
9632                      (const_int 0)))
9633    (set (match_operand:SWI48 0 "register_operand" "")
9634         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9635                             (match_operand:SWI48 1 "register_operand" "")
9636                             (match_dup 0)))
9637    (set (match_dup 1)
9638         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9639                             (match_operand:SWI48 3 "register_operand" "r")
9640                             (match_dup 1)))]
9641   "TARGET_CMOVE"
9642   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9643
9644 (define_expand "x86_shift<mode>_adj_2"
9645   [(use (match_operand:SWI48 0 "register_operand" ""))
9646    (use (match_operand:SWI48 1 "register_operand" ""))
9647    (use (match_operand:QI 2 "register_operand" ""))]
9648   ""
9649 {
9650   rtx label = gen_label_rtx ();
9651   rtx tmp;
9652
9653   emit_insn (gen_testqi_ccz_1 (operands[2],
9654                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9655
9656   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9657   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9658   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9659                               gen_rtx_LABEL_REF (VOIDmode, label),
9660                               pc_rtx);
9661   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9662   JUMP_LABEL (tmp) = label;
9663
9664   emit_move_insn (operands[0], operands[1]);
9665   ix86_expand_clear (operands[1]);
9666
9667   emit_label (label);
9668   LABEL_NUSES (label) = 1;
9669
9670   DONE;
9671 })
9672
9673 (define_insn "*ashl<mode>3_1"
9674   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9675         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l")
9676                       (match_operand:QI 2 "nonmemory_operand" "c<S>,M")))
9677    (clobber (reg:CC FLAGS_REG))]
9678   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9679 {
9680   switch (get_attr_type (insn))
9681     {
9682     case TYPE_ALU:
9683       gcc_assert (operands[2] == const1_rtx);
9684       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9685       return "add{<imodesuffix>}\t%0, %0";
9686
9687     case TYPE_LEA:
9688       return "#";
9689
9690     default:
9691       if (REG_P (operands[2]))
9692         return "sal{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9693       else if (operands[2] == const1_rtx
9694                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9695         return "sal{<imodesuffix>}\t%0";
9696       else
9697         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9698     }
9699 }
9700   [(set (attr "type")
9701      (cond [(eq_attr "alternative" "1")
9702               (const_string "lea")
9703             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9704                           (const_int 0))
9705                       (match_operand 0 "register_operand" ""))
9706                  (match_operand 2 "const1_operand" ""))
9707               (const_string "alu")
9708            ]
9709            (const_string "ishift")))
9710    (set (attr "length_immediate")
9711      (if_then_else
9712        (ior (eq_attr "type" "alu")
9713             (and (eq_attr "type" "ishift")
9714                  (and (match_operand 2 "const1_operand" "")
9715                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9716                           (const_int 0)))))
9717        (const_string "0")
9718        (const_string "*")))
9719    (set_attr "mode" "<MODE>")])
9720
9721 (define_insn "*ashlsi3_1_zext"
9722   [(set (match_operand:DI 0 "register_operand" "=r,r")
9723         (zero_extend:DI
9724           (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
9725                      (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
9726    (clobber (reg:CC FLAGS_REG))]
9727   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9728 {
9729   switch (get_attr_type (insn))
9730     {
9731     case TYPE_ALU:
9732       gcc_assert (operands[2] == const1_rtx);
9733       return "add{l}\t%k0, %k0";
9734
9735     case TYPE_LEA:
9736       return "#";
9737
9738     default:
9739       if (REG_P (operands[2]))
9740         return "sal{l}\t{%b2, %k0|%k0, %b2}";
9741       else if (operands[2] == const1_rtx
9742                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9743         return "sal{l}\t%k0";
9744       else
9745         return "sal{l}\t{%2, %k0|%k0, %2}";
9746     }
9747 }
9748   [(set (attr "type")
9749      (cond [(eq_attr "alternative" "1")
9750               (const_string "lea")
9751             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9752                      (const_int 0))
9753                  (match_operand 2 "const1_operand" ""))
9754               (const_string "alu")
9755            ]
9756            (const_string "ishift")))
9757    (set (attr "length_immediate")
9758      (if_then_else
9759        (ior (eq_attr "type" "alu")
9760             (and (eq_attr "type" "ishift")
9761                  (and (match_operand 2 "const1_operand" "")
9762                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9763                           (const_int 0)))))
9764        (const_string "0")
9765        (const_string "*")))
9766    (set_attr "mode" "SI")])
9767
9768 (define_insn "*ashlhi3_1"
9769   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9770         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
9771                    (match_operand:QI 2 "nonmemory_operand" "cI")))
9772    (clobber (reg:CC FLAGS_REG))]
9773   "TARGET_PARTIAL_REG_STALL
9774    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9775 {
9776   switch (get_attr_type (insn))
9777     {
9778     case TYPE_ALU:
9779       gcc_assert (operands[2] == const1_rtx);
9780       return "add{w}\t%0, %0";
9781
9782     default:
9783       if (REG_P (operands[2]))
9784         return "sal{w}\t{%b2, %0|%0, %b2}";
9785       else if (operands[2] == const1_rtx
9786                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9787         return "sal{w}\t%0";
9788       else
9789         return "sal{w}\t{%2, %0|%0, %2}";
9790     }
9791 }
9792   [(set (attr "type")
9793      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9794                           (const_int 0))
9795                       (match_operand 0 "register_operand" ""))
9796                  (match_operand 2 "const1_operand" ""))
9797               (const_string "alu")
9798            ]
9799            (const_string "ishift")))
9800    (set (attr "length_immediate")
9801      (if_then_else
9802        (ior (eq_attr "type" "alu")
9803             (and (eq_attr "type" "ishift")
9804                  (and (match_operand 2 "const1_operand" "")
9805                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9806                           (const_int 0)))))
9807        (const_string "0")
9808        (const_string "*")))
9809    (set_attr "mode" "HI")])
9810
9811 (define_insn "*ashlhi3_1_lea"
9812   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
9813         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9814                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9815    (clobber (reg:CC FLAGS_REG))]
9816   "!TARGET_PARTIAL_REG_STALL
9817    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9818 {
9819   switch (get_attr_type (insn))
9820     {
9821     case TYPE_LEA:
9822       return "#";
9823     case TYPE_ALU:
9824       gcc_assert (operands[2] == const1_rtx);
9825       return "add{w}\t%0, %0";
9826
9827     default:
9828       if (REG_P (operands[2]))
9829         return "sal{w}\t{%b2, %0|%0, %b2}";
9830       else if (operands[2] == const1_rtx
9831                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9832         return "sal{w}\t%0";
9833       else
9834         return "sal{w}\t{%2, %0|%0, %2}";
9835     }
9836 }
9837   [(set (attr "type")
9838      (cond [(eq_attr "alternative" "1")
9839               (const_string "lea")
9840             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9841                           (const_int 0))
9842                       (match_operand 0 "register_operand" ""))
9843                  (match_operand 2 "const1_operand" ""))
9844               (const_string "alu")
9845            ]
9846            (const_string "ishift")))
9847    (set (attr "length_immediate")
9848      (if_then_else
9849        (ior (eq_attr "type" "alu")
9850             (and (eq_attr "type" "ishift")
9851                  (and (match_operand 2 "const1_operand" "")
9852                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9853                           (const_int 0)))))
9854        (const_string "0")
9855        (const_string "*")))
9856    (set_attr "mode" "HI,SI")])
9857
9858 (define_insn "*ashlqi3_1"
9859   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9860         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
9861                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
9862    (clobber (reg:CC FLAGS_REG))]
9863   "TARGET_PARTIAL_REG_STALL
9864    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9865 {
9866   switch (get_attr_type (insn))
9867     {
9868     case TYPE_ALU:
9869       gcc_assert (operands[2] == const1_rtx);
9870       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9871         return "add{l}\t%k0, %k0";
9872       else
9873         return "add{b}\t%0, %0";
9874
9875     default:
9876       if (REG_P (operands[2]))
9877         {
9878           if (get_attr_mode (insn) == MODE_SI)
9879             return "sal{l}\t{%b2, %k0|%k0, %b2}";
9880           else
9881             return "sal{b}\t{%b2, %0|%0, %b2}";
9882         }
9883       else if (operands[2] == const1_rtx
9884                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9885         {
9886           if (get_attr_mode (insn) == MODE_SI)
9887             return "sal{l}\t%0";
9888           else
9889             return "sal{b}\t%0";
9890         }
9891       else
9892         {
9893           if (get_attr_mode (insn) == MODE_SI)
9894             return "sal{l}\t{%2, %k0|%k0, %2}";
9895           else
9896             return "sal{b}\t{%2, %0|%0, %2}";
9897         }
9898     }
9899 }
9900   [(set (attr "type")
9901      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9902                           (const_int 0))
9903                       (match_operand 0 "register_operand" ""))
9904                  (match_operand 2 "const1_operand" ""))
9905               (const_string "alu")
9906            ]
9907            (const_string "ishift")))
9908    (set (attr "length_immediate")
9909      (if_then_else
9910        (ior (eq_attr "type" "alu")
9911             (and (eq_attr "type" "ishift")
9912                  (and (match_operand 2 "const1_operand" "")
9913                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9914                           (const_int 0)))))
9915        (const_string "0")
9916        (const_string "*")))
9917    (set_attr "mode" "QI,SI")])
9918
9919 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9920 (define_insn "*ashlqi3_1_lea"
9921   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
9922         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9923                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9924    (clobber (reg:CC FLAGS_REG))]
9925   "!TARGET_PARTIAL_REG_STALL
9926    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9927 {
9928   switch (get_attr_type (insn))
9929     {
9930     case TYPE_LEA:
9931       return "#";
9932     case TYPE_ALU:
9933       gcc_assert (operands[2] == const1_rtx);
9934       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9935         return "add{l}\t%k0, %k0";
9936       else
9937         return "add{b}\t%0, %0";
9938
9939     default:
9940       if (REG_P (operands[2]))
9941         {
9942           if (get_attr_mode (insn) == MODE_SI)
9943             return "sal{l}\t{%b2, %k0|%k0, %b2}";
9944           else
9945             return "sal{b}\t{%b2, %0|%0, %b2}";
9946         }
9947       else if (operands[2] == const1_rtx
9948                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9949         {
9950           if (get_attr_mode (insn) == MODE_SI)
9951             return "sal{l}\t%0";
9952           else
9953             return "sal{b}\t%0";
9954         }
9955       else
9956         {
9957           if (get_attr_mode (insn) == MODE_SI)
9958             return "sal{l}\t{%2, %k0|%k0, %2}";
9959           else
9960             return "sal{b}\t{%2, %0|%0, %2}";
9961         }
9962     }
9963 }
9964   [(set (attr "type")
9965      (cond [(eq_attr "alternative" "2")
9966               (const_string "lea")
9967             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9968                           (const_int 0))
9969                       (match_operand 0 "register_operand" ""))
9970                  (match_operand 2 "const1_operand" ""))
9971               (const_string "alu")
9972            ]
9973            (const_string "ishift")))
9974    (set (attr "length_immediate")
9975      (if_then_else
9976        (ior (eq_attr "type" "alu")
9977             (and (eq_attr "type" "ishift")
9978                  (and (match_operand 2 "const1_operand" "")
9979                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9980                           (const_int 0)))))
9981        (const_string "0")
9982        (const_string "*")))
9983    (set_attr "mode" "QI,SI,SI")])
9984
9985 ;; Convert lea to the lea pattern to avoid flags dependency.
9986 (define_split
9987   [(set (match_operand:DI 0 "register_operand" "")
9988         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
9989                    (match_operand:QI 2 "const_int_operand" "")))
9990    (clobber (reg:CC FLAGS_REG))]
9991   "TARGET_64BIT && reload_completed
9992    && true_regnum (operands[0]) != true_regnum (operands[1])"
9993   [(set (match_dup 0)
9994         (mult:DI (match_dup 1)
9995                  (match_dup 2)))]
9996   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
9997
9998 ;; Convert lea to the lea pattern to avoid flags dependency.
9999 (define_split
10000   [(set (match_operand 0 "register_operand" "")
10001         (ashift (match_operand 1 "index_register_operand" "")
10002                 (match_operand:QI 2 "const_int_operand" "")))
10003    (clobber (reg:CC FLAGS_REG))]
10004   "reload_completed
10005    && true_regnum (operands[0]) != true_regnum (operands[1])
10006    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10007   [(const_int 0)]
10008 {
10009   rtx pat;
10010   enum machine_mode mode = GET_MODE (operands[0]);
10011
10012   if (GET_MODE_SIZE (mode) < 4)
10013     operands[0] = gen_lowpart (SImode, operands[0]);
10014   if (mode != Pmode)
10015     operands[1] = gen_lowpart (Pmode, operands[1]);
10016   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10017
10018   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10019   if (Pmode != SImode)
10020     pat = gen_rtx_SUBREG (SImode, pat, 0);
10021   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10022   DONE;
10023 })
10024
10025 ;; Rare case of shifting RSP is handled by generating move and shift
10026 (define_split
10027   [(set (match_operand 0 "register_operand" "")
10028         (ashift (match_operand 1 "register_operand" "")
10029                 (match_operand:QI 2 "const_int_operand" "")))
10030    (clobber (reg:CC FLAGS_REG))]
10031   "reload_completed
10032    && true_regnum (operands[0]) != true_regnum (operands[1])"
10033   [(const_int 0)]
10034 {
10035   rtx pat, clob;
10036   emit_move_insn (operands[0], operands[1]);
10037   pat = gen_rtx_SET (VOIDmode, operands[0],
10038                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
10039                                      operands[0], operands[2]));
10040   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10041   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10042   DONE;
10043 })
10044
10045 ;; Convert lea to the lea pattern to avoid flags dependency.
10046 (define_split
10047   [(set (match_operand:DI 0 "register_operand" "")
10048         (zero_extend:DI
10049           (ashift:SI (match_operand:SI 1 "register_operand" "")
10050                      (match_operand:QI 2 "const_int_operand" ""))))
10051    (clobber (reg:CC FLAGS_REG))]
10052   "TARGET_64BIT && reload_completed
10053    && true_regnum (operands[0]) != true_regnum (operands[1])"
10054   [(set (match_dup 0)
10055         (zero_extend:DI (subreg:SI (mult:SI (match_dup 1) (match_dup 2)) 0)))]
10056 {
10057   operands[1] = gen_lowpart (Pmode, operands[1]);
10058   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10059 })
10060
10061 ;; This pattern can't accept a variable shift count, since shifts by
10062 ;; zero don't affect the flags.  We assume that shifts by constant
10063 ;; zero are optimized away.
10064 (define_insn "*ashl<mode>3_cmp"
10065   [(set (reg FLAGS_REG)
10066         (compare
10067           (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10068                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10069           (const_int 0)))
10070    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10071         (ashift:SWI (match_dup 1) (match_dup 2)))]
10072   "(optimize_function_for_size_p (cfun)
10073     || !TARGET_PARTIAL_FLAG_REG_STALL
10074     || (operands[2] == const1_rtx
10075         && (TARGET_SHIFT1
10076             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
10077    && ix86_match_ccmode (insn, CCGOCmode)
10078    && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
10079 {
10080   switch (get_attr_type (insn))
10081     {
10082     case TYPE_ALU:
10083       gcc_assert (operands[2] == const1_rtx);
10084       return "add{<imodesuffix>}\t%0, %0";
10085
10086     default:
10087       if (operands[2] == const1_rtx
10088           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10089         return "sal{<imodesuffix>}\t%0";
10090       else
10091         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10092     }
10093 }
10094   [(set (attr "type")
10095      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10096                           (const_int 0))
10097                       (match_operand 0 "register_operand" ""))
10098                  (match_operand 2 "const1_operand" ""))
10099               (const_string "alu")
10100            ]
10101            (const_string "ishift")))
10102    (set (attr "length_immediate")
10103      (if_then_else
10104        (ior (eq_attr "type" "alu")
10105             (and (eq_attr "type" "ishift")
10106                  (and (match_operand 2 "const1_operand" "")
10107                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10108                           (const_int 0)))))
10109        (const_string "0")
10110        (const_string "*")))
10111    (set_attr "mode" "<MODE>")])
10112
10113 (define_insn "*ashlsi3_cmp_zext"
10114   [(set (reg FLAGS_REG)
10115         (compare
10116           (ashift:SI (match_operand:SI 1 "register_operand" "0")
10117                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10118           (const_int 0)))
10119    (set (match_operand:DI 0 "register_operand" "=r")
10120         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10121   "TARGET_64BIT
10122    && (optimize_function_for_size_p (cfun)
10123        || !TARGET_PARTIAL_FLAG_REG_STALL
10124        || (operands[2] == const1_rtx
10125            && (TARGET_SHIFT1
10126                || TARGET_DOUBLE_WITH_ADD)))
10127    && ix86_match_ccmode (insn, CCGOCmode)
10128    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10129 {
10130   switch (get_attr_type (insn))
10131     {
10132     case TYPE_ALU:
10133       gcc_assert (operands[2] == const1_rtx);
10134       return "add{l}\t%k0, %k0";
10135
10136     default:
10137       if (operands[2] == const1_rtx
10138           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10139         return "sal{l}\t%k0";
10140       else
10141         return "sal{l}\t{%2, %k0|%k0, %2}";
10142     }
10143 }
10144   [(set (attr "type")
10145      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10146                      (const_int 0))
10147                  (match_operand 2 "const1_operand" ""))
10148               (const_string "alu")
10149            ]
10150            (const_string "ishift")))
10151    (set (attr "length_immediate")
10152      (if_then_else
10153        (ior (eq_attr "type" "alu")
10154             (and (eq_attr "type" "ishift")
10155                  (and (match_operand 2 "const1_operand" "")
10156                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10157                           (const_int 0)))))
10158        (const_string "0")
10159        (const_string "*")))
10160    (set_attr "mode" "SI")])
10161
10162 (define_insn "*ashl<mode>3_cconly"
10163   [(set (reg FLAGS_REG)
10164         (compare
10165           (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10166                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10167           (const_int 0)))
10168    (clobber (match_scratch:SWI 0 "=<r>"))]
10169   "(optimize_function_for_size_p (cfun)
10170     || !TARGET_PARTIAL_FLAG_REG_STALL
10171     || (operands[2] == const1_rtx
10172         && (TARGET_SHIFT1
10173             || TARGET_DOUBLE_WITH_ADD)))
10174    && ix86_match_ccmode (insn, CCGOCmode)
10175    && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
10176 {
10177   switch (get_attr_type (insn))
10178     {
10179     case TYPE_ALU:
10180       gcc_assert (operands[2] == const1_rtx);
10181       return "add{<imodesuffix>}\t%0, %0";
10182
10183     default:
10184       if (operands[2] == const1_rtx
10185           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10186         return "sal{<imodesuffix>}\t%0";
10187       else
10188         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10189     }
10190 }
10191   [(set (attr "type")
10192      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10193                           (const_int 0))
10194                       (match_operand 0 "register_operand" ""))
10195                  (match_operand 2 "const1_operand" ""))
10196               (const_string "alu")
10197            ]
10198            (const_string "ishift")))
10199    (set (attr "length_immediate")
10200      (if_then_else
10201        (ior (eq_attr "type" "alu")
10202             (and (eq_attr "type" "ishift")
10203                  (and (match_operand 2 "const1_operand" "")
10204                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10205                           (const_int 0)))))
10206        (const_string "0")
10207        (const_string "*")))
10208    (set_attr "mode" "<MODE>")])
10209
10210 ;; See comment above `ashldi3' about how this works.
10211
10212 (define_expand "ashrti3"
10213   [(set (match_operand:TI 0 "register_operand" "")
10214         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
10215                      (match_operand:QI 2 "nonmemory_operand" "")))]
10216   "TARGET_64BIT"
10217   "ix86_expand_binary_operator (ASHIFTRT, TImode, operands); DONE;")
10218
10219 (define_insn "*ashrti3_1"
10220   [(set (match_operand:TI 0 "register_operand" "=r")
10221         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
10222                      (match_operand:QI 2 "nonmemory_operand" "Oc")))
10223    (clobber (reg:CC FLAGS_REG))]
10224   "TARGET_64BIT"
10225   "#"
10226   [(set_attr "type" "multi")])
10227
10228 (define_peephole2
10229   [(match_scratch:DI 3 "r")
10230    (parallel [(set (match_operand:TI 0 "register_operand" "")
10231                    (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
10232                                 (match_operand:QI 2 "nonmemory_operand" "")))
10233               (clobber (reg:CC FLAGS_REG))])
10234    (match_dup 3)]
10235   "TARGET_64BIT"
10236   [(const_int 0)]
10237   "ix86_split_ashr (operands, operands[3], TImode); DONE;")
10238
10239 (define_split
10240   [(set (match_operand:TI 0 "register_operand" "")
10241         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
10242                      (match_operand:QI 2 "nonmemory_operand" "")))
10243    (clobber (reg:CC FLAGS_REG))]
10244   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10245                     ? epilogue_completed : reload_completed)"
10246   [(const_int 0)]
10247   "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
10248
10249 (define_insn "x86_64_shrd"
10250   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
10251         (ior:DI (ashiftrt:DI (match_dup 0)
10252                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
10253                 (ashift:DI (match_operand:DI 1 "register_operand" "r")
10254                   (minus:QI (const_int 64) (match_dup 2)))))
10255    (clobber (reg:CC FLAGS_REG))]
10256   "TARGET_64BIT"
10257   "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
10258   [(set_attr "type" "ishift")
10259    (set_attr "prefix_0f" "1")
10260    (set_attr "mode" "DI")
10261    (set_attr "athlon_decode" "vector")
10262    (set_attr "amdfam10_decode" "vector")])
10263
10264 (define_expand "ashrdi3"
10265   [(set (match_operand:DI 0 "shiftdi_operand" "")
10266         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
10267                      (match_operand:QI 2 "nonmemory_operand" "")))]
10268   ""
10269   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
10270
10271 (define_expand "x86_64_shift_adj_3"
10272   [(use (match_operand:DI 0 "register_operand" ""))
10273    (use (match_operand:DI 1 "register_operand" ""))
10274    (use (match_operand:QI 2 "register_operand" ""))]
10275   ""
10276 {
10277   rtx label = gen_label_rtx ();
10278   rtx tmp;
10279
10280   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (64)));
10281
10282   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10283   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10284   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10285                               gen_rtx_LABEL_REF (VOIDmode, label),
10286                               pc_rtx);
10287   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10288   JUMP_LABEL (tmp) = label;
10289
10290   emit_move_insn (operands[0], operands[1]);
10291   emit_insn (gen_ashrdi3_63_rex64 (operands[1], operands[1], GEN_INT (63)));
10292
10293   emit_label (label);
10294   LABEL_NUSES (label) = 1;
10295
10296   DONE;
10297 })
10298
10299 (define_insn "ashrdi3_63_rex64"
10300   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
10301         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
10302                      (match_operand:DI 2 "const_int_operand" "i,i")))
10303    (clobber (reg:CC FLAGS_REG))]
10304   "TARGET_64BIT && INTVAL (operands[2]) == 63
10305    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10306    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10307   "@
10308    {cqto|cqo}
10309    sar{q}\t{%2, %0|%0, %2}"
10310   [(set_attr "type" "imovx,ishift")
10311    (set_attr "prefix_0f" "0,*")
10312    (set_attr "length_immediate" "0,*")
10313    (set_attr "modrm" "0,1")
10314    (set_attr "mode" "DI")])
10315
10316 (define_insn "*ashrdi3_1_one_bit_rex64"
10317   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10318         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10319                      (match_operand:QI 2 "const1_operand" "")))
10320    (clobber (reg:CC FLAGS_REG))]
10321   "TARGET_64BIT
10322    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
10323    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10324   "sar{q}\t%0"
10325   [(set_attr "type" "ishift")
10326    (set_attr "length_immediate" "0")
10327    (set_attr "mode" "DI")])
10328
10329 (define_insn "*ashrdi3_1_rex64"
10330   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
10331         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
10332                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
10333    (clobber (reg:CC FLAGS_REG))]
10334   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10335   "@
10336    sar{q}\t{%2, %0|%0, %2}
10337    sar{q}\t{%b2, %0|%0, %b2}"
10338   [(set_attr "type" "ishift")
10339    (set_attr "mode" "DI")])
10340
10341 ;; This pattern can't accept a variable shift count, since shifts by
10342 ;; zero don't affect the flags.  We assume that shifts by constant
10343 ;; zero are optimized away.
10344 (define_insn "*ashrdi3_one_bit_cmp_rex64"
10345   [(set (reg FLAGS_REG)
10346         (compare
10347           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10348                        (match_operand:QI 2 "const1_operand" ""))
10349           (const_int 0)))
10350    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10351         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
10352   "TARGET_64BIT
10353    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
10354    && ix86_match_ccmode (insn, CCGOCmode)
10355    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10356   "sar{q}\t%0"
10357   [(set_attr "type" "ishift")
10358    (set_attr "length_immediate" "0")
10359    (set_attr "mode" "DI")])
10360
10361 (define_insn "*ashrdi3_one_bit_cconly_rex64"
10362   [(set (reg FLAGS_REG)
10363         (compare
10364           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10365                        (match_operand:QI 2 "const1_operand" ""))
10366           (const_int 0)))
10367    (clobber (match_scratch:DI 0 "=r"))]
10368   "TARGET_64BIT
10369    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
10370    && ix86_match_ccmode (insn, CCGOCmode)
10371    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10372   "sar{q}\t%0"
10373   [(set_attr "type" "ishift")
10374    (set_attr "length_immediate" "0")
10375    (set_attr "mode" "DI")])
10376
10377 ;; This pattern can't accept a variable shift count, since shifts by
10378 ;; zero don't affect the flags.  We assume that shifts by constant
10379 ;; zero are optimized away.
10380 (define_insn "*ashrdi3_cmp_rex64"
10381   [(set (reg FLAGS_REG)
10382         (compare
10383           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10384                        (match_operand:QI 2 "const_1_to_63_operand" "J"))
10385           (const_int 0)))
10386    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10387         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
10388   "TARGET_64BIT
10389    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
10390    && ix86_match_ccmode (insn, CCGOCmode)
10391    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10392   "sar{q}\t{%2, %0|%0, %2}"
10393   [(set_attr "type" "ishift")
10394    (set_attr "mode" "DI")])
10395
10396 (define_insn "*ashrdi3_cconly_rex64"
10397   [(set (reg FLAGS_REG)
10398         (compare
10399           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10400                        (match_operand:QI 2 "const_1_to_63_operand" "J"))
10401           (const_int 0)))
10402    (clobber (match_scratch:DI 0 "=r"))]
10403   "TARGET_64BIT
10404    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
10405    && ix86_match_ccmode (insn, CCGOCmode)
10406    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10407   "sar{q}\t{%2, %0|%0, %2}"
10408   [(set_attr "type" "ishift")
10409    (set_attr "mode" "DI")])
10410
10411 (define_insn "*ashrdi3_1"
10412   [(set (match_operand:DI 0 "register_operand" "=r")
10413         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
10414                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
10415    (clobber (reg:CC FLAGS_REG))]
10416   "!TARGET_64BIT"
10417   "#"
10418   [(set_attr "type" "multi")])
10419
10420 ;; By default we don't ask for a scratch register, because when DImode
10421 ;; values are manipulated, registers are already at a premium.  But if
10422 ;; we have one handy, we won't turn it away.
10423 (define_peephole2
10424   [(match_scratch:SI 3 "r")
10425    (parallel [(set (match_operand:DI 0 "register_operand" "")
10426                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
10427                                 (match_operand:QI 2 "nonmemory_operand" "")))
10428               (clobber (reg:CC FLAGS_REG))])
10429    (match_dup 3)]
10430   "!TARGET_64BIT && TARGET_CMOVE"
10431   [(const_int 0)]
10432   "ix86_split_ashr (operands, operands[3], DImode); DONE;")
10433
10434 (define_split
10435   [(set (match_operand:DI 0 "register_operand" "")
10436         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
10437                      (match_operand:QI 2 "nonmemory_operand" "")))
10438    (clobber (reg:CC FLAGS_REG))]
10439   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10440                      ? epilogue_completed : reload_completed)"
10441   [(const_int 0)]
10442   "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
10443
10444 (define_insn "x86_shrd"
10445   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
10446         (ior:SI (ashiftrt:SI (match_dup 0)
10447                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
10448                 (ashift:SI (match_operand:SI 1 "register_operand" "r")
10449                   (minus:QI (const_int 32) (match_dup 2)))))
10450    (clobber (reg:CC FLAGS_REG))]
10451   ""
10452   "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
10453   [(set_attr "type" "ishift")
10454    (set_attr "prefix_0f" "1")
10455    (set_attr "pent_pair" "np")
10456    (set_attr "mode" "SI")])
10457
10458 (define_expand "x86_shift_adj_3"
10459   [(use (match_operand:SI 0 "register_operand" ""))
10460    (use (match_operand:SI 1 "register_operand" ""))
10461    (use (match_operand:QI 2 "register_operand" ""))]
10462   ""
10463 {
10464   rtx label = gen_label_rtx ();
10465   rtx tmp;
10466
10467   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10468
10469   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10470   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10471   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10472                               gen_rtx_LABEL_REF (VOIDmode, label),
10473                               pc_rtx);
10474   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10475   JUMP_LABEL (tmp) = label;
10476
10477   emit_move_insn (operands[0], operands[1]);
10478   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
10479
10480   emit_label (label);
10481   LABEL_NUSES (label) = 1;
10482
10483   DONE;
10484 })
10485
10486 (define_expand "ashrsi3_31"
10487   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
10488                    (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
10489                                 (match_operand:SI 2 "const_int_operand" "i,i")))
10490               (clobber (reg:CC FLAGS_REG))])]
10491   "")
10492
10493 (define_insn "*ashrsi3_31"
10494   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
10495         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
10496                      (match_operand:SI 2 "const_int_operand" "i,i")))
10497    (clobber (reg:CC FLAGS_REG))]
10498   "INTVAL (operands[2]) == 31
10499    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10500    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10501   "@
10502    {cltd|cdq}
10503    sar{l}\t{%2, %0|%0, %2}"
10504   [(set_attr "type" "imovx,ishift")
10505    (set_attr "prefix_0f" "0,*")
10506    (set_attr "length_immediate" "0,*")
10507    (set_attr "modrm" "0,1")
10508    (set_attr "mode" "SI")])
10509
10510 (define_insn "*ashrsi3_31_zext"
10511   [(set (match_operand:DI 0 "register_operand" "=*d,r")
10512         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
10513                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
10514    (clobber (reg:CC FLAGS_REG))]
10515   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10516    && INTVAL (operands[2]) == 31
10517    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10518   "@
10519    {cltd|cdq}
10520    sar{l}\t{%2, %k0|%k0, %2}"
10521   [(set_attr "type" "imovx,ishift")
10522    (set_attr "prefix_0f" "0,*")
10523    (set_attr "length_immediate" "0,*")
10524    (set_attr "modrm" "0,1")
10525    (set_attr "mode" "SI")])
10526
10527 (define_expand "ashrsi3"
10528   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10529         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
10530                      (match_operand:QI 2 "nonmemory_operand" "")))]
10531   ""
10532   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
10533
10534 (define_insn "*ashrsi3_1_one_bit"
10535   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10536         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10537                      (match_operand:QI 2 "const1_operand" "")))
10538    (clobber (reg:CC FLAGS_REG))]
10539   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
10540    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10541   "sar{l}\t%0"
10542   [(set_attr "type" "ishift")
10543    (set_attr "length_immediate" "0")
10544    (set_attr "mode" "SI")])
10545
10546 (define_insn "*ashrsi3_1_one_bit_zext"
10547   [(set (match_operand:DI 0 "register_operand" "=r")
10548         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
10549                                      (match_operand:QI 2 "const1_operand" ""))))
10550    (clobber (reg:CC FLAGS_REG))]
10551   "TARGET_64BIT
10552    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
10553    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10554   "sar{l}\t%k0"
10555   [(set_attr "type" "ishift")
10556    (set_attr "length_immediate" "0")
10557    (set_attr "mode" "SI")])
10558
10559 (define_insn "*ashrsi3_1"
10560   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
10561         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
10562                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
10563    (clobber (reg:CC FLAGS_REG))]
10564   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10565   "@
10566    sar{l}\t{%2, %0|%0, %2}
10567    sar{l}\t{%b2, %0|%0, %b2}"
10568   [(set_attr "type" "ishift")
10569    (set_attr "mode" "SI")])
10570
10571 (define_insn "*ashrsi3_1_zext"
10572   [(set (match_operand:DI 0 "register_operand" "=r,r")
10573         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
10574                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
10575    (clobber (reg:CC FLAGS_REG))]
10576   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10577   "@
10578    sar{l}\t{%2, %k0|%k0, %2}
10579    sar{l}\t{%b2, %k0|%k0, %b2}"
10580   [(set_attr "type" "ishift")
10581    (set_attr "mode" "SI")])
10582
10583 ;; This pattern can't accept a variable shift count, since shifts by
10584 ;; zero don't affect the flags.  We assume that shifts by constant
10585 ;; zero are optimized away.
10586 (define_insn "*ashrsi3_one_bit_cmp"
10587   [(set (reg FLAGS_REG)
10588         (compare
10589           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10590                        (match_operand:QI 2 "const1_operand" ""))
10591           (const_int 0)))
10592    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10593         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
10594   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
10595    && ix86_match_ccmode (insn, CCGOCmode)
10596    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10597   "sar{l}\t%0"
10598   [(set_attr "type" "ishift")
10599    (set_attr "length_immediate" "0")
10600    (set_attr "mode" "SI")])
10601
10602 (define_insn "*ashrsi3_one_bit_cconly"
10603   [(set (reg FLAGS_REG)
10604         (compare
10605           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10606                        (match_operand:QI 2 "const1_operand" ""))
10607           (const_int 0)))
10608    (clobber (match_scratch:SI 0 "=r"))]
10609   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
10610    && ix86_match_ccmode (insn, CCGOCmode)
10611    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10612   "sar{l}\t%0"
10613   [(set_attr "type" "ishift")
10614    (set_attr "length_immediate" "0")
10615    (set_attr "mode" "SI")])
10616
10617 (define_insn "*ashrsi3_one_bit_cmp_zext"
10618   [(set (reg FLAGS_REG)
10619         (compare
10620           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
10621                        (match_operand:QI 2 "const1_operand" ""))
10622           (const_int 0)))
10623    (set (match_operand:DI 0 "register_operand" "=r")
10624         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
10625   "TARGET_64BIT
10626    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
10627    && ix86_match_ccmode (insn, CCmode)
10628    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10629   "sar{l}\t%k0"
10630   [(set_attr "type" "ishift")
10631    (set_attr "length_immediate" "0")
10632    (set_attr "mode" "SI")])
10633
10634 ;; This pattern can't accept a variable shift count, since shifts by
10635 ;; zero don't affect the flags.  We assume that shifts by constant
10636 ;; zero are optimized away.
10637 (define_insn "*ashrsi3_cmp"
10638   [(set (reg FLAGS_REG)
10639         (compare
10640           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10641                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
10642           (const_int 0)))
10643    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10644         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
10645   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
10646    && ix86_match_ccmode (insn, CCGOCmode)
10647    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10648   "sar{l}\t{%2, %0|%0, %2}"
10649   [(set_attr "type" "ishift")
10650    (set_attr "mode" "SI")])
10651
10652 (define_insn "*ashrsi3_cconly"
10653   [(set (reg FLAGS_REG)
10654         (compare
10655           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10656                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
10657           (const_int 0)))
10658    (clobber (match_scratch:SI 0 "=r"))]
10659   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
10660    && ix86_match_ccmode (insn, CCGOCmode)
10661    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10662   "sar{l}\t{%2, %0|%0, %2}"
10663   [(set_attr "type" "ishift")
10664    (set_attr "mode" "SI")])
10665
10666 (define_insn "*ashrsi3_cmp_zext"
10667   [(set (reg FLAGS_REG)
10668         (compare
10669           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
10670                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
10671           (const_int 0)))
10672    (set (match_operand:DI 0 "register_operand" "=r")
10673         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
10674   "TARGET_64BIT
10675    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
10676    && ix86_match_ccmode (insn, CCGOCmode)
10677    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10678   "sar{l}\t{%2, %k0|%k0, %2}"
10679   [(set_attr "type" "ishift")
10680    (set_attr "mode" "SI")])
10681
10682 (define_expand "ashrhi3"
10683   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10684         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
10685                      (match_operand:QI 2 "nonmemory_operand" "")))]
10686   "TARGET_HIMODE_MATH"
10687   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
10688
10689 (define_insn "*ashrhi3_1_one_bit"
10690   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10691         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10692                      (match_operand:QI 2 "const1_operand" "")))
10693    (clobber (reg:CC FLAGS_REG))]
10694   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
10695    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
10696   "sar{w}\t%0"
10697   [(set_attr "type" "ishift")
10698    (set_attr "length_immediate" "0")
10699    (set_attr "mode" "HI")])
10700
10701 (define_insn "*ashrhi3_1"
10702   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
10703         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
10704                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
10705    (clobber (reg:CC FLAGS_REG))]
10706   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
10707   "@
10708    sar{w}\t{%2, %0|%0, %2}
10709    sar{w}\t{%b2, %0|%0, %b2}"
10710   [(set_attr "type" "ishift")
10711    (set_attr "mode" "HI")])
10712
10713 ;; This pattern can't accept a variable shift count, since shifts by
10714 ;; zero don't affect the flags.  We assume that shifts by constant
10715 ;; zero are optimized away.
10716 (define_insn "*ashrhi3_one_bit_cmp"
10717   [(set (reg FLAGS_REG)
10718         (compare
10719           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10720                        (match_operand:QI 2 "const1_operand" ""))
10721           (const_int 0)))
10722    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10723         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
10724   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
10725    && ix86_match_ccmode (insn, CCGOCmode)
10726    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
10727   "sar{w}\t%0"
10728   [(set_attr "type" "ishift")
10729    (set_attr "length_immediate" "0")
10730    (set_attr "mode" "HI")])
10731
10732 (define_insn "*ashrhi3_one_bit_cconly"
10733   [(set (reg FLAGS_REG)
10734         (compare
10735           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10736                        (match_operand:QI 2 "const1_operand" ""))
10737           (const_int 0)))
10738    (clobber (match_scratch:HI 0 "=r"))]
10739   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
10740    && ix86_match_ccmode (insn, CCGOCmode)
10741    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
10742   "sar{w}\t%0"
10743   [(set_attr "type" "ishift")
10744    (set_attr "length_immediate" "0")
10745    (set_attr "mode" "HI")])
10746
10747 ;; This pattern can't accept a variable shift count, since shifts by
10748 ;; zero don't affect the flags.  We assume that shifts by constant
10749 ;; zero are optimized away.
10750 (define_insn "*ashrhi3_cmp"
10751   [(set (reg FLAGS_REG)
10752         (compare
10753           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10754                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
10755           (const_int 0)))
10756    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10757         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
10758   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
10759    && ix86_match_ccmode (insn, CCGOCmode)
10760    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
10761   "sar{w}\t{%2, %0|%0, %2}"
10762   [(set_attr "type" "ishift")
10763    (set_attr "mode" "HI")])
10764
10765 (define_insn "*ashrhi3_cconly"
10766   [(set (reg FLAGS_REG)
10767         (compare
10768           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10769                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
10770           (const_int 0)))
10771    (clobber (match_scratch:HI 0 "=r"))]
10772   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
10773    && ix86_match_ccmode (insn, CCGOCmode)
10774    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
10775   "sar{w}\t{%2, %0|%0, %2}"
10776   [(set_attr "type" "ishift")
10777    (set_attr "mode" "HI")])
10778
10779 (define_expand "ashrqi3"
10780   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10781         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
10782                      (match_operand:QI 2 "nonmemory_operand" "")))]
10783   "TARGET_QIMODE_MATH"
10784   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
10785
10786 (define_insn "*ashrqi3_1_one_bit"
10787   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10788         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
10789                      (match_operand:QI 2 "const1_operand" "")))
10790    (clobber (reg:CC FLAGS_REG))]
10791   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
10792    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
10793   "sar{b}\t%0"
10794   [(set_attr "type" "ishift")
10795    (set_attr "length_immediate" "0")
10796    (set_attr "mode" "QI")])
10797
10798 (define_insn "*ashrqi3_1_one_bit_slp"
10799   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10800         (ashiftrt:QI (match_dup 0)
10801                      (match_operand:QI 1 "const1_operand" "")))
10802    (clobber (reg:CC FLAGS_REG))]
10803   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10804    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
10805    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
10806   "sar{b}\t%0"
10807   [(set_attr "type" "ishift1")
10808    (set_attr "length_immediate" "0")
10809    (set_attr "mode" "QI")])
10810
10811 (define_insn "*ashrqi3_1"
10812   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
10813         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
10814                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
10815    (clobber (reg:CC FLAGS_REG))]
10816   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
10817   "@
10818    sar{b}\t{%2, %0|%0, %2}
10819    sar{b}\t{%b2, %0|%0, %b2}"
10820   [(set_attr "type" "ishift")
10821    (set_attr "mode" "QI")])
10822
10823 (define_insn "*ashrqi3_1_slp"
10824   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
10825         (ashiftrt:QI (match_dup 0)
10826                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
10827    (clobber (reg:CC FLAGS_REG))]
10828   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10829    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
10830   "@
10831    sar{b}\t{%1, %0|%0, %1}
10832    sar{b}\t{%b1, %0|%0, %b1}"
10833   [(set_attr "type" "ishift1")
10834    (set_attr "mode" "QI")])
10835
10836 ;; This pattern can't accept a variable shift count, since shifts by
10837 ;; zero don't affect the flags.  We assume that shifts by constant
10838 ;; zero are optimized away.
10839 (define_insn "*ashrqi3_one_bit_cmp"
10840   [(set (reg FLAGS_REG)
10841         (compare
10842           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
10843                        (match_operand:QI 2 "const1_operand" "I"))
10844           (const_int 0)))
10845    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10846         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
10847   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
10848    && ix86_match_ccmode (insn, CCGOCmode)
10849    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
10850   "sar{b}\t%0"
10851   [(set_attr "type" "ishift")
10852    (set_attr "length_immediate" "0")
10853    (set_attr "mode" "QI")])
10854
10855 (define_insn "*ashrqi3_one_bit_cconly"
10856   [(set (reg FLAGS_REG)
10857         (compare
10858           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
10859                        (match_operand:QI 2 "const1_operand" ""))
10860           (const_int 0)))
10861    (clobber (match_scratch:QI 0 "=q"))]
10862   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
10863    && ix86_match_ccmode (insn, CCGOCmode)
10864    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
10865   "sar{b}\t%0"
10866   [(set_attr "type" "ishift")
10867    (set_attr "length_immediate" "0")
10868    (set_attr "mode" "QI")])
10869
10870 ;; This pattern can't accept a variable shift count, since shifts by
10871 ;; zero don't affect the flags.  We assume that shifts by constant
10872 ;; zero are optimized away.
10873 (define_insn "*ashrqi3_cmp"
10874   [(set (reg FLAGS_REG)
10875         (compare
10876           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
10877                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
10878           (const_int 0)))
10879    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10880         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
10881   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
10882    && ix86_match_ccmode (insn, CCGOCmode)
10883    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
10884   "sar{b}\t{%2, %0|%0, %2}"
10885   [(set_attr "type" "ishift")
10886    (set_attr "mode" "QI")])
10887
10888 (define_insn "*ashrqi3_cconly"
10889   [(set (reg FLAGS_REG)
10890         (compare
10891           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
10892                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
10893           (const_int 0)))
10894    (clobber (match_scratch:QI 0 "=q"))]
10895   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
10896    && ix86_match_ccmode (insn, CCGOCmode)
10897    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
10898   "sar{b}\t{%2, %0|%0, %2}"
10899   [(set_attr "type" "ishift")
10900    (set_attr "mode" "QI")])
10901
10902 \f
10903 ;; Logical shift instructions
10904
10905 ;; See comment above `ashldi3' about how this works.
10906
10907 (define_expand "lshrti3"
10908   [(set (match_operand:TI 0 "register_operand" "")
10909         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
10910                      (match_operand:QI 2 "nonmemory_operand" "")))]
10911   "TARGET_64BIT"
10912   "ix86_expand_binary_operator (LSHIFTRT, TImode, operands); DONE;")
10913
10914 (define_insn "*lshrti3_1"
10915   [(set (match_operand:TI 0 "register_operand" "=r")
10916         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
10917                      (match_operand:QI 2 "nonmemory_operand" "Oc")))
10918    (clobber (reg:CC FLAGS_REG))]
10919   "TARGET_64BIT"
10920   "#"
10921   [(set_attr "type" "multi")])
10922
10923 (define_peephole2
10924   [(match_scratch:DI 3 "r")
10925    (parallel [(set (match_operand:TI 0 "register_operand" "")
10926                    (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
10927                                 (match_operand:QI 2 "nonmemory_operand" "")))
10928               (clobber (reg:CC FLAGS_REG))])
10929    (match_dup 3)]
10930   "TARGET_64BIT"
10931   [(const_int 0)]
10932   "ix86_split_lshr (operands, operands[3], TImode); DONE;")
10933
10934 (define_split
10935   [(set (match_operand:TI 0 "register_operand" "")
10936         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
10937                      (match_operand:QI 2 "nonmemory_operand" "")))
10938    (clobber (reg:CC FLAGS_REG))]
10939   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10940                     ? epilogue_completed : reload_completed)"
10941   [(const_int 0)]
10942   "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
10943
10944 (define_expand "lshrdi3"
10945   [(set (match_operand:DI 0 "shiftdi_operand" "")
10946         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
10947                      (match_operand:QI 2 "nonmemory_operand" "")))]
10948   ""
10949   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
10950
10951 (define_insn "*lshrdi3_1_one_bit_rex64"
10952   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10953         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10954                      (match_operand:QI 2 "const1_operand" "")))
10955    (clobber (reg:CC FLAGS_REG))]
10956   "TARGET_64BIT
10957    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
10958    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
10959   "shr{q}\t%0"
10960   [(set_attr "type" "ishift")
10961    (set_attr "length_immediate" "0")
10962    (set_attr "mode" "DI")])
10963
10964 (define_insn "*lshrdi3_1_rex64"
10965   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
10966         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
10967                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
10968    (clobber (reg:CC FLAGS_REG))]
10969   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
10970   "@
10971    shr{q}\t{%2, %0|%0, %2}
10972    shr{q}\t{%b2, %0|%0, %b2}"
10973   [(set_attr "type" "ishift")
10974    (set_attr "mode" "DI")])
10975
10976 ;; This pattern can't accept a variable shift count, since shifts by
10977 ;; zero don't affect the flags.  We assume that shifts by constant
10978 ;; zero are optimized away.
10979 (define_insn "*lshrdi3_cmp_one_bit_rex64"
10980   [(set (reg FLAGS_REG)
10981         (compare
10982           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10983                        (match_operand:QI 2 "const1_operand" ""))
10984           (const_int 0)))
10985    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10986         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
10987   "TARGET_64BIT
10988    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
10989    && ix86_match_ccmode (insn, CCGOCmode)
10990    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
10991   "shr{q}\t%0"
10992   [(set_attr "type" "ishift")
10993    (set_attr "length_immediate" "0")
10994    (set_attr "mode" "DI")])
10995
10996 (define_insn "*lshrdi3_cconly_one_bit_rex64"
10997   [(set (reg FLAGS_REG)
10998         (compare
10999           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11000                        (match_operand:QI 2 "const1_operand" ""))
11001           (const_int 0)))
11002    (clobber (match_scratch:DI 0 "=r"))]
11003   "TARGET_64BIT
11004    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11005    && ix86_match_ccmode (insn, CCGOCmode)
11006    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11007   "shr{q}\t%0"
11008   [(set_attr "type" "ishift")
11009    (set_attr "length_immediate" "0")
11010    (set_attr "mode" "DI")])
11011
11012 ;; This pattern can't accept a variable shift count, since shifts by
11013 ;; zero don't affect the flags.  We assume that shifts by constant
11014 ;; zero are optimized away.
11015 (define_insn "*lshrdi3_cmp_rex64"
11016   [(set (reg FLAGS_REG)
11017         (compare
11018           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11019                        (match_operand:QI 2 "const_1_to_63_operand" "J"))
11020           (const_int 0)))
11021    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11022         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11023   "TARGET_64BIT
11024    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11025    && ix86_match_ccmode (insn, CCGOCmode)
11026    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11027   "shr{q}\t{%2, %0|%0, %2}"
11028   [(set_attr "type" "ishift")
11029    (set_attr "mode" "DI")])
11030
11031 (define_insn "*lshrdi3_cconly_rex64"
11032   [(set (reg FLAGS_REG)
11033         (compare
11034           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11035                        (match_operand:QI 2 "const_1_to_63_operand" "J"))
11036           (const_int 0)))
11037    (clobber (match_scratch:DI 0 "=r"))]
11038   "TARGET_64BIT
11039    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11040    && ix86_match_ccmode (insn, CCGOCmode)
11041    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11042   "shr{q}\t{%2, %0|%0, %2}"
11043   [(set_attr "type" "ishift")
11044    (set_attr "mode" "DI")])
11045
11046 (define_insn "*lshrdi3_1"
11047   [(set (match_operand:DI 0 "register_operand" "=r")
11048         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11049                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11050    (clobber (reg:CC FLAGS_REG))]
11051   "!TARGET_64BIT"
11052   "#"
11053   [(set_attr "type" "multi")])
11054
11055 ;; By default we don't ask for a scratch register, because when DImode
11056 ;; values are manipulated, registers are already at a premium.  But if
11057 ;; we have one handy, we won't turn it away.
11058 (define_peephole2
11059   [(match_scratch:SI 3 "r")
11060    (parallel [(set (match_operand:DI 0 "register_operand" "")
11061                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11062                                 (match_operand:QI 2 "nonmemory_operand" "")))
11063               (clobber (reg:CC FLAGS_REG))])
11064    (match_dup 3)]
11065   "!TARGET_64BIT && TARGET_CMOVE"
11066   [(const_int 0)]
11067   "ix86_split_lshr (operands, operands[3], DImode); DONE;")
11068
11069 (define_split
11070   [(set (match_operand:DI 0 "register_operand" "")
11071         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11072                      (match_operand:QI 2 "nonmemory_operand" "")))
11073    (clobber (reg:CC FLAGS_REG))]
11074   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11075                      ? epilogue_completed : reload_completed)"
11076   [(const_int 0)]
11077   "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
11078
11079 (define_expand "lshrsi3"
11080   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11081         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11082                      (match_operand:QI 2 "nonmemory_operand" "")))]
11083   ""
11084   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11085
11086 (define_insn "*lshrsi3_1_one_bit"
11087   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11088         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11089                      (match_operand:QI 2 "const1_operand" "")))
11090    (clobber (reg:CC FLAGS_REG))]
11091   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11092    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11093   "shr{l}\t%0"
11094   [(set_attr "type" "ishift")
11095    (set_attr "length_immediate" "0")
11096    (set_attr "mode" "SI")])
11097
11098 (define_insn "*lshrsi3_1_one_bit_zext"
11099   [(set (match_operand:DI 0 "register_operand" "=r")
11100         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
11101                      (match_operand:QI 2 "const1_operand" "")))
11102    (clobber (reg:CC FLAGS_REG))]
11103   "TARGET_64BIT
11104    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11105    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11106   "shr{l}\t%k0"
11107   [(set_attr "type" "ishift")
11108    (set_attr "length_immediate" "0")
11109    (set_attr "mode" "SI")])
11110
11111 (define_insn "*lshrsi3_1"
11112   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11113         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11114                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11115    (clobber (reg:CC FLAGS_REG))]
11116   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11117   "@
11118    shr{l}\t{%2, %0|%0, %2}
11119    shr{l}\t{%b2, %0|%0, %b2}"
11120   [(set_attr "type" "ishift")
11121    (set_attr "mode" "SI")])
11122
11123 (define_insn "*lshrsi3_1_zext"
11124   [(set (match_operand:DI 0 "register_operand" "=r,r")
11125         (zero_extend:DI
11126           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11127                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11128    (clobber (reg:CC FLAGS_REG))]
11129   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11130   "@
11131    shr{l}\t{%2, %k0|%k0, %2}
11132    shr{l}\t{%b2, %k0|%k0, %b2}"
11133   [(set_attr "type" "ishift")
11134    (set_attr "mode" "SI")])
11135
11136 ;; This pattern can't accept a variable shift count, since shifts by
11137 ;; zero don't affect the flags.  We assume that shifts by constant
11138 ;; zero are optimized away.
11139 (define_insn "*lshrsi3_one_bit_cmp"
11140   [(set (reg FLAGS_REG)
11141         (compare
11142           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11143                        (match_operand:QI 2 "const1_operand" ""))
11144           (const_int 0)))
11145    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11146         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11147   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11148    && ix86_match_ccmode (insn, CCGOCmode)
11149    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11150   "shr{l}\t%0"
11151   [(set_attr "type" "ishift")
11152    (set_attr "length_immediate" "0")
11153    (set_attr "mode" "SI")])
11154
11155 (define_insn "*lshrsi3_one_bit_cconly"
11156   [(set (reg FLAGS_REG)
11157         (compare
11158           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11159                        (match_operand:QI 2 "const1_operand" ""))
11160           (const_int 0)))
11161    (clobber (match_scratch:SI 0 "=r"))]
11162   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11163    && ix86_match_ccmode (insn, CCGOCmode)
11164    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11165   "shr{l}\t%0"
11166   [(set_attr "type" "ishift")
11167    (set_attr "length_immediate" "0")
11168    (set_attr "mode" "SI")])
11169
11170 (define_insn "*lshrsi3_cmp_one_bit_zext"
11171   [(set (reg FLAGS_REG)
11172         (compare
11173           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11174                        (match_operand:QI 2 "const1_operand" ""))
11175           (const_int 0)))
11176    (set (match_operand:DI 0 "register_operand" "=r")
11177         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11178   "TARGET_64BIT
11179    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11180    && ix86_match_ccmode (insn, CCGOCmode)
11181    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11182   "shr{l}\t%k0"
11183   [(set_attr "type" "ishift")
11184    (set_attr "length_immediate" "0")
11185    (set_attr "mode" "SI")])
11186
11187 ;; This pattern can't accept a variable shift count, since shifts by
11188 ;; zero don't affect the flags.  We assume that shifts by constant
11189 ;; zero are optimized away.
11190 (define_insn "*lshrsi3_cmp"
11191   [(set (reg FLAGS_REG)
11192         (compare
11193           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11194                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11195           (const_int 0)))
11196    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11197         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11198   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11199    && ix86_match_ccmode (insn, CCGOCmode)
11200    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11201   "shr{l}\t{%2, %0|%0, %2}"
11202   [(set_attr "type" "ishift")
11203    (set_attr "mode" "SI")])
11204
11205 (define_insn "*lshrsi3_cconly"
11206   [(set (reg FLAGS_REG)
11207       (compare
11208         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11209                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11210         (const_int 0)))
11211    (clobber (match_scratch:SI 0 "=r"))]
11212   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11213    && ix86_match_ccmode (insn, CCGOCmode)
11214    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11215   "shr{l}\t{%2, %0|%0, %2}"
11216   [(set_attr "type" "ishift")
11217    (set_attr "mode" "SI")])
11218
11219 (define_insn "*lshrsi3_cmp_zext"
11220   [(set (reg FLAGS_REG)
11221         (compare
11222           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11223                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11224           (const_int 0)))
11225    (set (match_operand:DI 0 "register_operand" "=r")
11226         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11227   "TARGET_64BIT
11228    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11229    && ix86_match_ccmode (insn, CCGOCmode)
11230    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11231   "shr{l}\t{%2, %k0|%k0, %2}"
11232   [(set_attr "type" "ishift")
11233    (set_attr "mode" "SI")])
11234
11235 (define_expand "lshrhi3"
11236   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11237         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11238                      (match_operand:QI 2 "nonmemory_operand" "")))]
11239   "TARGET_HIMODE_MATH"
11240   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
11241
11242 (define_insn "*lshrhi3_1_one_bit"
11243   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11244         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11245                      (match_operand:QI 2 "const1_operand" "")))
11246    (clobber (reg:CC FLAGS_REG))]
11247   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11248    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11249   "shr{w}\t%0"
11250   [(set_attr "type" "ishift")
11251    (set_attr "length_immediate" "0")
11252    (set_attr "mode" "HI")])
11253
11254 (define_insn "*lshrhi3_1"
11255   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11256         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11257                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11258    (clobber (reg:CC FLAGS_REG))]
11259   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11260   "@
11261    shr{w}\t{%2, %0|%0, %2}
11262    shr{w}\t{%b2, %0|%0, %b2}"
11263   [(set_attr "type" "ishift")
11264    (set_attr "mode" "HI")])
11265
11266 ;; This pattern can't accept a variable shift count, since shifts by
11267 ;; zero don't affect the flags.  We assume that shifts by constant
11268 ;; zero are optimized away.
11269 (define_insn "*lshrhi3_one_bit_cmp"
11270   [(set (reg FLAGS_REG)
11271         (compare
11272           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11273                        (match_operand:QI 2 "const1_operand" ""))
11274           (const_int 0)))
11275    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11276         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11277   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11278    && ix86_match_ccmode (insn, CCGOCmode)
11279    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11280   "shr{w}\t%0"
11281   [(set_attr "type" "ishift")
11282    (set_attr "length_immediate" "0")
11283    (set_attr "mode" "HI")])
11284
11285 (define_insn "*lshrhi3_one_bit_cconly"
11286   [(set (reg FLAGS_REG)
11287         (compare
11288           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11289                        (match_operand:QI 2 "const1_operand" ""))
11290           (const_int 0)))
11291    (clobber (match_scratch:HI 0 "=r"))]
11292   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11293    && ix86_match_ccmode (insn, CCGOCmode)
11294    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11295   "shr{w}\t%0"
11296   [(set_attr "type" "ishift")
11297    (set_attr "length_immediate" "0")
11298    (set_attr "mode" "HI")])
11299
11300 ;; This pattern can't accept a variable shift count, since shifts by
11301 ;; zero don't affect the flags.  We assume that shifts by constant
11302 ;; zero are optimized away.
11303 (define_insn "*lshrhi3_cmp"
11304   [(set (reg FLAGS_REG)
11305         (compare
11306           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11307                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11308           (const_int 0)))
11309    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11310         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11311   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11312    && ix86_match_ccmode (insn, CCGOCmode)
11313    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11314   "shr{w}\t{%2, %0|%0, %2}"
11315   [(set_attr "type" "ishift")
11316    (set_attr "mode" "HI")])
11317
11318 (define_insn "*lshrhi3_cconly"
11319   [(set (reg FLAGS_REG)
11320         (compare
11321           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11322                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11323           (const_int 0)))
11324    (clobber (match_scratch:HI 0 "=r"))]
11325   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11326    && ix86_match_ccmode (insn, CCGOCmode)
11327    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11328   "shr{w}\t{%2, %0|%0, %2}"
11329   [(set_attr "type" "ishift")
11330    (set_attr "mode" "HI")])
11331
11332 (define_expand "lshrqi3"
11333   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11334         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11335                      (match_operand:QI 2 "nonmemory_operand" "")))]
11336   "TARGET_QIMODE_MATH"
11337   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
11338
11339 (define_insn "*lshrqi3_1_one_bit"
11340   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11341         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11342                      (match_operand:QI 2 "const1_operand" "")))
11343    (clobber (reg:CC FLAGS_REG))]
11344   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11345    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11346   "shr{b}\t%0"
11347   [(set_attr "type" "ishift")
11348    (set_attr "length_immediate" "0")
11349    (set_attr "mode" "QI")])
11350
11351 (define_insn "*lshrqi3_1_one_bit_slp"
11352   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11353         (lshiftrt:QI (match_dup 0)
11354                      (match_operand:QI 1 "const1_operand" "")))
11355    (clobber (reg:CC FLAGS_REG))]
11356   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11357    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
11358   "shr{b}\t%0"
11359   [(set_attr "type" "ishift1")
11360    (set_attr "length_immediate" "0")
11361    (set_attr "mode" "QI")])
11362
11363 (define_insn "*lshrqi3_1"
11364   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11365         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11366                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11367    (clobber (reg:CC FLAGS_REG))]
11368   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11369   "@
11370    shr{b}\t{%2, %0|%0, %2}
11371    shr{b}\t{%b2, %0|%0, %b2}"
11372   [(set_attr "type" "ishift")
11373    (set_attr "mode" "QI")])
11374
11375 (define_insn "*lshrqi3_1_slp"
11376   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11377         (lshiftrt:QI (match_dup 0)
11378                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11379    (clobber (reg:CC FLAGS_REG))]
11380   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11381    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
11382   "@
11383    shr{b}\t{%1, %0|%0, %1}
11384    shr{b}\t{%b1, %0|%0, %b1}"
11385   [(set_attr "type" "ishift1")
11386    (set_attr "mode" "QI")])
11387
11388 ;; This pattern can't accept a variable shift count, since shifts by
11389 ;; zero don't affect the flags.  We assume that shifts by constant
11390 ;; zero are optimized away.
11391 (define_insn "*lshrqi2_one_bit_cmp"
11392   [(set (reg FLAGS_REG)
11393         (compare
11394           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11395                        (match_operand:QI 2 "const1_operand" ""))
11396           (const_int 0)))
11397    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11398         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11399   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11400    && ix86_match_ccmode (insn, CCGOCmode)
11401    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11402   "shr{b}\t%0"
11403   [(set_attr "type" "ishift")
11404    (set_attr "length_immediate" "0")
11405    (set_attr "mode" "QI")])
11406
11407 (define_insn "*lshrqi2_one_bit_cconly"
11408   [(set (reg FLAGS_REG)
11409         (compare
11410           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11411                        (match_operand:QI 2 "const1_operand" ""))
11412           (const_int 0)))
11413    (clobber (match_scratch:QI 0 "=q"))]
11414   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11415    && ix86_match_ccmode (insn, CCGOCmode)
11416    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11417   "shr{b}\t%0"
11418   [(set_attr "type" "ishift")
11419    (set_attr "length_immediate" "0")
11420    (set_attr "mode" "QI")])
11421
11422 ;; This pattern can't accept a variable shift count, since shifts by
11423 ;; zero don't affect the flags.  We assume that shifts by constant
11424 ;; zero are optimized away.
11425 (define_insn "*lshrqi2_cmp"
11426   [(set (reg FLAGS_REG)
11427         (compare
11428           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11429                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11430           (const_int 0)))
11431    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11432         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11433   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11434    && ix86_match_ccmode (insn, CCGOCmode)
11435    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11436   "shr{b}\t{%2, %0|%0, %2}"
11437   [(set_attr "type" "ishift")
11438    (set_attr "mode" "QI")])
11439
11440 (define_insn "*lshrqi2_cconly"
11441   [(set (reg FLAGS_REG)
11442         (compare
11443           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11444                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11445           (const_int 0)))
11446    (clobber (match_scratch:QI 0 "=q"))]
11447   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11448    && ix86_match_ccmode (insn, CCGOCmode)
11449    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11450   "shr{b}\t{%2, %0|%0, %2}"
11451   [(set_attr "type" "ishift")
11452    (set_attr "mode" "QI")])
11453 \f
11454 ;; Rotate instructions
11455
11456 (define_expand "rotldi3"
11457   [(set (match_operand:DI 0 "shiftdi_operand" "")
11458         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
11459                    (match_operand:QI 2 "nonmemory_operand" "")))]
11460  ""
11461 {
11462   if (TARGET_64BIT)
11463     {
11464       ix86_expand_binary_operator (ROTATE, DImode, operands);
11465       DONE;
11466     }
11467   if (!const_1_to_31_operand (operands[2], VOIDmode))
11468     FAIL;
11469   emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
11470   DONE;
11471 })
11472
11473 ;; Implement rotation using two double-precision shift instructions
11474 ;; and a scratch register.
11475 (define_insn_and_split "ix86_rotldi3"
11476  [(set (match_operand:DI 0 "register_operand" "=r")
11477        (rotate:DI (match_operand:DI 1 "register_operand" "0")
11478                   (match_operand:QI 2 "const_1_to_31_operand" "I")))
11479   (clobber (reg:CC FLAGS_REG))
11480   (clobber (match_scratch:SI 3 "=&r"))]
11481  "!TARGET_64BIT"
11482  ""
11483  "&& reload_completed"
11484  [(set (match_dup 3) (match_dup 4))
11485   (parallel
11486    [(set (match_dup 4)
11487          (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
11488                  (lshiftrt:SI (match_dup 5)
11489                               (minus:QI (const_int 32) (match_dup 2)))))
11490     (clobber (reg:CC FLAGS_REG))])
11491   (parallel
11492    [(set (match_dup 5)
11493          (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
11494                  (lshiftrt:SI (match_dup 3)
11495                               (minus:QI (const_int 32) (match_dup 2)))))
11496     (clobber (reg:CC FLAGS_REG))])]
11497  "split_di (&operands[0], 1, &operands[4], &operands[5]);")
11498
11499 (define_insn "*rotlsi3_1_one_bit_rex64"
11500   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11501         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11502                    (match_operand:QI 2 "const1_operand" "")))
11503    (clobber (reg:CC FLAGS_REG))]
11504   "TARGET_64BIT
11505    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11506    && ix86_binary_operator_ok (ROTATE, DImode, operands)"
11507   "rol{q}\t%0"
11508   [(set_attr "type" "rotate")
11509    (set_attr "length_immediate" "0")
11510    (set_attr "mode" "DI")])
11511
11512 (define_insn "*rotldi3_1_rex64"
11513   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11514         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11515                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
11516    (clobber (reg:CC FLAGS_REG))]
11517   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
11518   "@
11519    rol{q}\t{%2, %0|%0, %2}
11520    rol{q}\t{%b2, %0|%0, %b2}"
11521   [(set_attr "type" "rotate")
11522    (set_attr "mode" "DI")])
11523
11524 (define_expand "rotlsi3"
11525   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11526         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
11527                    (match_operand:QI 2 "nonmemory_operand" "")))]
11528   ""
11529   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
11530
11531 (define_insn "*rotlsi3_1_one_bit"
11532   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11533         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11534                    (match_operand:QI 2 "const1_operand" "")))
11535    (clobber (reg:CC FLAGS_REG))]
11536   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11537    && ix86_binary_operator_ok (ROTATE, SImode, operands)"
11538   "rol{l}\t%0"
11539   [(set_attr "type" "rotate")
11540    (set_attr "length_immediate" "0")
11541    (set_attr "mode" "SI")])
11542
11543 (define_insn "*rotlsi3_1_one_bit_zext"
11544   [(set (match_operand:DI 0 "register_operand" "=r")
11545         (zero_extend:DI
11546           (rotate:SI (match_operand:SI 1 "register_operand" "0")
11547                      (match_operand:QI 2 "const1_operand" ""))))
11548    (clobber (reg:CC FLAGS_REG))]
11549   "TARGET_64BIT
11550    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11551    && ix86_binary_operator_ok (ROTATE, SImode, operands)"
11552   "rol{l}\t%k0"
11553   [(set_attr "type" "rotate")
11554    (set_attr "length_immediate" "0")
11555    (set_attr "mode" "SI")])
11556
11557 (define_insn "*rotlsi3_1"
11558   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11559         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11560                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
11561    (clobber (reg:CC FLAGS_REG))]
11562   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
11563   "@
11564    rol{l}\t{%2, %0|%0, %2}
11565    rol{l}\t{%b2, %0|%0, %b2}"
11566   [(set_attr "type" "rotate")
11567    (set_attr "mode" "SI")])
11568
11569 (define_insn "*rotlsi3_1_zext"
11570   [(set (match_operand:DI 0 "register_operand" "=r,r")
11571         (zero_extend:DI
11572           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
11573                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11574    (clobber (reg:CC FLAGS_REG))]
11575   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
11576   "@
11577    rol{l}\t{%2, %k0|%k0, %2}
11578    rol{l}\t{%b2, %k0|%k0, %b2}"
11579   [(set_attr "type" "rotate")
11580    (set_attr "mode" "SI")])
11581
11582 (define_expand "rotlhi3"
11583   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11584         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
11585                    (match_operand:QI 2 "nonmemory_operand" "")))]
11586   "TARGET_HIMODE_MATH"
11587   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
11588
11589 (define_insn "*rotlhi3_1_one_bit"
11590   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11591         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11592                    (match_operand:QI 2 "const1_operand" "")))
11593    (clobber (reg:CC FLAGS_REG))]
11594   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11595    && ix86_binary_operator_ok (ROTATE, HImode, operands)"
11596   "rol{w}\t%0"
11597   [(set_attr "type" "rotate")
11598    (set_attr "length_immediate" "0")
11599    (set_attr "mode" "HI")])
11600
11601 (define_insn "*rotlhi3_1"
11602   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11603         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11604                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
11605    (clobber (reg:CC FLAGS_REG))]
11606   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
11607   "@
11608    rol{w}\t{%2, %0|%0, %2}
11609    rol{w}\t{%b2, %0|%0, %b2}"
11610   [(set_attr "type" "rotate")
11611    (set_attr "mode" "HI")])
11612
11613 (define_split
11614  [(set (match_operand:HI 0 "register_operand" "")
11615        (rotate:HI (match_dup 0) (const_int 8)))
11616   (clobber (reg:CC FLAGS_REG))]
11617  "reload_completed"
11618  [(parallel [(set (strict_low_part (match_dup 0))
11619                   (bswap:HI (match_dup 0)))
11620              (clobber (reg:CC FLAGS_REG))])]
11621  "")
11622
11623 (define_expand "rotlqi3"
11624   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11625         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
11626                    (match_operand:QI 2 "nonmemory_operand" "")))]
11627   "TARGET_QIMODE_MATH"
11628   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
11629
11630 (define_insn "*rotlqi3_1_one_bit_slp"
11631   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11632         (rotate:QI (match_dup 0)
11633                    (match_operand:QI 1 "const1_operand" "")))
11634    (clobber (reg:CC FLAGS_REG))]
11635   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11636    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
11637   "rol{b}\t%0"
11638   [(set_attr "type" "rotate1")
11639    (set_attr "length_immediate" "0")
11640    (set_attr "mode" "QI")])
11641
11642 (define_insn "*rotlqi3_1_one_bit"
11643   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11644         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11645                    (match_operand:QI 2 "const1_operand" "")))
11646    (clobber (reg:CC FLAGS_REG))]
11647   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11648    && ix86_binary_operator_ok (ROTATE, QImode, operands)"
11649   "rol{b}\t%0"
11650   [(set_attr "type" "rotate")
11651    (set_attr "length_immediate" "0")
11652    (set_attr "mode" "QI")])
11653
11654 (define_insn "*rotlqi3_1_slp"
11655   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11656         (rotate:QI (match_dup 0)
11657                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
11658    (clobber (reg:CC FLAGS_REG))]
11659   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11660    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
11661   "@
11662    rol{b}\t{%1, %0|%0, %1}
11663    rol{b}\t{%b1, %0|%0, %b1}"
11664   [(set_attr "type" "rotate1")
11665    (set_attr "mode" "QI")])
11666
11667 (define_insn "*rotlqi3_1"
11668   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11669         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11670                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
11671    (clobber (reg:CC FLAGS_REG))]
11672   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
11673   "@
11674    rol{b}\t{%2, %0|%0, %2}
11675    rol{b}\t{%b2, %0|%0, %b2}"
11676   [(set_attr "type" "rotate")
11677    (set_attr "mode" "QI")])
11678
11679 (define_expand "rotrdi3"
11680   [(set (match_operand:DI 0 "shiftdi_operand" "")
11681         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
11682                    (match_operand:QI 2 "nonmemory_operand" "")))]
11683  ""
11684 {
11685   if (TARGET_64BIT)
11686     {
11687       ix86_expand_binary_operator (ROTATERT, DImode, operands);
11688       DONE;
11689     }
11690   if (!const_1_to_31_operand (operands[2], VOIDmode))
11691     FAIL;
11692   emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
11693   DONE;
11694 })
11695
11696 ;; Implement rotation using two double-precision shift instructions
11697 ;; and a scratch register.
11698 (define_insn_and_split "ix86_rotrdi3"
11699  [(set (match_operand:DI 0 "register_operand" "=r")
11700        (rotatert:DI (match_operand:DI 1 "register_operand" "0")
11701                     (match_operand:QI 2 "const_1_to_31_operand" "I")))
11702   (clobber (reg:CC FLAGS_REG))
11703   (clobber (match_scratch:SI 3 "=&r"))]
11704  "!TARGET_64BIT"
11705  ""
11706  "&& reload_completed"
11707  [(set (match_dup 3) (match_dup 4))
11708   (parallel
11709    [(set (match_dup 4)
11710          (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
11711                  (ashift:SI (match_dup 5)
11712                             (minus:QI (const_int 32) (match_dup 2)))))
11713     (clobber (reg:CC FLAGS_REG))])
11714   (parallel
11715    [(set (match_dup 5)
11716          (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
11717                  (ashift:SI (match_dup 3)
11718                             (minus:QI (const_int 32) (match_dup 2)))))
11719     (clobber (reg:CC FLAGS_REG))])]
11720  "split_di (&operands[0], 1, &operands[4], &operands[5]);")
11721
11722 (define_insn "*rotrdi3_1_one_bit_rex64"
11723   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11724         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11725                      (match_operand:QI 2 "const1_operand" "")))
11726    (clobber (reg:CC FLAGS_REG))]
11727   "TARGET_64BIT
11728    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11729    && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
11730   "ror{q}\t%0"
11731   [(set_attr "type" "rotate")
11732    (set_attr "length_immediate" "0")
11733    (set_attr "mode" "DI")])
11734
11735 (define_insn "*rotrdi3_1_rex64"
11736   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11737         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11738                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11739    (clobber (reg:CC FLAGS_REG))]
11740   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
11741   "@
11742    ror{q}\t{%2, %0|%0, %2}
11743    ror{q}\t{%b2, %0|%0, %b2}"
11744   [(set_attr "type" "rotate")
11745    (set_attr "mode" "DI")])
11746
11747 (define_expand "rotrsi3"
11748   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11749         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
11750                      (match_operand:QI 2 "nonmemory_operand" "")))]
11751   ""
11752   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
11753
11754 (define_insn "*rotrsi3_1_one_bit"
11755   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11756         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11757                      (match_operand:QI 2 "const1_operand" "")))
11758    (clobber (reg:CC FLAGS_REG))]
11759   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11760    && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
11761   "ror{l}\t%0"
11762   [(set_attr "type" "rotate")
11763    (set_attr "length_immediate" "0")
11764    (set_attr "mode" "SI")])
11765
11766 (define_insn "*rotrsi3_1_one_bit_zext"
11767   [(set (match_operand:DI 0 "register_operand" "=r")
11768         (zero_extend:DI
11769           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
11770                        (match_operand:QI 2 "const1_operand" ""))))
11771    (clobber (reg:CC FLAGS_REG))]
11772   "TARGET_64BIT
11773    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11774    && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
11775   "ror{l}\t%k0"
11776   [(set_attr "type" "rotate")
11777    (set_attr "length_immediate" "0")
11778    (set_attr "mode" "SI")])
11779
11780 (define_insn "*rotrsi3_1"
11781   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11782         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11783                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11784    (clobber (reg:CC FLAGS_REG))]
11785   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
11786   "@
11787    ror{l}\t{%2, %0|%0, %2}
11788    ror{l}\t{%b2, %0|%0, %b2}"
11789   [(set_attr "type" "rotate")
11790    (set_attr "mode" "SI")])
11791
11792 (define_insn "*rotrsi3_1_zext"
11793   [(set (match_operand:DI 0 "register_operand" "=r,r")
11794         (zero_extend:DI
11795           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
11796                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11797    (clobber (reg:CC FLAGS_REG))]
11798   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
11799   "@
11800    ror{l}\t{%2, %k0|%k0, %2}
11801    ror{l}\t{%b2, %k0|%k0, %b2}"
11802   [(set_attr "type" "rotate")
11803    (set_attr "mode" "SI")])
11804
11805 (define_expand "rotrhi3"
11806   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11807         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
11808                      (match_operand:QI 2 "nonmemory_operand" "")))]
11809   "TARGET_HIMODE_MATH"
11810   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
11811
11812 (define_insn "*rotrhi3_one_bit"
11813   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11814         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11815                      (match_operand:QI 2 "const1_operand" "")))
11816    (clobber (reg:CC FLAGS_REG))]
11817   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11818    && ix86_binary_operator_ok (ROTATERT, HImode, operands)"
11819   "ror{w}\t%0"
11820   [(set_attr "type" "rotate")
11821    (set_attr "length_immediate" "0")
11822    (set_attr "mode" "HI")])
11823
11824 (define_insn "*rotrhi3_1"
11825   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11826         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11827                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11828    (clobber (reg:CC FLAGS_REG))]
11829   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
11830   "@
11831    ror{w}\t{%2, %0|%0, %2}
11832    ror{w}\t{%b2, %0|%0, %b2}"
11833   [(set_attr "type" "rotate")
11834    (set_attr "mode" "HI")])
11835
11836 (define_split
11837  [(set (match_operand:HI 0 "register_operand" "")
11838        (rotatert:HI (match_dup 0) (const_int 8)))
11839   (clobber (reg:CC FLAGS_REG))]
11840  "reload_completed"
11841  [(parallel [(set (strict_low_part (match_dup 0))
11842                   (bswap:HI (match_dup 0)))
11843              (clobber (reg:CC FLAGS_REG))])]
11844  "")
11845
11846 (define_expand "rotrqi3"
11847   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11848         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
11849                      (match_operand:QI 2 "nonmemory_operand" "")))]
11850   "TARGET_QIMODE_MATH"
11851   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
11852
11853 (define_insn "*rotrqi3_1_one_bit"
11854   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11855         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11856                      (match_operand:QI 2 "const1_operand" "")))
11857    (clobber (reg:CC FLAGS_REG))]
11858   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11859    && ix86_binary_operator_ok (ROTATERT, QImode, operands)"
11860   "ror{b}\t%0"
11861   [(set_attr "type" "rotate")
11862    (set_attr "length_immediate" "0")
11863    (set_attr "mode" "QI")])
11864
11865 (define_insn "*rotrqi3_1_one_bit_slp"
11866   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11867         (rotatert:QI (match_dup 0)
11868                      (match_operand:QI 1 "const1_operand" "")))
11869    (clobber (reg:CC FLAGS_REG))]
11870   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11871    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
11872   "ror{b}\t%0"
11873   [(set_attr "type" "rotate1")
11874    (set_attr "length_immediate" "0")
11875    (set_attr "mode" "QI")])
11876
11877 (define_insn "*rotrqi3_1"
11878   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11879         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11880                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11881    (clobber (reg:CC FLAGS_REG))]
11882   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
11883   "@
11884    ror{b}\t{%2, %0|%0, %2}
11885    ror{b}\t{%b2, %0|%0, %b2}"
11886   [(set_attr "type" "rotate")
11887    (set_attr "mode" "QI")])
11888
11889 (define_insn "*rotrqi3_1_slp"
11890   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11891         (rotatert:QI (match_dup 0)
11892                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11893    (clobber (reg:CC FLAGS_REG))]
11894   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11895    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
11896   "@
11897    ror{b}\t{%1, %0|%0, %1}
11898    ror{b}\t{%b1, %0|%0, %b1}"
11899   [(set_attr "type" "rotate1")
11900    (set_attr "mode" "QI")])
11901 \f
11902 ;; Bit set / bit test instructions
11903
11904 (define_expand "extv"
11905   [(set (match_operand:SI 0 "register_operand" "")
11906         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
11907                          (match_operand:SI 2 "const8_operand" "")
11908                          (match_operand:SI 3 "const8_operand" "")))]
11909   ""
11910 {
11911   /* Handle extractions from %ah et al.  */
11912   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
11913     FAIL;
11914
11915   /* From mips.md: extract_bit_field doesn't verify that our source
11916      matches the predicate, so check it again here.  */
11917   if (! ext_register_operand (operands[1], VOIDmode))
11918     FAIL;
11919 })
11920
11921 (define_expand "extzv"
11922   [(set (match_operand:SI 0 "register_operand" "")
11923         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
11924                          (match_operand:SI 2 "const8_operand" "")
11925                          (match_operand:SI 3 "const8_operand" "")))]
11926   ""
11927 {
11928   /* Handle extractions from %ah et al.  */
11929   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
11930     FAIL;
11931
11932   /* From mips.md: extract_bit_field doesn't verify that our source
11933      matches the predicate, so check it again here.  */
11934   if (! ext_register_operand (operands[1], VOIDmode))
11935     FAIL;
11936 })
11937
11938 (define_expand "insv"
11939   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
11940                       (match_operand 1 "const8_operand" "")
11941                       (match_operand 2 "const8_operand" ""))
11942         (match_operand 3 "register_operand" ""))]
11943   ""
11944 {
11945   /* Handle insertions to %ah et al.  */
11946   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
11947     FAIL;
11948
11949   /* From mips.md: insert_bit_field doesn't verify that our source
11950      matches the predicate, so check it again here.  */
11951   if (! ext_register_operand (operands[0], VOIDmode))
11952     FAIL;
11953
11954   if (TARGET_64BIT)
11955     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
11956   else
11957     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
11958
11959   DONE;
11960 })
11961
11962 ;; %%% bts, btr, btc, bt.
11963 ;; In general these instructions are *slow* when applied to memory,
11964 ;; since they enforce atomic operation.  When applied to registers,
11965 ;; it depends on the cpu implementation.  They're never faster than
11966 ;; the corresponding and/ior/xor operations, so with 32-bit there's
11967 ;; no point.  But in 64-bit, we can't hold the relevant immediates
11968 ;; within the instruction itself, so operating on bits in the high
11969 ;; 32-bits of a register becomes easier.
11970 ;;
11971 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
11972 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
11973 ;; negdf respectively, so they can never be disabled entirely.
11974
11975 (define_insn "*btsq"
11976   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
11977                          (const_int 1)
11978                          (match_operand:DI 1 "const_0_to_63_operand" ""))
11979         (const_int 1))
11980    (clobber (reg:CC FLAGS_REG))]
11981   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
11982   "bts{q}\t{%1, %0|%0, %1}"
11983   [(set_attr "type" "alu1")
11984    (set_attr "prefix_0f" "1")
11985    (set_attr "mode" "DI")])
11986
11987 (define_insn "*btrq"
11988   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
11989                          (const_int 1)
11990                          (match_operand:DI 1 "const_0_to_63_operand" ""))
11991         (const_int 0))
11992    (clobber (reg:CC FLAGS_REG))]
11993   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
11994   "btr{q}\t{%1, %0|%0, %1}"
11995   [(set_attr "type" "alu1")
11996    (set_attr "prefix_0f" "1")
11997    (set_attr "mode" "DI")])
11998
11999 (define_insn "*btcq"
12000   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12001                          (const_int 1)
12002                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12003         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
12004    (clobber (reg:CC FLAGS_REG))]
12005   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12006   "btc{q}\t{%1, %0|%0, %1}"
12007   [(set_attr "type" "alu1")
12008    (set_attr "prefix_0f" "1")
12009    (set_attr "mode" "DI")])
12010
12011 ;; Allow Nocona to avoid these instructions if a register is available.
12012
12013 (define_peephole2
12014   [(match_scratch:DI 2 "r")
12015    (parallel [(set (zero_extract:DI
12016                      (match_operand:DI 0 "register_operand" "")
12017                      (const_int 1)
12018                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12019                    (const_int 1))
12020               (clobber (reg:CC FLAGS_REG))])]
12021   "TARGET_64BIT && !TARGET_USE_BT"
12022   [(const_int 0)]
12023 {
12024   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12025   rtx op1;
12026
12027   if (HOST_BITS_PER_WIDE_INT >= 64)
12028     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12029   else if (i < HOST_BITS_PER_WIDE_INT)
12030     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12031   else
12032     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12033
12034   op1 = immed_double_const (lo, hi, DImode);
12035   if (i >= 31)
12036     {
12037       emit_move_insn (operands[2], op1);
12038       op1 = operands[2];
12039     }
12040
12041   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
12042   DONE;
12043 })
12044
12045 (define_peephole2
12046   [(match_scratch:DI 2 "r")
12047    (parallel [(set (zero_extract:DI
12048                      (match_operand:DI 0 "register_operand" "")
12049                      (const_int 1)
12050                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12051                    (const_int 0))
12052               (clobber (reg:CC FLAGS_REG))])]
12053   "TARGET_64BIT && !TARGET_USE_BT"
12054   [(const_int 0)]
12055 {
12056   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12057   rtx op1;
12058
12059   if (HOST_BITS_PER_WIDE_INT >= 64)
12060     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12061   else if (i < HOST_BITS_PER_WIDE_INT)
12062     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12063   else
12064     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12065
12066   op1 = immed_double_const (~lo, ~hi, DImode);
12067   if (i >= 32)
12068     {
12069       emit_move_insn (operands[2], op1);
12070       op1 = operands[2];
12071     }
12072
12073   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
12074   DONE;
12075 })
12076
12077 (define_peephole2
12078   [(match_scratch:DI 2 "r")
12079    (parallel [(set (zero_extract:DI
12080                      (match_operand:DI 0 "register_operand" "")
12081                      (const_int 1)
12082                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12083               (not:DI (zero_extract:DI
12084                         (match_dup 0) (const_int 1) (match_dup 1))))
12085               (clobber (reg:CC FLAGS_REG))])]
12086   "TARGET_64BIT && !TARGET_USE_BT"
12087   [(const_int 0)]
12088 {
12089   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12090   rtx op1;
12091
12092   if (HOST_BITS_PER_WIDE_INT >= 64)
12093     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12094   else if (i < HOST_BITS_PER_WIDE_INT)
12095     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12096   else
12097     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12098
12099   op1 = immed_double_const (lo, hi, DImode);
12100   if (i >= 31)
12101     {
12102       emit_move_insn (operands[2], op1);
12103       op1 = operands[2];
12104     }
12105
12106   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
12107   DONE;
12108 })
12109
12110 (define_insn "*btdi_rex64"
12111   [(set (reg:CCC FLAGS_REG)
12112         (compare:CCC
12113           (zero_extract:DI
12114             (match_operand:DI 0 "register_operand" "r")
12115             (const_int 1)
12116             (match_operand:DI 1 "nonmemory_operand" "rN"))
12117           (const_int 0)))]
12118   "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
12119   "bt{q}\t{%1, %0|%0, %1}"
12120   [(set_attr "type" "alu1")
12121    (set_attr "prefix_0f" "1")
12122    (set_attr "mode" "DI")])
12123
12124 (define_insn "*btsi"
12125   [(set (reg:CCC FLAGS_REG)
12126         (compare:CCC
12127           (zero_extract:SI
12128             (match_operand:SI 0 "register_operand" "r")
12129             (const_int 1)
12130             (match_operand:SI 1 "nonmemory_operand" "rN"))
12131           (const_int 0)))]
12132   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
12133   "bt{l}\t{%1, %0|%0, %1}"
12134   [(set_attr "type" "alu1")
12135    (set_attr "prefix_0f" "1")
12136    (set_attr "mode" "SI")])
12137 \f
12138 ;; Store-flag instructions.
12139
12140 ;; For all sCOND expanders, also expand the compare or test insn that
12141 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
12142
12143 (define_insn_and_split "*setcc_di_1"
12144   [(set (match_operand:DI 0 "register_operand" "=q")
12145         (match_operator:DI 1 "ix86_comparison_operator"
12146           [(reg FLAGS_REG) (const_int 0)]))]
12147   "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
12148   "#"
12149   "&& reload_completed"
12150   [(set (match_dup 2) (match_dup 1))
12151    (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
12152 {
12153   PUT_MODE (operands[1], QImode);
12154   operands[2] = gen_lowpart (QImode, operands[0]);
12155 })
12156
12157 (define_insn_and_split "*setcc_si_1_and"
12158   [(set (match_operand:SI 0 "register_operand" "=q")
12159         (match_operator:SI 1 "ix86_comparison_operator"
12160           [(reg FLAGS_REG) (const_int 0)]))
12161    (clobber (reg:CC FLAGS_REG))]
12162   "!TARGET_PARTIAL_REG_STALL
12163    && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
12164   "#"
12165   "&& reload_completed"
12166   [(set (match_dup 2) (match_dup 1))
12167    (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
12168               (clobber (reg:CC FLAGS_REG))])]
12169 {
12170   PUT_MODE (operands[1], QImode);
12171   operands[2] = gen_lowpart (QImode, operands[0]);
12172 })
12173
12174 (define_insn_and_split "*setcc_si_1_movzbl"
12175   [(set (match_operand:SI 0 "register_operand" "=q")
12176         (match_operator:SI 1 "ix86_comparison_operator"
12177           [(reg FLAGS_REG) (const_int 0)]))]
12178   "!TARGET_PARTIAL_REG_STALL
12179    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
12180   "#"
12181   "&& reload_completed"
12182   [(set (match_dup 2) (match_dup 1))
12183    (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
12184 {
12185   PUT_MODE (operands[1], QImode);
12186   operands[2] = gen_lowpart (QImode, operands[0]);
12187 })
12188
12189 (define_insn "*setcc_qi"
12190   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12191         (match_operator:QI 1 "ix86_comparison_operator"
12192           [(reg FLAGS_REG) (const_int 0)]))]
12193   ""
12194   "set%C1\t%0"
12195   [(set_attr "type" "setcc")
12196    (set_attr "mode" "QI")])
12197
12198 (define_insn "*setcc_qi_slp"
12199   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12200         (match_operator:QI 1 "ix86_comparison_operator"
12201           [(reg FLAGS_REG) (const_int 0)]))]
12202   ""
12203   "set%C1\t%0"
12204   [(set_attr "type" "setcc")
12205    (set_attr "mode" "QI")])
12206
12207 ;; In general it is not safe to assume too much about CCmode registers,
12208 ;; so simplify-rtx stops when it sees a second one.  Under certain
12209 ;; conditions this is safe on x86, so help combine not create
12210 ;;
12211 ;;      seta    %al
12212 ;;      testb   %al, %al
12213 ;;      sete    %al
12214
12215 (define_split
12216   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12217         (ne:QI (match_operator 1 "ix86_comparison_operator"
12218                  [(reg FLAGS_REG) (const_int 0)])
12219             (const_int 0)))]
12220   ""
12221   [(set (match_dup 0) (match_dup 1))]
12222 {
12223   PUT_MODE (operands[1], QImode);
12224 })
12225
12226 (define_split
12227   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12228         (ne:QI (match_operator 1 "ix86_comparison_operator"
12229                  [(reg FLAGS_REG) (const_int 0)])
12230             (const_int 0)))]
12231   ""
12232   [(set (match_dup 0) (match_dup 1))]
12233 {
12234   PUT_MODE (operands[1], QImode);
12235 })
12236
12237 (define_split
12238   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12239         (eq:QI (match_operator 1 "ix86_comparison_operator"
12240                  [(reg FLAGS_REG) (const_int 0)])
12241             (const_int 0)))]
12242   ""
12243   [(set (match_dup 0) (match_dup 1))]
12244 {
12245   rtx new_op1 = copy_rtx (operands[1]);
12246   operands[1] = new_op1;
12247   PUT_MODE (new_op1, QImode);
12248   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12249                                              GET_MODE (XEXP (new_op1, 0))));
12250
12251   /* Make sure that (a) the CCmode we have for the flags is strong
12252      enough for the reversed compare or (b) we have a valid FP compare.  */
12253   if (! ix86_comparison_operator (new_op1, VOIDmode))
12254     FAIL;
12255 })
12256
12257 (define_split
12258   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12259         (eq:QI (match_operator 1 "ix86_comparison_operator"
12260                  [(reg FLAGS_REG) (const_int 0)])
12261             (const_int 0)))]
12262   ""
12263   [(set (match_dup 0) (match_dup 1))]
12264 {
12265   rtx new_op1 = copy_rtx (operands[1]);
12266   operands[1] = new_op1;
12267   PUT_MODE (new_op1, QImode);
12268   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12269                                              GET_MODE (XEXP (new_op1, 0))));
12270
12271   /* Make sure that (a) the CCmode we have for the flags is strong
12272      enough for the reversed compare or (b) we have a valid FP compare.  */
12273   if (! ix86_comparison_operator (new_op1, VOIDmode))
12274     FAIL;
12275 })
12276
12277 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12278 ;; subsequent logical operations are used to imitate conditional moves.
12279 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12280 ;; it directly.
12281
12282 (define_insn "*avx_setcc<mode>"
12283   [(set (match_operand:MODEF 0 "register_operand" "=x")
12284         (match_operator:MODEF 1 "avx_comparison_float_operator"
12285           [(match_operand:MODEF 2 "register_operand" "x")
12286            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
12287   "TARGET_AVX"
12288   "vcmp%D1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
12289   [(set_attr "type" "ssecmp")
12290    (set_attr "prefix" "vex")
12291    (set_attr "length_immediate" "1")
12292    (set_attr "mode" "<MODE>")])
12293
12294 (define_insn "*sse_setcc<mode>"
12295   [(set (match_operand:MODEF 0 "register_operand" "=x")
12296         (match_operator:MODEF 1 "sse_comparison_operator"
12297           [(match_operand:MODEF 2 "register_operand" "0")
12298            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
12299   "SSE_FLOAT_MODE_P (<MODE>mode)"
12300   "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
12301   [(set_attr "type" "ssecmp")
12302    (set_attr "length_immediate" "1")
12303    (set_attr "mode" "<MODE>")])
12304 \f
12305 ;; Basic conditional jump instructions.
12306 ;; We ignore the overflow flag for signed branch instructions.
12307
12308 (define_insn "*jcc_1"
12309   [(set (pc)
12310         (if_then_else (match_operator 1 "ix86_comparison_operator"
12311                                       [(reg FLAGS_REG) (const_int 0)])
12312                       (label_ref (match_operand 0 "" ""))
12313                       (pc)))]
12314   ""
12315   "%+j%C1\t%l0"
12316   [(set_attr "type" "ibr")
12317    (set_attr "modrm" "0")
12318    (set (attr "length")
12319            (if_then_else (and (ge (minus (match_dup 0) (pc))
12320                                   (const_int -126))
12321                               (lt (minus (match_dup 0) (pc))
12322                                   (const_int 128)))
12323              (const_int 2)
12324              (const_int 6)))])
12325
12326 (define_insn "*jcc_2"
12327   [(set (pc)
12328         (if_then_else (match_operator 1 "ix86_comparison_operator"
12329                                       [(reg FLAGS_REG) (const_int 0)])
12330                       (pc)
12331                       (label_ref (match_operand 0 "" ""))))]
12332   ""
12333   "%+j%c1\t%l0"
12334   [(set_attr "type" "ibr")
12335    (set_attr "modrm" "0")
12336    (set (attr "length")
12337            (if_then_else (and (ge (minus (match_dup 0) (pc))
12338                                   (const_int -126))
12339                               (lt (minus (match_dup 0) (pc))
12340                                   (const_int 128)))
12341              (const_int 2)
12342              (const_int 6)))])
12343
12344 ;; In general it is not safe to assume too much about CCmode registers,
12345 ;; so simplify-rtx stops when it sees a second one.  Under certain
12346 ;; conditions this is safe on x86, so help combine not create
12347 ;;
12348 ;;      seta    %al
12349 ;;      testb   %al, %al
12350 ;;      je      Lfoo
12351
12352 (define_split
12353   [(set (pc)
12354         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
12355                                       [(reg FLAGS_REG) (const_int 0)])
12356                           (const_int 0))
12357                       (label_ref (match_operand 1 "" ""))
12358                       (pc)))]
12359   ""
12360   [(set (pc)
12361         (if_then_else (match_dup 0)
12362                       (label_ref (match_dup 1))
12363                       (pc)))]
12364 {
12365   PUT_MODE (operands[0], VOIDmode);
12366 })
12367
12368 (define_split
12369   [(set (pc)
12370         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
12371                                       [(reg FLAGS_REG) (const_int 0)])
12372                           (const_int 0))
12373                       (label_ref (match_operand 1 "" ""))
12374                       (pc)))]
12375   ""
12376   [(set (pc)
12377         (if_then_else (match_dup 0)
12378                       (label_ref (match_dup 1))
12379                       (pc)))]
12380 {
12381   rtx new_op0 = copy_rtx (operands[0]);
12382   operands[0] = new_op0;
12383   PUT_MODE (new_op0, VOIDmode);
12384   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
12385                                              GET_MODE (XEXP (new_op0, 0))));
12386
12387   /* Make sure that (a) the CCmode we have for the flags is strong
12388      enough for the reversed compare or (b) we have a valid FP compare.  */
12389   if (! ix86_comparison_operator (new_op0, VOIDmode))
12390     FAIL;
12391 })
12392
12393 ;; zero_extend in SImode is correct, since this is what combine pass
12394 ;; generates from shift insn with QImode operand.  Actually, the mode of
12395 ;; operand 2 (bit offset operand) doesn't matter since bt insn takes
12396 ;; appropriate modulo of the bit offset value.
12397
12398 (define_insn_and_split "*jcc_btdi_rex64"
12399   [(set (pc)
12400         (if_then_else (match_operator 0 "bt_comparison_operator"
12401                         [(zero_extract:DI
12402                            (match_operand:DI 1 "register_operand" "r")
12403                            (const_int 1)
12404                            (zero_extend:SI
12405                              (match_operand:QI 2 "register_operand" "r")))
12406                          (const_int 0)])
12407                       (label_ref (match_operand 3 "" ""))
12408                       (pc)))
12409    (clobber (reg:CC FLAGS_REG))]
12410   "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
12411   "#"
12412   "&& 1"
12413   [(set (reg:CCC FLAGS_REG)
12414         (compare:CCC
12415           (zero_extract:DI
12416             (match_dup 1)
12417             (const_int 1)
12418             (match_dup 2))
12419           (const_int 0)))
12420    (set (pc)
12421         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
12422                       (label_ref (match_dup 3))
12423                       (pc)))]
12424 {
12425   operands[2] = simplify_gen_subreg (DImode, operands[2], QImode, 0);
12426
12427   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
12428 })
12429
12430 ;; avoid useless masking of bit offset operand
12431 (define_insn_and_split "*jcc_btdi_mask_rex64"
12432   [(set (pc)
12433         (if_then_else (match_operator 0 "bt_comparison_operator"
12434                         [(zero_extract:DI
12435                            (match_operand:DI 1 "register_operand" "r")
12436                            (const_int 1)
12437                            (and:SI
12438                              (match_operand:SI 2 "register_operand" "r")
12439                              (match_operand:SI 3 "const_int_operand" "n")))])
12440                       (label_ref (match_operand 4 "" ""))
12441                       (pc)))
12442    (clobber (reg:CC FLAGS_REG))]
12443   "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))
12444    && (INTVAL (operands[3]) & 0x3f) == 0x3f"
12445   "#"
12446   "&& 1"
12447   [(set (reg:CCC FLAGS_REG)
12448         (compare:CCC
12449           (zero_extract:DI
12450             (match_dup 1)
12451             (const_int 1)
12452             (match_dup 2))
12453           (const_int 0)))
12454    (set (pc)
12455         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
12456                       (label_ref (match_dup 4))
12457                       (pc)))]
12458 {
12459   operands[2] = simplify_gen_subreg (DImode, operands[2], SImode, 0);
12460
12461   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
12462 })
12463
12464 (define_insn_and_split "*jcc_btsi"
12465   [(set (pc)
12466         (if_then_else (match_operator 0 "bt_comparison_operator"
12467                         [(zero_extract:SI
12468                            (match_operand:SI 1 "register_operand" "r")
12469                            (const_int 1)
12470                            (zero_extend:SI
12471                              (match_operand:QI 2 "register_operand" "r")))
12472                          (const_int 0)])
12473                       (label_ref (match_operand 3 "" ""))
12474                       (pc)))
12475    (clobber (reg:CC FLAGS_REG))]
12476   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
12477   "#"
12478   "&& 1"
12479   [(set (reg:CCC FLAGS_REG)
12480         (compare:CCC
12481           (zero_extract:SI
12482             (match_dup 1)
12483             (const_int 1)
12484             (match_dup 2))
12485           (const_int 0)))
12486    (set (pc)
12487         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
12488                       (label_ref (match_dup 3))
12489                       (pc)))]
12490 {
12491   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
12492
12493   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
12494 })
12495
12496 ;; avoid useless masking of bit offset operand
12497 (define_insn_and_split "*jcc_btsi_mask"
12498   [(set (pc)
12499         (if_then_else (match_operator 0 "bt_comparison_operator"
12500                         [(zero_extract:SI
12501                            (match_operand:SI 1 "register_operand" "r")
12502                            (const_int 1)
12503                            (and:SI
12504                              (match_operand:SI 2 "register_operand" "r")
12505                              (match_operand:SI 3 "const_int_operand" "n")))])
12506                       (label_ref (match_operand 4 "" ""))
12507                       (pc)))
12508    (clobber (reg:CC FLAGS_REG))]
12509   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
12510    && (INTVAL (operands[3]) & 0x1f) == 0x1f"
12511   "#"
12512   "&& 1"
12513   [(set (reg:CCC FLAGS_REG)
12514         (compare:CCC
12515           (zero_extract:SI
12516             (match_dup 1)
12517             (const_int 1)
12518             (match_dup 2))
12519           (const_int 0)))
12520    (set (pc)
12521         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
12522                       (label_ref (match_dup 4))
12523                       (pc)))]
12524   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
12525
12526 (define_insn_and_split "*jcc_btsi_1"
12527   [(set (pc)
12528         (if_then_else (match_operator 0 "bt_comparison_operator"
12529                         [(and:SI
12530                            (lshiftrt:SI
12531                              (match_operand:SI 1 "register_operand" "r")
12532                              (match_operand:QI 2 "register_operand" "r"))
12533                            (const_int 1))
12534                          (const_int 0)])
12535                       (label_ref (match_operand 3 "" ""))
12536                       (pc)))
12537    (clobber (reg:CC FLAGS_REG))]
12538   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
12539   "#"
12540   "&& 1"
12541   [(set (reg:CCC FLAGS_REG)
12542         (compare:CCC
12543           (zero_extract:SI
12544             (match_dup 1)
12545             (const_int 1)
12546             (match_dup 2))
12547           (const_int 0)))
12548    (set (pc)
12549         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
12550                       (label_ref (match_dup 3))
12551                       (pc)))]
12552 {
12553   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
12554
12555   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
12556 })
12557
12558 ;; avoid useless masking of bit offset operand
12559 (define_insn_and_split "*jcc_btsi_mask_1"
12560   [(set (pc)
12561         (if_then_else
12562           (match_operator 0 "bt_comparison_operator"
12563             [(and:SI
12564                (lshiftrt:SI
12565                  (match_operand:SI 1 "register_operand" "r")
12566                  (subreg:QI
12567                    (and:SI
12568                      (match_operand:SI 2 "register_operand" "r")
12569                      (match_operand:SI 3 "const_int_operand" "n")) 0))
12570                (const_int 1))
12571              (const_int 0)])
12572           (label_ref (match_operand 4 "" ""))
12573           (pc)))
12574    (clobber (reg:CC FLAGS_REG))]
12575   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
12576    && (INTVAL (operands[3]) & 0x1f) == 0x1f"
12577   "#"
12578   "&& 1"
12579   [(set (reg:CCC FLAGS_REG)
12580         (compare:CCC
12581           (zero_extract:SI
12582             (match_dup 1)
12583             (const_int 1)
12584             (match_dup 2))
12585           (const_int 0)))
12586    (set (pc)
12587         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
12588                       (label_ref (match_dup 4))
12589                       (pc)))]
12590   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
12591
12592 ;; Define combination compare-and-branch fp compare instructions to help
12593 ;; combine.
12594
12595 (define_insn "*fp_jcc_3_387"
12596   [(set (pc)
12597         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
12598                         [(match_operand 1 "register_operand" "f")
12599                          (match_operand 2 "nonimmediate_operand" "fm")])
12600           (label_ref (match_operand 3 "" ""))
12601           (pc)))
12602    (clobber (reg:CCFP FPSR_REG))
12603    (clobber (reg:CCFP FLAGS_REG))
12604    (clobber (match_scratch:HI 4 "=a"))]
12605   "TARGET_80387
12606    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
12607    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12608    && SELECT_CC_MODE (GET_CODE (operands[0]),
12609                       operands[1], operands[2]) == CCFPmode
12610    && !TARGET_CMOVE"
12611   "#")
12612
12613 (define_insn "*fp_jcc_4_387"
12614   [(set (pc)
12615         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
12616                         [(match_operand 1 "register_operand" "f")
12617                          (match_operand 2 "nonimmediate_operand" "fm")])
12618           (pc)
12619           (label_ref (match_operand 3 "" ""))))
12620    (clobber (reg:CCFP FPSR_REG))
12621    (clobber (reg:CCFP FLAGS_REG))
12622    (clobber (match_scratch:HI 4 "=a"))]
12623   "TARGET_80387
12624    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
12625    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12626    && SELECT_CC_MODE (GET_CODE (operands[0]),
12627                       operands[1], operands[2]) == CCFPmode
12628    && !TARGET_CMOVE"
12629   "#")
12630
12631 (define_insn "*fp_jcc_5_387"
12632   [(set (pc)
12633         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
12634                         [(match_operand 1 "register_operand" "f")
12635                          (match_operand 2 "register_operand" "f")])
12636           (label_ref (match_operand 3 "" ""))
12637           (pc)))
12638    (clobber (reg:CCFP FPSR_REG))
12639    (clobber (reg:CCFP FLAGS_REG))
12640    (clobber (match_scratch:HI 4 "=a"))]
12641   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
12642    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12643    && !TARGET_CMOVE"
12644   "#")
12645
12646 (define_insn "*fp_jcc_6_387"
12647   [(set (pc)
12648         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
12649                         [(match_operand 1 "register_operand" "f")
12650                          (match_operand 2 "register_operand" "f")])
12651           (pc)
12652           (label_ref (match_operand 3 "" ""))))
12653    (clobber (reg:CCFP FPSR_REG))
12654    (clobber (reg:CCFP FLAGS_REG))
12655    (clobber (match_scratch:HI 4 "=a"))]
12656   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
12657    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12658    && !TARGET_CMOVE"
12659   "#")
12660
12661 (define_insn "*fp_jcc_7_387"
12662   [(set (pc)
12663         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
12664                         [(match_operand 1 "register_operand" "f")
12665                          (match_operand 2 "const0_operand" "")])
12666           (label_ref (match_operand 3 "" ""))
12667           (pc)))
12668    (clobber (reg:CCFP FPSR_REG))
12669    (clobber (reg:CCFP FLAGS_REG))
12670    (clobber (match_scratch:HI 4 "=a"))]
12671   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
12672    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12673    && SELECT_CC_MODE (GET_CODE (operands[0]),
12674                       operands[1], operands[2]) == CCFPmode
12675    && !TARGET_CMOVE"
12676   "#")
12677
12678 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
12679 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
12680 ;; with a precedence over other operators and is always put in the first
12681 ;; place. Swap condition and operands to match ficom instruction.
12682
12683 (define_insn "*fp_jcc_8<mode>_387"
12684   [(set (pc)
12685         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
12686                         [(match_operator 1 "float_operator"
12687                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
12688                            (match_operand 3 "register_operand" "f,f")])
12689           (label_ref (match_operand 4 "" ""))
12690           (pc)))
12691    (clobber (reg:CCFP FPSR_REG))
12692    (clobber (reg:CCFP FLAGS_REG))
12693    (clobber (match_scratch:HI 5 "=a,a"))]
12694   "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
12695    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
12696    && GET_MODE (operands[1]) == GET_MODE (operands[3])
12697    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
12698    && !TARGET_CMOVE"
12699   "#")
12700
12701 (define_split
12702   [(set (pc)
12703         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
12704                         [(match_operand 1 "register_operand" "")
12705                          (match_operand 2 "nonimmediate_operand" "")])
12706           (match_operand 3 "" "")
12707           (match_operand 4 "" "")))
12708    (clobber (reg:CCFP FPSR_REG))
12709    (clobber (reg:CCFP FLAGS_REG))]
12710   "reload_completed"
12711   [(const_int 0)]
12712 {
12713   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
12714                         operands[3], operands[4], NULL_RTX, NULL_RTX);
12715   DONE;
12716 })
12717
12718 (define_split
12719   [(set (pc)
12720         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
12721                         [(match_operand 1 "register_operand" "")
12722                          (match_operand 2 "general_operand" "")])
12723           (match_operand 3 "" "")
12724           (match_operand 4 "" "")))
12725    (clobber (reg:CCFP FPSR_REG))
12726    (clobber (reg:CCFP FLAGS_REG))
12727    (clobber (match_scratch:HI 5 "=a"))]
12728   "reload_completed"
12729   [(const_int 0)]
12730 {
12731   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
12732                         operands[3], operands[4], operands[5], NULL_RTX);
12733   DONE;
12734 })
12735
12736 (define_split
12737   [(set (pc)
12738         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
12739                         [(match_operator 1 "float_operator"
12740                            [(match_operand:X87MODEI12 2 "memory_operand" "")])
12741                            (match_operand 3 "register_operand" "")])
12742           (match_operand 4 "" "")
12743           (match_operand 5 "" "")))
12744    (clobber (reg:CCFP FPSR_REG))
12745    (clobber (reg:CCFP FLAGS_REG))
12746    (clobber (match_scratch:HI 6 "=a"))]
12747   "reload_completed"
12748   [(const_int 0)]
12749 {
12750   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
12751   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
12752                         operands[3], operands[7],
12753                         operands[4], operands[5], operands[6], NULL_RTX);
12754   DONE;
12755 })
12756
12757 ;; %%% Kill this when reload knows how to do it.
12758 (define_split
12759   [(set (pc)
12760         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
12761                         [(match_operator 1 "float_operator"
12762                            [(match_operand:X87MODEI12 2 "register_operand" "")])
12763                            (match_operand 3 "register_operand" "")])
12764           (match_operand 4 "" "")
12765           (match_operand 5 "" "")))
12766    (clobber (reg:CCFP FPSR_REG))
12767    (clobber (reg:CCFP FLAGS_REG))
12768    (clobber (match_scratch:HI 6 "=a"))]
12769   "reload_completed"
12770   [(const_int 0)]
12771 {
12772   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
12773   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
12774   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
12775                         operands[3], operands[7],
12776                         operands[4], operands[5], operands[6], operands[2]);
12777   DONE;
12778 })
12779 \f
12780 ;; Unconditional and other jump instructions
12781
12782 (define_insn "jump"
12783   [(set (pc)
12784         (label_ref (match_operand 0 "" "")))]
12785   ""
12786   "jmp\t%l0"
12787   [(set_attr "type" "ibr")
12788    (set (attr "length")
12789            (if_then_else (and (ge (minus (match_dup 0) (pc))
12790                                   (const_int -126))
12791                               (lt (minus (match_dup 0) (pc))
12792                                   (const_int 128)))
12793              (const_int 2)
12794              (const_int 5)))
12795    (set_attr "modrm" "0")])
12796
12797 (define_expand "indirect_jump"
12798   [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
12799   ""
12800   "")
12801
12802 (define_insn "*indirect_jump"
12803   [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
12804   ""
12805   "jmp\t%A0"
12806   [(set_attr "type" "ibr")
12807    (set_attr "length_immediate" "0")])
12808
12809 (define_expand "tablejump"
12810   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
12811               (use (label_ref (match_operand 1 "" "")))])]
12812   ""
12813 {
12814   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
12815      relative.  Convert the relative address to an absolute address.  */
12816   if (flag_pic)
12817     {
12818       rtx op0, op1;
12819       enum rtx_code code;
12820
12821       /* We can't use @GOTOFF for text labels on VxWorks;
12822          see gotoff_operand.  */
12823       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
12824         {
12825           code = PLUS;
12826           op0 = operands[0];
12827           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
12828         }
12829       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
12830         {
12831           code = PLUS;
12832           op0 = operands[0];
12833           op1 = pic_offset_table_rtx;
12834         }
12835       else
12836         {
12837           code = MINUS;
12838           op0 = pic_offset_table_rtx;
12839           op1 = operands[0];
12840         }
12841
12842       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
12843                                          OPTAB_DIRECT);
12844     }
12845 })
12846
12847 (define_insn "*tablejump_1"
12848   [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
12849    (use (label_ref (match_operand 1 "" "")))]
12850   ""
12851   "jmp\t%A0"
12852   [(set_attr "type" "ibr")
12853    (set_attr "length_immediate" "0")])
12854 \f
12855 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
12856
12857 (define_peephole2
12858   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
12859    (set (match_operand:QI 1 "register_operand" "")
12860         (match_operator:QI 2 "ix86_comparison_operator"
12861           [(reg FLAGS_REG) (const_int 0)]))
12862    (set (match_operand 3 "q_regs_operand" "")
12863         (zero_extend (match_dup 1)))]
12864   "(peep2_reg_dead_p (3, operands[1])
12865     || operands_match_p (operands[1], operands[3]))
12866    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
12867   [(set (match_dup 4) (match_dup 0))
12868    (set (strict_low_part (match_dup 5))
12869         (match_dup 2))]
12870 {
12871   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12872   operands[5] = gen_lowpart (QImode, operands[3]);
12873   ix86_expand_clear (operands[3]);
12874 })
12875
12876 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
12877
12878 (define_peephole2
12879   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
12880    (set (match_operand:QI 1 "register_operand" "")
12881         (match_operator:QI 2 "ix86_comparison_operator"
12882           [(reg FLAGS_REG) (const_int 0)]))
12883    (parallel [(set (match_operand 3 "q_regs_operand" "")
12884                    (zero_extend (match_dup 1)))
12885               (clobber (reg:CC FLAGS_REG))])]
12886   "(peep2_reg_dead_p (3, operands[1])
12887     || operands_match_p (operands[1], operands[3]))
12888    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
12889   [(set (match_dup 4) (match_dup 0))
12890    (set (strict_low_part (match_dup 5))
12891         (match_dup 2))]
12892 {
12893   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12894   operands[5] = gen_lowpart (QImode, operands[3]);
12895   ix86_expand_clear (operands[3]);
12896 })
12897 \f
12898 ;; Call instructions.
12899
12900 ;; The predicates normally associated with named expanders are not properly
12901 ;; checked for calls.  This is a bug in the generic code, but it isn't that
12902 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
12903
12904 ;; P6 processors will jump to the address after the decrement when %esp
12905 ;; is used as a call operand, so they will execute return address as a code.
12906 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
12907  
12908 ;; Call subroutine returning no value.
12909
12910 (define_expand "call_pop"
12911   [(parallel [(call (match_operand:QI 0 "" "")
12912                     (match_operand:SI 1 "" ""))
12913               (set (reg:SI SP_REG)
12914                    (plus:SI (reg:SI SP_REG)
12915                             (match_operand:SI 3 "" "")))])]
12916   "!TARGET_64BIT"
12917 {
12918   ix86_expand_call (NULL, operands[0], operands[1],
12919                     operands[2], operands[3], 0);
12920   DONE;
12921 })
12922
12923 (define_insn "*call_pop_0"
12924   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
12925          (match_operand:SI 1 "" ""))
12926    (set (reg:SI SP_REG)
12927         (plus:SI (reg:SI SP_REG)
12928                  (match_operand:SI 2 "immediate_operand" "")))]
12929   "!TARGET_64BIT"
12930 {
12931   if (SIBLING_CALL_P (insn))
12932     return "jmp\t%P0";
12933   else
12934     return "call\t%P0";
12935 }
12936   [(set_attr "type" "call")])
12937
12938 (define_insn "*call_pop_1"
12939   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
12940          (match_operand:SI 1 "" ""))
12941    (set (reg:SI SP_REG)
12942         (plus:SI (reg:SI SP_REG)
12943                  (match_operand:SI 2 "immediate_operand" "i")))]
12944   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
12945 {
12946   if (constant_call_address_operand (operands[0], Pmode))
12947     return "call\t%P0";
12948   return "call\t%A0";
12949 }
12950   [(set_attr "type" "call")])
12951
12952 (define_insn "*sibcall_pop_1"
12953   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
12954          (match_operand:SI 1 "" ""))
12955    (set (reg:SI SP_REG)
12956         (plus:SI (reg:SI SP_REG)
12957                  (match_operand:SI 2 "immediate_operand" "i,i")))]
12958   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
12959   "@
12960    jmp\t%P0
12961    jmp\t%A0"
12962   [(set_attr "type" "call")])
12963
12964 (define_expand "call"
12965   [(call (match_operand:QI 0 "" "")
12966          (match_operand 1 "" ""))
12967    (use (match_operand 2 "" ""))]
12968   ""
12969 {
12970   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
12971   DONE;
12972 })
12973
12974 (define_expand "sibcall"
12975   [(call (match_operand:QI 0 "" "")
12976          (match_operand 1 "" ""))
12977    (use (match_operand 2 "" ""))]
12978   ""
12979 {
12980   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
12981   DONE;
12982 })
12983
12984 (define_insn "*call_0"
12985   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
12986          (match_operand 1 "" ""))]
12987   ""
12988 {
12989   if (SIBLING_CALL_P (insn))
12990     return "jmp\t%P0";
12991   else
12992     return "call\t%P0";
12993 }
12994   [(set_attr "type" "call")])
12995
12996 (define_insn "*call_1"
12997   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
12998          (match_operand 1 "" ""))]
12999   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
13000 {
13001   if (constant_call_address_operand (operands[0], Pmode))
13002     return "call\t%P0";
13003   return "call\t%A0";
13004 }
13005   [(set_attr "type" "call")])
13006
13007 (define_insn "*sibcall_1"
13008   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
13009          (match_operand 1 "" ""))]
13010   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
13011   "@
13012    jmp\t%P0
13013    jmp\t%A0"
13014   [(set_attr "type" "call")])
13015
13016 (define_insn "*call_1_rex64"
13017   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13018          (match_operand 1 "" ""))]
13019   "TARGET_64BIT && !SIBLING_CALL_P (insn)
13020    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
13021 {
13022   if (constant_call_address_operand (operands[0], Pmode))
13023     return "call\t%P0";
13024   return "call\t%A0";
13025 }
13026   [(set_attr "type" "call")])
13027
13028 (define_insn "*call_1_rex64_ms_sysv"
13029   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13030          (match_operand 1 "" ""))
13031    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
13032    (clobber (reg:TI XMM6_REG))
13033    (clobber (reg:TI XMM7_REG))
13034    (clobber (reg:TI XMM8_REG))
13035    (clobber (reg:TI XMM9_REG))
13036    (clobber (reg:TI XMM10_REG))
13037    (clobber (reg:TI XMM11_REG))
13038    (clobber (reg:TI XMM12_REG))
13039    (clobber (reg:TI XMM13_REG))
13040    (clobber (reg:TI XMM14_REG))
13041    (clobber (reg:TI XMM15_REG))
13042    (clobber (reg:DI SI_REG))
13043    (clobber (reg:DI DI_REG))]
13044   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
13045 {
13046   if (constant_call_address_operand (operands[0], Pmode))
13047     return "call\t%P0";
13048   return "call\t%A0";
13049 }
13050   [(set_attr "type" "call")])
13051
13052 (define_insn "*call_1_rex64_large"
13053   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
13054          (match_operand 1 "" ""))]
13055   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
13056   "call\t%A0"
13057   [(set_attr "type" "call")])
13058
13059 (define_insn "*sibcall_1_rex64"
13060   [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
13061          (match_operand 1 "" ""))]
13062   "TARGET_64BIT && SIBLING_CALL_P (insn)"
13063   "@
13064    jmp\t%P0
13065    jmp\t%A0"
13066   [(set_attr "type" "call")])
13067
13068 ;; Call subroutine, returning value in operand 0
13069 (define_expand "call_value_pop"
13070   [(parallel [(set (match_operand 0 "" "")
13071                    (call (match_operand:QI 1 "" "")
13072                          (match_operand:SI 2 "" "")))
13073               (set (reg:SI SP_REG)
13074                    (plus:SI (reg:SI SP_REG)
13075                             (match_operand:SI 4 "" "")))])]
13076   "!TARGET_64BIT"
13077 {
13078   ix86_expand_call (operands[0], operands[1], operands[2],
13079                     operands[3], operands[4], 0);
13080   DONE;
13081 })
13082
13083 (define_expand "call_value"
13084   [(set (match_operand 0 "" "")
13085         (call (match_operand:QI 1 "" "")
13086               (match_operand:SI 2 "" "")))
13087    (use (match_operand:SI 3 "" ""))]
13088   ;; Operand 3 is not used on the i386.
13089   ""
13090 {
13091   ix86_expand_call (operands[0], operands[1], operands[2],
13092                     operands[3], NULL, 0);
13093   DONE;
13094 })
13095
13096 (define_expand "sibcall_value"
13097   [(set (match_operand 0 "" "")
13098         (call (match_operand:QI 1 "" "")
13099               (match_operand:SI 2 "" "")))
13100    (use (match_operand:SI 3 "" ""))]
13101   ;; Operand 3 is not used on the i386.
13102   ""
13103 {
13104   ix86_expand_call (operands[0], operands[1], operands[2],
13105                     operands[3], NULL, 1);
13106   DONE;
13107 })
13108
13109 ;; Call subroutine returning any type.
13110
13111 (define_expand "untyped_call"
13112   [(parallel [(call (match_operand 0 "" "")
13113                     (const_int 0))
13114               (match_operand 1 "" "")
13115               (match_operand 2 "" "")])]
13116   ""
13117 {
13118   int i;
13119
13120   /* In order to give reg-stack an easier job in validating two
13121      coprocessor registers as containing a possible return value,
13122      simply pretend the untyped call returns a complex long double
13123      value. 
13124
13125      We can't use SSE_REGPARM_MAX here since callee is unprototyped
13126      and should have the default ABI.  */
13127
13128   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13129                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13130                     operands[0], const0_rtx,
13131                     GEN_INT ((TARGET_64BIT
13132                               ? (ix86_abi == SYSV_ABI
13133                                  ? X86_64_SSE_REGPARM_MAX
13134                                  : X86_64_MS_SSE_REGPARM_MAX)
13135                               : X86_32_SSE_REGPARM_MAX)
13136                              - 1),
13137                     NULL, 0);
13138
13139   for (i = 0; i < XVECLEN (operands[2], 0); i++)
13140     {
13141       rtx set = XVECEXP (operands[2], 0, i);
13142       emit_move_insn (SET_DEST (set), SET_SRC (set));
13143     }
13144
13145   /* The optimizer does not know that the call sets the function value
13146      registers we stored in the result block.  We avoid problems by
13147      claiming that all hard registers are used and clobbered at this
13148      point.  */
13149   emit_insn (gen_blockage ());
13150
13151   DONE;
13152 })
13153 \f
13154 ;; Prologue and epilogue instructions
13155
13156 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13157 ;; all of memory.  This blocks insns from being moved across this point.
13158
13159 (define_insn "blockage"
13160   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
13161   ""
13162   ""
13163   [(set_attr "length" "0")])
13164
13165 ;; Do not schedule instructions accessing memory across this point.
13166
13167 (define_expand "memory_blockage"
13168   [(set (match_dup 0)
13169         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
13170   ""
13171 {
13172   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
13173   MEM_VOLATILE_P (operands[0]) = 1;
13174 })
13175
13176 (define_insn "*memory_blockage"
13177   [(set (match_operand:BLK 0 "" "")
13178         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
13179   ""
13180   ""
13181   [(set_attr "length" "0")])
13182
13183 ;; As USE insns aren't meaningful after reload, this is used instead
13184 ;; to prevent deleting instructions setting registers for PIC code
13185 (define_insn "prologue_use"
13186   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
13187   ""
13188   ""
13189   [(set_attr "length" "0")])
13190
13191 ;; Insn emitted into the body of a function to return from a function.
13192 ;; This is only done if the function's epilogue is known to be simple.
13193 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13194
13195 (define_expand "return"
13196   [(return)]
13197   "ix86_can_use_return_insn_p ()"
13198 {
13199   if (crtl->args.pops_args)
13200     {
13201       rtx popc = GEN_INT (crtl->args.pops_args);
13202       emit_jump_insn (gen_return_pop_internal (popc));
13203       DONE;
13204     }
13205 })
13206
13207 (define_insn "return_internal"
13208   [(return)]
13209   "reload_completed"
13210   "ret"
13211   [(set_attr "length" "1")
13212    (set_attr "atom_unit" "jeu")
13213    (set_attr "length_immediate" "0")
13214    (set_attr "modrm" "0")])
13215
13216 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13217 ;; instruction Athlon and K8 have.
13218
13219 (define_insn "return_internal_long"
13220   [(return)
13221    (unspec [(const_int 0)] UNSPEC_REP)]
13222   "reload_completed"
13223   "rep\;ret"
13224   [(set_attr "length" "2")
13225    (set_attr "atom_unit" "jeu")
13226    (set_attr "length_immediate" "0")
13227    (set_attr "prefix_rep" "1")
13228    (set_attr "modrm" "0")])
13229
13230 (define_insn "return_pop_internal"
13231   [(return)
13232    (use (match_operand:SI 0 "const_int_operand" ""))]
13233   "reload_completed"
13234   "ret\t%0"
13235   [(set_attr "length" "3")
13236    (set_attr "atom_unit" "jeu")
13237    (set_attr "length_immediate" "2")
13238    (set_attr "modrm" "0")])
13239
13240 (define_insn "return_indirect_internal"
13241   [(return)
13242    (use (match_operand:SI 0 "register_operand" "r"))]
13243   "reload_completed"
13244   "jmp\t%A0"
13245   [(set_attr "type" "ibr")
13246    (set_attr "length_immediate" "0")])
13247
13248 (define_insn "nop"
13249   [(const_int 0)]
13250   ""
13251   "nop"
13252   [(set_attr "length" "1")
13253    (set_attr "length_immediate" "0")
13254    (set_attr "modrm" "0")])
13255
13256 (define_insn "vswapmov"
13257   [(set (match_operand:SI 0 "register_operand" "=r")
13258         (match_operand:SI 1 "register_operand" "r"))
13259    (unspec_volatile [(const_int 0)] UNSPECV_VSWAPMOV)]
13260   ""
13261   "movl.s\t{%1, %0|%0, %1}"
13262   [(set_attr "length" "2")
13263    (set_attr "length_immediate" "0")
13264    (set_attr "modrm" "0")])
13265
13266 ;; Pad to 16-byte boundary, max skip in op0.  Used to avoid
13267 ;; branch prediction penalty for the third jump in a 16-byte
13268 ;; block on K8.
13269
13270 (define_insn "pad"
13271   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
13272   ""
13273 {
13274 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
13275   ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
13276 #else
13277   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13278      The align insn is used to avoid 3 jump instructions in the row to improve
13279      branch prediction and the benefits hardly outweigh the cost of extra 8
13280      nops on the average inserted by full alignment pseudo operation.  */
13281 #endif
13282   return "";
13283 }
13284   [(set_attr "length" "16")])
13285
13286 (define_expand "prologue"
13287   [(const_int 0)]
13288   ""
13289   "ix86_expand_prologue (); DONE;")
13290
13291 (define_insn "set_got"
13292   [(set (match_operand:SI 0 "register_operand" "=r")
13293         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13294    (clobber (reg:CC FLAGS_REG))]
13295   "!TARGET_64BIT"
13296   { return output_set_got (operands[0], NULL_RTX); }
13297   [(set_attr "type" "multi")
13298    (set_attr "length" "12")])
13299
13300 (define_insn "set_got_labelled"
13301   [(set (match_operand:SI 0 "register_operand" "=r")
13302         (unspec:SI [(label_ref (match_operand 1 "" ""))]
13303          UNSPEC_SET_GOT))
13304    (clobber (reg:CC FLAGS_REG))]
13305   "!TARGET_64BIT"
13306   { return output_set_got (operands[0], operands[1]); }
13307   [(set_attr "type" "multi")
13308    (set_attr "length" "12")])
13309
13310 (define_insn "set_got_rex64"
13311   [(set (match_operand:DI 0 "register_operand" "=r")
13312         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
13313   "TARGET_64BIT"
13314   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
13315   [(set_attr "type" "lea")
13316    (set_attr "length_address" "4")
13317    (set_attr "mode" "DI")])
13318
13319 (define_insn "set_rip_rex64"
13320   [(set (match_operand:DI 0 "register_operand" "=r")
13321         (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
13322   "TARGET_64BIT"
13323   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
13324   [(set_attr "type" "lea")
13325    (set_attr "length_address" "4")
13326    (set_attr "mode" "DI")])
13327
13328 (define_insn "set_got_offset_rex64"
13329   [(set (match_operand:DI 0 "register_operand" "=r")
13330         (unspec:DI
13331           [(label_ref (match_operand 1 "" ""))]
13332           UNSPEC_SET_GOT_OFFSET))]
13333   "TARGET_64BIT"
13334   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
13335   [(set_attr "type" "imov")
13336    (set_attr "length_immediate" "0")
13337    (set_attr "length_address" "8")
13338    (set_attr "mode" "DI")])
13339
13340 (define_expand "epilogue"
13341   [(const_int 0)]
13342   ""
13343   "ix86_expand_epilogue (1); DONE;")
13344
13345 (define_expand "sibcall_epilogue"
13346   [(const_int 0)]
13347   ""
13348   "ix86_expand_epilogue (0); DONE;")
13349
13350 (define_expand "eh_return"
13351   [(use (match_operand 0 "register_operand" ""))]
13352   ""
13353 {
13354   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13355
13356   /* Tricky bit: we write the address of the handler to which we will
13357      be returning into someone else's stack frame, one word below the
13358      stack address we wish to restore.  */
13359   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13360   tmp = plus_constant (tmp, -UNITS_PER_WORD);
13361   tmp = gen_rtx_MEM (Pmode, tmp);
13362   emit_move_insn (tmp, ra);
13363
13364   emit_jump_insn (gen_eh_return_internal ());
13365   emit_barrier ();
13366   DONE;
13367 })
13368
13369 (define_insn_and_split "eh_return_internal"
13370   [(eh_return)]
13371   ""
13372   "#"
13373   "epilogue_completed"
13374   [(const_int 0)]
13375   "ix86_expand_epilogue (2); DONE;")
13376
13377 (define_insn "leave"
13378   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13379    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
13380    (clobber (mem:BLK (scratch)))]
13381   "!TARGET_64BIT"
13382   "leave"
13383   [(set_attr "type" "leave")])
13384
13385 (define_insn "leave_rex64"
13386   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13387    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
13388    (clobber (mem:BLK (scratch)))]
13389   "TARGET_64BIT"
13390   "leave"
13391   [(set_attr "type" "leave")])
13392 \f
13393 (define_expand "ffssi2"
13394   [(parallel
13395      [(set (match_operand:SI 0 "register_operand" "")
13396            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
13397       (clobber (match_scratch:SI 2 ""))
13398       (clobber (reg:CC FLAGS_REG))])]
13399   ""
13400 {
13401   if (TARGET_CMOVE)
13402     {
13403       emit_insn (gen_ffs_cmove (operands[0], operands[1]));
13404       DONE;
13405     }
13406 })
13407
13408 (define_expand "ffs_cmove"
13409   [(set (match_dup 2) (const_int -1))
13410    (parallel [(set (reg:CCZ FLAGS_REG)
13411                    (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "")
13412                                 (const_int 0)))
13413               (set (match_operand:SI 0 "register_operand" "")
13414                    (ctz:SI (match_dup 1)))])
13415    (set (match_dup 0) (if_then_else:SI
13416                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
13417                         (match_dup 2)
13418                         (match_dup 0)))
13419    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13420               (clobber (reg:CC FLAGS_REG))])]
13421   "TARGET_CMOVE"
13422   "operands[2] = gen_reg_rtx (SImode);")
13423
13424 (define_insn_and_split "*ffs_no_cmove"
13425   [(set (match_operand:SI 0 "register_operand" "=r")
13426         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13427    (clobber (match_scratch:SI 2 "=&q"))
13428    (clobber (reg:CC FLAGS_REG))]
13429   "!TARGET_CMOVE"
13430   "#"
13431   "&& reload_completed"
13432   [(parallel [(set (reg:CCZ FLAGS_REG)
13433                    (compare:CCZ (match_dup 1) (const_int 0)))
13434               (set (match_dup 0) (ctz:SI (match_dup 1)))])
13435    (set (strict_low_part (match_dup 3))
13436         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
13437    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
13438               (clobber (reg:CC FLAGS_REG))])
13439    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
13440               (clobber (reg:CC FLAGS_REG))])
13441    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13442               (clobber (reg:CC FLAGS_REG))])]
13443 {
13444   operands[3] = gen_lowpart (QImode, operands[2]);
13445   ix86_expand_clear (operands[2]);
13446 })
13447
13448 (define_insn "*ffssi_1"
13449   [(set (reg:CCZ FLAGS_REG)
13450         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
13451                      (const_int 0)))
13452    (set (match_operand:SI 0 "register_operand" "=r")
13453         (ctz:SI (match_dup 1)))]
13454   ""
13455   "bsf{l}\t{%1, %0|%0, %1}"
13456   [(set_attr "type" "alu1")
13457    (set_attr "prefix_0f" "1")
13458    (set_attr "mode" "SI")])
13459
13460 (define_expand "ffsdi2"
13461   [(set (match_dup 2) (const_int -1))
13462    (parallel [(set (reg:CCZ FLAGS_REG)
13463                    (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "")
13464                                 (const_int 0)))
13465               (set (match_operand:DI 0 "register_operand" "")
13466                    (ctz:DI (match_dup 1)))])
13467    (set (match_dup 0) (if_then_else:DI
13468                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
13469                         (match_dup 2)
13470                         (match_dup 0)))
13471    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
13472               (clobber (reg:CC FLAGS_REG))])]
13473   "TARGET_64BIT"
13474   "operands[2] = gen_reg_rtx (DImode);")
13475
13476 (define_insn "*ffsdi_1"
13477   [(set (reg:CCZ FLAGS_REG)
13478         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
13479                      (const_int 0)))
13480    (set (match_operand:DI 0 "register_operand" "=r")
13481         (ctz:DI (match_dup 1)))]
13482   "TARGET_64BIT"
13483   "bsf{q}\t{%1, %0|%0, %1}"
13484   [(set_attr "type" "alu1")
13485    (set_attr "prefix_0f" "1")
13486    (set_attr "mode" "DI")])
13487
13488 (define_insn "ctzsi2"
13489   [(set (match_operand:SI 0 "register_operand" "=r")
13490         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13491    (clobber (reg:CC FLAGS_REG))]
13492   ""
13493   "bsf{l}\t{%1, %0|%0, %1}"
13494   [(set_attr "type" "alu1")
13495    (set_attr "prefix_0f" "1")
13496    (set_attr "mode" "SI")])
13497
13498 (define_insn "ctzdi2"
13499   [(set (match_operand:DI 0 "register_operand" "=r")
13500         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
13501    (clobber (reg:CC FLAGS_REG))]
13502   "TARGET_64BIT"
13503   "bsf{q}\t{%1, %0|%0, %1}"
13504   [(set_attr "type" "alu1")
13505    (set_attr "prefix_0f" "1")
13506    (set_attr "mode" "DI")])
13507
13508 (define_expand "clzsi2"
13509   [(parallel
13510      [(set (match_operand:SI 0 "register_operand" "")
13511            (minus:SI (const_int 31)
13512                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
13513       (clobber (reg:CC FLAGS_REG))])
13514    (parallel
13515      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
13516       (clobber (reg:CC FLAGS_REG))])]
13517   ""
13518 {
13519   if (TARGET_ABM)
13520     {
13521       emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
13522       DONE;
13523     }
13524 })
13525
13526 (define_insn "clzsi2_abm"
13527   [(set (match_operand:SI 0 "register_operand" "=r")
13528         (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13529    (clobber (reg:CC FLAGS_REG))]
13530   "TARGET_ABM"
13531   "lzcnt{l}\t{%1, %0|%0, %1}"
13532   [(set_attr "prefix_rep" "1")
13533    (set_attr "type" "bitmanip")
13534    (set_attr "mode" "SI")])
13535
13536 (define_insn "bsr"
13537   [(set (match_operand:SI 0 "register_operand" "=r")
13538         (minus:SI (const_int 31)
13539                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
13540    (clobber (reg:CC FLAGS_REG))]
13541   ""
13542   "bsr{l}\t{%1, %0|%0, %1}"
13543   [(set_attr "type" "alu1")
13544    (set_attr "prefix_0f" "1")
13545    (set_attr "mode" "SI")])
13546
13547 (define_insn "popcount<mode>2"
13548   [(set (match_operand:SWI248 0 "register_operand" "=r")
13549         (popcount:SWI248
13550           (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
13551    (clobber (reg:CC FLAGS_REG))]
13552   "TARGET_POPCNT"
13553 {
13554 #if TARGET_MACHO
13555   return "popcnt\t{%1, %0|%0, %1}";
13556 #else
13557   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13558 #endif
13559 }
13560   [(set_attr "prefix_rep" "1")
13561    (set_attr "type" "bitmanip")
13562    (set_attr "mode" "<MODE>")])
13563
13564 (define_insn "*popcount<mode>2_cmp"
13565   [(set (reg FLAGS_REG)
13566         (compare
13567           (popcount:SWI248
13568             (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
13569           (const_int 0)))
13570    (set (match_operand:SWI248 0 "register_operand" "=r")
13571         (popcount:SWI248 (match_dup 1)))]
13572   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
13573 {
13574 #if TARGET_MACHO
13575   return "popcnt\t{%1, %0|%0, %1}";
13576 #else
13577   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13578 #endif
13579 }
13580   [(set_attr "prefix_rep" "1")
13581    (set_attr "type" "bitmanip")
13582    (set_attr "mode" "<MODE>")])
13583
13584 (define_insn "*popcountsi2_cmp_zext"
13585   [(set (reg FLAGS_REG)
13586         (compare
13587           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
13588           (const_int 0)))
13589    (set (match_operand:DI 0 "register_operand" "=r")
13590         (zero_extend:DI(popcount:SI (match_dup 1))))]
13591   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
13592 {
13593 #if TARGET_MACHO
13594   return "popcnt\t{%1, %0|%0, %1}";
13595 #else
13596   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13597 #endif
13598 }
13599   [(set_attr "prefix_rep" "1")
13600    (set_attr "type" "bitmanip")
13601    (set_attr "mode" "SI")])
13602
13603 (define_expand "bswapsi2"
13604   [(set (match_operand:SI 0 "register_operand" "")
13605         (bswap:SI (match_operand:SI 1 "register_operand" "")))]
13606   ""
13607 {
13608   if (!(TARGET_BSWAP || TARGET_MOVBE))
13609     {
13610       rtx x = operands[0];
13611
13612       emit_move_insn (x, operands[1]);
13613       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
13614       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
13615       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
13616       DONE;
13617     }
13618 })
13619
13620 (define_insn "*bswapsi_movbe"
13621   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,m")
13622         (bswap:SI (match_operand:SI 1 "nonimmediate_operand" "0,m,r")))]
13623   "TARGET_MOVBE && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13624   "@
13625     bswap\t%0
13626     movbe\t{%1, %0|%0, %1}
13627     movbe\t{%1, %0|%0, %1}"
13628   [(set_attr "type" "*,imov,imov")
13629    (set_attr "modrm" "*,1,1")
13630    (set_attr "prefix_0f" "1")
13631    (set_attr "prefix_extra" "*,1,1")
13632    (set_attr "length" "2,*,*")
13633    (set_attr "mode" "SI")])
13634
13635 (define_insn "*bswapsi_1"
13636   [(set (match_operand:SI 0 "register_operand" "=r")
13637         (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
13638   "TARGET_BSWAP"
13639   "bswap\t%0"
13640   [(set_attr "prefix_0f" "1")
13641    (set_attr "length" "2")])
13642
13643 (define_insn "*bswaphi_lowpart_1"
13644   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
13645         (bswap:HI (match_dup 0)))
13646    (clobber (reg:CC FLAGS_REG))]
13647   "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
13648   "@
13649     xchg{b}\t{%h0, %b0|%b0, %h0}
13650     rol{w}\t{$8, %0|%0, 8}"
13651   [(set_attr "length" "2,4")
13652    (set_attr "mode" "QI,HI")])
13653
13654 (define_insn "bswaphi_lowpart"
13655   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
13656         (bswap:HI (match_dup 0)))
13657    (clobber (reg:CC FLAGS_REG))]
13658   ""
13659   "rol{w}\t{$8, %0|%0, 8}"
13660   [(set_attr "length" "4")
13661    (set_attr "mode" "HI")])
13662
13663 (define_expand "bswapdi2"
13664   [(set (match_operand:DI 0 "register_operand" "")
13665         (bswap:DI (match_operand:DI 1 "register_operand" "")))]
13666   "TARGET_64BIT"
13667   "")
13668
13669 (define_insn "*bswapdi_movbe"
13670   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m")
13671         (bswap:DI (match_operand:DI 1 "nonimmediate_operand" "0,m,r")))]
13672   "TARGET_64BIT && TARGET_MOVBE
13673    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13674   "@
13675     bswap\t%0
13676     movbe\t{%1, %0|%0, %1}
13677     movbe\t{%1, %0|%0, %1}"
13678   [(set_attr "type" "*,imov,imov")
13679    (set_attr "modrm" "*,1,1")
13680    (set_attr "prefix_0f" "1")
13681    (set_attr "prefix_extra" "*,1,1")
13682    (set_attr "length" "3,*,*")
13683    (set_attr "mode" "DI")])
13684
13685 (define_insn "*bswapdi_1"
13686   [(set (match_operand:DI 0 "register_operand" "=r")
13687         (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
13688   "TARGET_64BIT"
13689   "bswap\t%0"
13690   [(set_attr "prefix_0f" "1")
13691    (set_attr "length" "3")])
13692
13693 (define_expand "clzdi2"
13694   [(parallel
13695      [(set (match_operand:DI 0 "register_operand" "")
13696            (minus:DI (const_int 63)
13697                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
13698       (clobber (reg:CC FLAGS_REG))])
13699    (parallel
13700      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
13701       (clobber (reg:CC FLAGS_REG))])]
13702   "TARGET_64BIT"
13703 {
13704   if (TARGET_ABM)
13705     {
13706       emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
13707       DONE;
13708     }
13709 })
13710
13711 (define_insn "clzdi2_abm"
13712   [(set (match_operand:DI 0 "register_operand" "=r")
13713         (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
13714    (clobber (reg:CC FLAGS_REG))]
13715   "TARGET_64BIT && TARGET_ABM"
13716   "lzcnt{q}\t{%1, %0|%0, %1}"
13717   [(set_attr "prefix_rep" "1")
13718    (set_attr "type" "bitmanip")
13719    (set_attr "mode" "DI")])
13720
13721 (define_insn "bsr_rex64"
13722   [(set (match_operand:DI 0 "register_operand" "=r")
13723         (minus:DI (const_int 63)
13724                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
13725    (clobber (reg:CC FLAGS_REG))]
13726   "TARGET_64BIT"
13727   "bsr{q}\t{%1, %0|%0, %1}"
13728   [(set_attr "type" "alu1")
13729    (set_attr "prefix_0f" "1")
13730    (set_attr "mode" "DI")])
13731
13732 (define_expand "clzhi2"
13733   [(parallel
13734      [(set (match_operand:HI 0 "register_operand" "")
13735            (minus:HI (const_int 15)
13736                      (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
13737       (clobber (reg:CC FLAGS_REG))])
13738    (parallel
13739      [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
13740       (clobber (reg:CC FLAGS_REG))])]
13741   ""
13742 {
13743   if (TARGET_ABM)
13744     {
13745       emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
13746       DONE;
13747     }
13748 })
13749
13750 (define_insn "clzhi2_abm"
13751   [(set (match_operand:HI 0 "register_operand" "=r")
13752         (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm")))
13753    (clobber (reg:CC FLAGS_REG))]
13754   "TARGET_ABM"
13755   "lzcnt{w}\t{%1, %0|%0, %1}"
13756   [(set_attr "prefix_rep" "1")
13757    (set_attr "type" "bitmanip")
13758    (set_attr "mode" "HI")])
13759
13760 (define_insn "*bsrhi"
13761   [(set (match_operand:HI 0 "register_operand" "=r")
13762         (minus:HI (const_int 15)
13763                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
13764    (clobber (reg:CC FLAGS_REG))]
13765   ""
13766   "bsr{w}\t{%1, %0|%0, %1}"
13767   [(set_attr "type" "alu1")
13768    (set_attr "prefix_0f" "1")
13769    (set_attr "mode" "HI")])
13770
13771 (define_expand "paritydi2"
13772   [(set (match_operand:DI 0 "register_operand" "")
13773         (parity:DI (match_operand:DI 1 "register_operand" "")))]
13774   "! TARGET_POPCNT"
13775 {
13776   rtx scratch = gen_reg_rtx (QImode);
13777   rtx cond;
13778
13779   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
13780                                 NULL_RTX, operands[1]));
13781
13782   cond = gen_rtx_fmt_ee (ORDERED, QImode,
13783                          gen_rtx_REG (CCmode, FLAGS_REG),
13784                          const0_rtx);
13785   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
13786
13787   if (TARGET_64BIT)
13788     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
13789   else
13790     {
13791       rtx tmp = gen_reg_rtx (SImode);
13792
13793       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
13794       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
13795     }
13796   DONE;
13797 })
13798
13799 (define_insn_and_split "paritydi2_cmp"
13800   [(set (reg:CC FLAGS_REG)
13801         (parity:CC (match_operand:DI 3 "register_operand" "0")))
13802    (clobber (match_scratch:DI 0 "=r"))
13803    (clobber (match_scratch:SI 1 "=&r"))
13804    (clobber (match_scratch:HI 2 "=Q"))]
13805   "! TARGET_POPCNT"
13806   "#"
13807   "&& reload_completed"
13808   [(parallel
13809      [(set (match_dup 1)
13810            (xor:SI (match_dup 1) (match_dup 4)))
13811       (clobber (reg:CC FLAGS_REG))])
13812    (parallel
13813      [(set (reg:CC FLAGS_REG)
13814            (parity:CC (match_dup 1)))
13815       (clobber (match_dup 1))
13816       (clobber (match_dup 2))])]
13817 {
13818   operands[4] = gen_lowpart (SImode, operands[3]);
13819
13820   if (TARGET_64BIT)
13821     {
13822       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
13823       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
13824     }
13825   else
13826     operands[1] = gen_highpart (SImode, operands[3]);
13827 })
13828
13829 (define_expand "paritysi2"
13830   [(set (match_operand:SI 0 "register_operand" "")
13831         (parity:SI (match_operand:SI 1 "register_operand" "")))]
13832   "! TARGET_POPCNT"
13833 {
13834   rtx scratch = gen_reg_rtx (QImode);
13835   rtx cond;
13836
13837   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
13838
13839   cond = gen_rtx_fmt_ee (ORDERED, QImode,
13840                          gen_rtx_REG (CCmode, FLAGS_REG),
13841                          const0_rtx);
13842   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
13843
13844   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
13845   DONE;
13846 })
13847
13848 (define_insn_and_split "paritysi2_cmp"
13849   [(set (reg:CC FLAGS_REG)
13850         (parity:CC (match_operand:SI 2 "register_operand" "0")))
13851    (clobber (match_scratch:SI 0 "=r"))
13852    (clobber (match_scratch:HI 1 "=&Q"))]
13853   "! TARGET_POPCNT"
13854   "#"
13855   "&& reload_completed"
13856   [(parallel
13857      [(set (match_dup 1)
13858            (xor:HI (match_dup 1) (match_dup 3)))
13859       (clobber (reg:CC FLAGS_REG))])
13860    (parallel
13861      [(set (reg:CC FLAGS_REG)
13862            (parity:CC (match_dup 1)))
13863       (clobber (match_dup 1))])]
13864 {
13865   operands[3] = gen_lowpart (HImode, operands[2]);
13866
13867   emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
13868   emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
13869 })
13870
13871 (define_insn "*parityhi2_cmp"
13872   [(set (reg:CC FLAGS_REG)
13873         (parity:CC (match_operand:HI 1 "register_operand" "0")))
13874    (clobber (match_scratch:HI 0 "=Q"))]
13875   "! TARGET_POPCNT"
13876   "xor{b}\t{%h0, %b0|%b0, %h0}"
13877   [(set_attr "length" "2")
13878    (set_attr "mode" "HI")])
13879
13880 (define_insn "*parityqi2_cmp"
13881   [(set (reg:CC FLAGS_REG)
13882         (parity:CC (match_operand:QI 0 "register_operand" "q")))]
13883   "! TARGET_POPCNT"
13884   "test{b}\t%0, %0"
13885   [(set_attr "length" "2")
13886    (set_attr "mode" "QI")])
13887 \f
13888 ;; Thread-local storage patterns for ELF.
13889 ;;
13890 ;; Note that these code sequences must appear exactly as shown
13891 ;; in order to allow linker relaxation.
13892
13893 (define_insn "*tls_global_dynamic_32_gnu"
13894   [(set (match_operand:SI 0 "register_operand" "=a")
13895         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13896                     (match_operand:SI 2 "tls_symbolic_operand" "")
13897                     (match_operand:SI 3 "call_insn_operand" "")]
13898                     UNSPEC_TLS_GD))
13899    (clobber (match_scratch:SI 4 "=d"))
13900    (clobber (match_scratch:SI 5 "=c"))
13901    (clobber (reg:CC FLAGS_REG))]
13902   "!TARGET_64BIT && TARGET_GNU_TLS"
13903   "lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}\;call\t%P3"
13904   [(set_attr "type" "multi")
13905    (set_attr "length" "12")])
13906
13907 (define_expand "tls_global_dynamic_32"
13908   [(parallel [(set (match_operand:SI 0 "register_operand" "")
13909                    (unspec:SI
13910                     [(match_dup 2)
13911                      (match_operand:SI 1 "tls_symbolic_operand" "")
13912                      (match_dup 3)]
13913                     UNSPEC_TLS_GD))
13914               (clobber (match_scratch:SI 4 ""))
13915               (clobber (match_scratch:SI 5 ""))
13916               (clobber (reg:CC FLAGS_REG))])]
13917   ""
13918 {
13919   if (flag_pic)
13920     operands[2] = pic_offset_table_rtx;
13921   else
13922     {
13923       operands[2] = gen_reg_rtx (Pmode);
13924       emit_insn (gen_set_got (operands[2]));
13925     }
13926   if (TARGET_GNU2_TLS)
13927     {
13928        emit_insn (gen_tls_dynamic_gnu2_32
13929                   (operands[0], operands[1], operands[2]));
13930        DONE;
13931     }
13932   operands[3] = ix86_tls_get_addr ();
13933 })
13934
13935 (define_insn "*tls_global_dynamic_64"
13936   [(set (match_operand:DI 0 "register_operand" "=a")
13937         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
13938                  (match_operand:DI 3 "" "")))
13939    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
13940               UNSPEC_TLS_GD)]
13941   "TARGET_64BIT"
13942   { 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"; }
13943   [(set_attr "type" "multi")
13944    (set_attr "length" "16")])
13945
13946 (define_expand "tls_global_dynamic_64"
13947   [(parallel [(set (match_operand:DI 0 "register_operand" "")
13948                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
13949               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
13950                          UNSPEC_TLS_GD)])]
13951   ""
13952 {
13953   if (TARGET_GNU2_TLS)
13954     {
13955        emit_insn (gen_tls_dynamic_gnu2_64
13956                   (operands[0], operands[1]));
13957        DONE;
13958     }
13959   operands[2] = ix86_tls_get_addr ();
13960 })
13961
13962 (define_insn "*tls_local_dynamic_base_32_gnu"
13963   [(set (match_operand:SI 0 "register_operand" "=a")
13964         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13965                     (match_operand:SI 2 "call_insn_operand" "")]
13966                    UNSPEC_TLS_LD_BASE))
13967    (clobber (match_scratch:SI 3 "=d"))
13968    (clobber (match_scratch:SI 4 "=c"))
13969    (clobber (reg:CC FLAGS_REG))]
13970   "!TARGET_64BIT && TARGET_GNU_TLS"
13971   "lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}\;call\t%P2"
13972   [(set_attr "type" "multi")
13973    (set_attr "length" "11")])
13974
13975 (define_expand "tls_local_dynamic_base_32"
13976   [(parallel [(set (match_operand:SI 0 "register_operand" "")
13977                    (unspec:SI [(match_dup 1) (match_dup 2)]
13978                               UNSPEC_TLS_LD_BASE))
13979               (clobber (match_scratch:SI 3 ""))
13980               (clobber (match_scratch:SI 4 ""))
13981               (clobber (reg:CC FLAGS_REG))])]
13982   ""
13983 {
13984   if (flag_pic)
13985     operands[1] = pic_offset_table_rtx;
13986   else
13987     {
13988       operands[1] = gen_reg_rtx (Pmode);
13989       emit_insn (gen_set_got (operands[1]));
13990     }
13991   if (TARGET_GNU2_TLS)
13992     {
13993        emit_insn (gen_tls_dynamic_gnu2_32
13994                   (operands[0], ix86_tls_module_base (), operands[1]));
13995        DONE;
13996     }
13997   operands[2] = ix86_tls_get_addr ();
13998 })
13999
14000 (define_insn "*tls_local_dynamic_base_64"
14001   [(set (match_operand:DI 0 "register_operand" "=a")
14002         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14003                  (match_operand:DI 2 "" "")))
14004    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14005   "TARGET_64BIT"
14006   "lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}\;call\t%P1"
14007   [(set_attr "type" "multi")
14008    (set_attr "length" "12")])
14009
14010 (define_expand "tls_local_dynamic_base_64"
14011   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14012                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
14013               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14014   ""
14015 {
14016   if (TARGET_GNU2_TLS)
14017     {
14018        emit_insn (gen_tls_dynamic_gnu2_64
14019                   (operands[0], ix86_tls_module_base ()));
14020        DONE;
14021     }
14022   operands[1] = ix86_tls_get_addr ();
14023 })
14024
14025 ;; Local dynamic of a single variable is a lose.  Show combine how
14026 ;; to convert that back to global dynamic.
14027
14028 (define_insn_and_split "*tls_local_dynamic_32_once"
14029   [(set (match_operand:SI 0 "register_operand" "=a")
14030         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14031                              (match_operand:SI 2 "call_insn_operand" "")]
14032                             UNSPEC_TLS_LD_BASE)
14033                  (const:SI (unspec:SI
14034                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
14035                             UNSPEC_DTPOFF))))
14036    (clobber (match_scratch:SI 4 "=d"))
14037    (clobber (match_scratch:SI 5 "=c"))
14038    (clobber (reg:CC FLAGS_REG))]
14039   ""
14040   "#"
14041   ""
14042   [(parallel [(set (match_dup 0)
14043                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14044                               UNSPEC_TLS_GD))
14045               (clobber (match_dup 4))
14046               (clobber (match_dup 5))
14047               (clobber (reg:CC FLAGS_REG))])]
14048   "")
14049
14050 ;; Load and add the thread base pointer from %gs:0.
14051
14052 (define_insn "*load_tp_si"
14053   [(set (match_operand:SI 0 "register_operand" "=r")
14054         (unspec:SI [(const_int 0)] UNSPEC_TP))]
14055   "!TARGET_64BIT"
14056   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
14057   [(set_attr "type" "imov")
14058    (set_attr "modrm" "0")
14059    (set_attr "length" "7")
14060    (set_attr "memory" "load")
14061    (set_attr "imm_disp" "false")])
14062
14063 (define_insn "*add_tp_si"
14064   [(set (match_operand:SI 0 "register_operand" "=r")
14065         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14066                  (match_operand:SI 1 "register_operand" "0")))
14067    (clobber (reg:CC FLAGS_REG))]
14068   "!TARGET_64BIT"
14069   "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
14070   [(set_attr "type" "alu")
14071    (set_attr "modrm" "0")
14072    (set_attr "length" "7")
14073    (set_attr "memory" "load")
14074    (set_attr "imm_disp" "false")])
14075
14076 (define_insn "*load_tp_di"
14077   [(set (match_operand:DI 0 "register_operand" "=r")
14078         (unspec:DI [(const_int 0)] UNSPEC_TP))]
14079   "TARGET_64BIT"
14080   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
14081   [(set_attr "type" "imov")
14082    (set_attr "modrm" "0")
14083    (set_attr "length" "7")
14084    (set_attr "memory" "load")
14085    (set_attr "imm_disp" "false")])
14086
14087 (define_insn "*add_tp_di"
14088   [(set (match_operand:DI 0 "register_operand" "=r")
14089         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14090                  (match_operand:DI 1 "register_operand" "0")))
14091    (clobber (reg:CC FLAGS_REG))]
14092   "TARGET_64BIT"
14093   "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
14094   [(set_attr "type" "alu")
14095    (set_attr "modrm" "0")
14096    (set_attr "length" "7")
14097    (set_attr "memory" "load")
14098    (set_attr "imm_disp" "false")])
14099
14100 ;; GNU2 TLS patterns can be split.
14101
14102 (define_expand "tls_dynamic_gnu2_32"
14103   [(set (match_dup 3)
14104         (plus:SI (match_operand:SI 2 "register_operand" "")
14105                  (const:SI
14106                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
14107                              UNSPEC_TLSDESC))))
14108    (parallel
14109     [(set (match_operand:SI 0 "register_operand" "")
14110           (unspec:SI [(match_dup 1) (match_dup 3)
14111                       (match_dup 2) (reg:SI SP_REG)]
14112                       UNSPEC_TLSDESC))
14113      (clobber (reg:CC FLAGS_REG))])]
14114   "!TARGET_64BIT && TARGET_GNU2_TLS"
14115 {
14116   operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14117   ix86_tls_descriptor_calls_expanded_in_cfun = true;
14118 })
14119
14120 (define_insn "*tls_dynamic_lea_32"
14121   [(set (match_operand:SI 0 "register_operand" "=r")
14122         (plus:SI (match_operand:SI 1 "register_operand" "b")
14123                  (const:SI
14124                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
14125                               UNSPEC_TLSDESC))))]
14126   "!TARGET_64BIT && TARGET_GNU2_TLS"
14127   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
14128   [(set_attr "type" "lea")
14129    (set_attr "mode" "SI")
14130    (set_attr "length" "6")
14131    (set_attr "length_address" "4")])
14132
14133 (define_insn "*tls_dynamic_call_32"
14134   [(set (match_operand:SI 0 "register_operand" "=a")
14135         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
14136                     (match_operand:SI 2 "register_operand" "0")
14137                     ;; we have to make sure %ebx still points to the GOT
14138                     (match_operand:SI 3 "register_operand" "b")
14139                     (reg:SI SP_REG)]
14140                    UNSPEC_TLSDESC))
14141    (clobber (reg:CC FLAGS_REG))]
14142   "!TARGET_64BIT && TARGET_GNU2_TLS"
14143   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
14144   [(set_attr "type" "call")
14145    (set_attr "length" "2")
14146    (set_attr "length_address" "0")])
14147
14148 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
14149   [(set (match_operand:SI 0 "register_operand" "=&a")
14150         (plus:SI
14151          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
14152                      (match_operand:SI 4 "" "")
14153                      (match_operand:SI 2 "register_operand" "b")
14154                      (reg:SI SP_REG)]
14155                     UNSPEC_TLSDESC)
14156          (const:SI (unspec:SI
14157                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
14158                     UNSPEC_DTPOFF))))
14159    (clobber (reg:CC FLAGS_REG))]
14160   "!TARGET_64BIT && TARGET_GNU2_TLS"
14161   "#"
14162   ""
14163   [(set (match_dup 0) (match_dup 5))]
14164 {
14165   operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14166   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
14167 })
14168
14169 (define_expand "tls_dynamic_gnu2_64"
14170   [(set (match_dup 2)
14171         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14172                    UNSPEC_TLSDESC))
14173    (parallel
14174     [(set (match_operand:DI 0 "register_operand" "")
14175           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
14176                      UNSPEC_TLSDESC))
14177      (clobber (reg:CC FLAGS_REG))])]
14178   "TARGET_64BIT && TARGET_GNU2_TLS"
14179 {
14180   operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14181   ix86_tls_descriptor_calls_expanded_in_cfun = true;
14182 })
14183
14184 (define_insn "*tls_dynamic_lea_64"
14185   [(set (match_operand:DI 0 "register_operand" "=r")
14186         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14187                    UNSPEC_TLSDESC))]
14188   "TARGET_64BIT && TARGET_GNU2_TLS"
14189   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
14190   [(set_attr "type" "lea")
14191    (set_attr "mode" "DI")
14192    (set_attr "length" "7")
14193    (set_attr "length_address" "4")])
14194
14195 (define_insn "*tls_dynamic_call_64"
14196   [(set (match_operand:DI 0 "register_operand" "=a")
14197         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
14198                     (match_operand:DI 2 "register_operand" "0")
14199                     (reg:DI SP_REG)]
14200                    UNSPEC_TLSDESC))
14201    (clobber (reg:CC FLAGS_REG))]
14202   "TARGET_64BIT && TARGET_GNU2_TLS"
14203   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
14204   [(set_attr "type" "call")
14205    (set_attr "length" "2")
14206    (set_attr "length_address" "0")])
14207
14208 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
14209   [(set (match_operand:DI 0 "register_operand" "=&a")
14210         (plus:DI
14211          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
14212                      (match_operand:DI 3 "" "")
14213                      (reg:DI SP_REG)]
14214                     UNSPEC_TLSDESC)
14215          (const:DI (unspec:DI
14216                     [(match_operand:DI 1 "tls_symbolic_operand" "")]
14217                     UNSPEC_DTPOFF))))
14218    (clobber (reg:CC FLAGS_REG))]
14219   "TARGET_64BIT && TARGET_GNU2_TLS"
14220   "#"
14221   ""
14222   [(set (match_dup 0) (match_dup 4))]
14223 {
14224   operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14225   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
14226 })
14227
14228 ;;
14229 \f
14230 ;; These patterns match the binary 387 instructions for addM3, subM3,
14231 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
14232 ;; SFmode.  The first is the normal insn, the second the same insn but
14233 ;; with one operand a conversion, and the third the same insn but with
14234 ;; the other operand a conversion.  The conversion may be SFmode or
14235 ;; SImode if the target mode DFmode, but only SImode if the target mode
14236 ;; is SFmode.
14237
14238 ;; Gcc is slightly more smart about handling normal two address instructions
14239 ;; so use special patterns for add and mull.
14240
14241 (define_insn "*fop_<mode>_comm_mixed_avx"
14242   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
14243         (match_operator:MODEF 3 "binary_fp_operator"
14244           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
14245            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
14246   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
14247    && COMMUTATIVE_ARITH_P (operands[3])
14248    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14249   "* return output_387_binary_op (insn, operands);"
14250   [(set (attr "type")
14251         (if_then_else (eq_attr "alternative" "1")
14252            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
14253               (const_string "ssemul")
14254               (const_string "sseadd"))
14255            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
14256               (const_string "fmul")
14257               (const_string "fop"))))
14258    (set_attr "prefix" "orig,maybe_vex")
14259    (set_attr "mode" "<MODE>")])
14260
14261 (define_insn "*fop_<mode>_comm_mixed"
14262   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
14263         (match_operator:MODEF 3 "binary_fp_operator"
14264           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
14265            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
14266   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
14267    && COMMUTATIVE_ARITH_P (operands[3])
14268    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14269   "* return output_387_binary_op (insn, operands);"
14270   [(set (attr "type")
14271         (if_then_else (eq_attr "alternative" "1")
14272            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
14273               (const_string "ssemul")
14274               (const_string "sseadd"))
14275            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
14276               (const_string "fmul")
14277               (const_string "fop"))))
14278    (set_attr "mode" "<MODE>")])
14279
14280 (define_insn "*fop_<mode>_comm_avx"
14281   [(set (match_operand:MODEF 0 "register_operand" "=x")
14282         (match_operator:MODEF 3 "binary_fp_operator"
14283           [(match_operand:MODEF 1 "nonimmediate_operand" "%x")
14284            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
14285   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14286    && COMMUTATIVE_ARITH_P (operands[3])
14287    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14288   "* return output_387_binary_op (insn, operands);"
14289   [(set (attr "type")
14290         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
14291            (const_string "ssemul")
14292            (const_string "sseadd")))
14293    (set_attr "prefix" "vex")
14294    (set_attr "mode" "<MODE>")])
14295
14296 (define_insn "*fop_<mode>_comm_sse"
14297   [(set (match_operand:MODEF 0 "register_operand" "=x")
14298         (match_operator:MODEF 3 "binary_fp_operator"
14299           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
14300            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
14301   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14302    && COMMUTATIVE_ARITH_P (operands[3])
14303    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14304   "* return output_387_binary_op (insn, operands);"
14305   [(set (attr "type")
14306         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
14307            (const_string "ssemul")
14308            (const_string "sseadd")))
14309    (set_attr "mode" "<MODE>")])
14310
14311 (define_insn "*fop_<mode>_comm_i387"
14312   [(set (match_operand:MODEF 0 "register_operand" "=f")
14313         (match_operator:MODEF 3 "binary_fp_operator"
14314           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
14315            (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
14316   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
14317    && COMMUTATIVE_ARITH_P (operands[3])
14318    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14319   "* return output_387_binary_op (insn, operands);"
14320   [(set (attr "type")
14321         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
14322            (const_string "fmul")
14323            (const_string "fop")))
14324    (set_attr "mode" "<MODE>")])
14325
14326 (define_insn "*fop_<mode>_1_mixed_avx"
14327   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
14328         (match_operator:MODEF 3 "binary_fp_operator"
14329           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,x")
14330            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
14331   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
14332    && !COMMUTATIVE_ARITH_P (operands[3])
14333    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14334   "* return output_387_binary_op (insn, operands);"
14335   [(set (attr "type")
14336         (cond [(and (eq_attr "alternative" "2")
14337                     (match_operand:MODEF 3 "mult_operator" ""))
14338                  (const_string "ssemul")
14339                (and (eq_attr "alternative" "2")
14340                     (match_operand:MODEF 3 "div_operator" ""))
14341                  (const_string "ssediv")
14342                (eq_attr "alternative" "2")
14343                  (const_string "sseadd")
14344                (match_operand:MODEF 3 "mult_operator" "")
14345                  (const_string "fmul")
14346                (match_operand:MODEF 3 "div_operator" "")
14347                  (const_string "fdiv")
14348               ]
14349               (const_string "fop")))
14350    (set_attr "prefix" "orig,orig,maybe_vex")
14351    (set_attr "mode" "<MODE>")])
14352
14353 (define_insn "*fop_<mode>_1_mixed"
14354   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
14355         (match_operator:MODEF 3 "binary_fp_operator"
14356           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
14357            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
14358   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
14359    && !COMMUTATIVE_ARITH_P (operands[3])
14360    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14361   "* return output_387_binary_op (insn, operands);"
14362   [(set (attr "type")
14363         (cond [(and (eq_attr "alternative" "2")
14364                     (match_operand:MODEF 3 "mult_operator" ""))
14365                  (const_string "ssemul")
14366                (and (eq_attr "alternative" "2")
14367                     (match_operand:MODEF 3 "div_operator" ""))
14368                  (const_string "ssediv")
14369                (eq_attr "alternative" "2")
14370                  (const_string "sseadd")
14371                (match_operand:MODEF 3 "mult_operator" "")
14372                  (const_string "fmul")
14373                (match_operand:MODEF 3 "div_operator" "")
14374                  (const_string "fdiv")
14375               ]
14376               (const_string "fop")))
14377    (set_attr "mode" "<MODE>")])
14378
14379 (define_insn "*rcpsf2_sse"
14380   [(set (match_operand:SF 0 "register_operand" "=x")
14381         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
14382                    UNSPEC_RCP))]
14383   "TARGET_SSE_MATH"
14384   "%vrcpss\t{%1, %d0|%d0, %1}"
14385   [(set_attr "type" "sse")
14386    (set_attr "atom_sse_attr" "rcp")
14387    (set_attr "prefix" "maybe_vex")
14388    (set_attr "mode" "SF")])
14389
14390 (define_insn "*fop_<mode>_1_avx"
14391   [(set (match_operand:MODEF 0 "register_operand" "=x")
14392         (match_operator:MODEF 3 "binary_fp_operator"
14393           [(match_operand:MODEF 1 "register_operand" "x")
14394            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
14395   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14396    && !COMMUTATIVE_ARITH_P (operands[3])"
14397   "* return output_387_binary_op (insn, operands);"
14398   [(set (attr "type")
14399         (cond [(match_operand:MODEF 3 "mult_operator" "")
14400                  (const_string "ssemul")
14401                (match_operand:MODEF 3 "div_operator" "")
14402                  (const_string "ssediv")
14403               ]
14404               (const_string "sseadd")))
14405    (set_attr "prefix" "vex")
14406    (set_attr "mode" "<MODE>")])
14407
14408 (define_insn "*fop_<mode>_1_sse"
14409   [(set (match_operand:MODEF 0 "register_operand" "=x")
14410         (match_operator:MODEF 3 "binary_fp_operator"
14411           [(match_operand:MODEF 1 "register_operand" "0")
14412            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
14413   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14414    && !COMMUTATIVE_ARITH_P (operands[3])"
14415   "* return output_387_binary_op (insn, operands);"
14416   [(set (attr "type")
14417         (cond [(match_operand:MODEF 3 "mult_operator" "")
14418                  (const_string "ssemul")
14419                (match_operand:MODEF 3 "div_operator" "")
14420                  (const_string "ssediv")
14421               ]
14422               (const_string "sseadd")))
14423    (set_attr "mode" "<MODE>")])
14424
14425 ;; This pattern is not fully shadowed by the pattern above.
14426 (define_insn "*fop_<mode>_1_i387"
14427   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
14428         (match_operator:MODEF 3 "binary_fp_operator"
14429           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
14430            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
14431   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
14432    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14433    && !COMMUTATIVE_ARITH_P (operands[3])
14434    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14435   "* return output_387_binary_op (insn, operands);"
14436   [(set (attr "type")
14437         (cond [(match_operand:MODEF 3 "mult_operator" "")
14438                  (const_string "fmul")
14439                (match_operand:MODEF 3 "div_operator" "")
14440                  (const_string "fdiv")
14441               ]
14442               (const_string "fop")))
14443    (set_attr "mode" "<MODE>")])
14444
14445 ;; ??? Add SSE splitters for these!
14446 (define_insn "*fop_<MODEF:mode>_2_i387"
14447   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
14448         (match_operator:MODEF 3 "binary_fp_operator"
14449           [(float:MODEF
14450              (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14451            (match_operand:MODEF 2 "register_operand" "0,0")]))]
14452   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
14453    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
14454    && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
14455   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14456   [(set (attr "type")
14457         (cond [(match_operand:MODEF 3 "mult_operator" "")
14458                  (const_string "fmul")
14459                (match_operand:MODEF 3 "div_operator" "")
14460                  (const_string "fdiv")
14461               ]
14462               (const_string "fop")))
14463    (set_attr "fp_int_src" "true")
14464    (set_attr "mode" "<X87MODEI12:MODE>")])
14465
14466 (define_insn "*fop_<MODEF:mode>_3_i387"
14467   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
14468         (match_operator:MODEF 3 "binary_fp_operator"
14469           [(match_operand:MODEF 1 "register_operand" "0,0")
14470            (float:MODEF
14471              (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14472   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
14473    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
14474    && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
14475   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14476   [(set (attr "type")
14477         (cond [(match_operand:MODEF 3 "mult_operator" "")
14478                  (const_string "fmul")
14479                (match_operand:MODEF 3 "div_operator" "")
14480                  (const_string "fdiv")
14481               ]
14482               (const_string "fop")))
14483    (set_attr "fp_int_src" "true")
14484    (set_attr "mode" "<MODE>")])
14485
14486 (define_insn "*fop_df_4_i387"
14487   [(set (match_operand:DF 0 "register_operand" "=f,f")
14488         (match_operator:DF 3 "binary_fp_operator"
14489            [(float_extend:DF
14490              (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14491             (match_operand:DF 2 "register_operand" "0,f")]))]
14492   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
14493    && !(TARGET_SSE2 && TARGET_SSE_MATH)
14494    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14495   "* return output_387_binary_op (insn, operands);"
14496   [(set (attr "type")
14497         (cond [(match_operand:DF 3 "mult_operator" "")
14498                  (const_string "fmul")
14499                (match_operand:DF 3 "div_operator" "")
14500                  (const_string "fdiv")
14501               ]
14502               (const_string "fop")))
14503    (set_attr "mode" "SF")])
14504
14505 (define_insn "*fop_df_5_i387"
14506   [(set (match_operand:DF 0 "register_operand" "=f,f")
14507         (match_operator:DF 3 "binary_fp_operator"
14508           [(match_operand:DF 1 "register_operand" "0,f")
14509            (float_extend:DF
14510             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14511   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
14512    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14513   "* return output_387_binary_op (insn, operands);"
14514   [(set (attr "type")
14515         (cond [(match_operand:DF 3 "mult_operator" "")
14516                  (const_string "fmul")
14517                (match_operand:DF 3 "div_operator" "")
14518                  (const_string "fdiv")
14519               ]
14520               (const_string "fop")))
14521    (set_attr "mode" "SF")])
14522
14523 (define_insn "*fop_df_6_i387"
14524   [(set (match_operand:DF 0 "register_operand" "=f,f")
14525         (match_operator:DF 3 "binary_fp_operator"
14526           [(float_extend:DF
14527             (match_operand:SF 1 "register_operand" "0,f"))
14528            (float_extend:DF
14529             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14530   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
14531    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14532   "* return output_387_binary_op (insn, operands);"
14533   [(set (attr "type")
14534         (cond [(match_operand:DF 3 "mult_operator" "")
14535                  (const_string "fmul")
14536                (match_operand:DF 3 "div_operator" "")
14537                  (const_string "fdiv")
14538               ]
14539               (const_string "fop")))
14540    (set_attr "mode" "SF")])
14541
14542 (define_insn "*fop_xf_comm_i387"
14543   [(set (match_operand:XF 0 "register_operand" "=f")
14544         (match_operator:XF 3 "binary_fp_operator"
14545                         [(match_operand:XF 1 "register_operand" "%0")
14546                          (match_operand:XF 2 "register_operand" "f")]))]
14547   "TARGET_80387
14548    && COMMUTATIVE_ARITH_P (operands[3])"
14549   "* return output_387_binary_op (insn, operands);"
14550   [(set (attr "type")
14551         (if_then_else (match_operand:XF 3 "mult_operator" "")
14552            (const_string "fmul")
14553            (const_string "fop")))
14554    (set_attr "mode" "XF")])
14555
14556 (define_insn "*fop_xf_1_i387"
14557   [(set (match_operand:XF 0 "register_operand" "=f,f")
14558         (match_operator:XF 3 "binary_fp_operator"
14559                         [(match_operand:XF 1 "register_operand" "0,f")
14560                          (match_operand:XF 2 "register_operand" "f,0")]))]
14561   "TARGET_80387
14562    && !COMMUTATIVE_ARITH_P (operands[3])"
14563   "* return output_387_binary_op (insn, operands);"
14564   [(set (attr "type")
14565         (cond [(match_operand:XF 3 "mult_operator" "")
14566                  (const_string "fmul")
14567                (match_operand:XF 3 "div_operator" "")
14568                  (const_string "fdiv")
14569               ]
14570               (const_string "fop")))
14571    (set_attr "mode" "XF")])
14572
14573 (define_insn "*fop_xf_2_i387"
14574   [(set (match_operand:XF 0 "register_operand" "=f,f")
14575         (match_operator:XF 3 "binary_fp_operator"
14576           [(float:XF
14577              (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14578            (match_operand:XF 2 "register_operand" "0,0")]))]
14579   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
14580   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14581   [(set (attr "type")
14582         (cond [(match_operand:XF 3 "mult_operator" "")
14583                  (const_string "fmul")
14584                (match_operand:XF 3 "div_operator" "")
14585                  (const_string "fdiv")
14586               ]
14587               (const_string "fop")))
14588    (set_attr "fp_int_src" "true")
14589    (set_attr "mode" "<MODE>")])
14590
14591 (define_insn "*fop_xf_3_i387"
14592   [(set (match_operand:XF 0 "register_operand" "=f,f")
14593         (match_operator:XF 3 "binary_fp_operator"
14594           [(match_operand:XF 1 "register_operand" "0,0")
14595            (float:XF
14596              (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14597   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
14598   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14599   [(set (attr "type")
14600         (cond [(match_operand:XF 3 "mult_operator" "")
14601                  (const_string "fmul")
14602                (match_operand:XF 3 "div_operator" "")
14603                  (const_string "fdiv")
14604               ]
14605               (const_string "fop")))
14606    (set_attr "fp_int_src" "true")
14607    (set_attr "mode" "<MODE>")])
14608
14609 (define_insn "*fop_xf_4_i387"
14610   [(set (match_operand:XF 0 "register_operand" "=f,f")
14611         (match_operator:XF 3 "binary_fp_operator"
14612            [(float_extend:XF
14613               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
14614             (match_operand:XF 2 "register_operand" "0,f")]))]
14615   "TARGET_80387"
14616   "* return output_387_binary_op (insn, operands);"
14617   [(set (attr "type")
14618         (cond [(match_operand:XF 3 "mult_operator" "")
14619                  (const_string "fmul")
14620                (match_operand:XF 3 "div_operator" "")
14621                  (const_string "fdiv")
14622               ]
14623               (const_string "fop")))
14624    (set_attr "mode" "<MODE>")])
14625
14626 (define_insn "*fop_xf_5_i387"
14627   [(set (match_operand:XF 0 "register_operand" "=f,f")
14628         (match_operator:XF 3 "binary_fp_operator"
14629           [(match_operand:XF 1 "register_operand" "0,f")
14630            (float_extend:XF
14631              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
14632   "TARGET_80387"
14633   "* return output_387_binary_op (insn, operands);"
14634   [(set (attr "type")
14635         (cond [(match_operand:XF 3 "mult_operator" "")
14636                  (const_string "fmul")
14637                (match_operand:XF 3 "div_operator" "")
14638                  (const_string "fdiv")
14639               ]
14640               (const_string "fop")))
14641    (set_attr "mode" "<MODE>")])
14642
14643 (define_insn "*fop_xf_6_i387"
14644   [(set (match_operand:XF 0 "register_operand" "=f,f")
14645         (match_operator:XF 3 "binary_fp_operator"
14646           [(float_extend:XF
14647              (match_operand:MODEF 1 "register_operand" "0,f"))
14648            (float_extend:XF
14649              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
14650   "TARGET_80387"
14651   "* return output_387_binary_op (insn, operands);"
14652   [(set (attr "type")
14653         (cond [(match_operand:XF 3 "mult_operator" "")
14654                  (const_string "fmul")
14655                (match_operand:XF 3 "div_operator" "")
14656                  (const_string "fdiv")
14657               ]
14658               (const_string "fop")))
14659    (set_attr "mode" "<MODE>")])
14660
14661 (define_split
14662   [(set (match_operand 0 "register_operand" "")
14663         (match_operator 3 "binary_fp_operator"
14664            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
14665             (match_operand 2 "register_operand" "")]))]
14666   "reload_completed
14667    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
14668    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
14669   [(const_int 0)]
14670 {
14671   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
14672   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14673   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14674                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14675                                           GET_MODE (operands[3]),
14676                                           operands[4],
14677                                           operands[2])));
14678   ix86_free_from_memory (GET_MODE (operands[1]));
14679   DONE;
14680 })
14681
14682 (define_split
14683   [(set (match_operand 0 "register_operand" "")
14684         (match_operator 3 "binary_fp_operator"
14685            [(match_operand 1 "register_operand" "")
14686             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
14687   "reload_completed
14688    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
14689    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
14690   [(const_int 0)]
14691 {
14692   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14693   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14694   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14695                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14696                                           GET_MODE (operands[3]),
14697                                           operands[1],
14698                                           operands[4])));
14699   ix86_free_from_memory (GET_MODE (operands[2]));
14700   DONE;
14701 })
14702 \f
14703 ;; FPU special functions.
14704
14705 ;; This pattern implements a no-op XFmode truncation for
14706 ;; all fancy i386 XFmode math functions.
14707
14708 (define_insn "truncxf<mode>2_i387_noop_unspec"
14709   [(set (match_operand:MODEF 0 "register_operand" "=f")
14710         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
14711         UNSPEC_TRUNC_NOOP))]
14712   "TARGET_USE_FANCY_MATH_387"
14713   "* return output_387_reg_move (insn, operands);"
14714   [(set_attr "type" "fmov")
14715    (set_attr "mode" "<MODE>")])
14716
14717 (define_insn "sqrtxf2"
14718   [(set (match_operand:XF 0 "register_operand" "=f")
14719         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14720   "TARGET_USE_FANCY_MATH_387"
14721   "fsqrt"
14722   [(set_attr "type" "fpspc")
14723    (set_attr "mode" "XF")
14724    (set_attr "athlon_decode" "direct")
14725    (set_attr "amdfam10_decode" "direct")])
14726
14727 (define_insn "sqrt_extend<mode>xf2_i387"
14728   [(set (match_operand:XF 0 "register_operand" "=f")
14729         (sqrt:XF
14730           (float_extend:XF
14731             (match_operand:MODEF 1 "register_operand" "0"))))]
14732   "TARGET_USE_FANCY_MATH_387"
14733   "fsqrt"
14734   [(set_attr "type" "fpspc")
14735    (set_attr "mode" "XF")
14736    (set_attr "athlon_decode" "direct")
14737    (set_attr "amdfam10_decode" "direct")])
14738
14739 (define_insn "*rsqrtsf2_sse"
14740   [(set (match_operand:SF 0 "register_operand" "=x")
14741         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
14742                    UNSPEC_RSQRT))]
14743   "TARGET_SSE_MATH"
14744   "%vrsqrtss\t{%1, %d0|%d0, %1}"
14745   [(set_attr "type" "sse")
14746    (set_attr "atom_sse_attr" "rcp")
14747    (set_attr "prefix" "maybe_vex")
14748    (set_attr "mode" "SF")])
14749
14750 (define_expand "rsqrtsf2"
14751   [(set (match_operand:SF 0 "register_operand" "")
14752         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
14753                    UNSPEC_RSQRT))]
14754   "TARGET_SSE_MATH"
14755 {
14756   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
14757   DONE;
14758 })
14759
14760 (define_insn "*sqrt<mode>2_sse"
14761   [(set (match_operand:MODEF 0 "register_operand" "=x")
14762         (sqrt:MODEF
14763           (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
14764   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
14765   "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}"
14766   [(set_attr "type" "sse")
14767    (set_attr "atom_sse_attr" "sqrt")
14768    (set_attr "prefix" "maybe_vex")
14769    (set_attr "mode" "<MODE>")
14770    (set_attr "athlon_decode" "*")
14771    (set_attr "amdfam10_decode" "*")])
14772
14773 (define_expand "sqrt<mode>2"
14774   [(set (match_operand:MODEF 0 "register_operand" "")
14775         (sqrt:MODEF
14776           (match_operand:MODEF 1 "nonimmediate_operand" "")))]
14777   "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
14778    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
14779 {
14780   if (<MODE>mode == SFmode
14781       && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
14782       && flag_finite_math_only && !flag_trapping_math
14783       && flag_unsafe_math_optimizations)
14784     {
14785       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
14786       DONE;
14787     }
14788
14789   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
14790     {
14791       rtx op0 = gen_reg_rtx (XFmode);
14792       rtx op1 = force_reg (<MODE>mode, operands[1]);
14793
14794       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
14795       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
14796       DONE;
14797    }
14798 })
14799
14800 (define_insn "fpremxf4_i387"
14801   [(set (match_operand:XF 0 "register_operand" "=f")
14802         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14803                     (match_operand:XF 3 "register_operand" "1")]
14804                    UNSPEC_FPREM_F))
14805    (set (match_operand:XF 1 "register_operand" "=u")
14806         (unspec:XF [(match_dup 2) (match_dup 3)]
14807                    UNSPEC_FPREM_U))
14808    (set (reg:CCFP FPSR_REG)
14809         (unspec:CCFP [(match_dup 2) (match_dup 3)]
14810                      UNSPEC_C2_FLAG))]
14811   "TARGET_USE_FANCY_MATH_387"
14812   "fprem"
14813   [(set_attr "type" "fpspc")
14814    (set_attr "mode" "XF")])
14815
14816 (define_expand "fmodxf3"
14817   [(use (match_operand:XF 0 "register_operand" ""))
14818    (use (match_operand:XF 1 "general_operand" ""))
14819    (use (match_operand:XF 2 "general_operand" ""))]
14820   "TARGET_USE_FANCY_MATH_387"
14821 {
14822   rtx label = gen_label_rtx ();
14823
14824   rtx op1 = gen_reg_rtx (XFmode);
14825   rtx op2 = gen_reg_rtx (XFmode);
14826
14827   emit_move_insn (op2, operands[2]);
14828   emit_move_insn (op1, operands[1]);
14829
14830   emit_label (label);
14831   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
14832   ix86_emit_fp_unordered_jump (label);
14833   LABEL_NUSES (label) = 1;
14834
14835   emit_move_insn (operands[0], op1);
14836   DONE;
14837 })
14838
14839 (define_expand "fmod<mode>3"
14840   [(use (match_operand:MODEF 0 "register_operand" ""))
14841    (use (match_operand:MODEF 1 "general_operand" ""))
14842    (use (match_operand:MODEF 2 "general_operand" ""))]
14843   "TARGET_USE_FANCY_MATH_387"
14844 {
14845   rtx label = gen_label_rtx ();
14846
14847   rtx op1 = gen_reg_rtx (XFmode);
14848   rtx op2 = gen_reg_rtx (XFmode);
14849
14850   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14851   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14852
14853   emit_label (label);
14854   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
14855   ix86_emit_fp_unordered_jump (label);
14856   LABEL_NUSES (label) = 1;
14857
14858   /* Truncate the result properly for strict SSE math.  */
14859   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14860       && !TARGET_MIX_SSE_I387)
14861     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
14862   else
14863     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
14864
14865   DONE;
14866 })
14867
14868 (define_insn "fprem1xf4_i387"
14869   [(set (match_operand:XF 0 "register_operand" "=f")
14870         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14871                     (match_operand:XF 3 "register_operand" "1")]
14872                    UNSPEC_FPREM1_F))
14873    (set (match_operand:XF 1 "register_operand" "=u")
14874         (unspec:XF [(match_dup 2) (match_dup 3)]
14875                    UNSPEC_FPREM1_U))
14876    (set (reg:CCFP FPSR_REG)
14877         (unspec:CCFP [(match_dup 2) (match_dup 3)]
14878                      UNSPEC_C2_FLAG))]
14879   "TARGET_USE_FANCY_MATH_387"
14880   "fprem1"
14881   [(set_attr "type" "fpspc")
14882    (set_attr "mode" "XF")])
14883
14884 (define_expand "remainderxf3"
14885   [(use (match_operand:XF 0 "register_operand" ""))
14886    (use (match_operand:XF 1 "general_operand" ""))
14887    (use (match_operand:XF 2 "general_operand" ""))]
14888   "TARGET_USE_FANCY_MATH_387"
14889 {
14890   rtx label = gen_label_rtx ();
14891
14892   rtx op1 = gen_reg_rtx (XFmode);
14893   rtx op2 = gen_reg_rtx (XFmode);
14894
14895   emit_move_insn (op2, operands[2]);
14896   emit_move_insn (op1, operands[1]);
14897
14898   emit_label (label);
14899   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
14900   ix86_emit_fp_unordered_jump (label);
14901   LABEL_NUSES (label) = 1;
14902
14903   emit_move_insn (operands[0], op1);
14904   DONE;
14905 })
14906
14907 (define_expand "remainder<mode>3"
14908   [(use (match_operand:MODEF 0 "register_operand" ""))
14909    (use (match_operand:MODEF 1 "general_operand" ""))
14910    (use (match_operand:MODEF 2 "general_operand" ""))]
14911   "TARGET_USE_FANCY_MATH_387"
14912 {
14913   rtx label = gen_label_rtx ();
14914
14915   rtx op1 = gen_reg_rtx (XFmode);
14916   rtx op2 = gen_reg_rtx (XFmode);
14917
14918   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14919   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14920
14921   emit_label (label);
14922
14923   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
14924   ix86_emit_fp_unordered_jump (label);
14925   LABEL_NUSES (label) = 1;
14926
14927   /* Truncate the result properly for strict SSE math.  */
14928   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14929       && !TARGET_MIX_SSE_I387)
14930     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
14931   else
14932     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
14933
14934   DONE;
14935 })
14936
14937 (define_insn "*sinxf2_i387"
14938   [(set (match_operand:XF 0 "register_operand" "=f")
14939         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
14940   "TARGET_USE_FANCY_MATH_387
14941    && flag_unsafe_math_optimizations"
14942   "fsin"
14943   [(set_attr "type" "fpspc")
14944    (set_attr "mode" "XF")])
14945
14946 (define_insn "*sin_extend<mode>xf2_i387"
14947   [(set (match_operand:XF 0 "register_operand" "=f")
14948         (unspec:XF [(float_extend:XF
14949                       (match_operand:MODEF 1 "register_operand" "0"))]
14950                    UNSPEC_SIN))]
14951   "TARGET_USE_FANCY_MATH_387
14952    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14953        || TARGET_MIX_SSE_I387)
14954    && flag_unsafe_math_optimizations"
14955   "fsin"
14956   [(set_attr "type" "fpspc")
14957    (set_attr "mode" "XF")])
14958
14959 (define_insn "*cosxf2_i387"
14960   [(set (match_operand:XF 0 "register_operand" "=f")
14961         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
14962   "TARGET_USE_FANCY_MATH_387
14963    && flag_unsafe_math_optimizations"
14964   "fcos"
14965   [(set_attr "type" "fpspc")
14966    (set_attr "mode" "XF")])
14967
14968 (define_insn "*cos_extend<mode>xf2_i387"
14969   [(set (match_operand:XF 0 "register_operand" "=f")
14970         (unspec:XF [(float_extend:XF
14971                       (match_operand:MODEF 1 "register_operand" "0"))]
14972                    UNSPEC_COS))]
14973   "TARGET_USE_FANCY_MATH_387
14974    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14975        || TARGET_MIX_SSE_I387)
14976    && flag_unsafe_math_optimizations"
14977   "fcos"
14978   [(set_attr "type" "fpspc")
14979    (set_attr "mode" "XF")])
14980
14981 ;; When sincos pattern is defined, sin and cos builtin functions will be
14982 ;; expanded to sincos pattern with one of its outputs left unused.
14983 ;; CSE pass will figure out if two sincos patterns can be combined,
14984 ;; otherwise sincos pattern will be split back to sin or cos pattern,
14985 ;; depending on the unused output.
14986
14987 (define_insn "sincosxf3"
14988   [(set (match_operand:XF 0 "register_operand" "=f")
14989         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14990                    UNSPEC_SINCOS_COS))
14991    (set (match_operand:XF 1 "register_operand" "=u")
14992         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14993   "TARGET_USE_FANCY_MATH_387
14994    && flag_unsafe_math_optimizations"
14995   "fsincos"
14996   [(set_attr "type" "fpspc")
14997    (set_attr "mode" "XF")])
14998
14999 (define_split
15000   [(set (match_operand:XF 0 "register_operand" "")
15001         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15002                    UNSPEC_SINCOS_COS))
15003    (set (match_operand:XF 1 "register_operand" "")
15004         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15005   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15006    && !(reload_completed || reload_in_progress)"
15007   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15008   "")
15009
15010 (define_split
15011   [(set (match_operand:XF 0 "register_operand" "")
15012         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15013                    UNSPEC_SINCOS_COS))
15014    (set (match_operand:XF 1 "register_operand" "")
15015         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15016   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15017    && !(reload_completed || reload_in_progress)"
15018   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15019   "")
15020
15021 (define_insn "sincos_extend<mode>xf3_i387"
15022   [(set (match_operand:XF 0 "register_operand" "=f")
15023         (unspec:XF [(float_extend:XF
15024                       (match_operand:MODEF 2 "register_operand" "0"))]
15025                    UNSPEC_SINCOS_COS))
15026    (set (match_operand:XF 1 "register_operand" "=u")
15027         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
15028   "TARGET_USE_FANCY_MATH_387
15029    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15030        || TARGET_MIX_SSE_I387)
15031    && flag_unsafe_math_optimizations"
15032   "fsincos"
15033   [(set_attr "type" "fpspc")
15034    (set_attr "mode" "XF")])
15035
15036 (define_split
15037   [(set (match_operand:XF 0 "register_operand" "")
15038         (unspec:XF [(float_extend:XF
15039                       (match_operand:MODEF 2 "register_operand" ""))]
15040                    UNSPEC_SINCOS_COS))
15041    (set (match_operand:XF 1 "register_operand" "")
15042         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
15043   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15044    && !(reload_completed || reload_in_progress)"
15045   [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
15046   "")
15047
15048 (define_split
15049   [(set (match_operand:XF 0 "register_operand" "")
15050         (unspec:XF [(float_extend:XF
15051                       (match_operand:MODEF 2 "register_operand" ""))]
15052                    UNSPEC_SINCOS_COS))
15053    (set (match_operand:XF 1 "register_operand" "")
15054         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
15055   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15056    && !(reload_completed || reload_in_progress)"
15057   [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
15058   "")
15059
15060 (define_expand "sincos<mode>3"
15061   [(use (match_operand:MODEF 0 "register_operand" ""))
15062    (use (match_operand:MODEF 1 "register_operand" ""))
15063    (use (match_operand:MODEF 2 "register_operand" ""))]
15064   "TARGET_USE_FANCY_MATH_387
15065    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15066        || TARGET_MIX_SSE_I387)
15067    && flag_unsafe_math_optimizations"
15068 {
15069   rtx op0 = gen_reg_rtx (XFmode);
15070   rtx op1 = gen_reg_rtx (XFmode);
15071
15072   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
15073   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15074   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
15075   DONE;
15076 })
15077
15078 (define_insn "fptanxf4_i387"
15079   [(set (match_operand:XF 0 "register_operand" "=f")
15080         (match_operand:XF 3 "const_double_operand" "F"))
15081    (set (match_operand:XF 1 "register_operand" "=u")
15082         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15083                    UNSPEC_TAN))]
15084   "TARGET_USE_FANCY_MATH_387
15085    && flag_unsafe_math_optimizations
15086    && standard_80387_constant_p (operands[3]) == 2"
15087   "fptan"
15088   [(set_attr "type" "fpspc")
15089    (set_attr "mode" "XF")])
15090
15091 (define_insn "fptan_extend<mode>xf4_i387"
15092   [(set (match_operand:MODEF 0 "register_operand" "=f")
15093         (match_operand:MODEF 3 "const_double_operand" "F"))
15094    (set (match_operand:XF 1 "register_operand" "=u")
15095         (unspec:XF [(float_extend:XF
15096                       (match_operand:MODEF 2 "register_operand" "0"))]
15097                    UNSPEC_TAN))]
15098   "TARGET_USE_FANCY_MATH_387
15099    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15100        || TARGET_MIX_SSE_I387)
15101    && flag_unsafe_math_optimizations
15102    && standard_80387_constant_p (operands[3]) == 2"
15103   "fptan"
15104   [(set_attr "type" "fpspc")
15105    (set_attr "mode" "XF")])
15106
15107 (define_expand "tanxf2"
15108   [(use (match_operand:XF 0 "register_operand" ""))
15109    (use (match_operand:XF 1 "register_operand" ""))]
15110   "TARGET_USE_FANCY_MATH_387
15111    && flag_unsafe_math_optimizations"
15112 {
15113   rtx one = gen_reg_rtx (XFmode);
15114   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
15115
15116   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
15117   DONE;
15118 })
15119
15120 (define_expand "tan<mode>2"
15121   [(use (match_operand:MODEF 0 "register_operand" ""))
15122    (use (match_operand:MODEF 1 "register_operand" ""))]
15123   "TARGET_USE_FANCY_MATH_387
15124    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15125        || TARGET_MIX_SSE_I387)
15126    && flag_unsafe_math_optimizations"
15127 {
15128   rtx op0 = gen_reg_rtx (XFmode);
15129
15130   rtx one = gen_reg_rtx (<MODE>mode);
15131   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
15132
15133   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
15134                                              operands[1], op2));
15135   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15136   DONE;
15137 })
15138
15139 (define_insn "*fpatanxf3_i387"
15140   [(set (match_operand:XF 0 "register_operand" "=f")
15141         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
15142                     (match_operand:XF 2 "register_operand" "u")]
15143                    UNSPEC_FPATAN))
15144    (clobber (match_scratch:XF 3 "=2"))]
15145   "TARGET_USE_FANCY_MATH_387
15146    && flag_unsafe_math_optimizations"
15147   "fpatan"
15148   [(set_attr "type" "fpspc")
15149    (set_attr "mode" "XF")])
15150
15151 (define_insn "fpatan_extend<mode>xf3_i387"
15152   [(set (match_operand:XF 0 "register_operand" "=f")
15153         (unspec:XF [(float_extend:XF
15154                       (match_operand:MODEF 1 "register_operand" "0"))
15155                     (float_extend:XF
15156                       (match_operand:MODEF 2 "register_operand" "u"))]
15157                    UNSPEC_FPATAN))
15158    (clobber (match_scratch:XF 3 "=2"))]
15159   "TARGET_USE_FANCY_MATH_387
15160    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15161        || TARGET_MIX_SSE_I387)
15162    && flag_unsafe_math_optimizations"
15163   "fpatan"
15164   [(set_attr "type" "fpspc")
15165    (set_attr "mode" "XF")])
15166
15167 (define_expand "atan2xf3"
15168   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15169                    (unspec:XF [(match_operand:XF 2 "register_operand" "")
15170                                (match_operand:XF 1 "register_operand" "")]
15171                               UNSPEC_FPATAN))
15172               (clobber (match_scratch:XF 3 ""))])]
15173   "TARGET_USE_FANCY_MATH_387
15174    && flag_unsafe_math_optimizations"
15175   "")
15176
15177 (define_expand "atan2<mode>3"
15178   [(use (match_operand:MODEF 0 "register_operand" ""))
15179    (use (match_operand:MODEF 1 "register_operand" ""))
15180    (use (match_operand:MODEF 2 "register_operand" ""))]
15181   "TARGET_USE_FANCY_MATH_387
15182    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15183        || TARGET_MIX_SSE_I387)
15184    && flag_unsafe_math_optimizations"
15185 {
15186   rtx op0 = gen_reg_rtx (XFmode);
15187
15188   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
15189   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15190   DONE;
15191 })
15192
15193 (define_expand "atanxf2"
15194   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15195                    (unspec:XF [(match_dup 2)
15196                                (match_operand:XF 1 "register_operand" "")]
15197                               UNSPEC_FPATAN))
15198               (clobber (match_scratch:XF 3 ""))])]
15199   "TARGET_USE_FANCY_MATH_387
15200    && flag_unsafe_math_optimizations"
15201 {
15202   operands[2] = gen_reg_rtx (XFmode);
15203   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15204 })
15205
15206 (define_expand "atan<mode>2"
15207   [(use (match_operand:MODEF 0 "register_operand" ""))
15208    (use (match_operand:MODEF 1 "register_operand" ""))]
15209   "TARGET_USE_FANCY_MATH_387
15210    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15211        || TARGET_MIX_SSE_I387)
15212    && flag_unsafe_math_optimizations"
15213 {
15214   rtx op0 = gen_reg_rtx (XFmode);
15215
15216   rtx op2 = gen_reg_rtx (<MODE>mode);
15217   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
15218
15219   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
15220   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15221   DONE;
15222 })
15223
15224 (define_expand "asinxf2"
15225   [(set (match_dup 2)
15226         (mult:XF (match_operand:XF 1 "register_operand" "")
15227                  (match_dup 1)))
15228    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15229    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15230    (parallel [(set (match_operand:XF 0 "register_operand" "")
15231                    (unspec:XF [(match_dup 5) (match_dup 1)]
15232                               UNSPEC_FPATAN))
15233               (clobber (match_scratch:XF 6 ""))])]
15234   "TARGET_USE_FANCY_MATH_387
15235    && flag_unsafe_math_optimizations"
15236 {
15237   int i;
15238
15239   if (optimize_insn_for_size_p ())
15240     FAIL;
15241
15242   for (i = 2; i < 6; i++)
15243     operands[i] = gen_reg_rtx (XFmode);
15244
15245   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15246 })
15247
15248 (define_expand "asin<mode>2"
15249   [(use (match_operand:MODEF 0 "register_operand" ""))
15250    (use (match_operand:MODEF 1 "general_operand" ""))]
15251  "TARGET_USE_FANCY_MATH_387
15252    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15253        || TARGET_MIX_SSE_I387)
15254    && flag_unsafe_math_optimizations"
15255 {
15256   rtx op0 = gen_reg_rtx (XFmode);
15257   rtx op1 = gen_reg_rtx (XFmode);
15258
15259   if (optimize_insn_for_size_p ())
15260     FAIL;
15261
15262   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15263   emit_insn (gen_asinxf2 (op0, op1));
15264   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15265   DONE;
15266 })
15267
15268 (define_expand "acosxf2"
15269   [(set (match_dup 2)
15270         (mult:XF (match_operand:XF 1 "register_operand" "")
15271                  (match_dup 1)))
15272    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15273    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15274    (parallel [(set (match_operand:XF 0 "register_operand" "")
15275                    (unspec:XF [(match_dup 1) (match_dup 5)]
15276                               UNSPEC_FPATAN))
15277               (clobber (match_scratch:XF 6 ""))])]
15278   "TARGET_USE_FANCY_MATH_387
15279    && flag_unsafe_math_optimizations"
15280 {
15281   int i;
15282
15283   if (optimize_insn_for_size_p ())
15284     FAIL;
15285
15286   for (i = 2; i < 6; i++)
15287     operands[i] = gen_reg_rtx (XFmode);
15288
15289   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15290 })
15291
15292 (define_expand "acos<mode>2"
15293   [(use (match_operand:MODEF 0 "register_operand" ""))
15294    (use (match_operand:MODEF 1 "general_operand" ""))]
15295  "TARGET_USE_FANCY_MATH_387
15296    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15297        || TARGET_MIX_SSE_I387)
15298    && flag_unsafe_math_optimizations"
15299 {
15300   rtx op0 = gen_reg_rtx (XFmode);
15301   rtx op1 = gen_reg_rtx (XFmode);
15302
15303   if (optimize_insn_for_size_p ())
15304     FAIL;
15305
15306   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15307   emit_insn (gen_acosxf2 (op0, op1));
15308   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15309   DONE;
15310 })
15311
15312 (define_insn "fyl2xxf3_i387"
15313   [(set (match_operand:XF 0 "register_operand" "=f")
15314         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
15315                     (match_operand:XF 2 "register_operand" "u")]
15316                    UNSPEC_FYL2X))
15317    (clobber (match_scratch:XF 3 "=2"))]
15318   "TARGET_USE_FANCY_MATH_387
15319    && flag_unsafe_math_optimizations"
15320   "fyl2x"
15321   [(set_attr "type" "fpspc")
15322    (set_attr "mode" "XF")])
15323
15324 (define_insn "fyl2x_extend<mode>xf3_i387"
15325   [(set (match_operand:XF 0 "register_operand" "=f")
15326         (unspec:XF [(float_extend:XF
15327                       (match_operand:MODEF 1 "register_operand" "0"))
15328                     (match_operand:XF 2 "register_operand" "u")]
15329                    UNSPEC_FYL2X))
15330    (clobber (match_scratch:XF 3 "=2"))]
15331   "TARGET_USE_FANCY_MATH_387
15332    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15333        || TARGET_MIX_SSE_I387)
15334    && flag_unsafe_math_optimizations"
15335   "fyl2x"
15336   [(set_attr "type" "fpspc")
15337    (set_attr "mode" "XF")])
15338
15339 (define_expand "logxf2"
15340   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15341                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15342                                (match_dup 2)] UNSPEC_FYL2X))
15343               (clobber (match_scratch:XF 3 ""))])]
15344   "TARGET_USE_FANCY_MATH_387
15345    && flag_unsafe_math_optimizations"
15346 {
15347   operands[2] = gen_reg_rtx (XFmode);
15348   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
15349 })
15350
15351 (define_expand "log<mode>2"
15352   [(use (match_operand:MODEF 0 "register_operand" ""))
15353    (use (match_operand:MODEF 1 "register_operand" ""))]
15354   "TARGET_USE_FANCY_MATH_387
15355    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15356        || TARGET_MIX_SSE_I387)
15357    && flag_unsafe_math_optimizations"
15358 {
15359   rtx op0 = gen_reg_rtx (XFmode);
15360
15361   rtx op2 = gen_reg_rtx (XFmode);
15362   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
15363
15364   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
15365   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15366   DONE;
15367 })
15368
15369 (define_expand "log10xf2"
15370   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15371                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15372                                (match_dup 2)] UNSPEC_FYL2X))
15373               (clobber (match_scratch:XF 3 ""))])]
15374   "TARGET_USE_FANCY_MATH_387
15375    && flag_unsafe_math_optimizations"
15376 {
15377   operands[2] = gen_reg_rtx (XFmode);
15378   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
15379 })
15380
15381 (define_expand "log10<mode>2"
15382   [(use (match_operand:MODEF 0 "register_operand" ""))
15383    (use (match_operand:MODEF 1 "register_operand" ""))]
15384   "TARGET_USE_FANCY_MATH_387
15385    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15386        || TARGET_MIX_SSE_I387)
15387    && flag_unsafe_math_optimizations"
15388 {
15389   rtx op0 = gen_reg_rtx (XFmode);
15390
15391   rtx op2 = gen_reg_rtx (XFmode);
15392   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
15393
15394   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
15395   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15396   DONE;
15397 })
15398
15399 (define_expand "log2xf2"
15400   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15401                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15402                                (match_dup 2)] UNSPEC_FYL2X))
15403               (clobber (match_scratch:XF 3 ""))])]
15404   "TARGET_USE_FANCY_MATH_387
15405    && flag_unsafe_math_optimizations"
15406 {
15407   operands[2] = gen_reg_rtx (XFmode);
15408   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15409 })
15410
15411 (define_expand "log2<mode>2"
15412   [(use (match_operand:MODEF 0 "register_operand" ""))
15413    (use (match_operand:MODEF 1 "register_operand" ""))]
15414   "TARGET_USE_FANCY_MATH_387
15415    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15416        || TARGET_MIX_SSE_I387)
15417    && flag_unsafe_math_optimizations"
15418 {
15419   rtx op0 = gen_reg_rtx (XFmode);
15420
15421   rtx op2 = gen_reg_rtx (XFmode);
15422   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
15423
15424   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
15425   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15426   DONE;
15427 })
15428
15429 (define_insn "fyl2xp1xf3_i387"
15430   [(set (match_operand:XF 0 "register_operand" "=f")
15431         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
15432                     (match_operand:XF 2 "register_operand" "u")]
15433                    UNSPEC_FYL2XP1))
15434    (clobber (match_scratch:XF 3 "=2"))]
15435   "TARGET_USE_FANCY_MATH_387
15436    && flag_unsafe_math_optimizations"
15437   "fyl2xp1"
15438   [(set_attr "type" "fpspc")
15439    (set_attr "mode" "XF")])
15440
15441 (define_insn "fyl2xp1_extend<mode>xf3_i387"
15442   [(set (match_operand:XF 0 "register_operand" "=f")
15443         (unspec:XF [(float_extend:XF
15444                       (match_operand:MODEF 1 "register_operand" "0"))
15445                     (match_operand:XF 2 "register_operand" "u")]
15446                    UNSPEC_FYL2XP1))
15447    (clobber (match_scratch:XF 3 "=2"))]
15448   "TARGET_USE_FANCY_MATH_387
15449    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15450        || TARGET_MIX_SSE_I387)
15451    && flag_unsafe_math_optimizations"
15452   "fyl2xp1"
15453   [(set_attr "type" "fpspc")
15454    (set_attr "mode" "XF")])
15455
15456 (define_expand "log1pxf2"
15457   [(use (match_operand:XF 0 "register_operand" ""))
15458    (use (match_operand:XF 1 "register_operand" ""))]
15459   "TARGET_USE_FANCY_MATH_387
15460    && flag_unsafe_math_optimizations"
15461 {
15462   if (optimize_insn_for_size_p ())
15463     FAIL;
15464
15465   ix86_emit_i387_log1p (operands[0], operands[1]);
15466   DONE;
15467 })
15468
15469 (define_expand "log1p<mode>2"
15470   [(use (match_operand:MODEF 0 "register_operand" ""))
15471    (use (match_operand:MODEF 1 "register_operand" ""))]
15472   "TARGET_USE_FANCY_MATH_387
15473    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15474        || TARGET_MIX_SSE_I387)
15475    && flag_unsafe_math_optimizations"
15476 {
15477   rtx op0;
15478
15479   if (optimize_insn_for_size_p ())
15480     FAIL;
15481
15482   op0 = gen_reg_rtx (XFmode);
15483
15484   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
15485
15486   ix86_emit_i387_log1p (op0, operands[1]);
15487   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15488   DONE;
15489 })
15490
15491 (define_insn "fxtractxf3_i387"
15492   [(set (match_operand:XF 0 "register_operand" "=f")
15493         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15494                    UNSPEC_XTRACT_FRACT))
15495    (set (match_operand:XF 1 "register_operand" "=u")
15496         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
15497   "TARGET_USE_FANCY_MATH_387
15498    && flag_unsafe_math_optimizations"
15499   "fxtract"
15500   [(set_attr "type" "fpspc")
15501    (set_attr "mode" "XF")])
15502
15503 (define_insn "fxtract_extend<mode>xf3_i387"
15504   [(set (match_operand:XF 0 "register_operand" "=f")
15505         (unspec:XF [(float_extend:XF
15506                       (match_operand:MODEF 2 "register_operand" "0"))]
15507                    UNSPEC_XTRACT_FRACT))
15508    (set (match_operand:XF 1 "register_operand" "=u")
15509         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
15510   "TARGET_USE_FANCY_MATH_387
15511    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15512        || TARGET_MIX_SSE_I387)
15513    && flag_unsafe_math_optimizations"
15514   "fxtract"
15515   [(set_attr "type" "fpspc")
15516    (set_attr "mode" "XF")])
15517
15518 (define_expand "logbxf2"
15519   [(parallel [(set (match_dup 2)
15520                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15521                               UNSPEC_XTRACT_FRACT))
15522               (set (match_operand:XF 0 "register_operand" "")
15523                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15524   "TARGET_USE_FANCY_MATH_387
15525    && flag_unsafe_math_optimizations"
15526 {
15527   operands[2] = gen_reg_rtx (XFmode);
15528 })
15529
15530 (define_expand "logb<mode>2"
15531   [(use (match_operand:MODEF 0 "register_operand" ""))
15532    (use (match_operand:MODEF 1 "register_operand" ""))]
15533   "TARGET_USE_FANCY_MATH_387
15534    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15535        || TARGET_MIX_SSE_I387)
15536    && flag_unsafe_math_optimizations"
15537 {
15538   rtx op0 = gen_reg_rtx (XFmode);
15539   rtx op1 = gen_reg_rtx (XFmode);
15540
15541   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
15542   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
15543   DONE;
15544 })
15545
15546 (define_expand "ilogbxf2"
15547   [(use (match_operand:SI 0 "register_operand" ""))
15548    (use (match_operand:XF 1 "register_operand" ""))]
15549   "TARGET_USE_FANCY_MATH_387
15550    && flag_unsafe_math_optimizations"
15551 {
15552   rtx op0, op1;
15553
15554   if (optimize_insn_for_size_p ())
15555     FAIL;
15556
15557   op0 = gen_reg_rtx (XFmode);
15558   op1 = gen_reg_rtx (XFmode);
15559
15560   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
15561   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
15562   DONE;
15563 })
15564
15565 (define_expand "ilogb<mode>2"
15566   [(use (match_operand:SI 0 "register_operand" ""))
15567    (use (match_operand:MODEF 1 "register_operand" ""))]
15568   "TARGET_USE_FANCY_MATH_387
15569    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15570        || TARGET_MIX_SSE_I387)
15571    && flag_unsafe_math_optimizations"
15572 {
15573   rtx op0, op1;
15574
15575   if (optimize_insn_for_size_p ())
15576     FAIL;
15577
15578   op0 = gen_reg_rtx (XFmode);
15579   op1 = gen_reg_rtx (XFmode);
15580
15581   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
15582   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
15583   DONE;
15584 })
15585
15586 (define_insn "*f2xm1xf2_i387"
15587   [(set (match_operand:XF 0 "register_operand" "=f")
15588         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15589                    UNSPEC_F2XM1))]
15590   "TARGET_USE_FANCY_MATH_387
15591    && flag_unsafe_math_optimizations"
15592   "f2xm1"
15593   [(set_attr "type" "fpspc")
15594    (set_attr "mode" "XF")])
15595
15596 (define_insn "*fscalexf4_i387"
15597   [(set (match_operand:XF 0 "register_operand" "=f")
15598         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15599                     (match_operand:XF 3 "register_operand" "1")]
15600                    UNSPEC_FSCALE_FRACT))
15601    (set (match_operand:XF 1 "register_operand" "=u")
15602         (unspec:XF [(match_dup 2) (match_dup 3)]
15603                    UNSPEC_FSCALE_EXP))]
15604   "TARGET_USE_FANCY_MATH_387
15605    && flag_unsafe_math_optimizations"
15606   "fscale"
15607   [(set_attr "type" "fpspc")
15608    (set_attr "mode" "XF")])
15609
15610 (define_expand "expNcorexf3"
15611   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
15612                                (match_operand:XF 2 "register_operand" "")))
15613    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15614    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15615    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15616    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15617    (parallel [(set (match_operand:XF 0 "register_operand" "")
15618                    (unspec:XF [(match_dup 8) (match_dup 4)]
15619                               UNSPEC_FSCALE_FRACT))
15620               (set (match_dup 9)
15621                    (unspec:XF [(match_dup 8) (match_dup 4)]
15622                               UNSPEC_FSCALE_EXP))])]
15623   "TARGET_USE_FANCY_MATH_387
15624    && flag_unsafe_math_optimizations"
15625 {
15626   int i;
15627
15628   if (optimize_insn_for_size_p ())
15629     FAIL;
15630
15631   for (i = 3; i < 10; i++)
15632     operands[i] = gen_reg_rtx (XFmode);
15633
15634   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
15635 })
15636
15637 (define_expand "expxf2"
15638   [(use (match_operand:XF 0 "register_operand" ""))
15639    (use (match_operand:XF 1 "register_operand" ""))]
15640   "TARGET_USE_FANCY_MATH_387
15641    && flag_unsafe_math_optimizations"
15642 {
15643   rtx op2;
15644
15645   if (optimize_insn_for_size_p ())
15646     FAIL;
15647
15648   op2 = gen_reg_rtx (XFmode);
15649   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
15650
15651   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
15652   DONE;
15653 })
15654
15655 (define_expand "exp<mode>2"
15656   [(use (match_operand:MODEF 0 "register_operand" ""))
15657    (use (match_operand:MODEF 1 "general_operand" ""))]
15658  "TARGET_USE_FANCY_MATH_387
15659    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15660        || TARGET_MIX_SSE_I387)
15661    && flag_unsafe_math_optimizations"
15662 {
15663   rtx op0, op1;
15664
15665   if (optimize_insn_for_size_p ())
15666     FAIL;
15667
15668   op0 = gen_reg_rtx (XFmode);
15669   op1 = gen_reg_rtx (XFmode);
15670
15671   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15672   emit_insn (gen_expxf2 (op0, op1));
15673   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15674   DONE;
15675 })
15676
15677 (define_expand "exp10xf2"
15678   [(use (match_operand:XF 0 "register_operand" ""))
15679    (use (match_operand:XF 1 "register_operand" ""))]
15680   "TARGET_USE_FANCY_MATH_387
15681    && flag_unsafe_math_optimizations"
15682 {
15683   rtx op2;
15684
15685   if (optimize_insn_for_size_p ())
15686     FAIL;
15687
15688   op2 = gen_reg_rtx (XFmode);
15689   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
15690
15691   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
15692   DONE;
15693 })
15694
15695 (define_expand "exp10<mode>2"
15696   [(use (match_operand:MODEF 0 "register_operand" ""))
15697    (use (match_operand:MODEF 1 "general_operand" ""))]
15698  "TARGET_USE_FANCY_MATH_387
15699    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15700        || TARGET_MIX_SSE_I387)
15701    && flag_unsafe_math_optimizations"
15702 {
15703   rtx op0, op1;
15704
15705   if (optimize_insn_for_size_p ())
15706     FAIL;
15707
15708   op0 = gen_reg_rtx (XFmode);
15709   op1 = gen_reg_rtx (XFmode);
15710
15711   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15712   emit_insn (gen_exp10xf2 (op0, op1));
15713   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15714   DONE;
15715 })
15716
15717 (define_expand "exp2xf2"
15718   [(use (match_operand:XF 0 "register_operand" ""))
15719    (use (match_operand:XF 1 "register_operand" ""))]
15720   "TARGET_USE_FANCY_MATH_387
15721    && flag_unsafe_math_optimizations"
15722 {
15723   rtx op2;
15724
15725   if (optimize_insn_for_size_p ())
15726     FAIL;
15727
15728   op2 = gen_reg_rtx (XFmode);
15729   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
15730
15731   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
15732   DONE;
15733 })
15734
15735 (define_expand "exp2<mode>2"
15736   [(use (match_operand:MODEF 0 "register_operand" ""))
15737    (use (match_operand:MODEF 1 "general_operand" ""))]
15738  "TARGET_USE_FANCY_MATH_387
15739    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15740        || TARGET_MIX_SSE_I387)
15741    && flag_unsafe_math_optimizations"
15742 {
15743   rtx op0, op1;
15744
15745   if (optimize_insn_for_size_p ())
15746     FAIL;
15747
15748   op0 = gen_reg_rtx (XFmode);
15749   op1 = gen_reg_rtx (XFmode);
15750
15751   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15752   emit_insn (gen_exp2xf2 (op0, op1));
15753   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15754   DONE;
15755 })
15756
15757 (define_expand "expm1xf2"
15758   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
15759                                (match_dup 2)))
15760    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15761    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15762    (set (match_dup 9) (float_extend:XF (match_dup 13)))
15763    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15764    (parallel [(set (match_dup 7)
15765                    (unspec:XF [(match_dup 6) (match_dup 4)]
15766                               UNSPEC_FSCALE_FRACT))
15767               (set (match_dup 8)
15768                    (unspec:XF [(match_dup 6) (match_dup 4)]
15769                               UNSPEC_FSCALE_EXP))])
15770    (parallel [(set (match_dup 10)
15771                    (unspec:XF [(match_dup 9) (match_dup 8)]
15772                               UNSPEC_FSCALE_FRACT))
15773               (set (match_dup 11)
15774                    (unspec:XF [(match_dup 9) (match_dup 8)]
15775                               UNSPEC_FSCALE_EXP))])
15776    (set (match_dup 12) (minus:XF (match_dup 10)
15777                                  (float_extend:XF (match_dup 13))))
15778    (set (match_operand:XF 0 "register_operand" "")
15779         (plus:XF (match_dup 12) (match_dup 7)))]
15780   "TARGET_USE_FANCY_MATH_387
15781    && flag_unsafe_math_optimizations"
15782 {
15783   int i;
15784
15785   if (optimize_insn_for_size_p ())
15786     FAIL;
15787
15788   for (i = 2; i < 13; i++)
15789     operands[i] = gen_reg_rtx (XFmode);
15790
15791   operands[13]
15792     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
15793
15794   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
15795 })
15796
15797 (define_expand "expm1<mode>2"
15798   [(use (match_operand:MODEF 0 "register_operand" ""))
15799    (use (match_operand:MODEF 1 "general_operand" ""))]
15800  "TARGET_USE_FANCY_MATH_387
15801    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15802        || TARGET_MIX_SSE_I387)
15803    && flag_unsafe_math_optimizations"
15804 {
15805   rtx op0, op1;
15806
15807   if (optimize_insn_for_size_p ())
15808     FAIL;
15809
15810   op0 = gen_reg_rtx (XFmode);
15811   op1 = gen_reg_rtx (XFmode);
15812
15813   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15814   emit_insn (gen_expm1xf2 (op0, op1));
15815   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15816   DONE;
15817 })
15818
15819 (define_expand "ldexpxf3"
15820   [(set (match_dup 3)
15821         (float:XF (match_operand:SI 2 "register_operand" "")))
15822    (parallel [(set (match_operand:XF 0 " register_operand" "")
15823                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15824                                (match_dup 3)]
15825                               UNSPEC_FSCALE_FRACT))
15826               (set (match_dup 4)
15827                    (unspec:XF [(match_dup 1) (match_dup 3)]
15828                               UNSPEC_FSCALE_EXP))])]
15829   "TARGET_USE_FANCY_MATH_387
15830    && flag_unsafe_math_optimizations"
15831 {
15832   if (optimize_insn_for_size_p ())
15833     FAIL;
15834
15835   operands[3] = gen_reg_rtx (XFmode);
15836   operands[4] = gen_reg_rtx (XFmode);
15837 })
15838
15839 (define_expand "ldexp<mode>3"
15840   [(use (match_operand:MODEF 0 "register_operand" ""))
15841    (use (match_operand:MODEF 1 "general_operand" ""))
15842    (use (match_operand:SI 2 "register_operand" ""))]
15843  "TARGET_USE_FANCY_MATH_387
15844    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15845        || TARGET_MIX_SSE_I387)
15846    && flag_unsafe_math_optimizations"
15847 {
15848   rtx op0, op1;
15849
15850   if (optimize_insn_for_size_p ())
15851     FAIL;
15852
15853   op0 = gen_reg_rtx (XFmode);
15854   op1 = gen_reg_rtx (XFmode);
15855
15856   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15857   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
15858   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15859   DONE;
15860 })
15861
15862 (define_expand "scalbxf3"
15863   [(parallel [(set (match_operand:XF 0 " register_operand" "")
15864                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15865                                (match_operand:XF 2 "register_operand" "")]
15866                               UNSPEC_FSCALE_FRACT))
15867               (set (match_dup 3)
15868                    (unspec:XF [(match_dup 1) (match_dup 2)]
15869                               UNSPEC_FSCALE_EXP))])]
15870   "TARGET_USE_FANCY_MATH_387
15871    && flag_unsafe_math_optimizations"
15872 {
15873   if (optimize_insn_for_size_p ())
15874     FAIL;
15875
15876   operands[3] = gen_reg_rtx (XFmode);
15877 })
15878
15879 (define_expand "scalb<mode>3"
15880   [(use (match_operand:MODEF 0 "register_operand" ""))
15881    (use (match_operand:MODEF 1 "general_operand" ""))
15882    (use (match_operand:MODEF 2 "general_operand" ""))]
15883  "TARGET_USE_FANCY_MATH_387
15884    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15885        || TARGET_MIX_SSE_I387)
15886    && flag_unsafe_math_optimizations"
15887 {
15888   rtx op0, op1, op2;
15889
15890   if (optimize_insn_for_size_p ())
15891     FAIL;
15892
15893   op0 = gen_reg_rtx (XFmode);
15894   op1 = gen_reg_rtx (XFmode);
15895   op2 = gen_reg_rtx (XFmode);
15896
15897   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15898   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15899   emit_insn (gen_scalbxf3 (op0, op1, op2));
15900   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15901   DONE;
15902 })
15903
15904 (define_expand "significandxf2"
15905   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15906                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15907                               UNSPEC_XTRACT_FRACT))
15908               (set (match_dup 2)
15909                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15910   "TARGET_USE_FANCY_MATH_387
15911    && flag_unsafe_math_optimizations"
15912 {
15913   operands[2] = gen_reg_rtx (XFmode);
15914 })
15915
15916 (define_expand "significand<mode>2"
15917   [(use (match_operand:MODEF 0 "register_operand" ""))
15918    (use (match_operand:MODEF 1 "register_operand" ""))]
15919   "TARGET_USE_FANCY_MATH_387
15920    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15921        || TARGET_MIX_SSE_I387)
15922    && flag_unsafe_math_optimizations"
15923 {
15924   rtx op0 = gen_reg_rtx (XFmode);
15925   rtx op1 = gen_reg_rtx (XFmode);
15926
15927   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
15928   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15929   DONE;
15930 })
15931 \f
15932
15933 (define_insn "sse4_1_round<mode>2"
15934   [(set (match_operand:MODEF 0 "register_operand" "=x")
15935         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
15936                        (match_operand:SI 2 "const_0_to_15_operand" "n")]
15937                       UNSPEC_ROUND))]
15938   "TARGET_ROUND"
15939   "%vrounds<ssemodefsuffix>\t{%2, %1, %d0|%d0, %1, %2}"
15940   [(set_attr "type" "ssecvt")
15941    (set_attr "prefix_extra" "1")
15942    (set_attr "prefix" "maybe_vex")
15943    (set_attr "mode" "<MODE>")])
15944
15945 (define_insn "rintxf2"
15946   [(set (match_operand:XF 0 "register_operand" "=f")
15947         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15948                    UNSPEC_FRNDINT))]
15949   "TARGET_USE_FANCY_MATH_387
15950    && flag_unsafe_math_optimizations"
15951   "frndint"
15952   [(set_attr "type" "fpspc")
15953    (set_attr "mode" "XF")])
15954
15955 (define_expand "rint<mode>2"
15956   [(use (match_operand:MODEF 0 "register_operand" ""))
15957    (use (match_operand:MODEF 1 "register_operand" ""))]
15958   "(TARGET_USE_FANCY_MATH_387
15959     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15960         || TARGET_MIX_SSE_I387)
15961     && flag_unsafe_math_optimizations)
15962    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15963        && !flag_trapping_math)"
15964 {
15965   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15966       && !flag_trapping_math)
15967     {
15968       if (!TARGET_ROUND && optimize_insn_for_size_p ())
15969         FAIL;
15970       if (TARGET_ROUND)
15971         emit_insn (gen_sse4_1_round<mode>2
15972                    (operands[0], operands[1], GEN_INT (0x04)));
15973       else
15974         ix86_expand_rint (operand0, operand1);
15975     }
15976   else
15977     {
15978       rtx op0 = gen_reg_rtx (XFmode);
15979       rtx op1 = gen_reg_rtx (XFmode);
15980
15981       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15982       emit_insn (gen_rintxf2 (op0, op1));
15983
15984       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15985     }
15986   DONE;
15987 })
15988
15989 (define_expand "round<mode>2"
15990   [(match_operand:MODEF 0 "register_operand" "")
15991    (match_operand:MODEF 1 "nonimmediate_operand" "")]
15992   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15993    && !flag_trapping_math && !flag_rounding_math"
15994 {
15995   if (optimize_insn_for_size_p ())
15996     FAIL;
15997   if (TARGET_64BIT || (<MODE>mode != DFmode))
15998     ix86_expand_round (operand0, operand1);
15999   else
16000     ix86_expand_rounddf_32 (operand0, operand1);
16001   DONE;
16002 })
16003
16004 (define_insn_and_split "*fistdi2_1"
16005   [(set (match_operand:DI 0 "nonimmediate_operand" "")
16006         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16007                    UNSPEC_FIST))]
16008   "TARGET_USE_FANCY_MATH_387
16009    && can_create_pseudo_p ()"
16010   "#"
16011   "&& 1"
16012   [(const_int 0)]
16013 {
16014   if (memory_operand (operands[0], VOIDmode))
16015     emit_insn (gen_fistdi2 (operands[0], operands[1]));
16016   else
16017     {
16018       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
16019       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
16020                                          operands[2]));
16021     }
16022   DONE;
16023 }
16024   [(set_attr "type" "fpspc")
16025    (set_attr "mode" "DI")])
16026
16027 (define_insn "fistdi2"
16028   [(set (match_operand:DI 0 "memory_operand" "=m")
16029         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16030                    UNSPEC_FIST))
16031    (clobber (match_scratch:XF 2 "=&1f"))]
16032   "TARGET_USE_FANCY_MATH_387"
16033   "* return output_fix_trunc (insn, operands, 0);"
16034   [(set_attr "type" "fpspc")
16035    (set_attr "mode" "DI")])
16036
16037 (define_insn "fistdi2_with_temp"
16038   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16039         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16040                    UNSPEC_FIST))
16041    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
16042    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
16043   "TARGET_USE_FANCY_MATH_387"
16044   "#"
16045   [(set_attr "type" "fpspc")
16046    (set_attr "mode" "DI")])
16047
16048 (define_split
16049   [(set (match_operand:DI 0 "register_operand" "")
16050         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16051                    UNSPEC_FIST))
16052    (clobber (match_operand:DI 2 "memory_operand" ""))
16053    (clobber (match_scratch 3 ""))]
16054   "reload_completed"
16055   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16056               (clobber (match_dup 3))])
16057    (set (match_dup 0) (match_dup 2))]
16058   "")
16059
16060 (define_split
16061   [(set (match_operand:DI 0 "memory_operand" "")
16062         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16063                    UNSPEC_FIST))
16064    (clobber (match_operand:DI 2 "memory_operand" ""))
16065    (clobber (match_scratch 3 ""))]
16066   "reload_completed"
16067   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16068               (clobber (match_dup 3))])]
16069   "")
16070
16071 (define_insn_and_split "*fist<mode>2_1"
16072   [(set (match_operand:X87MODEI12 0 "register_operand" "")
16073         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16074                            UNSPEC_FIST))]
16075   "TARGET_USE_FANCY_MATH_387
16076    && can_create_pseudo_p ()"
16077   "#"
16078   "&& 1"
16079   [(const_int 0)]
16080 {
16081   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16082   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
16083                                         operands[2]));
16084   DONE;
16085 }
16086   [(set_attr "type" "fpspc")
16087    (set_attr "mode" "<MODE>")])
16088
16089 (define_insn "fist<mode>2"
16090   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
16091         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16092                            UNSPEC_FIST))]
16093   "TARGET_USE_FANCY_MATH_387"
16094   "* return output_fix_trunc (insn, operands, 0);"
16095   [(set_attr "type" "fpspc")
16096    (set_attr "mode" "<MODE>")])
16097
16098 (define_insn "fist<mode>2_with_temp"
16099   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
16100         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16101                            UNSPEC_FIST))
16102    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
16103   "TARGET_USE_FANCY_MATH_387"
16104   "#"
16105   [(set_attr "type" "fpspc")
16106    (set_attr "mode" "<MODE>")])
16107
16108 (define_split
16109   [(set (match_operand:X87MODEI12 0 "register_operand" "")
16110         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16111                            UNSPEC_FIST))
16112    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16113   "reload_completed"
16114   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
16115    (set (match_dup 0) (match_dup 2))]
16116   "")
16117
16118 (define_split
16119   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
16120         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16121                            UNSPEC_FIST))
16122    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16123   "reload_completed"
16124   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
16125   "")
16126
16127 (define_expand "lrintxf<mode>2"
16128   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
16129      (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
16130                       UNSPEC_FIST))]
16131   "TARGET_USE_FANCY_MATH_387"
16132   "")
16133
16134 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
16135   [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
16136      (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
16137                         UNSPEC_FIX_NOTRUNC))]
16138   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
16139    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
16140   "")
16141
16142 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
16143   [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
16144    (match_operand:MODEF 1 "register_operand" "")]
16145   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
16146    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
16147    && !flag_trapping_math && !flag_rounding_math"
16148 {
16149   if (optimize_insn_for_size_p ())
16150     FAIL;
16151   ix86_expand_lround (operand0, operand1);
16152   DONE;
16153 })
16154
16155 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16156 (define_insn_and_split "frndintxf2_floor"
16157   [(set (match_operand:XF 0 "register_operand" "")
16158         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16159          UNSPEC_FRNDINT_FLOOR))
16160    (clobber (reg:CC FLAGS_REG))]
16161   "TARGET_USE_FANCY_MATH_387
16162    && flag_unsafe_math_optimizations
16163    && can_create_pseudo_p ()"
16164   "#"
16165   "&& 1"
16166   [(const_int 0)]
16167 {
16168   ix86_optimize_mode_switching[I387_FLOOR] = 1;
16169
16170   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16171   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
16172
16173   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
16174                                         operands[2], operands[3]));
16175   DONE;
16176 }
16177   [(set_attr "type" "frndint")
16178    (set_attr "i387_cw" "floor")
16179    (set_attr "mode" "XF")])
16180
16181 (define_insn "frndintxf2_floor_i387"
16182   [(set (match_operand:XF 0 "register_operand" "=f")
16183         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16184          UNSPEC_FRNDINT_FLOOR))
16185    (use (match_operand:HI 2 "memory_operand" "m"))
16186    (use (match_operand:HI 3 "memory_operand" "m"))]
16187   "TARGET_USE_FANCY_MATH_387
16188    && flag_unsafe_math_optimizations"
16189   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16190   [(set_attr "type" "frndint")
16191    (set_attr "i387_cw" "floor")
16192    (set_attr "mode" "XF")])
16193
16194 (define_expand "floorxf2"
16195   [(use (match_operand:XF 0 "register_operand" ""))
16196    (use (match_operand:XF 1 "register_operand" ""))]
16197   "TARGET_USE_FANCY_MATH_387
16198    && flag_unsafe_math_optimizations"
16199 {
16200   if (optimize_insn_for_size_p ())
16201     FAIL;
16202   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
16203   DONE;
16204 })
16205
16206 (define_expand "floor<mode>2"
16207   [(use (match_operand:MODEF 0 "register_operand" ""))
16208    (use (match_operand:MODEF 1 "register_operand" ""))]
16209   "(TARGET_USE_FANCY_MATH_387
16210     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16211         || TARGET_MIX_SSE_I387)
16212     && flag_unsafe_math_optimizations)
16213    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16214        && !flag_trapping_math)"
16215 {
16216   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16217       && !flag_trapping_math
16218       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
16219     {
16220       if (!TARGET_ROUND && optimize_insn_for_size_p ())
16221         FAIL;
16222       if (TARGET_ROUND)
16223         emit_insn (gen_sse4_1_round<mode>2
16224                    (operands[0], operands[1], GEN_INT (0x01)));
16225       else if (TARGET_64BIT || (<MODE>mode != DFmode))
16226         ix86_expand_floorceil (operand0, operand1, true);
16227       else
16228         ix86_expand_floorceildf_32 (operand0, operand1, true);
16229     }
16230   else
16231     {
16232       rtx op0, op1;
16233
16234       if (optimize_insn_for_size_p ())
16235         FAIL;
16236
16237       op0 = gen_reg_rtx (XFmode);
16238       op1 = gen_reg_rtx (XFmode);
16239       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16240       emit_insn (gen_frndintxf2_floor (op0, op1));
16241
16242       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16243     }
16244   DONE;
16245 })
16246
16247 (define_insn_and_split "*fist<mode>2_floor_1"
16248   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
16249         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
16250          UNSPEC_FIST_FLOOR))
16251    (clobber (reg:CC FLAGS_REG))]
16252   "TARGET_USE_FANCY_MATH_387
16253    && flag_unsafe_math_optimizations
16254    && can_create_pseudo_p ()"
16255   "#"
16256   "&& 1"
16257   [(const_int 0)]
16258 {
16259   ix86_optimize_mode_switching[I387_FLOOR] = 1;
16260
16261   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16262   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
16263   if (memory_operand (operands[0], VOIDmode))
16264     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
16265                                       operands[2], operands[3]));
16266   else
16267     {
16268       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16269       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
16270                                                   operands[2], operands[3],
16271                                                   operands[4]));
16272     }
16273   DONE;
16274 }
16275   [(set_attr "type" "fistp")
16276    (set_attr "i387_cw" "floor")
16277    (set_attr "mode" "<MODE>")])
16278
16279 (define_insn "fistdi2_floor"
16280   [(set (match_operand:DI 0 "memory_operand" "=m")
16281         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16282          UNSPEC_FIST_FLOOR))
16283    (use (match_operand:HI 2 "memory_operand" "m"))
16284    (use (match_operand:HI 3 "memory_operand" "m"))
16285    (clobber (match_scratch:XF 4 "=&1f"))]
16286   "TARGET_USE_FANCY_MATH_387
16287    && flag_unsafe_math_optimizations"
16288   "* return output_fix_trunc (insn, operands, 0);"
16289   [(set_attr "type" "fistp")
16290    (set_attr "i387_cw" "floor")
16291    (set_attr "mode" "DI")])
16292
16293 (define_insn "fistdi2_floor_with_temp"
16294   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16295         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16296          UNSPEC_FIST_FLOOR))
16297    (use (match_operand:HI 2 "memory_operand" "m,m"))
16298    (use (match_operand:HI 3 "memory_operand" "m,m"))
16299    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
16300    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
16301   "TARGET_USE_FANCY_MATH_387
16302    && flag_unsafe_math_optimizations"
16303   "#"
16304   [(set_attr "type" "fistp")
16305    (set_attr "i387_cw" "floor")
16306    (set_attr "mode" "DI")])
16307
16308 (define_split
16309   [(set (match_operand:DI 0 "register_operand" "")
16310         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16311          UNSPEC_FIST_FLOOR))
16312    (use (match_operand:HI 2 "memory_operand" ""))
16313    (use (match_operand:HI 3 "memory_operand" ""))
16314    (clobber (match_operand:DI 4 "memory_operand" ""))
16315    (clobber (match_scratch 5 ""))]
16316   "reload_completed"
16317   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
16318               (use (match_dup 2))
16319               (use (match_dup 3))
16320               (clobber (match_dup 5))])
16321    (set (match_dup 0) (match_dup 4))]
16322   "")
16323
16324 (define_split
16325   [(set (match_operand:DI 0 "memory_operand" "")
16326         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16327          UNSPEC_FIST_FLOOR))
16328    (use (match_operand:HI 2 "memory_operand" ""))
16329    (use (match_operand:HI 3 "memory_operand" ""))
16330    (clobber (match_operand:DI 4 "memory_operand" ""))
16331    (clobber (match_scratch 5 ""))]
16332   "reload_completed"
16333   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
16334               (use (match_dup 2))
16335               (use (match_dup 3))
16336               (clobber (match_dup 5))])]
16337   "")
16338
16339 (define_insn "fist<mode>2_floor"
16340   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
16341         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16342          UNSPEC_FIST_FLOOR))
16343    (use (match_operand:HI 2 "memory_operand" "m"))
16344    (use (match_operand:HI 3 "memory_operand" "m"))]
16345   "TARGET_USE_FANCY_MATH_387
16346    && flag_unsafe_math_optimizations"
16347   "* return output_fix_trunc (insn, operands, 0);"
16348   [(set_attr "type" "fistp")
16349    (set_attr "i387_cw" "floor")
16350    (set_attr "mode" "<MODE>")])
16351
16352 (define_insn "fist<mode>2_floor_with_temp"
16353   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
16354         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
16355          UNSPEC_FIST_FLOOR))
16356    (use (match_operand:HI 2 "memory_operand" "m,m"))
16357    (use (match_operand:HI 3 "memory_operand" "m,m"))
16358    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
16359   "TARGET_USE_FANCY_MATH_387
16360    && flag_unsafe_math_optimizations"
16361   "#"
16362   [(set_attr "type" "fistp")
16363    (set_attr "i387_cw" "floor")
16364    (set_attr "mode" "<MODE>")])
16365
16366 (define_split
16367   [(set (match_operand:X87MODEI12 0 "register_operand" "")
16368         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16369          UNSPEC_FIST_FLOOR))
16370    (use (match_operand:HI 2 "memory_operand" ""))
16371    (use (match_operand:HI 3 "memory_operand" ""))
16372    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
16373   "reload_completed"
16374   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
16375                                   UNSPEC_FIST_FLOOR))
16376               (use (match_dup 2))
16377               (use (match_dup 3))])
16378    (set (match_dup 0) (match_dup 4))]
16379   "")
16380
16381 (define_split
16382   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
16383         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16384          UNSPEC_FIST_FLOOR))
16385    (use (match_operand:HI 2 "memory_operand" ""))
16386    (use (match_operand:HI 3 "memory_operand" ""))
16387    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
16388   "reload_completed"
16389   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
16390                                   UNSPEC_FIST_FLOOR))
16391               (use (match_dup 2))
16392               (use (match_dup 3))])]
16393   "")
16394
16395 (define_expand "lfloorxf<mode>2"
16396   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
16397                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
16398                     UNSPEC_FIST_FLOOR))
16399               (clobber (reg:CC FLAGS_REG))])]
16400   "TARGET_USE_FANCY_MATH_387
16401    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16402    && flag_unsafe_math_optimizations"
16403   "")
16404
16405 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
16406   [(match_operand:SWI48 0 "nonimmediate_operand" "")
16407    (match_operand:MODEF 1 "register_operand" "")]
16408   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
16409    && !flag_trapping_math"
16410 {
16411   if (TARGET_64BIT && optimize_insn_for_size_p ())
16412     FAIL;
16413   ix86_expand_lfloorceil (operand0, operand1, true);
16414   DONE;
16415 })
16416
16417 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16418 (define_insn_and_split "frndintxf2_ceil"
16419   [(set (match_operand:XF 0 "register_operand" "")
16420         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16421          UNSPEC_FRNDINT_CEIL))
16422    (clobber (reg:CC FLAGS_REG))]
16423   "TARGET_USE_FANCY_MATH_387
16424    && flag_unsafe_math_optimizations
16425    && can_create_pseudo_p ()"
16426   "#"
16427   "&& 1"
16428   [(const_int 0)]
16429 {
16430   ix86_optimize_mode_switching[I387_CEIL] = 1;
16431
16432   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16433   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
16434
16435   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
16436                                        operands[2], operands[3]));
16437   DONE;
16438 }
16439   [(set_attr "type" "frndint")
16440    (set_attr "i387_cw" "ceil")
16441    (set_attr "mode" "XF")])
16442
16443 (define_insn "frndintxf2_ceil_i387"
16444   [(set (match_operand:XF 0 "register_operand" "=f")
16445         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16446          UNSPEC_FRNDINT_CEIL))
16447    (use (match_operand:HI 2 "memory_operand" "m"))
16448    (use (match_operand:HI 3 "memory_operand" "m"))]
16449   "TARGET_USE_FANCY_MATH_387
16450    && flag_unsafe_math_optimizations"
16451   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16452   [(set_attr "type" "frndint")
16453    (set_attr "i387_cw" "ceil")
16454    (set_attr "mode" "XF")])
16455
16456 (define_expand "ceilxf2"
16457   [(use (match_operand:XF 0 "register_operand" ""))
16458    (use (match_operand:XF 1 "register_operand" ""))]
16459   "TARGET_USE_FANCY_MATH_387
16460    && flag_unsafe_math_optimizations"
16461 {
16462   if (optimize_insn_for_size_p ())
16463     FAIL;
16464   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
16465   DONE;
16466 })
16467
16468 (define_expand "ceil<mode>2"
16469   [(use (match_operand:MODEF 0 "register_operand" ""))
16470    (use (match_operand:MODEF 1 "register_operand" ""))]
16471   "(TARGET_USE_FANCY_MATH_387
16472     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16473         || TARGET_MIX_SSE_I387)
16474     && flag_unsafe_math_optimizations)
16475    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16476        && !flag_trapping_math)"
16477 {
16478   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16479       && !flag_trapping_math
16480       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
16481     {
16482       if (TARGET_ROUND)
16483         emit_insn (gen_sse4_1_round<mode>2
16484                    (operands[0], operands[1], GEN_INT (0x02)));
16485       else if (optimize_insn_for_size_p ())
16486         FAIL;
16487       else if (TARGET_64BIT || (<MODE>mode != DFmode))
16488         ix86_expand_floorceil (operand0, operand1, false);
16489       else
16490         ix86_expand_floorceildf_32 (operand0, operand1, false);
16491     }
16492   else
16493     {
16494       rtx op0, op1;
16495
16496       if (optimize_insn_for_size_p ())
16497         FAIL;
16498
16499       op0 = gen_reg_rtx (XFmode);
16500       op1 = gen_reg_rtx (XFmode);
16501       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16502       emit_insn (gen_frndintxf2_ceil (op0, op1));
16503
16504       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16505     }
16506   DONE;
16507 })
16508
16509 (define_insn_and_split "*fist<mode>2_ceil_1"
16510   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
16511         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
16512          UNSPEC_FIST_CEIL))
16513    (clobber (reg:CC FLAGS_REG))]
16514   "TARGET_USE_FANCY_MATH_387
16515    && flag_unsafe_math_optimizations
16516    && can_create_pseudo_p ()"
16517   "#"
16518   "&& 1"
16519   [(const_int 0)]
16520 {
16521   ix86_optimize_mode_switching[I387_CEIL] = 1;
16522
16523   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16524   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
16525   if (memory_operand (operands[0], VOIDmode))
16526     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
16527                                      operands[2], operands[3]));
16528   else
16529     {
16530       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16531       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
16532                                                  operands[2], operands[3],
16533                                                  operands[4]));
16534     }
16535   DONE;
16536 }
16537   [(set_attr "type" "fistp")
16538    (set_attr "i387_cw" "ceil")
16539    (set_attr "mode" "<MODE>")])
16540
16541 (define_insn "fistdi2_ceil"
16542   [(set (match_operand:DI 0 "memory_operand" "=m")
16543         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16544          UNSPEC_FIST_CEIL))
16545    (use (match_operand:HI 2 "memory_operand" "m"))
16546    (use (match_operand:HI 3 "memory_operand" "m"))
16547    (clobber (match_scratch:XF 4 "=&1f"))]
16548   "TARGET_USE_FANCY_MATH_387
16549    && flag_unsafe_math_optimizations"
16550   "* return output_fix_trunc (insn, operands, 0);"
16551   [(set_attr "type" "fistp")
16552    (set_attr "i387_cw" "ceil")
16553    (set_attr "mode" "DI")])
16554
16555 (define_insn "fistdi2_ceil_with_temp"
16556   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16557         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16558          UNSPEC_FIST_CEIL))
16559    (use (match_operand:HI 2 "memory_operand" "m,m"))
16560    (use (match_operand:HI 3 "memory_operand" "m,m"))
16561    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
16562    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
16563   "TARGET_USE_FANCY_MATH_387
16564    && flag_unsafe_math_optimizations"
16565   "#"
16566   [(set_attr "type" "fistp")
16567    (set_attr "i387_cw" "ceil")
16568    (set_attr "mode" "DI")])
16569
16570 (define_split
16571   [(set (match_operand:DI 0 "register_operand" "")
16572         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16573          UNSPEC_FIST_CEIL))
16574    (use (match_operand:HI 2 "memory_operand" ""))
16575    (use (match_operand:HI 3 "memory_operand" ""))
16576    (clobber (match_operand:DI 4 "memory_operand" ""))
16577    (clobber (match_scratch 5 ""))]
16578   "reload_completed"
16579   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
16580               (use (match_dup 2))
16581               (use (match_dup 3))
16582               (clobber (match_dup 5))])
16583    (set (match_dup 0) (match_dup 4))]
16584   "")
16585
16586 (define_split
16587   [(set (match_operand:DI 0 "memory_operand" "")
16588         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16589          UNSPEC_FIST_CEIL))
16590    (use (match_operand:HI 2 "memory_operand" ""))
16591    (use (match_operand:HI 3 "memory_operand" ""))
16592    (clobber (match_operand:DI 4 "memory_operand" ""))
16593    (clobber (match_scratch 5 ""))]
16594   "reload_completed"
16595   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
16596               (use (match_dup 2))
16597               (use (match_dup 3))
16598               (clobber (match_dup 5))])]
16599   "")
16600
16601 (define_insn "fist<mode>2_ceil"
16602   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
16603         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16604          UNSPEC_FIST_CEIL))
16605    (use (match_operand:HI 2 "memory_operand" "m"))
16606    (use (match_operand:HI 3 "memory_operand" "m"))]
16607   "TARGET_USE_FANCY_MATH_387
16608    && flag_unsafe_math_optimizations"
16609   "* return output_fix_trunc (insn, operands, 0);"
16610   [(set_attr "type" "fistp")
16611    (set_attr "i387_cw" "ceil")
16612    (set_attr "mode" "<MODE>")])
16613
16614 (define_insn "fist<mode>2_ceil_with_temp"
16615   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
16616         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
16617          UNSPEC_FIST_CEIL))
16618    (use (match_operand:HI 2 "memory_operand" "m,m"))
16619    (use (match_operand:HI 3 "memory_operand" "m,m"))
16620    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
16621   "TARGET_USE_FANCY_MATH_387
16622    && flag_unsafe_math_optimizations"
16623   "#"
16624   [(set_attr "type" "fistp")
16625    (set_attr "i387_cw" "ceil")
16626    (set_attr "mode" "<MODE>")])
16627
16628 (define_split
16629   [(set (match_operand:X87MODEI12 0 "register_operand" "")
16630         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16631          UNSPEC_FIST_CEIL))
16632    (use (match_operand:HI 2 "memory_operand" ""))
16633    (use (match_operand:HI 3 "memory_operand" ""))
16634    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
16635   "reload_completed"
16636   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
16637                                   UNSPEC_FIST_CEIL))
16638               (use (match_dup 2))
16639               (use (match_dup 3))])
16640    (set (match_dup 0) (match_dup 4))]
16641   "")
16642
16643 (define_split
16644   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
16645         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16646          UNSPEC_FIST_CEIL))
16647    (use (match_operand:HI 2 "memory_operand" ""))
16648    (use (match_operand:HI 3 "memory_operand" ""))
16649    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
16650   "reload_completed"
16651   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
16652                                   UNSPEC_FIST_CEIL))
16653               (use (match_dup 2))
16654               (use (match_dup 3))])]
16655   "")
16656
16657 (define_expand "lceilxf<mode>2"
16658   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
16659                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
16660                     UNSPEC_FIST_CEIL))
16661               (clobber (reg:CC FLAGS_REG))])]
16662   "TARGET_USE_FANCY_MATH_387
16663    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16664    && flag_unsafe_math_optimizations"
16665   "")
16666
16667 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
16668   [(match_operand:SWI48 0 "nonimmediate_operand" "")
16669    (match_operand:MODEF 1 "register_operand" "")]
16670   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
16671    && !flag_trapping_math"
16672 {
16673   ix86_expand_lfloorceil (operand0, operand1, false);
16674   DONE;
16675 })
16676
16677 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16678 (define_insn_and_split "frndintxf2_trunc"
16679   [(set (match_operand:XF 0 "register_operand" "")
16680         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16681          UNSPEC_FRNDINT_TRUNC))
16682    (clobber (reg:CC FLAGS_REG))]
16683   "TARGET_USE_FANCY_MATH_387
16684    && flag_unsafe_math_optimizations
16685    && can_create_pseudo_p ()"
16686   "#"
16687   "&& 1"
16688   [(const_int 0)]
16689 {
16690   ix86_optimize_mode_switching[I387_TRUNC] = 1;
16691
16692   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16693   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
16694
16695   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
16696                                         operands[2], operands[3]));
16697   DONE;
16698 }
16699   [(set_attr "type" "frndint")
16700    (set_attr "i387_cw" "trunc")
16701    (set_attr "mode" "XF")])
16702
16703 (define_insn "frndintxf2_trunc_i387"
16704   [(set (match_operand:XF 0 "register_operand" "=f")
16705         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16706          UNSPEC_FRNDINT_TRUNC))
16707    (use (match_operand:HI 2 "memory_operand" "m"))
16708    (use (match_operand:HI 3 "memory_operand" "m"))]
16709   "TARGET_USE_FANCY_MATH_387
16710    && flag_unsafe_math_optimizations"
16711   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16712   [(set_attr "type" "frndint")
16713    (set_attr "i387_cw" "trunc")
16714    (set_attr "mode" "XF")])
16715
16716 (define_expand "btruncxf2"
16717   [(use (match_operand:XF 0 "register_operand" ""))
16718    (use (match_operand:XF 1 "register_operand" ""))]
16719   "TARGET_USE_FANCY_MATH_387
16720    && flag_unsafe_math_optimizations"
16721 {
16722   if (optimize_insn_for_size_p ())
16723     FAIL;
16724   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
16725   DONE;
16726 })
16727
16728 (define_expand "btrunc<mode>2"
16729   [(use (match_operand:MODEF 0 "register_operand" ""))
16730    (use (match_operand:MODEF 1 "register_operand" ""))]
16731   "(TARGET_USE_FANCY_MATH_387
16732     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16733         || TARGET_MIX_SSE_I387)
16734     && flag_unsafe_math_optimizations)
16735    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16736        && !flag_trapping_math)"
16737 {
16738   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16739       && !flag_trapping_math
16740       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
16741     {
16742       if (TARGET_ROUND)
16743         emit_insn (gen_sse4_1_round<mode>2
16744                    (operands[0], operands[1], GEN_INT (0x03)));
16745       else if (optimize_insn_for_size_p ())
16746         FAIL;
16747       else if (TARGET_64BIT || (<MODE>mode != DFmode))
16748         ix86_expand_trunc (operand0, operand1);
16749       else
16750         ix86_expand_truncdf_32 (operand0, operand1);
16751     }
16752   else
16753     {
16754       rtx op0, op1;
16755
16756       if (optimize_insn_for_size_p ())
16757         FAIL;
16758
16759       op0 = gen_reg_rtx (XFmode);
16760       op1 = gen_reg_rtx (XFmode);
16761       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16762       emit_insn (gen_frndintxf2_trunc (op0, op1));
16763
16764       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16765     }
16766   DONE;
16767 })
16768
16769 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16770 (define_insn_and_split "frndintxf2_mask_pm"
16771   [(set (match_operand:XF 0 "register_operand" "")
16772         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16773          UNSPEC_FRNDINT_MASK_PM))
16774    (clobber (reg:CC FLAGS_REG))]
16775   "TARGET_USE_FANCY_MATH_387
16776    && flag_unsafe_math_optimizations
16777    && can_create_pseudo_p ()"
16778   "#"
16779   "&& 1"
16780   [(const_int 0)]
16781 {
16782   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
16783
16784   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16785   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
16786
16787   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
16788                                           operands[2], operands[3]));
16789   DONE;
16790 }
16791   [(set_attr "type" "frndint")
16792    (set_attr "i387_cw" "mask_pm")
16793    (set_attr "mode" "XF")])
16794
16795 (define_insn "frndintxf2_mask_pm_i387"
16796   [(set (match_operand:XF 0 "register_operand" "=f")
16797         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16798          UNSPEC_FRNDINT_MASK_PM))
16799    (use (match_operand:HI 2 "memory_operand" "m"))
16800    (use (match_operand:HI 3 "memory_operand" "m"))]
16801   "TARGET_USE_FANCY_MATH_387
16802    && flag_unsafe_math_optimizations"
16803   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
16804   [(set_attr "type" "frndint")
16805    (set_attr "i387_cw" "mask_pm")
16806    (set_attr "mode" "XF")])
16807
16808 (define_expand "nearbyintxf2"
16809   [(use (match_operand:XF 0 "register_operand" ""))
16810    (use (match_operand:XF 1 "register_operand" ""))]
16811   "TARGET_USE_FANCY_MATH_387
16812    && flag_unsafe_math_optimizations"
16813 {
16814   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
16815
16816   DONE;
16817 })
16818
16819 (define_expand "nearbyint<mode>2"
16820   [(use (match_operand:MODEF 0 "register_operand" ""))
16821    (use (match_operand:MODEF 1 "register_operand" ""))]
16822   "TARGET_USE_FANCY_MATH_387
16823    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16824        || TARGET_MIX_SSE_I387)
16825    && flag_unsafe_math_optimizations"
16826 {
16827   rtx op0 = gen_reg_rtx (XFmode);
16828   rtx op1 = gen_reg_rtx (XFmode);
16829
16830   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16831   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
16832
16833   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16834   DONE;
16835 })
16836
16837 (define_insn "fxam<mode>2_i387"
16838   [(set (match_operand:HI 0 "register_operand" "=a")
16839         (unspec:HI
16840           [(match_operand:X87MODEF 1 "register_operand" "f")]
16841           UNSPEC_FXAM))]
16842   "TARGET_USE_FANCY_MATH_387"
16843   "fxam\n\tfnstsw\t%0"
16844   [(set_attr "type" "multi")
16845    (set_attr "length" "4")
16846    (set_attr "unit" "i387")
16847    (set_attr "mode" "<MODE>")])
16848
16849 (define_insn_and_split "fxam<mode>2_i387_with_temp"
16850   [(set (match_operand:HI 0 "register_operand" "")
16851         (unspec:HI
16852           [(match_operand:MODEF 1 "memory_operand" "")]
16853           UNSPEC_FXAM_MEM))]
16854   "TARGET_USE_FANCY_MATH_387
16855    && can_create_pseudo_p ()"
16856   "#"
16857   "&& 1"
16858   [(set (match_dup 2)(match_dup 1))
16859    (set (match_dup 0)
16860         (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
16861 {
16862   operands[2] = gen_reg_rtx (<MODE>mode);
16863
16864   MEM_VOLATILE_P (operands[1]) = 1;
16865 }
16866   [(set_attr "type" "multi")
16867    (set_attr "unit" "i387")
16868    (set_attr "mode" "<MODE>")])
16869
16870 (define_expand "isinfxf2"
16871   [(use (match_operand:SI 0 "register_operand" ""))
16872    (use (match_operand:XF 1 "register_operand" ""))]
16873   "TARGET_USE_FANCY_MATH_387
16874    && TARGET_C99_FUNCTIONS"
16875 {
16876   rtx mask = GEN_INT (0x45);
16877   rtx val = GEN_INT (0x05);
16878
16879   rtx cond;
16880
16881   rtx scratch = gen_reg_rtx (HImode);
16882   rtx res = gen_reg_rtx (QImode);
16883
16884   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
16885
16886   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
16887   emit_insn (gen_cmpqi_ext_3 (scratch, val));
16888   cond = gen_rtx_fmt_ee (EQ, QImode,
16889                          gen_rtx_REG (CCmode, FLAGS_REG),
16890                          const0_rtx);
16891   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
16892   emit_insn (gen_zero_extendqisi2 (operands[0], res));
16893   DONE;
16894 })
16895
16896 (define_expand "isinf<mode>2"
16897   [(use (match_operand:SI 0 "register_operand" ""))
16898    (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
16899   "TARGET_USE_FANCY_MATH_387
16900    && TARGET_C99_FUNCTIONS
16901    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16902 {
16903   rtx mask = GEN_INT (0x45);
16904   rtx val = GEN_INT (0x05);
16905
16906   rtx cond;
16907
16908   rtx scratch = gen_reg_rtx (HImode);
16909   rtx res = gen_reg_rtx (QImode);
16910
16911   /* Remove excess precision by forcing value through memory. */
16912   if (memory_operand (operands[1], VOIDmode))
16913     emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
16914   else
16915     {
16916       enum ix86_stack_slot slot = (virtuals_instantiated
16917                                    ? SLOT_TEMP
16918                                    : SLOT_VIRTUAL);
16919       rtx temp = assign_386_stack_local (<MODE>mode, slot);
16920
16921       emit_move_insn (temp, operands[1]);
16922       emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
16923     }
16924
16925   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
16926   emit_insn (gen_cmpqi_ext_3 (scratch, val));
16927   cond = gen_rtx_fmt_ee (EQ, QImode,
16928                          gen_rtx_REG (CCmode, FLAGS_REG),
16929                          const0_rtx);
16930   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
16931   emit_insn (gen_zero_extendqisi2 (operands[0], res));
16932   DONE;
16933 })
16934
16935 (define_expand "signbit<mode>2"
16936   [(use (match_operand:SI 0 "register_operand" ""))
16937    (use (match_operand:X87MODEF 1 "register_operand" ""))]
16938   "TARGET_USE_FANCY_MATH_387
16939    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16940 {
16941   rtx mask = GEN_INT (0x0200);
16942
16943   rtx scratch = gen_reg_rtx (HImode);
16944
16945   emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
16946   emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
16947   DONE;
16948 })
16949 \f
16950 ;; Block operation instructions
16951
16952 (define_insn "cld"
16953   [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
16954   ""
16955   "cld"
16956   [(set_attr "length" "1")
16957    (set_attr "length_immediate" "0")
16958    (set_attr "modrm" "0")])
16959
16960 (define_expand "movmemsi"
16961   [(use (match_operand:BLK 0 "memory_operand" ""))
16962    (use (match_operand:BLK 1 "memory_operand" ""))
16963    (use (match_operand:SI 2 "nonmemory_operand" ""))
16964    (use (match_operand:SI 3 "const_int_operand" ""))
16965    (use (match_operand:SI 4 "const_int_operand" ""))
16966    (use (match_operand:SI 5 "const_int_operand" ""))]
16967   ""
16968 {
16969  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
16970                          operands[4], operands[5]))
16971    DONE;
16972  else
16973    FAIL;
16974 })
16975
16976 (define_expand "movmemdi"
16977   [(use (match_operand:BLK 0 "memory_operand" ""))
16978    (use (match_operand:BLK 1 "memory_operand" ""))
16979    (use (match_operand:DI 2 "nonmemory_operand" ""))
16980    (use (match_operand:DI 3 "const_int_operand" ""))
16981    (use (match_operand:SI 4 "const_int_operand" ""))
16982    (use (match_operand:SI 5 "const_int_operand" ""))]
16983   "TARGET_64BIT"
16984 {
16985  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
16986                          operands[4], operands[5]))
16987    DONE;
16988  else
16989    FAIL;
16990 })
16991
16992 ;; Most CPUs don't like single string operations
16993 ;; Handle this case here to simplify previous expander.
16994
16995 (define_expand "strmov"
16996   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
16997    (set (match_operand 1 "memory_operand" "") (match_dup 4))
16998    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
16999               (clobber (reg:CC FLAGS_REG))])
17000    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
17001               (clobber (reg:CC FLAGS_REG))])]
17002   ""
17003 {
17004   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
17005
17006   /* If .md ever supports :P for Pmode, these can be directly
17007      in the pattern above.  */
17008   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
17009   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
17010
17011   /* Can't use this if the user has appropriated esi or edi.  */
17012   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
17013       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
17014     {
17015       emit_insn (gen_strmov_singleop (operands[0], operands[1],
17016                                       operands[2], operands[3],
17017                                       operands[5], operands[6]));
17018       DONE;
17019     }
17020
17021   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
17022 })
17023
17024 (define_expand "strmov_singleop"
17025   [(parallel [(set (match_operand 1 "memory_operand" "")
17026                    (match_operand 3 "memory_operand" ""))
17027               (set (match_operand 0 "register_operand" "")
17028                    (match_operand 4 "" ""))
17029               (set (match_operand 2 "register_operand" "")
17030                    (match_operand 5 "" ""))])]
17031   ""
17032   "ix86_current_function_needs_cld = 1;")
17033
17034 (define_insn "*strmovdi_rex_1"
17035   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
17036         (mem:DI (match_operand:DI 3 "register_operand" "1")))
17037    (set (match_operand:DI 0 "register_operand" "=D")
17038         (plus:DI (match_dup 2)
17039                  (const_int 8)))
17040    (set (match_operand:DI 1 "register_operand" "=S")
17041         (plus:DI (match_dup 3)
17042                  (const_int 8)))]
17043   "TARGET_64BIT"
17044   "movsq"
17045   [(set_attr "type" "str")
17046    (set_attr "mode" "DI")
17047    (set_attr "memory" "both")])
17048
17049 (define_insn "*strmovsi_1"
17050   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
17051         (mem:SI (match_operand:SI 3 "register_operand" "1")))
17052    (set (match_operand:SI 0 "register_operand" "=D")
17053         (plus:SI (match_dup 2)
17054                  (const_int 4)))
17055    (set (match_operand:SI 1 "register_operand" "=S")
17056         (plus:SI (match_dup 3)
17057                  (const_int 4)))]
17058   "!TARGET_64BIT"
17059   "movs{l|d}"
17060   [(set_attr "type" "str")
17061    (set_attr "mode" "SI")
17062    (set_attr "memory" "both")])
17063
17064 (define_insn "*strmovsi_rex_1"
17065   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
17066         (mem:SI (match_operand:DI 3 "register_operand" "1")))
17067    (set (match_operand:DI 0 "register_operand" "=D")
17068         (plus:DI (match_dup 2)
17069                  (const_int 4)))
17070    (set (match_operand:DI 1 "register_operand" "=S")
17071         (plus:DI (match_dup 3)
17072                  (const_int 4)))]
17073   "TARGET_64BIT"
17074   "movs{l|d}"
17075   [(set_attr "type" "str")
17076    (set_attr "mode" "SI")
17077    (set_attr "memory" "both")])
17078
17079 (define_insn "*strmovhi_1"
17080   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
17081         (mem:HI (match_operand:SI 3 "register_operand" "1")))
17082    (set (match_operand:SI 0 "register_operand" "=D")
17083         (plus:SI (match_dup 2)
17084                  (const_int 2)))
17085    (set (match_operand:SI 1 "register_operand" "=S")
17086         (plus:SI (match_dup 3)
17087                  (const_int 2)))]
17088   "!TARGET_64BIT"
17089   "movsw"
17090   [(set_attr "type" "str")
17091    (set_attr "memory" "both")
17092    (set_attr "mode" "HI")])
17093
17094 (define_insn "*strmovhi_rex_1"
17095   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
17096         (mem:HI (match_operand:DI 3 "register_operand" "1")))
17097    (set (match_operand:DI 0 "register_operand" "=D")
17098         (plus:DI (match_dup 2)
17099                  (const_int 2)))
17100    (set (match_operand:DI 1 "register_operand" "=S")
17101         (plus:DI (match_dup 3)
17102                  (const_int 2)))]
17103   "TARGET_64BIT"
17104   "movsw"
17105   [(set_attr "type" "str")
17106    (set_attr "memory" "both")
17107    (set_attr "mode" "HI")])
17108
17109 (define_insn "*strmovqi_1"
17110   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
17111         (mem:QI (match_operand:SI 3 "register_operand" "1")))
17112    (set (match_operand:SI 0 "register_operand" "=D")
17113         (plus:SI (match_dup 2)
17114                  (const_int 1)))
17115    (set (match_operand:SI 1 "register_operand" "=S")
17116         (plus:SI (match_dup 3)
17117                  (const_int 1)))]
17118   "!TARGET_64BIT"
17119   "movsb"
17120   [(set_attr "type" "str")
17121    (set_attr "memory" "both")
17122    (set_attr "mode" "QI")])
17123
17124 (define_insn "*strmovqi_rex_1"
17125   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
17126         (mem:QI (match_operand:DI 3 "register_operand" "1")))
17127    (set (match_operand:DI 0 "register_operand" "=D")
17128         (plus:DI (match_dup 2)
17129                  (const_int 1)))
17130    (set (match_operand:DI 1 "register_operand" "=S")
17131         (plus:DI (match_dup 3)
17132                  (const_int 1)))]
17133   "TARGET_64BIT"
17134   "movsb"
17135   [(set_attr "type" "str")
17136    (set_attr "memory" "both")
17137    (set_attr "prefix_rex" "0")
17138    (set_attr "mode" "QI")])
17139
17140 (define_expand "rep_mov"
17141   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
17142               (set (match_operand 0 "register_operand" "")
17143                    (match_operand 5 "" ""))
17144               (set (match_operand 2 "register_operand" "")
17145                    (match_operand 6 "" ""))
17146               (set (match_operand 1 "memory_operand" "")
17147                    (match_operand 3 "memory_operand" ""))
17148               (use (match_dup 4))])]
17149   ""
17150   "ix86_current_function_needs_cld = 1;")
17151
17152 (define_insn "*rep_movdi_rex64"
17153   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17154    (set (match_operand:DI 0 "register_operand" "=D")
17155         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17156                             (const_int 3))
17157                  (match_operand:DI 3 "register_operand" "0")))
17158    (set (match_operand:DI 1 "register_operand" "=S")
17159         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
17160                  (match_operand:DI 4 "register_operand" "1")))
17161    (set (mem:BLK (match_dup 3))
17162         (mem:BLK (match_dup 4)))
17163    (use (match_dup 5))]
17164   "TARGET_64BIT"
17165   "rep movsq"
17166   [(set_attr "type" "str")
17167    (set_attr "prefix_rep" "1")
17168    (set_attr "memory" "both")
17169    (set_attr "mode" "DI")])
17170
17171 (define_insn "*rep_movsi"
17172   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17173    (set (match_operand:SI 0 "register_operand" "=D")
17174         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
17175                             (const_int 2))
17176                  (match_operand:SI 3 "register_operand" "0")))
17177    (set (match_operand:SI 1 "register_operand" "=S")
17178         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
17179                  (match_operand:SI 4 "register_operand" "1")))
17180    (set (mem:BLK (match_dup 3))
17181         (mem:BLK (match_dup 4)))
17182    (use (match_dup 5))]
17183   "!TARGET_64BIT"
17184   "rep movs{l|d}"
17185   [(set_attr "type" "str")
17186    (set_attr "prefix_rep" "1")
17187    (set_attr "memory" "both")
17188    (set_attr "mode" "SI")])
17189
17190 (define_insn "*rep_movsi_rex64"
17191   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17192    (set (match_operand:DI 0 "register_operand" "=D")
17193         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17194                             (const_int 2))
17195                  (match_operand:DI 3 "register_operand" "0")))
17196    (set (match_operand:DI 1 "register_operand" "=S")
17197         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
17198                  (match_operand:DI 4 "register_operand" "1")))
17199    (set (mem:BLK (match_dup 3))
17200         (mem:BLK (match_dup 4)))
17201    (use (match_dup 5))]
17202   "TARGET_64BIT"
17203   "rep movs{l|d}"
17204   [(set_attr "type" "str")
17205    (set_attr "prefix_rep" "1")
17206    (set_attr "memory" "both")
17207    (set_attr "mode" "SI")])
17208
17209 (define_insn "*rep_movqi"
17210   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17211    (set (match_operand:SI 0 "register_operand" "=D")
17212         (plus:SI (match_operand:SI 3 "register_operand" "0")
17213                  (match_operand:SI 5 "register_operand" "2")))
17214    (set (match_operand:SI 1 "register_operand" "=S")
17215         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
17216    (set (mem:BLK (match_dup 3))
17217         (mem:BLK (match_dup 4)))
17218    (use (match_dup 5))]
17219   "!TARGET_64BIT"
17220   "rep movsb"
17221   [(set_attr "type" "str")
17222    (set_attr "prefix_rep" "1")
17223    (set_attr "memory" "both")
17224    (set_attr "mode" "SI")])
17225
17226 (define_insn "*rep_movqi_rex64"
17227   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17228    (set (match_operand:DI 0 "register_operand" "=D")
17229         (plus:DI (match_operand:DI 3 "register_operand" "0")
17230                  (match_operand:DI 5 "register_operand" "2")))
17231    (set (match_operand:DI 1 "register_operand" "=S")
17232         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
17233    (set (mem:BLK (match_dup 3))
17234         (mem:BLK (match_dup 4)))
17235    (use (match_dup 5))]
17236   "TARGET_64BIT"
17237   "rep movsb"
17238   [(set_attr "type" "str")
17239    (set_attr "prefix_rep" "1")
17240    (set_attr "memory" "both")
17241    (set_attr "mode" "SI")])
17242
17243 (define_expand "setmemsi"
17244    [(use (match_operand:BLK 0 "memory_operand" ""))
17245     (use (match_operand:SI 1 "nonmemory_operand" ""))
17246     (use (match_operand 2 "const_int_operand" ""))
17247     (use (match_operand 3 "const_int_operand" ""))
17248     (use (match_operand:SI 4 "const_int_operand" ""))
17249     (use (match_operand:SI 5 "const_int_operand" ""))]
17250   ""
17251 {
17252  if (ix86_expand_setmem (operands[0], operands[1],
17253                          operands[2], operands[3],
17254                          operands[4], operands[5]))
17255    DONE;
17256  else
17257    FAIL;
17258 })
17259
17260 (define_expand "setmemdi"
17261    [(use (match_operand:BLK 0 "memory_operand" ""))
17262     (use (match_operand:DI 1 "nonmemory_operand" ""))
17263     (use (match_operand 2 "const_int_operand" ""))
17264     (use (match_operand 3 "const_int_operand" ""))
17265     (use (match_operand 4 "const_int_operand" ""))
17266     (use (match_operand 5 "const_int_operand" ""))]
17267   "TARGET_64BIT"
17268 {
17269  if (ix86_expand_setmem (operands[0], operands[1],
17270                          operands[2], operands[3],
17271                          operands[4], operands[5]))
17272    DONE;
17273  else
17274    FAIL;
17275 })
17276
17277 ;; Most CPUs don't like single string operations
17278 ;; Handle this case here to simplify previous expander.
17279
17280 (define_expand "strset"
17281   [(set (match_operand 1 "memory_operand" "")
17282         (match_operand 2 "register_operand" ""))
17283    (parallel [(set (match_operand 0 "register_operand" "")
17284                    (match_dup 3))
17285               (clobber (reg:CC FLAGS_REG))])]
17286   ""
17287 {
17288   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
17289     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
17290
17291   /* If .md ever supports :P for Pmode, this can be directly
17292      in the pattern above.  */
17293   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
17294                               GEN_INT (GET_MODE_SIZE (GET_MODE
17295                                                       (operands[2]))));
17296   if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
17297     {
17298       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
17299                                       operands[3]));
17300       DONE;
17301     }
17302 })
17303
17304 (define_expand "strset_singleop"
17305   [(parallel [(set (match_operand 1 "memory_operand" "")
17306                    (match_operand 2 "register_operand" ""))
17307               (set (match_operand 0 "register_operand" "")
17308                    (match_operand 3 "" ""))])]
17309   ""
17310   "ix86_current_function_needs_cld = 1;")
17311
17312 (define_insn "*strsetdi_rex_1"
17313   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
17314         (match_operand:DI 2 "register_operand" "a"))
17315    (set (match_operand:DI 0 "register_operand" "=D")
17316         (plus:DI (match_dup 1)
17317                  (const_int 8)))]
17318   "TARGET_64BIT"
17319   "stosq"
17320   [(set_attr "type" "str")
17321    (set_attr "memory" "store")
17322    (set_attr "mode" "DI")])
17323
17324 (define_insn "*strsetsi_1"
17325   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
17326         (match_operand:SI 2 "register_operand" "a"))
17327    (set (match_operand:SI 0 "register_operand" "=D")
17328         (plus:SI (match_dup 1)
17329                  (const_int 4)))]
17330   "!TARGET_64BIT"
17331   "stos{l|d}"
17332   [(set_attr "type" "str")
17333    (set_attr "memory" "store")
17334    (set_attr "mode" "SI")])
17335
17336 (define_insn "*strsetsi_rex_1"
17337   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
17338         (match_operand:SI 2 "register_operand" "a"))
17339    (set (match_operand:DI 0 "register_operand" "=D")
17340         (plus:DI (match_dup 1)
17341                  (const_int 4)))]
17342   "TARGET_64BIT"
17343   "stos{l|d}"
17344   [(set_attr "type" "str")
17345    (set_attr "memory" "store")
17346    (set_attr "mode" "SI")])
17347
17348 (define_insn "*strsethi_1"
17349   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
17350         (match_operand:HI 2 "register_operand" "a"))
17351    (set (match_operand:SI 0 "register_operand" "=D")
17352         (plus:SI (match_dup 1)
17353                  (const_int 2)))]
17354   "!TARGET_64BIT"
17355   "stosw"
17356   [(set_attr "type" "str")
17357    (set_attr "memory" "store")
17358    (set_attr "mode" "HI")])
17359
17360 (define_insn "*strsethi_rex_1"
17361   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
17362         (match_operand:HI 2 "register_operand" "a"))
17363    (set (match_operand:DI 0 "register_operand" "=D")
17364         (plus:DI (match_dup 1)
17365                  (const_int 2)))]
17366   "TARGET_64BIT"
17367   "stosw"
17368   [(set_attr "type" "str")
17369    (set_attr "memory" "store")
17370    (set_attr "mode" "HI")])
17371
17372 (define_insn "*strsetqi_1"
17373   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
17374         (match_operand:QI 2 "register_operand" "a"))
17375    (set (match_operand:SI 0 "register_operand" "=D")
17376         (plus:SI (match_dup 1)
17377                  (const_int 1)))]
17378   "!TARGET_64BIT"
17379   "stosb"
17380   [(set_attr "type" "str")
17381    (set_attr "memory" "store")
17382    (set_attr "mode" "QI")])
17383
17384 (define_insn "*strsetqi_rex_1"
17385   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
17386         (match_operand:QI 2 "register_operand" "a"))
17387    (set (match_operand:DI 0 "register_operand" "=D")
17388         (plus:DI (match_dup 1)
17389                  (const_int 1)))]
17390   "TARGET_64BIT"
17391   "stosb"
17392   [(set_attr "type" "str")
17393    (set_attr "memory" "store")
17394    (set_attr "prefix_rex" "0")
17395    (set_attr "mode" "QI")])
17396
17397 (define_expand "rep_stos"
17398   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
17399               (set (match_operand 0 "register_operand" "")
17400                    (match_operand 4 "" ""))
17401               (set (match_operand 2 "memory_operand" "") (const_int 0))
17402               (use (match_operand 3 "register_operand" ""))
17403               (use (match_dup 1))])]
17404   ""
17405   "ix86_current_function_needs_cld = 1;")
17406
17407 (define_insn "*rep_stosdi_rex64"
17408   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17409    (set (match_operand:DI 0 "register_operand" "=D")
17410         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17411                             (const_int 3))
17412                  (match_operand:DI 3 "register_operand" "0")))
17413    (set (mem:BLK (match_dup 3))
17414         (const_int 0))
17415    (use (match_operand:DI 2 "register_operand" "a"))
17416    (use (match_dup 4))]
17417   "TARGET_64BIT"
17418   "rep stosq"
17419   [(set_attr "type" "str")
17420    (set_attr "prefix_rep" "1")
17421    (set_attr "memory" "store")
17422    (set_attr "mode" "DI")])
17423
17424 (define_insn "*rep_stossi"
17425   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17426    (set (match_operand:SI 0 "register_operand" "=D")
17427         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
17428                             (const_int 2))
17429                  (match_operand:SI 3 "register_operand" "0")))
17430    (set (mem:BLK (match_dup 3))
17431         (const_int 0))
17432    (use (match_operand:SI 2 "register_operand" "a"))
17433    (use (match_dup 4))]
17434   "!TARGET_64BIT"
17435   "rep stos{l|d}"
17436   [(set_attr "type" "str")
17437    (set_attr "prefix_rep" "1")
17438    (set_attr "memory" "store")
17439    (set_attr "mode" "SI")])
17440
17441 (define_insn "*rep_stossi_rex64"
17442   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17443    (set (match_operand:DI 0 "register_operand" "=D")
17444         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17445                             (const_int 2))
17446                  (match_operand:DI 3 "register_operand" "0")))
17447    (set (mem:BLK (match_dup 3))
17448         (const_int 0))
17449    (use (match_operand:SI 2 "register_operand" "a"))
17450    (use (match_dup 4))]
17451   "TARGET_64BIT"
17452   "rep stos{l|d}"
17453   [(set_attr "type" "str")
17454    (set_attr "prefix_rep" "1")
17455    (set_attr "memory" "store")
17456    (set_attr "mode" "SI")])
17457
17458 (define_insn "*rep_stosqi"
17459   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17460    (set (match_operand:SI 0 "register_operand" "=D")
17461         (plus:SI (match_operand:SI 3 "register_operand" "0")
17462                  (match_operand:SI 4 "register_operand" "1")))
17463    (set (mem:BLK (match_dup 3))
17464         (const_int 0))
17465    (use (match_operand:QI 2 "register_operand" "a"))
17466    (use (match_dup 4))]
17467   "!TARGET_64BIT"
17468   "rep stosb"
17469   [(set_attr "type" "str")
17470    (set_attr "prefix_rep" "1")
17471    (set_attr "memory" "store")
17472    (set_attr "mode" "QI")])
17473
17474 (define_insn "*rep_stosqi_rex64"
17475   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17476    (set (match_operand:DI 0 "register_operand" "=D")
17477         (plus:DI (match_operand:DI 3 "register_operand" "0")
17478                  (match_operand:DI 4 "register_operand" "1")))
17479    (set (mem:BLK (match_dup 3))
17480         (const_int 0))
17481    (use (match_operand:QI 2 "register_operand" "a"))
17482    (use (match_dup 4))]
17483   "TARGET_64BIT"
17484   "rep stosb"
17485   [(set_attr "type" "str")
17486    (set_attr "prefix_rep" "1")
17487    (set_attr "memory" "store")
17488    (set_attr "prefix_rex" "0")
17489    (set_attr "mode" "QI")])
17490
17491 (define_expand "cmpstrnsi"
17492   [(set (match_operand:SI 0 "register_operand" "")
17493         (compare:SI (match_operand:BLK 1 "general_operand" "")
17494                     (match_operand:BLK 2 "general_operand" "")))
17495    (use (match_operand 3 "general_operand" ""))
17496    (use (match_operand 4 "immediate_operand" ""))]
17497   ""
17498 {
17499   rtx addr1, addr2, out, outlow, count, countreg, align;
17500
17501   if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
17502     FAIL;
17503
17504   /* Can't use this if the user has appropriated esi or edi.  */
17505   if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
17506     FAIL;
17507
17508   out = operands[0];
17509   if (!REG_P (out))
17510     out = gen_reg_rtx (SImode);
17511
17512   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
17513   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
17514   if (addr1 != XEXP (operands[1], 0))
17515     operands[1] = replace_equiv_address_nv (operands[1], addr1);
17516   if (addr2 != XEXP (operands[2], 0))
17517     operands[2] = replace_equiv_address_nv (operands[2], addr2);
17518
17519   count = operands[3];
17520   countreg = ix86_zero_extend_to_Pmode (count);
17521
17522   /* %%% Iff we are testing strict equality, we can use known alignment
17523      to good advantage.  This may be possible with combine, particularly
17524      once cc0 is dead.  */
17525   align = operands[4];
17526
17527   if (CONST_INT_P (count))
17528     {
17529       if (INTVAL (count) == 0)
17530         {
17531           emit_move_insn (operands[0], const0_rtx);
17532           DONE;
17533         }
17534       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
17535                                      operands[1], operands[2]));
17536     }
17537   else
17538     {
17539       rtx (*cmp_insn)(rtx, rtx);
17540
17541       if (TARGET_64BIT)
17542         cmp_insn = gen_cmpdi_1;
17543       else
17544         cmp_insn = gen_cmpsi_1;
17545       emit_insn (cmp_insn (countreg, countreg));
17546       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
17547                                   operands[1], operands[2]));
17548     }
17549
17550   outlow = gen_lowpart (QImode, out);
17551   emit_insn (gen_cmpintqi (outlow));
17552   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
17553
17554   if (operands[0] != out)
17555     emit_move_insn (operands[0], out);
17556
17557   DONE;
17558 })
17559
17560 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
17561
17562 (define_expand "cmpintqi"
17563   [(set (match_dup 1)
17564         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17565    (set (match_dup 2)
17566         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17567    (parallel [(set (match_operand:QI 0 "register_operand" "")
17568                    (minus:QI (match_dup 1)
17569                              (match_dup 2)))
17570               (clobber (reg:CC FLAGS_REG))])]
17571   ""
17572   "operands[1] = gen_reg_rtx (QImode);
17573    operands[2] = gen_reg_rtx (QImode);")
17574
17575 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
17576 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
17577
17578 (define_expand "cmpstrnqi_nz_1"
17579   [(parallel [(set (reg:CC FLAGS_REG)
17580                    (compare:CC (match_operand 4 "memory_operand" "")
17581                                (match_operand 5 "memory_operand" "")))
17582               (use (match_operand 2 "register_operand" ""))
17583               (use (match_operand:SI 3 "immediate_operand" ""))
17584               (clobber (match_operand 0 "register_operand" ""))
17585               (clobber (match_operand 1 "register_operand" ""))
17586               (clobber (match_dup 2))])]
17587   ""
17588   "ix86_current_function_needs_cld = 1;")
17589
17590 (define_insn "*cmpstrnqi_nz_1"
17591   [(set (reg:CC FLAGS_REG)
17592         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17593                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
17594    (use (match_operand:SI 6 "register_operand" "2"))
17595    (use (match_operand:SI 3 "immediate_operand" "i"))
17596    (clobber (match_operand:SI 0 "register_operand" "=S"))
17597    (clobber (match_operand:SI 1 "register_operand" "=D"))
17598    (clobber (match_operand:SI 2 "register_operand" "=c"))]
17599   "!TARGET_64BIT"
17600   "repz cmpsb"
17601   [(set_attr "type" "str")
17602    (set_attr "mode" "QI")
17603    (set_attr "prefix_rep" "1")])
17604
17605 (define_insn "*cmpstrnqi_nz_rex_1"
17606   [(set (reg:CC FLAGS_REG)
17607         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
17608                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
17609    (use (match_operand:DI 6 "register_operand" "2"))
17610    (use (match_operand:SI 3 "immediate_operand" "i"))
17611    (clobber (match_operand:DI 0 "register_operand" "=S"))
17612    (clobber (match_operand:DI 1 "register_operand" "=D"))
17613    (clobber (match_operand:DI 2 "register_operand" "=c"))]
17614   "TARGET_64BIT"
17615   "repz cmpsb"
17616   [(set_attr "type" "str")
17617    (set_attr "mode" "QI")
17618    (set_attr "prefix_rex" "0")
17619    (set_attr "prefix_rep" "1")])
17620
17621 ;; The same, but the count is not known to not be zero.
17622
17623 (define_expand "cmpstrnqi_1"
17624   [(parallel [(set (reg:CC FLAGS_REG)
17625                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
17626                                      (const_int 0))
17627                   (compare:CC (match_operand 4 "memory_operand" "")
17628                               (match_operand 5 "memory_operand" ""))
17629                   (const_int 0)))
17630               (use (match_operand:SI 3 "immediate_operand" ""))
17631               (use (reg:CC FLAGS_REG))
17632               (clobber (match_operand 0 "register_operand" ""))
17633               (clobber (match_operand 1 "register_operand" ""))
17634               (clobber (match_dup 2))])]
17635   ""
17636   "ix86_current_function_needs_cld = 1;")
17637
17638 (define_insn "*cmpstrnqi_1"
17639   [(set (reg:CC FLAGS_REG)
17640         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
17641                              (const_int 0))
17642           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17643                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
17644           (const_int 0)))
17645    (use (match_operand:SI 3 "immediate_operand" "i"))
17646    (use (reg:CC FLAGS_REG))
17647    (clobber (match_operand:SI 0 "register_operand" "=S"))
17648    (clobber (match_operand:SI 1 "register_operand" "=D"))
17649    (clobber (match_operand:SI 2 "register_operand" "=c"))]
17650   "!TARGET_64BIT"
17651   "repz cmpsb"
17652   [(set_attr "type" "str")
17653    (set_attr "mode" "QI")
17654    (set_attr "prefix_rep" "1")])
17655
17656 (define_insn "*cmpstrnqi_rex_1"
17657   [(set (reg:CC FLAGS_REG)
17658         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
17659                              (const_int 0))
17660           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
17661                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
17662           (const_int 0)))
17663    (use (match_operand:SI 3 "immediate_operand" "i"))
17664    (use (reg:CC FLAGS_REG))
17665    (clobber (match_operand:DI 0 "register_operand" "=S"))
17666    (clobber (match_operand:DI 1 "register_operand" "=D"))
17667    (clobber (match_operand:DI 2 "register_operand" "=c"))]
17668   "TARGET_64BIT"
17669   "repz cmpsb"
17670   [(set_attr "type" "str")
17671    (set_attr "mode" "QI")
17672    (set_attr "prefix_rex" "0")
17673    (set_attr "prefix_rep" "1")])
17674
17675 (define_expand "strlensi"
17676   [(set (match_operand:SI 0 "register_operand" "")
17677         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
17678                     (match_operand:QI 2 "immediate_operand" "")
17679                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
17680   ""
17681 {
17682  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17683    DONE;
17684  else
17685    FAIL;
17686 })
17687
17688 (define_expand "strlendi"
17689   [(set (match_operand:DI 0 "register_operand" "")
17690         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
17691                     (match_operand:QI 2 "immediate_operand" "")
17692                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
17693   ""
17694 {
17695  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17696    DONE;
17697  else
17698    FAIL;
17699 })
17700
17701 (define_expand "strlenqi_1"
17702   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
17703               (clobber (match_operand 1 "register_operand" ""))
17704               (clobber (reg:CC FLAGS_REG))])]
17705   ""
17706   "ix86_current_function_needs_cld = 1;")
17707
17708 (define_insn "*strlenqi_1"
17709   [(set (match_operand:SI 0 "register_operand" "=&c")
17710         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
17711                     (match_operand:QI 2 "register_operand" "a")
17712                     (match_operand:SI 3 "immediate_operand" "i")
17713                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
17714    (clobber (match_operand:SI 1 "register_operand" "=D"))
17715    (clobber (reg:CC FLAGS_REG))]
17716   "!TARGET_64BIT"
17717   "repnz scasb"
17718   [(set_attr "type" "str")
17719    (set_attr "mode" "QI")
17720    (set_attr "prefix_rep" "1")])
17721
17722 (define_insn "*strlenqi_rex_1"
17723   [(set (match_operand:DI 0 "register_operand" "=&c")
17724         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
17725                     (match_operand:QI 2 "register_operand" "a")
17726                     (match_operand:DI 3 "immediate_operand" "i")
17727                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
17728    (clobber (match_operand:DI 1 "register_operand" "=D"))
17729    (clobber (reg:CC FLAGS_REG))]
17730   "TARGET_64BIT"
17731   "repnz scasb"
17732   [(set_attr "type" "str")
17733    (set_attr "mode" "QI")
17734    (set_attr "prefix_rex" "0")
17735    (set_attr "prefix_rep" "1")])
17736
17737 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
17738 ;; handled in combine, but it is not currently up to the task.
17739 ;; When used for their truth value, the cmpstrn* expanders generate
17740 ;; code like this:
17741 ;;
17742 ;;   repz cmpsb
17743 ;;   seta       %al
17744 ;;   setb       %dl
17745 ;;   cmpb       %al, %dl
17746 ;;   jcc        label
17747 ;;
17748 ;; The intermediate three instructions are unnecessary.
17749
17750 ;; This one handles cmpstrn*_nz_1...
17751 (define_peephole2
17752   [(parallel[
17753      (set (reg:CC FLAGS_REG)
17754           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17755                       (mem:BLK (match_operand 5 "register_operand" ""))))
17756      (use (match_operand 6 "register_operand" ""))
17757      (use (match_operand:SI 3 "immediate_operand" ""))
17758      (clobber (match_operand 0 "register_operand" ""))
17759      (clobber (match_operand 1 "register_operand" ""))
17760      (clobber (match_operand 2 "register_operand" ""))])
17761    (set (match_operand:QI 7 "register_operand" "")
17762         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17763    (set (match_operand:QI 8 "register_operand" "")
17764         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17765    (set (reg FLAGS_REG)
17766         (compare (match_dup 7) (match_dup 8)))
17767   ]
17768   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17769   [(parallel[
17770      (set (reg:CC FLAGS_REG)
17771           (compare:CC (mem:BLK (match_dup 4))
17772                       (mem:BLK (match_dup 5))))
17773      (use (match_dup 6))
17774      (use (match_dup 3))
17775      (clobber (match_dup 0))
17776      (clobber (match_dup 1))
17777      (clobber (match_dup 2))])]
17778   "")
17779
17780 ;; ...and this one handles cmpstrn*_1.
17781 (define_peephole2
17782   [(parallel[
17783      (set (reg:CC FLAGS_REG)
17784           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
17785                                (const_int 0))
17786             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17787                         (mem:BLK (match_operand 5 "register_operand" "")))
17788             (const_int 0)))
17789      (use (match_operand:SI 3 "immediate_operand" ""))
17790      (use (reg:CC FLAGS_REG))
17791      (clobber (match_operand 0 "register_operand" ""))
17792      (clobber (match_operand 1 "register_operand" ""))
17793      (clobber (match_operand 2 "register_operand" ""))])
17794    (set (match_operand:QI 7 "register_operand" "")
17795         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17796    (set (match_operand:QI 8 "register_operand" "")
17797         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17798    (set (reg FLAGS_REG)
17799         (compare (match_dup 7) (match_dup 8)))
17800   ]
17801   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17802   [(parallel[
17803      (set (reg:CC FLAGS_REG)
17804           (if_then_else:CC (ne (match_dup 6)
17805                                (const_int 0))
17806             (compare:CC (mem:BLK (match_dup 4))
17807                         (mem:BLK (match_dup 5)))
17808             (const_int 0)))
17809      (use (match_dup 3))
17810      (use (reg:CC FLAGS_REG))
17811      (clobber (match_dup 0))
17812      (clobber (match_dup 1))
17813      (clobber (match_dup 2))])]
17814   "")
17815
17816
17817 \f
17818 ;; Conditional move instructions.
17819
17820 (define_expand "mov<mode>cc"
17821   [(set (match_operand:SWIM 0 "register_operand" "")
17822         (if_then_else:SWIM (match_operand 1 "comparison_operator" "")
17823                            (match_operand:SWIM 2 "general_operand" "")
17824                            (match_operand:SWIM 3 "general_operand" "")))]
17825   ""
17826   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
17827
17828 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
17829 ;; the register first winds up with `sbbl $0,reg', which is also weird.
17830 ;; So just document what we're doing explicitly.
17831
17832 (define_expand "x86_mov<mode>cc_0_m1"
17833   [(parallel
17834     [(set (match_operand:SWI48 0 "register_operand" "")
17835           (if_then_else:SWI48
17836             (match_operator:SWI48 2 "ix86_carry_flag_operator"
17837              [(match_operand 1 "flags_reg_operand" "")
17838               (const_int 0)])
17839             (const_int -1)
17840             (const_int 0)))
17841      (clobber (reg:CC FLAGS_REG))])]
17842   ""
17843   "")
17844
17845 (define_insn "*x86_mov<mode>cc_0_m1"
17846   [(set (match_operand:SWI48 0 "register_operand" "=r")
17847         (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
17848                              [(reg FLAGS_REG) (const_int 0)])
17849           (const_int -1)
17850           (const_int 0)))
17851    (clobber (reg:CC FLAGS_REG))]
17852   ""
17853   "sbb{<imodesuffix>}\t%0, %0"
17854   ; Since we don't have the proper number of operands for an alu insn,
17855   ; fill in all the blanks.
17856   [(set_attr "type" "alu")
17857    (set_attr "use_carry" "1")
17858    (set_attr "pent_pair" "pu")
17859    (set_attr "memory" "none")
17860    (set_attr "imm_disp" "false")
17861    (set_attr "mode" "<MODE>")
17862    (set_attr "length_immediate" "0")])
17863
17864 (define_insn "*x86_mov<mode>cc_0_m1_se"
17865   [(set (match_operand:SWI48 0 "register_operand" "=r")
17866         (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
17867                              [(reg FLAGS_REG) (const_int 0)])
17868                             (const_int 1)
17869                             (const_int 0)))
17870    (clobber (reg:CC FLAGS_REG))]
17871   ""
17872   "sbb{<imodesuffix>}\t%0, %0"
17873   [(set_attr "type" "alu")
17874    (set_attr "use_carry" "1")
17875    (set_attr "pent_pair" "pu")
17876    (set_attr "memory" "none")
17877    (set_attr "imm_disp" "false")
17878    (set_attr "mode" "<MODE>")
17879    (set_attr "length_immediate" "0")])
17880
17881 (define_insn "*x86_mov<mode>cc_0_m1_neg"
17882   [(set (match_operand:SWI48 0 "register_operand" "=r")
17883         (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
17884                     [(reg FLAGS_REG) (const_int 0)])))]
17885   ""
17886   "sbb{<imodesuffix>}\t%0, %0"
17887   [(set_attr "type" "alu")
17888    (set_attr "use_carry" "1")
17889    (set_attr "pent_pair" "pu")
17890    (set_attr "memory" "none")
17891    (set_attr "imm_disp" "false")
17892    (set_attr "mode" "<MODE>")
17893    (set_attr "length_immediate" "0")])
17894
17895 (define_insn "*mov<mode>cc_noc"
17896   [(set (match_operand:SWI248 0 "register_operand" "=r,r")
17897         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
17898                                [(reg FLAGS_REG) (const_int 0)])
17899           (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
17900           (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
17901   "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17902   "@
17903    cmov%O2%C1\t{%2, %0|%0, %2}
17904    cmov%O2%c1\t{%3, %0|%0, %3}"
17905   [(set_attr "type" "icmov")
17906    (set_attr "mode" "<MODE>")])
17907
17908 (define_insn_and_split "*movqicc_noc"
17909   [(set (match_operand:QI 0 "register_operand" "=r,r")
17910         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
17911                            [(match_operand 4 "flags_reg_operand" "")
17912                             (const_int 0)])
17913                       (match_operand:QI 2 "register_operand" "r,0")
17914                       (match_operand:QI 3 "register_operand" "0,r")))]
17915   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
17916   "#"
17917   "&& reload_completed"
17918   [(set (match_dup 0)
17919         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17920                       (match_dup 2)
17921                       (match_dup 3)))]
17922   "operands[0] = gen_lowpart (SImode, operands[0]);
17923    operands[2] = gen_lowpart (SImode, operands[2]);
17924    operands[3] = gen_lowpart (SImode, operands[3]);"
17925   [(set_attr "type" "icmov")
17926    (set_attr "mode" "SI")])
17927
17928 (define_expand "mov<mode>cc"
17929   [(set (match_operand:X87MODEF 0 "register_operand" "")
17930         (if_then_else:X87MODEF
17931           (match_operand 1 "ix86_fp_comparison_operator" "")
17932           (match_operand:X87MODEF 2 "register_operand" "")
17933           (match_operand:X87MODEF 3 "register_operand" "")))]
17934   "(TARGET_80387 && TARGET_CMOVE)
17935    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
17936   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
17937
17938 (define_insn "*movsfcc_1_387"
17939   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
17940         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
17941                                 [(reg FLAGS_REG) (const_int 0)])
17942                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
17943                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
17944   "TARGET_80387 && TARGET_CMOVE
17945    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17946   "@
17947    fcmov%F1\t{%2, %0|%0, %2}
17948    fcmov%f1\t{%3, %0|%0, %3}
17949    cmov%O2%C1\t{%2, %0|%0, %2}
17950    cmov%O2%c1\t{%3, %0|%0, %3}"
17951   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17952    (set_attr "mode" "SF,SF,SI,SI")])
17953
17954 (define_insn "*movdfcc_1"
17955   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
17956         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17957                                 [(reg FLAGS_REG) (const_int 0)])
17958                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
17959                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
17960   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
17961    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17962   "@
17963    fcmov%F1\t{%2, %0|%0, %2}
17964    fcmov%f1\t{%3, %0|%0, %3}
17965    #
17966    #"
17967   [(set_attr "type" "fcmov,fcmov,multi,multi")
17968    (set_attr "mode" "DF")])
17969
17970 (define_insn "*movdfcc_1_rex64"
17971   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
17972         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17973                                 [(reg FLAGS_REG) (const_int 0)])
17974                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
17975                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
17976   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
17977    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17978   "@
17979    fcmov%F1\t{%2, %0|%0, %2}
17980    fcmov%f1\t{%3, %0|%0, %3}
17981    cmov%O2%C1\t{%2, %0|%0, %2}
17982    cmov%O2%c1\t{%3, %0|%0, %3}"
17983   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17984    (set_attr "mode" "DF")])
17985
17986 (define_split
17987   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
17988         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17989                                 [(match_operand 4 "flags_reg_operand" "")
17990                                  (const_int 0)])
17991                       (match_operand:DF 2 "nonimmediate_operand" "")
17992                       (match_operand:DF 3 "nonimmediate_operand" "")))]
17993   "!TARGET_64BIT && reload_completed"
17994   [(set (match_dup 2)
17995         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17996                       (match_dup 5)
17997                       (match_dup 6)))
17998    (set (match_dup 3)
17999         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18000                       (match_dup 7)
18001                       (match_dup 8)))]
18002   "split_di (&operands[2], 2, &operands[5], &operands[7]);
18003    split_di (&operands[0], 1, &operands[2], &operands[3]);")
18004
18005 (define_insn "*movxfcc_1"
18006   [(set (match_operand:XF 0 "register_operand" "=f,f")
18007         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
18008                                 [(reg FLAGS_REG) (const_int 0)])
18009                       (match_operand:XF 2 "register_operand" "f,0")
18010                       (match_operand:XF 3 "register_operand" "0,f")))]
18011   "TARGET_80387 && TARGET_CMOVE"
18012   "@
18013    fcmov%F1\t{%2, %0|%0, %2}
18014    fcmov%f1\t{%3, %0|%0, %3}"
18015   [(set_attr "type" "fcmov")
18016    (set_attr "mode" "XF")])
18017
18018 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
18019 ;; the scalar versions to have only XMM registers as operands.
18020
18021 ;; XOP conditional move
18022 (define_insn "*xop_pcmov_<mode>"
18023   [(set (match_operand:MODEF 0 "register_operand" "=x")
18024         (if_then_else:MODEF
18025           (match_operand:MODEF 1 "register_operand" "x")
18026           (match_operand:MODEF 2 "register_operand" "x")
18027           (match_operand:MODEF 3 "register_operand" "x")))]
18028   "TARGET_XOP"
18029   "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
18030   [(set_attr "type" "sse4arg")])
18031
18032 ;; These versions of the min/max patterns are intentionally ignorant of
18033 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
18034 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
18035 ;; are undefined in this condition, we're certain this is correct.
18036
18037 (define_insn "*avx_<code><mode>3"
18038   [(set (match_operand:MODEF 0 "register_operand" "=x")
18039         (smaxmin:MODEF
18040           (match_operand:MODEF 1 "nonimmediate_operand" "%x")
18041           (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
18042   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
18043   "v<maxminfprefix>s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
18044   [(set_attr "type" "sseadd")
18045    (set_attr "prefix" "vex")
18046    (set_attr "mode" "<MODE>")])
18047
18048 (define_insn "<code><mode>3"
18049   [(set (match_operand:MODEF 0 "register_operand" "=x")
18050         (smaxmin:MODEF
18051           (match_operand:MODEF 1 "nonimmediate_operand" "%0")
18052           (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
18053   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
18054   "<maxminfprefix>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
18055   [(set_attr "type" "sseadd")
18056    (set_attr "mode" "<MODE>")])
18057
18058 ;; These versions of the min/max patterns implement exactly the operations
18059 ;;   min = (op1 < op2 ? op1 : op2)
18060 ;;   max = (!(op1 < op2) ? op1 : op2)
18061 ;; Their operands are not commutative, and thus they may be used in the
18062 ;; presence of -0.0 and NaN.
18063
18064 (define_insn "*avx_ieee_smin<mode>3"
18065   [(set (match_operand:MODEF 0 "register_operand" "=x")
18066         (unspec:MODEF
18067           [(match_operand:MODEF 1 "register_operand" "x")
18068            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
18069          UNSPEC_IEEE_MIN))]
18070   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
18071   "vmins<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
18072   [(set_attr "type" "sseadd")
18073    (set_attr "prefix" "vex")
18074    (set_attr "mode" "<MODE>")])
18075
18076 (define_insn "*ieee_smin<mode>3"
18077   [(set (match_operand:MODEF 0 "register_operand" "=x")
18078         (unspec:MODEF
18079           [(match_operand:MODEF 1 "register_operand" "0")
18080            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
18081          UNSPEC_IEEE_MIN))]
18082   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
18083   "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
18084   [(set_attr "type" "sseadd")
18085    (set_attr "mode" "<MODE>")])
18086
18087 (define_insn "*avx_ieee_smax<mode>3"
18088   [(set (match_operand:MODEF 0 "register_operand" "=x")
18089         (unspec:MODEF
18090           [(match_operand:MODEF 1 "register_operand" "0")
18091            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
18092          UNSPEC_IEEE_MAX))]
18093   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
18094   "vmaxs<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
18095   [(set_attr "type" "sseadd")
18096    (set_attr "prefix" "vex")
18097    (set_attr "mode" "<MODE>")])
18098
18099 (define_insn "*ieee_smax<mode>3"
18100   [(set (match_operand:MODEF 0 "register_operand" "=x")
18101         (unspec:MODEF
18102           [(match_operand:MODEF 1 "register_operand" "0")
18103            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
18104          UNSPEC_IEEE_MAX))]
18105   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
18106   "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
18107   [(set_attr "type" "sseadd")
18108    (set_attr "mode" "<MODE>")])
18109
18110 ;; Make two stack loads independent:
18111 ;;   fld aa              fld aa
18112 ;;   fld %st(0)     ->   fld bb
18113 ;;   fmul bb             fmul %st(1), %st
18114 ;;
18115 ;; Actually we only match the last two instructions for simplicity.
18116 (define_peephole2
18117   [(set (match_operand 0 "fp_register_operand" "")
18118         (match_operand 1 "fp_register_operand" ""))
18119    (set (match_dup 0)
18120         (match_operator 2 "binary_fp_operator"
18121            [(match_dup 0)
18122             (match_operand 3 "memory_operand" "")]))]
18123   "REGNO (operands[0]) != REGNO (operands[1])"
18124   [(set (match_dup 0) (match_dup 3))
18125    (set (match_dup 0) (match_dup 4))]
18126
18127   ;; The % modifier is not operational anymore in peephole2's, so we have to
18128   ;; swap the operands manually in the case of addition and multiplication.
18129   "if (COMMUTATIVE_ARITH_P (operands[2]))
18130      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
18131                                  operands[0], operands[1]);
18132    else
18133      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
18134                                  operands[1], operands[0]);")
18135
18136 ;; Conditional addition patterns
18137 (define_expand "add<mode>cc"
18138   [(match_operand:SWI 0 "register_operand" "")
18139    (match_operand 1 "comparison_operator" "")
18140    (match_operand:SWI 2 "register_operand" "")
18141    (match_operand:SWI 3 "const_int_operand" "")]
18142   ""
18143   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
18144
18145 \f
18146 ;; Misc patterns (?)
18147
18148 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
18149 ;; Otherwise there will be nothing to keep
18150 ;;
18151 ;; [(set (reg ebp) (reg esp))]
18152 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
18153 ;;  (clobber (eflags)]
18154 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
18155 ;;
18156 ;; in proper program order.
18157 (define_insn "pro_epilogue_adjust_stack_1"
18158   [(set (match_operand:SI 0 "register_operand" "=r,r")
18159         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
18160                  (match_operand:SI 2 "immediate_operand" "i,i")))
18161    (clobber (reg:CC FLAGS_REG))
18162    (clobber (mem:BLK (scratch)))]
18163   "!TARGET_64BIT"
18164 {
18165   switch (get_attr_type (insn))
18166     {
18167     case TYPE_IMOV:
18168       return "mov{l}\t{%1, %0|%0, %1}";
18169
18170     case TYPE_ALU:
18171       if (CONST_INT_P (operands[2])
18172           && (INTVAL (operands[2]) == 128
18173               || (INTVAL (operands[2]) < 0
18174                   && INTVAL (operands[2]) != -128)))
18175         {
18176           operands[2] = GEN_INT (-INTVAL (operands[2]));
18177           return "sub{l}\t{%2, %0|%0, %2}";
18178         }
18179       return "add{l}\t{%2, %0|%0, %2}";
18180
18181     case TYPE_LEA:
18182       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18183       return "lea{l}\t{%a2, %0|%0, %a2}";
18184
18185     default:
18186       gcc_unreachable ();
18187     }
18188 }
18189   [(set (attr "type")
18190         (cond [(and (eq_attr "alternative" "0") 
18191                     (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
18192                  (const_string "alu")
18193                (match_operand:SI 2 "const0_operand" "")
18194                  (const_string "imov")
18195               ]
18196               (const_string "lea")))
18197    (set (attr "length_immediate")
18198         (cond [(eq_attr "type" "imov")
18199                  (const_string "0")
18200                (and (eq_attr "type" "alu")
18201                     (match_operand 2 "const128_operand" ""))
18202                  (const_string "1")
18203               ]
18204               (const_string "*")))
18205    (set_attr "mode" "SI")])
18206
18207 (define_insn "pro_epilogue_adjust_stack_rex64"
18208   [(set (match_operand:DI 0 "register_operand" "=r,r")
18209         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18210                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
18211    (clobber (reg:CC FLAGS_REG))
18212    (clobber (mem:BLK (scratch)))]
18213   "TARGET_64BIT"
18214 {
18215   switch (get_attr_type (insn))
18216     {
18217     case TYPE_IMOV:
18218       return "mov{q}\t{%1, %0|%0, %1}";
18219
18220     case TYPE_ALU:
18221       if (CONST_INT_P (operands[2])
18222           /* Avoid overflows.  */
18223           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
18224           && (INTVAL (operands[2]) == 128
18225               || (INTVAL (operands[2]) < 0
18226                   && INTVAL (operands[2]) != -128)))
18227         {
18228           operands[2] = GEN_INT (-INTVAL (operands[2]));
18229           return "sub{q}\t{%2, %0|%0, %2}";
18230         }
18231       return "add{q}\t{%2, %0|%0, %2}";
18232
18233     case TYPE_LEA:
18234       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18235       return "lea{q}\t{%a2, %0|%0, %a2}";
18236
18237     default:
18238       gcc_unreachable ();
18239     }
18240 }
18241   [(set (attr "type")
18242         (cond [(and (eq_attr "alternative" "0")
18243                     (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
18244                  (const_string "alu")
18245                (match_operand:DI 2 "const0_operand" "")
18246                  (const_string "imov")
18247               ]
18248               (const_string "lea")))
18249    (set (attr "length_immediate")
18250         (cond [(eq_attr "type" "imov")
18251                  (const_string "0")
18252                (and (eq_attr "type" "alu")
18253                     (match_operand 2 "const128_operand" ""))
18254                  (const_string "1")
18255               ]
18256               (const_string "*")))
18257    (set_attr "mode" "DI")])
18258
18259 (define_insn "pro_epilogue_adjust_stack_rex64_2"
18260   [(set (match_operand:DI 0 "register_operand" "=r,r")
18261         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18262                  (match_operand:DI 3 "immediate_operand" "i,i")))
18263    (use (match_operand:DI 2 "register_operand" "r,r"))
18264    (clobber (reg:CC FLAGS_REG))
18265    (clobber (mem:BLK (scratch)))]
18266   "TARGET_64BIT"
18267 {
18268   switch (get_attr_type (insn))
18269     {
18270     case TYPE_ALU:
18271       return "add{q}\t{%2, %0|%0, %2}";
18272
18273     case TYPE_LEA:
18274       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
18275       return "lea{q}\t{%a2, %0|%0, %a2}";
18276
18277     default:
18278       gcc_unreachable ();
18279     }
18280 }
18281   [(set_attr "type" "alu,lea")
18282    (set_attr "mode" "DI")])
18283
18284 (define_insn "allocate_stack_worker_32"
18285   [(set (match_operand:SI 0 "register_operand" "=a")
18286         (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")]
18287                             UNSPECV_STACK_PROBE))
18288    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 1)))
18289    (clobber (reg:CC FLAGS_REG))]
18290   "!TARGET_64BIT && TARGET_STACK_PROBE"
18291   "call\t___chkstk"
18292   [(set_attr "type" "multi")
18293    (set_attr "length" "5")])
18294
18295 (define_insn "allocate_stack_worker_64"
18296   [(set (match_operand:DI 0 "register_operand" "=a")
18297         (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "0")]
18298                             UNSPECV_STACK_PROBE))
18299    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 1)))
18300    (clobber (reg:DI R10_REG))
18301    (clobber (reg:DI R11_REG))
18302    (clobber (reg:CC FLAGS_REG))]
18303   "TARGET_64BIT && TARGET_STACK_PROBE"
18304   "call\t___chkstk"
18305   [(set_attr "type" "multi")
18306    (set_attr "length" "5")])
18307
18308 (define_expand "allocate_stack"
18309   [(match_operand 0 "register_operand" "")
18310    (match_operand 1 "general_operand" "")]
18311   "TARGET_STACK_PROBE"
18312 {
18313   rtx x;
18314
18315 #ifndef CHECK_STACK_LIMIT
18316 #define CHECK_STACK_LIMIT 0
18317 #endif
18318
18319   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
18320       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
18321     {
18322       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
18323                                stack_pointer_rtx, 0, OPTAB_DIRECT);
18324       if (x != stack_pointer_rtx)
18325         emit_move_insn (stack_pointer_rtx, x);
18326     }
18327   else
18328     {
18329       x = copy_to_mode_reg (Pmode, operands[1]);
18330       if (TARGET_64BIT)
18331         x = gen_allocate_stack_worker_64 (x, x);
18332       else
18333         x = gen_allocate_stack_worker_32 (x, x);
18334       emit_insn (x);
18335     }
18336
18337   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
18338   DONE;
18339 })
18340
18341 ;; Use IOR for stack probes, this is shorter.
18342 (define_expand "probe_stack"
18343   [(match_operand 0 "memory_operand" "")]
18344   ""
18345 {
18346   if (GET_MODE (operands[0]) == DImode)
18347     emit_insn (gen_iordi3 (operands[0], operands[0], const0_rtx));
18348   else
18349     emit_insn (gen_iorsi3 (operands[0], operands[0], const0_rtx));
18350   DONE;
18351 })
18352
18353 (define_expand "builtin_setjmp_receiver"
18354   [(label_ref (match_operand 0 "" ""))]
18355   "!TARGET_64BIT && flag_pic"
18356 {
18357 #if TARGET_MACHO
18358   if (TARGET_MACHO)
18359     {
18360       rtx xops[3];
18361       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
18362       rtx label_rtx = gen_label_rtx ();
18363       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
18364       xops[0] = xops[1] = picreg;
18365       xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
18366       ix86_expand_binary_operator (MINUS, SImode, xops);
18367     }
18368   else
18369 #endif
18370     emit_insn (gen_set_got (pic_offset_table_rtx));
18371   DONE;
18372 })
18373 \f
18374 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
18375
18376 (define_split
18377   [(set (match_operand 0 "register_operand" "")
18378         (match_operator 3 "promotable_binary_operator"
18379            [(match_operand 1 "register_operand" "")
18380             (match_operand 2 "aligned_operand" "")]))
18381    (clobber (reg:CC FLAGS_REG))]
18382   "! TARGET_PARTIAL_REG_STALL && reload_completed
18383    && ((GET_MODE (operands[0]) == HImode
18384         && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
18385             /* ??? next two lines just !satisfies_constraint_K (...) */
18386             || !CONST_INT_P (operands[2])
18387             || satisfies_constraint_K (operands[2])))
18388        || (GET_MODE (operands[0]) == QImode
18389            && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
18390   [(parallel [(set (match_dup 0)
18391                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18392               (clobber (reg:CC FLAGS_REG))])]
18393   "operands[0] = gen_lowpart (SImode, operands[0]);
18394    operands[1] = gen_lowpart (SImode, operands[1]);
18395    if (GET_CODE (operands[3]) != ASHIFT)
18396      operands[2] = gen_lowpart (SImode, operands[2]);
18397    PUT_MODE (operands[3], SImode);")
18398
18399 ; Promote the QImode tests, as i386 has encoding of the AND
18400 ; instruction with 32-bit sign-extended immediate and thus the
18401 ; instruction size is unchanged, except in the %eax case for
18402 ; which it is increased by one byte, hence the ! optimize_size.
18403 (define_split
18404   [(set (match_operand 0 "flags_reg_operand" "")
18405         (match_operator 2 "compare_operator"
18406           [(and (match_operand 3 "aligned_operand" "")
18407                 (match_operand 4 "const_int_operand" ""))
18408            (const_int 0)]))
18409    (set (match_operand 1 "register_operand" "")
18410         (and (match_dup 3) (match_dup 4)))]
18411   "! TARGET_PARTIAL_REG_STALL && reload_completed
18412    && optimize_insn_for_speed_p ()
18413    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
18414        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
18415    /* Ensure that the operand will remain sign-extended immediate.  */
18416    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
18417   [(parallel [(set (match_dup 0)
18418                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
18419                                     (const_int 0)]))
18420               (set (match_dup 1)
18421                    (and:SI (match_dup 3) (match_dup 4)))])]
18422 {
18423   operands[4]
18424     = gen_int_mode (INTVAL (operands[4])
18425                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
18426   operands[1] = gen_lowpart (SImode, operands[1]);
18427   operands[3] = gen_lowpart (SImode, operands[3]);
18428 })
18429
18430 ; Don't promote the QImode tests, as i386 doesn't have encoding of
18431 ; the TEST instruction with 32-bit sign-extended immediate and thus
18432 ; the instruction size would at least double, which is not what we
18433 ; want even with ! optimize_size.
18434 (define_split
18435   [(set (match_operand 0 "flags_reg_operand" "")
18436         (match_operator 1 "compare_operator"
18437           [(and (match_operand:HI 2 "aligned_operand" "")
18438                 (match_operand:HI 3 "const_int_operand" ""))
18439            (const_int 0)]))]
18440   "! TARGET_PARTIAL_REG_STALL && reload_completed
18441    && ! TARGET_FAST_PREFIX
18442    && optimize_insn_for_speed_p ()
18443    /* Ensure that the operand will remain sign-extended immediate.  */
18444    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
18445   [(set (match_dup 0)
18446         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18447                          (const_int 0)]))]
18448 {
18449   operands[3]
18450     = gen_int_mode (INTVAL (operands[3])
18451                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
18452   operands[2] = gen_lowpart (SImode, operands[2]);
18453 })
18454
18455 (define_split
18456   [(set (match_operand 0 "register_operand" "")
18457         (neg (match_operand 1 "register_operand" "")))
18458    (clobber (reg:CC FLAGS_REG))]
18459   "! TARGET_PARTIAL_REG_STALL && reload_completed
18460    && (GET_MODE (operands[0]) == HImode
18461        || (GET_MODE (operands[0]) == QImode
18462            && (TARGET_PROMOTE_QImode
18463                || optimize_insn_for_size_p ())))"
18464   [(parallel [(set (match_dup 0)
18465                    (neg:SI (match_dup 1)))
18466               (clobber (reg:CC FLAGS_REG))])]
18467   "operands[0] = gen_lowpart (SImode, operands[0]);
18468    operands[1] = gen_lowpart (SImode, operands[1]);")
18469
18470 (define_split
18471   [(set (match_operand 0 "register_operand" "")
18472         (not (match_operand 1 "register_operand" "")))]
18473   "! TARGET_PARTIAL_REG_STALL && reload_completed
18474    && (GET_MODE (operands[0]) == HImode
18475        || (GET_MODE (operands[0]) == QImode
18476            && (TARGET_PROMOTE_QImode
18477                || optimize_insn_for_size_p ())))"
18478   [(set (match_dup 0)
18479         (not:SI (match_dup 1)))]
18480   "operands[0] = gen_lowpart (SImode, operands[0]);
18481    operands[1] = gen_lowpart (SImode, operands[1]);")
18482
18483 (define_split
18484   [(set (match_operand 0 "register_operand" "")
18485         (if_then_else (match_operator 1 "comparison_operator"
18486                                 [(reg FLAGS_REG) (const_int 0)])
18487                       (match_operand 2 "register_operand" "")
18488                       (match_operand 3 "register_operand" "")))]
18489   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
18490    && (GET_MODE (operands[0]) == HImode
18491        || (GET_MODE (operands[0]) == QImode
18492            && (TARGET_PROMOTE_QImode
18493                || optimize_insn_for_size_p ())))"
18494   [(set (match_dup 0)
18495         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
18496   "operands[0] = gen_lowpart (SImode, operands[0]);
18497    operands[2] = gen_lowpart (SImode, operands[2]);
18498    operands[3] = gen_lowpart (SImode, operands[3]);")
18499
18500 \f
18501 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
18502 ;; transform a complex memory operation into two memory to register operations.
18503
18504 ;; Don't push memory operands
18505 (define_peephole2
18506   [(set (match_operand:SI 0 "push_operand" "")
18507         (match_operand:SI 1 "memory_operand" ""))
18508    (match_scratch:SI 2 "r")]
18509   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
18510    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18511   [(set (match_dup 2) (match_dup 1))
18512    (set (match_dup 0) (match_dup 2))]
18513   "")
18514
18515 (define_peephole2
18516   [(set (match_operand:DI 0 "push_operand" "")
18517         (match_operand:DI 1 "memory_operand" ""))
18518    (match_scratch:DI 2 "r")]
18519   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
18520    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18521   [(set (match_dup 2) (match_dup 1))
18522    (set (match_dup 0) (match_dup 2))]
18523   "")
18524
18525 ;; We need to handle SFmode only, because DFmode and XFmode is split to
18526 ;; SImode pushes.
18527 (define_peephole2
18528   [(set (match_operand:SF 0 "push_operand" "")
18529         (match_operand:SF 1 "memory_operand" ""))
18530    (match_scratch:SF 2 "r")]
18531   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
18532    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18533   [(set (match_dup 2) (match_dup 1))
18534    (set (match_dup 0) (match_dup 2))]
18535   "")
18536
18537 (define_peephole2
18538   [(set (match_operand:HI 0 "push_operand" "")
18539         (match_operand:HI 1 "memory_operand" ""))
18540    (match_scratch:HI 2 "r")]
18541   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
18542    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18543   [(set (match_dup 2) (match_dup 1))
18544    (set (match_dup 0) (match_dup 2))]
18545   "")
18546
18547 (define_peephole2
18548   [(set (match_operand:QI 0 "push_operand" "")
18549         (match_operand:QI 1 "memory_operand" ""))
18550    (match_scratch:QI 2 "q")]
18551   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
18552    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18553   [(set (match_dup 2) (match_dup 1))
18554    (set (match_dup 0) (match_dup 2))]
18555   "")
18556
18557 ;; Don't move an immediate directly to memory when the instruction
18558 ;; gets too big.
18559 (define_peephole2
18560   [(match_scratch:SI 1 "r")
18561    (set (match_operand:SI 0 "memory_operand" "")
18562         (const_int 0))]
18563   "optimize_insn_for_speed_p ()
18564    && ! TARGET_USE_MOV0
18565    && TARGET_SPLIT_LONG_MOVES
18566    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
18567    && peep2_regno_dead_p (0, FLAGS_REG)"
18568   [(parallel [(set (match_dup 1) (const_int 0))
18569               (clobber (reg:CC FLAGS_REG))])
18570    (set (match_dup 0) (match_dup 1))]
18571   "")
18572
18573 (define_peephole2
18574   [(match_scratch:HI 1 "r")
18575    (set (match_operand:HI 0 "memory_operand" "")
18576         (const_int 0))]
18577   "optimize_insn_for_speed_p ()
18578    && ! TARGET_USE_MOV0
18579    && TARGET_SPLIT_LONG_MOVES
18580    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
18581    && peep2_regno_dead_p (0, FLAGS_REG)"
18582   [(parallel [(set (match_dup 2) (const_int 0))
18583               (clobber (reg:CC FLAGS_REG))])
18584    (set (match_dup 0) (match_dup 1))]
18585   "operands[2] = gen_lowpart (SImode, operands[1]);")
18586
18587 (define_peephole2
18588   [(match_scratch:QI 1 "q")
18589    (set (match_operand:QI 0 "memory_operand" "")
18590         (const_int 0))]
18591   "optimize_insn_for_speed_p ()
18592    && ! TARGET_USE_MOV0
18593    && TARGET_SPLIT_LONG_MOVES
18594    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
18595    && peep2_regno_dead_p (0, FLAGS_REG)"
18596   [(parallel [(set (match_dup 2) (const_int 0))
18597               (clobber (reg:CC FLAGS_REG))])
18598    (set (match_dup 0) (match_dup 1))]
18599   "operands[2] = gen_lowpart (SImode, operands[1]);")
18600
18601 (define_peephole2
18602   [(match_scratch:SI 2 "r")
18603    (set (match_operand:SI 0 "memory_operand" "")
18604         (match_operand:SI 1 "immediate_operand" ""))]
18605   "optimize_insn_for_speed_p ()
18606    && TARGET_SPLIT_LONG_MOVES
18607    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
18608   [(set (match_dup 2) (match_dup 1))
18609    (set (match_dup 0) (match_dup 2))]
18610   "")
18611
18612 (define_peephole2
18613   [(match_scratch:HI 2 "r")
18614    (set (match_operand:HI 0 "memory_operand" "")
18615         (match_operand:HI 1 "immediate_operand" ""))]
18616   "optimize_insn_for_speed_p ()
18617    && TARGET_SPLIT_LONG_MOVES
18618    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
18619   [(set (match_dup 2) (match_dup 1))
18620    (set (match_dup 0) (match_dup 2))]
18621   "")
18622
18623 (define_peephole2
18624   [(match_scratch:QI 2 "q")
18625    (set (match_operand:QI 0 "memory_operand" "")
18626         (match_operand:QI 1 "immediate_operand" ""))]
18627   "optimize_insn_for_speed_p ()
18628    && TARGET_SPLIT_LONG_MOVES
18629    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
18630   [(set (match_dup 2) (match_dup 1))
18631    (set (match_dup 0) (match_dup 2))]
18632   "")
18633
18634 ;; Don't compare memory with zero, load and use a test instead.
18635 (define_peephole2
18636   [(set (match_operand 0 "flags_reg_operand" "")
18637         (match_operator 1 "compare_operator"
18638           [(match_operand:SI 2 "memory_operand" "")
18639            (const_int 0)]))
18640    (match_scratch:SI 3 "r")]
18641   "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
18642   [(set (match_dup 3) (match_dup 2))
18643    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
18644   "")
18645
18646 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
18647 ;; Don't split NOTs with a displacement operand, because resulting XOR
18648 ;; will not be pairable anyway.
18649 ;;
18650 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
18651 ;; represented using a modRM byte.  The XOR replacement is long decoded,
18652 ;; so this split helps here as well.
18653 ;;
18654 ;; Note: Can't do this as a regular split because we can't get proper
18655 ;; lifetime information then.
18656
18657 (define_peephole2
18658   [(set (match_operand:SI 0 "nonimmediate_operand" "")
18659         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
18660   "optimize_insn_for_speed_p ()
18661    && ((TARGET_NOT_UNPAIRABLE
18662         && (!MEM_P (operands[0])
18663             || !memory_displacement_operand (operands[0], SImode)))
18664        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
18665    && peep2_regno_dead_p (0, FLAGS_REG)"
18666   [(parallel [(set (match_dup 0)
18667                    (xor:SI (match_dup 1) (const_int -1)))
18668               (clobber (reg:CC FLAGS_REG))])]
18669   "")
18670
18671 (define_peephole2
18672   [(set (match_operand:HI 0 "nonimmediate_operand" "")
18673         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
18674   "optimize_insn_for_speed_p ()
18675    && ((TARGET_NOT_UNPAIRABLE
18676         && (!MEM_P (operands[0])
18677             || !memory_displacement_operand (operands[0], HImode)))
18678        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
18679    && peep2_regno_dead_p (0, FLAGS_REG)"
18680   [(parallel [(set (match_dup 0)
18681                    (xor:HI (match_dup 1) (const_int -1)))
18682               (clobber (reg:CC FLAGS_REG))])]
18683   "")
18684
18685 (define_peephole2
18686   [(set (match_operand:QI 0 "nonimmediate_operand" "")
18687         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
18688   "optimize_insn_for_speed_p ()
18689    && ((TARGET_NOT_UNPAIRABLE
18690         && (!MEM_P (operands[0])
18691             || !memory_displacement_operand (operands[0], QImode)))
18692        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
18693    && peep2_regno_dead_p (0, FLAGS_REG)"
18694   [(parallel [(set (match_dup 0)
18695                    (xor:QI (match_dup 1) (const_int -1)))
18696               (clobber (reg:CC FLAGS_REG))])]
18697   "")
18698
18699 ;; Non pairable "test imm, reg" instructions can be translated to
18700 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
18701 ;; byte opcode instead of two, have a short form for byte operands),
18702 ;; so do it for other CPUs as well.  Given that the value was dead,
18703 ;; this should not create any new dependencies.  Pass on the sub-word
18704 ;; versions if we're concerned about partial register stalls.
18705
18706 (define_peephole2
18707   [(set (match_operand 0 "flags_reg_operand" "")
18708         (match_operator 1 "compare_operator"
18709           [(and:SI (match_operand:SI 2 "register_operand" "")
18710                    (match_operand:SI 3 "immediate_operand" ""))
18711            (const_int 0)]))]
18712   "ix86_match_ccmode (insn, CCNOmode)
18713    && (true_regnum (operands[2]) != AX_REG
18714        || satisfies_constraint_K (operands[3]))
18715    && peep2_reg_dead_p (1, operands[2])"
18716   [(parallel
18717      [(set (match_dup 0)
18718            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18719                             (const_int 0)]))
18720       (set (match_dup 2)
18721            (and:SI (match_dup 2) (match_dup 3)))])]
18722   "")
18723
18724 ;; We don't need to handle HImode case, because it will be promoted to SImode
18725 ;; on ! TARGET_PARTIAL_REG_STALL
18726
18727 (define_peephole2
18728   [(set (match_operand 0 "flags_reg_operand" "")
18729         (match_operator 1 "compare_operator"
18730           [(and:QI (match_operand:QI 2 "register_operand" "")
18731                    (match_operand:QI 3 "immediate_operand" ""))
18732            (const_int 0)]))]
18733   "! TARGET_PARTIAL_REG_STALL
18734    && ix86_match_ccmode (insn, CCNOmode)
18735    && true_regnum (operands[2]) != AX_REG
18736    && peep2_reg_dead_p (1, operands[2])"
18737   [(parallel
18738      [(set (match_dup 0)
18739            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
18740                             (const_int 0)]))
18741       (set (match_dup 2)
18742            (and:QI (match_dup 2) (match_dup 3)))])]
18743   "")
18744
18745 (define_peephole2
18746   [(set (match_operand 0 "flags_reg_operand" "")
18747         (match_operator 1 "compare_operator"
18748           [(and:SI
18749              (zero_extract:SI
18750                (match_operand 2 "ext_register_operand" "")
18751                (const_int 8)
18752                (const_int 8))
18753              (match_operand 3 "const_int_operand" ""))
18754            (const_int 0)]))]
18755   "! TARGET_PARTIAL_REG_STALL
18756    && ix86_match_ccmode (insn, CCNOmode)
18757    && true_regnum (operands[2]) != AX_REG
18758    && peep2_reg_dead_p (1, operands[2])"
18759   [(parallel [(set (match_dup 0)
18760                    (match_op_dup 1
18761                      [(and:SI
18762                         (zero_extract:SI
18763                           (match_dup 2)
18764                           (const_int 8)
18765                           (const_int 8))
18766                         (match_dup 3))
18767                       (const_int 0)]))
18768               (set (zero_extract:SI (match_dup 2)
18769                                     (const_int 8)
18770                                     (const_int 8))
18771                    (and:SI
18772                      (zero_extract:SI
18773                        (match_dup 2)
18774                        (const_int 8)
18775                        (const_int 8))
18776                      (match_dup 3)))])]
18777   "")
18778
18779 ;; Don't do logical operations with memory inputs.
18780 (define_peephole2
18781   [(match_scratch:SI 2 "r")
18782    (parallel [(set (match_operand:SI 0 "register_operand" "")
18783                    (match_operator:SI 3 "arith_or_logical_operator"
18784                      [(match_dup 0)
18785                       (match_operand:SI 1 "memory_operand" "")]))
18786               (clobber (reg:CC FLAGS_REG))])]
18787   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
18788   [(set (match_dup 2) (match_dup 1))
18789    (parallel [(set (match_dup 0)
18790                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
18791               (clobber (reg:CC FLAGS_REG))])]
18792   "")
18793
18794 (define_peephole2
18795   [(match_scratch:SI 2 "r")
18796    (parallel [(set (match_operand:SI 0 "register_operand" "")
18797                    (match_operator:SI 3 "arith_or_logical_operator"
18798                      [(match_operand:SI 1 "memory_operand" "")
18799                       (match_dup 0)]))
18800               (clobber (reg:CC FLAGS_REG))])]
18801   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
18802   [(set (match_dup 2) (match_dup 1))
18803    (parallel [(set (match_dup 0)
18804                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
18805               (clobber (reg:CC FLAGS_REG))])]
18806   "")
18807
18808 ;; Prefer Load+RegOp to Mov+MemOp.  Watch out for cases when the memory address
18809 ;; refers to the destination of the load!
18810
18811 (define_peephole2
18812   [(set (match_operand:SI 0 "register_operand" "")
18813         (match_operand:SI 1 "register_operand" ""))
18814    (parallel [(set (match_dup 0)
18815                    (match_operator:SI 3 "commutative_operator"
18816                      [(match_dup 0)
18817                       (match_operand:SI 2 "memory_operand" "")]))
18818               (clobber (reg:CC FLAGS_REG))])]
18819   "REGNO (operands[0]) != REGNO (operands[1])
18820    && GENERAL_REGNO_P (REGNO (operands[0]))
18821    && GENERAL_REGNO_P (REGNO (operands[1]))"
18822   [(set (match_dup 0) (match_dup 4))
18823    (parallel [(set (match_dup 0)
18824                    (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
18825               (clobber (reg:CC FLAGS_REG))])]
18826   "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
18827
18828 (define_peephole2
18829   [(set (match_operand 0 "register_operand" "")
18830         (match_operand 1 "register_operand" ""))
18831    (set (match_dup 0)
18832                    (match_operator 3 "commutative_operator"
18833                      [(match_dup 0)
18834                       (match_operand 2 "memory_operand" "")]))]
18835   "REGNO (operands[0]) != REGNO (operands[1])
18836    && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1])) 
18837        || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
18838   [(set (match_dup 0) (match_dup 2))
18839    (set (match_dup 0)
18840         (match_op_dup 3 [(match_dup 0) (match_dup 1)]))]
18841   "")
18842
18843 ; Don't do logical operations with memory outputs
18844 ;
18845 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
18846 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
18847 ; the same decoder scheduling characteristics as the original.
18848
18849 (define_peephole2
18850   [(match_scratch:SI 2 "r")
18851    (parallel [(set (match_operand:SI 0 "memory_operand" "")
18852                    (match_operator:SI 3 "arith_or_logical_operator"
18853                      [(match_dup 0)
18854                       (match_operand:SI 1 "nonmemory_operand" "")]))
18855               (clobber (reg:CC FLAGS_REG))])]
18856   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
18857    /* Do not split stack checking probes.  */
18858    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
18859   [(set (match_dup 2) (match_dup 0))
18860    (parallel [(set (match_dup 2)
18861                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
18862               (clobber (reg:CC FLAGS_REG))])
18863    (set (match_dup 0) (match_dup 2))]
18864   "")
18865
18866 (define_peephole2
18867   [(match_scratch:SI 2 "r")
18868    (parallel [(set (match_operand:SI 0 "memory_operand" "")
18869                    (match_operator:SI 3 "arith_or_logical_operator"
18870                      [(match_operand:SI 1 "nonmemory_operand" "")
18871                       (match_dup 0)]))
18872               (clobber (reg:CC FLAGS_REG))])]
18873   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
18874    /* Do not split stack checking probes.  */
18875    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
18876   [(set (match_dup 2) (match_dup 0))
18877    (parallel [(set (match_dup 2)
18878                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18879               (clobber (reg:CC FLAGS_REG))])
18880    (set (match_dup 0) (match_dup 2))]
18881   "")
18882
18883 ;; Attempt to always use XOR for zeroing registers.
18884 (define_peephole2
18885   [(set (match_operand 0 "register_operand" "")
18886         (match_operand 1 "const0_operand" ""))]
18887   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
18888    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
18889    && GENERAL_REG_P (operands[0])
18890    && peep2_regno_dead_p (0, FLAGS_REG)"
18891   [(parallel [(set (match_dup 0) (const_int 0))
18892               (clobber (reg:CC FLAGS_REG))])]
18893 {
18894   operands[0] = gen_lowpart (word_mode, operands[0]);
18895 })
18896
18897 (define_peephole2
18898   [(set (strict_low_part (match_operand 0 "register_operand" ""))
18899         (const_int 0))]
18900   "(GET_MODE (operands[0]) == QImode
18901     || GET_MODE (operands[0]) == HImode)
18902    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
18903    && peep2_regno_dead_p (0, FLAGS_REG)"
18904   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
18905               (clobber (reg:CC FLAGS_REG))])])
18906
18907 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
18908 (define_peephole2
18909   [(set (match_operand 0 "register_operand" "")
18910         (const_int -1))]
18911   "(GET_MODE (operands[0]) == HImode
18912     || GET_MODE (operands[0]) == SImode
18913     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
18914    && (optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
18915    && peep2_regno_dead_p (0, FLAGS_REG)"
18916   [(parallel [(set (match_dup 0) (const_int -1))
18917               (clobber (reg:CC FLAGS_REG))])]
18918   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
18919                               operands[0]);")
18920
18921 ;; Attempt to convert simple leas to adds. These can be created by
18922 ;; move expanders.
18923 (define_peephole2
18924   [(set (match_operand:SI 0 "register_operand" "")
18925         (plus:SI (match_dup 0)
18926                  (match_operand:SI 1 "nonmemory_operand" "")))]
18927   "peep2_regno_dead_p (0, FLAGS_REG)"
18928   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
18929               (clobber (reg:CC FLAGS_REG))])]
18930   "")
18931
18932 (define_peephole2
18933   [(set (match_operand:SI 0 "register_operand" "")
18934         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
18935                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
18936   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
18937   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
18938               (clobber (reg:CC FLAGS_REG))])]
18939   "operands[2] = gen_lowpart (SImode, operands[2]);")
18940
18941 (define_peephole2
18942   [(set (match_operand:DI 0 "register_operand" "")
18943         (plus:DI (match_dup 0)
18944                  (match_operand:DI 1 "x86_64_general_operand" "")))]
18945   "peep2_regno_dead_p (0, FLAGS_REG)"
18946   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
18947               (clobber (reg:CC FLAGS_REG))])]
18948   "")
18949
18950 (define_peephole2
18951   [(set (match_operand:SI 0 "register_operand" "")
18952         (mult:SI (match_dup 0)
18953                  (match_operand:SI 1 "const_int_operand" "")))]
18954   "exact_log2 (INTVAL (operands[1])) >= 0
18955    && peep2_regno_dead_p (0, FLAGS_REG)"
18956   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
18957               (clobber (reg:CC FLAGS_REG))])]
18958   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
18959
18960 (define_peephole2
18961   [(set (match_operand:DI 0 "register_operand" "")
18962         (mult:DI (match_dup 0)
18963                  (match_operand:DI 1 "const_int_operand" "")))]
18964   "exact_log2 (INTVAL (operands[1])) >= 0
18965    && peep2_regno_dead_p (0, FLAGS_REG)"
18966   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
18967               (clobber (reg:CC FLAGS_REG))])]
18968   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
18969
18970 (define_peephole2
18971   [(set (match_operand:SI 0 "register_operand" "")
18972         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
18973                    (match_operand:DI 2 "const_int_operand" "")) 0))]
18974   "exact_log2 (INTVAL (operands[2])) >= 0
18975    && REGNO (operands[0]) == REGNO (operands[1])
18976    && peep2_regno_dead_p (0, FLAGS_REG)"
18977   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
18978               (clobber (reg:CC FLAGS_REG))])]
18979   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
18980
18981 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
18982 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
18983 ;; many CPUs it is also faster, since special hardware to avoid esp
18984 ;; dependencies is present.
18985
18986 ;; While some of these conversions may be done using splitters, we use peepholes
18987 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
18988
18989 ;; Convert prologue esp subtractions to push.
18990 ;; We need register to push.  In order to keep verify_flow_info happy we have
18991 ;; two choices
18992 ;; - use scratch and clobber it in order to avoid dependencies
18993 ;; - use already live register
18994 ;; We can't use the second way right now, since there is no reliable way how to
18995 ;; verify that given register is live.  First choice will also most likely in
18996 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
18997 ;; call clobbered registers are dead.  We may want to use base pointer as an
18998 ;; alternative when no register is available later.
18999
19000 (define_peephole2
19001   [(match_scratch:SI 0 "r")
19002    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19003               (clobber (reg:CC FLAGS_REG))
19004               (clobber (mem:BLK (scratch)))])]
19005   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
19006   [(clobber (match_dup 0))
19007    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19008               (clobber (mem:BLK (scratch)))])])
19009
19010 (define_peephole2
19011   [(match_scratch:SI 0 "r")
19012    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19013               (clobber (reg:CC FLAGS_REG))
19014               (clobber (mem:BLK (scratch)))])]
19015   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
19016   [(clobber (match_dup 0))
19017    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19018    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19019               (clobber (mem:BLK (scratch)))])])
19020
19021 ;; Convert esp subtractions to push.
19022 (define_peephole2
19023   [(match_scratch:SI 0 "r")
19024    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19025               (clobber (reg:CC FLAGS_REG))])]
19026   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
19027   [(clobber (match_dup 0))
19028    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19029
19030 (define_peephole2
19031   [(match_scratch:SI 0 "r")
19032    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19033               (clobber (reg:CC FLAGS_REG))])]
19034   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
19035   [(clobber (match_dup 0))
19036    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19037    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19038
19039 ;; Convert epilogue deallocator to pop.
19040 (define_peephole2
19041   [(match_scratch:SI 0 "r")
19042    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19043               (clobber (reg:CC FLAGS_REG))
19044               (clobber (mem:BLK (scratch)))])]
19045   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
19046   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19047               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19048               (clobber (mem:BLK (scratch)))])]
19049   "")
19050
19051 ;; Two pops case is tricky, since pop causes dependency on destination register.
19052 ;; We use two registers if available.
19053 (define_peephole2
19054   [(match_scratch:SI 0 "r")
19055    (match_scratch:SI 1 "r")
19056    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19057               (clobber (reg:CC FLAGS_REG))
19058               (clobber (mem:BLK (scratch)))])]
19059   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
19060   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19061               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19062               (clobber (mem:BLK (scratch)))])
19063    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19064               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19065   "")
19066
19067 (define_peephole2
19068   [(match_scratch:SI 0 "r")
19069    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19070               (clobber (reg:CC FLAGS_REG))
19071               (clobber (mem:BLK (scratch)))])]
19072   "optimize_insn_for_size_p ()"
19073   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19074               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19075               (clobber (mem:BLK (scratch)))])
19076    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19077               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19078   "")
19079
19080 ;; Convert esp additions to pop.
19081 (define_peephole2
19082   [(match_scratch:SI 0 "r")
19083    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19084               (clobber (reg:CC FLAGS_REG))])]
19085   ""
19086   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19087               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19088   "")
19089
19090 ;; Two pops case is tricky, since pop causes dependency on destination register.
19091 ;; We use two registers if available.
19092 (define_peephole2
19093   [(match_scratch:SI 0 "r")
19094    (match_scratch:SI 1 "r")
19095    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19096               (clobber (reg:CC FLAGS_REG))])]
19097   ""
19098   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19099               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19100    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19101               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19102   "")
19103
19104 (define_peephole2
19105   [(match_scratch:SI 0 "r")
19106    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19107               (clobber (reg:CC FLAGS_REG))])]
19108   "optimize_insn_for_size_p ()"
19109   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19110               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19111    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19112               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19113   "")
19114 \f
19115 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
19116 ;; required and register dies.  Similarly for 128 to -128.
19117 (define_peephole2
19118   [(set (match_operand 0 "flags_reg_operand" "")
19119         (match_operator 1 "compare_operator"
19120           [(match_operand 2 "register_operand" "")
19121            (match_operand 3 "const_int_operand" "")]))]
19122   "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
19123      && incdec_operand (operands[3], GET_MODE (operands[3])))
19124     || (!TARGET_FUSE_CMP_AND_BRANCH
19125         && INTVAL (operands[3]) == 128))
19126    && ix86_match_ccmode (insn, CCGCmode)
19127    && peep2_reg_dead_p (1, operands[2])"
19128   [(parallel [(set (match_dup 0)
19129                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
19130               (clobber (match_dup 2))])]
19131   "")
19132 \f
19133 (define_peephole2
19134   [(match_scratch:DI 0 "r")
19135    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19136               (clobber (reg:CC FLAGS_REG))
19137               (clobber (mem:BLK (scratch)))])]
19138   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
19139   [(clobber (match_dup 0))
19140    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19141               (clobber (mem:BLK (scratch)))])])
19142
19143 (define_peephole2
19144   [(match_scratch:DI 0 "r")
19145    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19146               (clobber (reg:CC FLAGS_REG))
19147               (clobber (mem:BLK (scratch)))])]
19148   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
19149   [(clobber (match_dup 0))
19150    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19151    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19152               (clobber (mem:BLK (scratch)))])])
19153
19154 ;; Convert esp subtractions to push.
19155 (define_peephole2
19156   [(match_scratch:DI 0 "r")
19157    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19158               (clobber (reg:CC FLAGS_REG))])]
19159   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
19160   [(clobber (match_dup 0))
19161    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19162
19163 (define_peephole2
19164   [(match_scratch:DI 0 "r")
19165    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19166               (clobber (reg:CC FLAGS_REG))])]
19167   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
19168   [(clobber (match_dup 0))
19169    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19170    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19171
19172 ;; Convert epilogue deallocator to pop.
19173 (define_peephole2
19174   [(match_scratch:DI 0 "r")
19175    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19176               (clobber (reg:CC FLAGS_REG))
19177               (clobber (mem:BLK (scratch)))])]
19178   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
19179   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19180               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19181               (clobber (mem:BLK (scratch)))])]
19182   "")
19183
19184 ;; Two pops case is tricky, since pop causes dependency on destination register.
19185 ;; We use two registers if available.
19186 (define_peephole2
19187   [(match_scratch:DI 0 "r")
19188    (match_scratch:DI 1 "r")
19189    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19190               (clobber (reg:CC FLAGS_REG))
19191               (clobber (mem:BLK (scratch)))])]
19192   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
19193   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19194               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19195               (clobber (mem:BLK (scratch)))])
19196    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19197               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19198   "")
19199
19200 (define_peephole2
19201   [(match_scratch:DI 0 "r")
19202    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19203               (clobber (reg:CC FLAGS_REG))
19204               (clobber (mem:BLK (scratch)))])]
19205   "optimize_insn_for_size_p ()"
19206   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19207               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19208               (clobber (mem:BLK (scratch)))])
19209    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19210               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19211   "")
19212
19213 ;; Convert esp additions to pop.
19214 (define_peephole2
19215   [(match_scratch:DI 0 "r")
19216    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19217               (clobber (reg:CC FLAGS_REG))])]
19218   ""
19219   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19220               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19221   "")
19222
19223 ;; Two pops case is tricky, since pop causes dependency on destination register.
19224 ;; We use two registers if available.
19225 (define_peephole2
19226   [(match_scratch:DI 0 "r")
19227    (match_scratch:DI 1 "r")
19228    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19229               (clobber (reg:CC FLAGS_REG))])]
19230   ""
19231   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19232               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19233    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19234               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19235   "")
19236
19237 (define_peephole2
19238   [(match_scratch:DI 0 "r")
19239    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19240               (clobber (reg:CC FLAGS_REG))])]
19241   "optimize_insn_for_size_p ()"
19242   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19243               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19244    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19245               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19246   "")
19247 \f
19248 ;; Convert imul by three, five and nine into lea
19249 (define_peephole2
19250   [(parallel
19251     [(set (match_operand:SI 0 "register_operand" "")
19252           (mult:SI (match_operand:SI 1 "register_operand" "")
19253                    (match_operand:SI 2 "const_int_operand" "")))
19254      (clobber (reg:CC FLAGS_REG))])]
19255   "INTVAL (operands[2]) == 3
19256    || INTVAL (operands[2]) == 5
19257    || INTVAL (operands[2]) == 9"
19258   [(set (match_dup 0)
19259         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
19260                  (match_dup 1)))]
19261   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19262
19263 (define_peephole2
19264   [(parallel
19265     [(set (match_operand:SI 0 "register_operand" "")
19266           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19267                    (match_operand:SI 2 "const_int_operand" "")))
19268      (clobber (reg:CC FLAGS_REG))])]
19269   "optimize_insn_for_speed_p ()
19270    && (INTVAL (operands[2]) == 3
19271        || INTVAL (operands[2]) == 5
19272        || INTVAL (operands[2]) == 9)"
19273   [(set (match_dup 0) (match_dup 1))
19274    (set (match_dup 0)
19275         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
19276                  (match_dup 0)))]
19277   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19278
19279 (define_peephole2
19280   [(parallel
19281     [(set (match_operand:DI 0 "register_operand" "")
19282           (mult:DI (match_operand:DI 1 "register_operand" "")
19283                    (match_operand:DI 2 "const_int_operand" "")))
19284      (clobber (reg:CC FLAGS_REG))])]
19285   "TARGET_64BIT
19286    && (INTVAL (operands[2]) == 3
19287        || INTVAL (operands[2]) == 5
19288        || INTVAL (operands[2]) == 9)"
19289   [(set (match_dup 0)
19290         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
19291                  (match_dup 1)))]
19292   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19293
19294 (define_peephole2
19295   [(parallel
19296     [(set (match_operand:DI 0 "register_operand" "")
19297           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19298                    (match_operand:DI 2 "const_int_operand" "")))
19299      (clobber (reg:CC FLAGS_REG))])]
19300   "TARGET_64BIT
19301    && optimize_insn_for_speed_p ()
19302    && (INTVAL (operands[2]) == 3
19303        || INTVAL (operands[2]) == 5
19304        || INTVAL (operands[2]) == 9)"
19305   [(set (match_dup 0) (match_dup 1))
19306    (set (match_dup 0)
19307         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
19308                  (match_dup 0)))]
19309   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19310
19311 ;; Imul $32bit_imm, mem, reg is vector decoded, while
19312 ;; imul $32bit_imm, reg, reg is direct decoded.
19313 (define_peephole2
19314   [(match_scratch:DI 3 "r")
19315    (parallel [(set (match_operand:DI 0 "register_operand" "")
19316                    (mult:DI (match_operand:DI 1 "memory_operand" "")
19317                             (match_operand:DI 2 "immediate_operand" "")))
19318               (clobber (reg:CC FLAGS_REG))])]
19319   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
19320    && !satisfies_constraint_K (operands[2])"
19321   [(set (match_dup 3) (match_dup 1))
19322    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
19323               (clobber (reg:CC FLAGS_REG))])]
19324 "")
19325
19326 (define_peephole2
19327   [(match_scratch:SI 3 "r")
19328    (parallel [(set (match_operand:SI 0 "register_operand" "")
19329                    (mult:SI (match_operand:SI 1 "memory_operand" "")
19330                             (match_operand:SI 2 "immediate_operand" "")))
19331               (clobber (reg:CC FLAGS_REG))])]
19332   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
19333    && !satisfies_constraint_K (operands[2])"
19334   [(set (match_dup 3) (match_dup 1))
19335    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
19336               (clobber (reg:CC FLAGS_REG))])]
19337 "")
19338
19339 (define_peephole2
19340   [(match_scratch:SI 3 "r")
19341    (parallel [(set (match_operand:DI 0 "register_operand" "")
19342                    (zero_extend:DI
19343                      (mult:SI (match_operand:SI 1 "memory_operand" "")
19344                               (match_operand:SI 2 "immediate_operand" ""))))
19345               (clobber (reg:CC FLAGS_REG))])]
19346   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
19347    && !satisfies_constraint_K (operands[2])"
19348   [(set (match_dup 3) (match_dup 1))
19349    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19350               (clobber (reg:CC FLAGS_REG))])]
19351 "")
19352
19353 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19354 ;; Convert it into imul reg, reg
19355 ;; It would be better to force assembler to encode instruction using long
19356 ;; immediate, but there is apparently no way to do so.
19357 (define_peephole2
19358   [(parallel [(set (match_operand:DI 0 "register_operand" "")
19359                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19360                             (match_operand:DI 2 "const_int_operand" "")))
19361               (clobber (reg:CC FLAGS_REG))])
19362    (match_scratch:DI 3 "r")]
19363   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
19364    && satisfies_constraint_K (operands[2])"
19365   [(set (match_dup 3) (match_dup 2))
19366    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
19367               (clobber (reg:CC FLAGS_REG))])]
19368 {
19369   if (!rtx_equal_p (operands[0], operands[1]))
19370     emit_move_insn (operands[0], operands[1]);
19371 })
19372
19373 (define_peephole2
19374   [(parallel [(set (match_operand:SI 0 "register_operand" "")
19375                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19376                             (match_operand:SI 2 "const_int_operand" "")))
19377               (clobber (reg:CC FLAGS_REG))])
19378    (match_scratch:SI 3 "r")]
19379   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
19380    && satisfies_constraint_K (operands[2])"
19381   [(set (match_dup 3) (match_dup 2))
19382    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
19383               (clobber (reg:CC FLAGS_REG))])]
19384 {
19385   if (!rtx_equal_p (operands[0], operands[1]))
19386     emit_move_insn (operands[0], operands[1]);
19387 })
19388
19389 (define_peephole2
19390   [(parallel [(set (match_operand:HI 0 "register_operand" "")
19391                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
19392                             (match_operand:HI 2 "immediate_operand" "")))
19393               (clobber (reg:CC FLAGS_REG))])
19394    (match_scratch:HI 3 "r")]
19395   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()"
19396   [(set (match_dup 3) (match_dup 2))
19397    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
19398               (clobber (reg:CC FLAGS_REG))])]
19399 {
19400   if (!rtx_equal_p (operands[0], operands[1]))
19401     emit_move_insn (operands[0], operands[1]);
19402 })
19403
19404 ;; After splitting up read-modify operations, array accesses with memory
19405 ;; operands might end up in form:
19406 ;;  sall    $2, %eax
19407 ;;  movl    4(%esp), %edx
19408 ;;  addl    %edx, %eax
19409 ;; instead of pre-splitting:
19410 ;;  sall    $2, %eax
19411 ;;  addl    4(%esp), %eax
19412 ;; Turn it into:
19413 ;;  movl    4(%esp), %edx
19414 ;;  leal    (%edx,%eax,4), %eax
19415
19416 (define_peephole2
19417   [(parallel [(set (match_operand 0 "register_operand" "")
19418                    (ashift (match_operand 1 "register_operand" "")
19419                            (match_operand 2 "const_int_operand" "")))
19420                (clobber (reg:CC FLAGS_REG))])
19421    (set (match_operand 3 "register_operand")
19422         (match_operand 4 "x86_64_general_operand" ""))
19423    (parallel [(set (match_operand 5 "register_operand" "")
19424                    (plus (match_operand 6 "register_operand" "")
19425                          (match_operand 7 "register_operand" "")))
19426                    (clobber (reg:CC FLAGS_REG))])]
19427   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
19428    /* Validate MODE for lea.  */
19429    && ((!TARGET_PARTIAL_REG_STALL
19430         && (GET_MODE (operands[0]) == QImode
19431             || GET_MODE (operands[0]) == HImode))
19432        || GET_MODE (operands[0]) == SImode
19433        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
19434    /* We reorder load and the shift.  */
19435    && !rtx_equal_p (operands[1], operands[3])
19436    && !reg_overlap_mentioned_p (operands[0], operands[4])
19437    /* Last PLUS must consist of operand 0 and 3.  */
19438    && !rtx_equal_p (operands[0], operands[3])
19439    && (rtx_equal_p (operands[3], operands[6])
19440        || rtx_equal_p (operands[3], operands[7]))
19441    && (rtx_equal_p (operands[0], operands[6])
19442        || rtx_equal_p (operands[0], operands[7]))
19443    /* The intermediate operand 0 must die or be same as output.  */
19444    && (rtx_equal_p (operands[0], operands[5])
19445        || peep2_reg_dead_p (3, operands[0]))"
19446   [(set (match_dup 3) (match_dup 4))
19447    (set (match_dup 0) (match_dup 1))]
19448 {
19449   enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
19450   int scale = 1 << INTVAL (operands[2]);
19451   rtx index = gen_lowpart (Pmode, operands[1]);
19452   rtx base = gen_lowpart (Pmode, operands[3]);
19453   rtx dest = gen_lowpart (mode, operands[5]);
19454
19455   operands[1] = gen_rtx_PLUS (Pmode, base,
19456                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
19457   if (mode != Pmode)
19458     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
19459   operands[0] = dest;
19460 })
19461 \f
19462 ;; Call-value patterns last so that the wildcard operand does not
19463 ;; disrupt insn-recog's switch tables.
19464
19465 (define_insn "*call_value_pop_0"
19466   [(set (match_operand 0 "" "")
19467         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19468               (match_operand:SI 2 "" "")))
19469    (set (reg:SI SP_REG)
19470         (plus:SI (reg:SI SP_REG)
19471                  (match_operand:SI 3 "immediate_operand" "")))]
19472   "!TARGET_64BIT"
19473 {
19474   if (SIBLING_CALL_P (insn))
19475     return "jmp\t%P1";
19476   else
19477     return "call\t%P1";
19478 }
19479   [(set_attr "type" "callv")])
19480
19481 (define_insn "*call_value_pop_1"
19482   [(set (match_operand 0 "" "")
19483         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
19484               (match_operand:SI 2 "" "")))
19485    (set (reg:SI SP_REG)
19486         (plus:SI (reg:SI SP_REG)
19487                  (match_operand:SI 3 "immediate_operand" "i")))]
19488   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
19489 {
19490   if (constant_call_address_operand (operands[1], Pmode))
19491     return "call\t%P1";
19492   return "call\t%A1";
19493 }
19494   [(set_attr "type" "callv")])
19495
19496 (define_insn "*sibcall_value_pop_1"
19497   [(set (match_operand 0 "" "")
19498         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
19499               (match_operand:SI 2 "" "")))
19500    (set (reg:SI SP_REG)
19501         (plus:SI (reg:SI SP_REG)
19502                  (match_operand:SI 3 "immediate_operand" "i,i")))]
19503   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
19504   "@
19505    jmp\t%P1
19506    jmp\t%A1"
19507   [(set_attr "type" "callv")])
19508
19509 (define_insn "*call_value_0"
19510   [(set (match_operand 0 "" "")
19511         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19512               (match_operand:SI 2 "" "")))]
19513   "!TARGET_64BIT"
19514 {
19515   if (SIBLING_CALL_P (insn))
19516     return "jmp\t%P1";
19517   else
19518     return "call\t%P1";
19519 }
19520   [(set_attr "type" "callv")])
19521
19522 (define_insn "*call_value_0_rex64"
19523   [(set (match_operand 0 "" "")
19524         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19525               (match_operand:DI 2 "const_int_operand" "")))]
19526   "TARGET_64BIT"
19527 {
19528   if (SIBLING_CALL_P (insn))
19529     return "jmp\t%P1";
19530   else
19531     return "call\t%P1";
19532 }
19533   [(set_attr "type" "callv")])
19534
19535 (define_insn "*call_value_0_rex64_ms_sysv"
19536   [(set (match_operand 0 "" "")
19537         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19538               (match_operand:DI 2 "const_int_operand" "")))
19539    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
19540    (clobber (reg:TI XMM6_REG))
19541    (clobber (reg:TI XMM7_REG))
19542    (clobber (reg:TI XMM8_REG))
19543    (clobber (reg:TI XMM9_REG))
19544    (clobber (reg:TI XMM10_REG))
19545    (clobber (reg:TI XMM11_REG))
19546    (clobber (reg:TI XMM12_REG))
19547    (clobber (reg:TI XMM13_REG))
19548    (clobber (reg:TI XMM14_REG))
19549    (clobber (reg:TI XMM15_REG))
19550    (clobber (reg:DI SI_REG))
19551    (clobber (reg:DI DI_REG))]
19552   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
19553 {
19554   if (SIBLING_CALL_P (insn))
19555     return "jmp\t%P1";
19556   else
19557     return "call\t%P1";
19558 }
19559   [(set_attr "type" "callv")])
19560
19561 (define_insn "*call_value_1"
19562   [(set (match_operand 0 "" "")
19563         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
19564               (match_operand:SI 2 "" "")))]
19565   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
19566 {
19567   if (constant_call_address_operand (operands[1], Pmode))
19568     return "call\t%P1";
19569   return "call\t%A1";
19570 }
19571   [(set_attr "type" "callv")])
19572
19573 (define_insn "*sibcall_value_1"
19574   [(set (match_operand 0 "" "")
19575         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
19576               (match_operand:SI 2 "" "")))]
19577   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
19578   "@
19579    jmp\t%P1
19580    jmp\t%A1"
19581   [(set_attr "type" "callv")])
19582
19583 (define_insn "*call_value_1_rex64"
19584   [(set (match_operand 0 "" "")
19585         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
19586               (match_operand:DI 2 "" "")))]
19587   "TARGET_64BIT && !SIBLING_CALL_P (insn)
19588    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
19589 {
19590   if (constant_call_address_operand (operands[1], Pmode))
19591     return "call\t%P1";
19592   return "call\t%A1";
19593 }
19594   [(set_attr "type" "callv")])
19595
19596 (define_insn "*call_value_1_rex64_ms_sysv"
19597   [(set (match_operand 0 "" "")
19598         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
19599               (match_operand:DI 2 "" "")))
19600    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
19601    (clobber (reg:TI XMM6_REG))
19602    (clobber (reg:TI XMM7_REG))
19603    (clobber (reg:TI XMM8_REG))
19604    (clobber (reg:TI XMM9_REG))
19605    (clobber (reg:TI XMM10_REG))
19606    (clobber (reg:TI XMM11_REG))
19607    (clobber (reg:TI XMM12_REG))
19608    (clobber (reg:TI XMM13_REG))
19609    (clobber (reg:TI XMM14_REG))
19610    (clobber (reg:TI XMM15_REG))
19611    (clobber (reg:DI SI_REG))
19612    (clobber (reg:DI DI_REG))]
19613   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
19614 {
19615   if (constant_call_address_operand (operands[1], Pmode))
19616     return "call\t%P1";
19617   return "call\t%A1";
19618 }
19619   [(set_attr "type" "callv")])
19620
19621 (define_insn "*call_value_1_rex64_large"
19622   [(set (match_operand 0 "" "")
19623         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
19624               (match_operand:DI 2 "" "")))]
19625   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
19626   "call\t%A1"
19627   [(set_attr "type" "callv")])
19628
19629 (define_insn "*sibcall_value_1_rex64"
19630   [(set (match_operand 0 "" "")
19631         (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
19632               (match_operand:DI 2 "" "")))]
19633   "TARGET_64BIT && SIBLING_CALL_P (insn)"
19634   "@
19635    jmp\t%P1
19636    jmp\t%A1"
19637   [(set_attr "type" "callv")])
19638 \f
19639 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
19640 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
19641 ;; caught for use by garbage collectors and the like.  Using an insn that
19642 ;; maps to SIGILL makes it more likely the program will rightfully die.
19643 ;; Keeping with tradition, "6" is in honor of #UD.
19644 (define_insn "trap"
19645   [(trap_if (const_int 1) (const_int 6))]
19646   ""
19647   { return ASM_SHORT "0x0b0f"; }
19648   [(set_attr "length" "2")])
19649
19650 (define_expand "sse_prologue_save"
19651   [(parallel [(set (match_operand:BLK 0 "" "")
19652                    (unspec:BLK [(reg:DI XMM0_REG)
19653                                 (reg:DI XMM1_REG)
19654                                 (reg:DI XMM2_REG)
19655                                 (reg:DI XMM3_REG)
19656                                 (reg:DI XMM4_REG)
19657                                 (reg:DI XMM5_REG)
19658                                 (reg:DI XMM6_REG)
19659                                 (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE))
19660               (use (match_operand:DI 1 "register_operand" ""))
19661               (use (match_operand:DI 2 "immediate_operand" ""))
19662               (use (label_ref:DI (match_operand 3 "" "")))])]
19663   "TARGET_64BIT"
19664   "")
19665
19666 (define_insn "*sse_prologue_save_insn"
19667   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
19668                           (match_operand:DI 4 "const_int_operand" "n")))
19669         (unspec:BLK [(reg:DI XMM0_REG)
19670                      (reg:DI XMM1_REG)
19671                      (reg:DI XMM2_REG)
19672                      (reg:DI XMM3_REG)
19673                      (reg:DI XMM4_REG)
19674                      (reg:DI XMM5_REG)
19675                      (reg:DI XMM6_REG)
19676                      (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE))
19677    (use (match_operand:DI 1 "register_operand" "r"))
19678    (use (match_operand:DI 2 "const_int_operand" "i"))
19679    (use (label_ref:DI (match_operand 3 "" "X")))]
19680   "TARGET_64BIT
19681    && INTVAL (operands[4]) + X86_64_SSE_REGPARM_MAX * 16 - 16 < 128
19682    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
19683 {
19684   int i;
19685   operands[0] = gen_rtx_MEM (Pmode,
19686                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
19687   /* VEX instruction with a REX prefix will #UD.  */
19688   if (TARGET_AVX && GET_CODE (XEXP (operands[0], 0)) != PLUS)
19689     gcc_unreachable ();
19690
19691   output_asm_insn ("jmp\t%A1", operands);
19692   for (i = X86_64_SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
19693     {
19694       operands[4] = adjust_address (operands[0], DImode, i*16);
19695       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
19696       PUT_MODE (operands[4], TImode);
19697       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
19698         output_asm_insn ("rex", operands);
19699       output_asm_insn ("%vmovaps\t{%5, %4|%4, %5}", operands);
19700     }
19701   (*targetm.asm_out.internal_label) (asm_out_file, "L",
19702                                      CODE_LABEL_NUMBER (operands[3]));
19703   return "";
19704 }
19705   [(set_attr "type" "other")
19706    (set_attr "length_immediate" "0")
19707    (set_attr "length_address" "0")
19708    (set (attr "length")
19709      (if_then_else
19710        (eq (symbol_ref "TARGET_AVX") (const_int 0))
19711        (const_string "34")
19712        (const_string "42")))
19713    (set_attr "memory" "store")
19714    (set_attr "modrm" "0")
19715    (set_attr "prefix" "maybe_vex")
19716    (set_attr "mode" "DI")])
19717
19718 (define_expand "prefetch"
19719   [(prefetch (match_operand 0 "address_operand" "")
19720              (match_operand:SI 1 "const_int_operand" "")
19721              (match_operand:SI 2 "const_int_operand" ""))]
19722   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
19723 {
19724   int rw = INTVAL (operands[1]);
19725   int locality = INTVAL (operands[2]);
19726
19727   gcc_assert (rw == 0 || rw == 1);
19728   gcc_assert (locality >= 0 && locality <= 3);
19729   gcc_assert (GET_MODE (operands[0]) == Pmode
19730               || GET_MODE (operands[0]) == VOIDmode);
19731
19732   /* Use 3dNOW prefetch in case we are asking for write prefetch not
19733      supported by SSE counterpart or the SSE prefetch is not available
19734      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
19735      of locality.  */
19736   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
19737     operands[2] = GEN_INT (3);
19738   else
19739     operands[1] = const0_rtx;
19740 })
19741
19742 (define_insn "*prefetch_sse"
19743   [(prefetch (match_operand:SI 0 "address_operand" "p")
19744              (const_int 0)
19745              (match_operand:SI 1 "const_int_operand" ""))]
19746   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
19747 {
19748   static const char * const patterns[4] = {
19749    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
19750   };
19751
19752   int locality = INTVAL (operands[1]);
19753   gcc_assert (locality >= 0 && locality <= 3);
19754
19755   return patterns[locality];
19756 }
19757   [(set_attr "type" "sse")
19758    (set_attr "atom_sse_attr" "prefetch")
19759    (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
19760    (set_attr "memory" "none")])
19761
19762 (define_insn "*prefetch_sse_rex"
19763   [(prefetch (match_operand:DI 0 "address_operand" "p")
19764              (const_int 0)
19765              (match_operand:SI 1 "const_int_operand" ""))]
19766   "TARGET_PREFETCH_SSE && TARGET_64BIT"
19767 {
19768   static const char * const patterns[4] = {
19769    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
19770   };
19771
19772   int locality = INTVAL (operands[1]);
19773   gcc_assert (locality >= 0 && locality <= 3);
19774
19775   return patterns[locality];
19776 }
19777   [(set_attr "type" "sse")
19778    (set_attr "atom_sse_attr" "prefetch")
19779    (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
19780    (set_attr "memory" "none")])
19781
19782 (define_insn "*prefetch_3dnow"
19783   [(prefetch (match_operand:SI 0 "address_operand" "p")
19784              (match_operand:SI 1 "const_int_operand" "n")
19785              (const_int 3))]
19786   "TARGET_3DNOW && !TARGET_64BIT"
19787 {
19788   if (INTVAL (operands[1]) == 0)
19789     return "prefetch\t%a0";
19790   else
19791     return "prefetchw\t%a0";
19792 }
19793   [(set_attr "type" "mmx")
19794    (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
19795    (set_attr "memory" "none")])
19796
19797 (define_insn "*prefetch_3dnow_rex"
19798   [(prefetch (match_operand:DI 0 "address_operand" "p")
19799              (match_operand:SI 1 "const_int_operand" "n")
19800              (const_int 3))]
19801   "TARGET_3DNOW && TARGET_64BIT"
19802 {
19803   if (INTVAL (operands[1]) == 0)
19804     return "prefetch\t%a0";
19805   else
19806     return "prefetchw\t%a0";
19807 }
19808   [(set_attr "type" "mmx")
19809    (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
19810    (set_attr "memory" "none")])
19811
19812 (define_expand "stack_protect_set"
19813   [(match_operand 0 "memory_operand" "")
19814    (match_operand 1 "memory_operand" "")]
19815   ""
19816 {
19817 #ifdef TARGET_THREAD_SSP_OFFSET
19818   if (TARGET_64BIT)
19819     emit_insn (gen_stack_tls_protect_set_di (operands[0],
19820                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
19821   else
19822     emit_insn (gen_stack_tls_protect_set_si (operands[0],
19823                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
19824 #else
19825   if (TARGET_64BIT)
19826     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
19827   else
19828     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
19829 #endif
19830   DONE;
19831 })
19832
19833 (define_insn "stack_protect_set_si"
19834   [(set (match_operand:SI 0 "memory_operand" "=m")
19835         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
19836    (set (match_scratch:SI 2 "=&r") (const_int 0))
19837    (clobber (reg:CC FLAGS_REG))]
19838   ""
19839   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
19840   [(set_attr "type" "multi")])
19841
19842 (define_insn "stack_protect_set_di"
19843   [(set (match_operand:DI 0 "memory_operand" "=m")
19844         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
19845    (set (match_scratch:DI 2 "=&r") (const_int 0))
19846    (clobber (reg:CC FLAGS_REG))]
19847   "TARGET_64BIT"
19848   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
19849   [(set_attr "type" "multi")])
19850
19851 (define_insn "stack_tls_protect_set_si"
19852   [(set (match_operand:SI 0 "memory_operand" "=m")
19853         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
19854    (set (match_scratch:SI 2 "=&r") (const_int 0))
19855    (clobber (reg:CC FLAGS_REG))]
19856   ""
19857   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
19858   [(set_attr "type" "multi")])
19859
19860 (define_insn "stack_tls_protect_set_di"
19861   [(set (match_operand:DI 0 "memory_operand" "=m")
19862         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
19863    (set (match_scratch:DI 2 "=&r") (const_int 0))
19864    (clobber (reg:CC FLAGS_REG))]
19865   "TARGET_64BIT"
19866   {
19867      /* The kernel uses a different segment register for performance reasons; a
19868         system call would not have to trash the userspace segment register,
19869         which would be expensive */
19870      if (ix86_cmodel != CM_KERNEL)
19871         return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
19872      else
19873         return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
19874   }
19875   [(set_attr "type" "multi")])
19876
19877 (define_expand "stack_protect_test"
19878   [(match_operand 0 "memory_operand" "")
19879    (match_operand 1 "memory_operand" "")
19880    (match_operand 2 "" "")]
19881   ""
19882 {
19883   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
19884
19885 #ifdef TARGET_THREAD_SSP_OFFSET
19886   if (TARGET_64BIT)
19887     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
19888                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
19889   else
19890     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
19891                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
19892 #else
19893   if (TARGET_64BIT)
19894     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
19895   else
19896     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
19897 #endif
19898
19899   emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
19900                                   flags, const0_rtx, operands[2]));
19901   DONE;
19902 })
19903
19904 (define_insn "stack_protect_test_si"
19905   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
19906         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
19907                      (match_operand:SI 2 "memory_operand" "m")]
19908                     UNSPEC_SP_TEST))
19909    (clobber (match_scratch:SI 3 "=&r"))]
19910   ""
19911   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
19912   [(set_attr "type" "multi")])
19913
19914 (define_insn "stack_protect_test_di"
19915   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
19916         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
19917                      (match_operand:DI 2 "memory_operand" "m")]
19918                     UNSPEC_SP_TEST))
19919    (clobber (match_scratch:DI 3 "=&r"))]
19920   "TARGET_64BIT"
19921   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
19922   [(set_attr "type" "multi")])
19923
19924 (define_insn "stack_tls_protect_test_si"
19925   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
19926         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
19927                      (match_operand:SI 2 "const_int_operand" "i")]
19928                     UNSPEC_SP_TLS_TEST))
19929    (clobber (match_scratch:SI 3 "=r"))]
19930   ""
19931   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
19932   [(set_attr "type" "multi")])
19933
19934 (define_insn "stack_tls_protect_test_di"
19935   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
19936         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
19937                      (match_operand:DI 2 "const_int_operand" "i")]
19938                     UNSPEC_SP_TLS_TEST))
19939    (clobber (match_scratch:DI 3 "=r"))]
19940   "TARGET_64BIT"
19941   {
19942      /* The kernel uses a different segment register for performance reasons; a
19943         system call would not have to trash the userspace segment register,
19944         which would be expensive */
19945      if (ix86_cmodel != CM_KERNEL)
19946         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
19947      else
19948         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
19949   }
19950   [(set_attr "type" "multi")])
19951
19952 (define_insn "sse4_2_crc32<mode>"
19953   [(set (match_operand:SI 0 "register_operand" "=r")
19954         (unspec:SI
19955           [(match_operand:SI 1 "register_operand" "0")
19956            (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
19957           UNSPEC_CRC32))]
19958   "TARGET_SSE4_2 || TARGET_CRC32"
19959   "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
19960   [(set_attr "type" "sselog1")
19961    (set_attr "prefix_rep" "1")
19962    (set_attr "prefix_extra" "1")
19963    (set (attr "prefix_data16")
19964      (if_then_else (match_operand:HI 2 "" "")
19965        (const_string "1")
19966        (const_string "*")))
19967    (set (attr "prefix_rex")
19968      (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
19969        (const_string "1")
19970        (const_string "*")))
19971    (set_attr "mode" "SI")])
19972
19973 (define_insn "sse4_2_crc32di"
19974   [(set (match_operand:DI 0 "register_operand" "=r")
19975         (unspec:DI
19976           [(match_operand:DI 1 "register_operand" "0")
19977            (match_operand:DI 2 "nonimmediate_operand" "rm")]
19978           UNSPEC_CRC32))]
19979   "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
19980   "crc32{q}\t{%2, %0|%0, %2}"
19981   [(set_attr "type" "sselog1")
19982    (set_attr "prefix_rep" "1")
19983    (set_attr "prefix_extra" "1")
19984    (set_attr "mode" "DI")])
19985
19986 (define_expand "rdpmc"
19987   [(match_operand:DI 0 "register_operand" "")
19988    (match_operand:SI 1 "register_operand" "")]
19989   ""
19990 {
19991   rtx reg = gen_reg_rtx (DImode);
19992   rtx si;
19993
19994   /* Force operand 1 into ECX.  */
19995   rtx ecx = gen_rtx_REG (SImode, CX_REG);
19996   emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
19997   si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
19998                                 UNSPECV_RDPMC);
19999
20000   if (TARGET_64BIT)
20001     {
20002       rtvec vec = rtvec_alloc (2);
20003       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
20004       rtx upper = gen_reg_rtx (DImode);
20005       rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
20006                                         gen_rtvec (1, const0_rtx),
20007                                         UNSPECV_RDPMC);
20008       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
20009       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
20010       emit_insn (load);
20011       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
20012                                    NULL, 1, OPTAB_DIRECT);
20013       reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
20014                                  OPTAB_DIRECT);
20015     }
20016   else
20017     emit_insn (gen_rtx_SET (VOIDmode, reg, si));
20018   emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
20019   DONE;
20020 })
20021
20022 (define_insn "*rdpmc"
20023   [(set (match_operand:DI 0 "register_operand" "=A")
20024         (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
20025                             UNSPECV_RDPMC))]
20026   "!TARGET_64BIT"
20027   "rdpmc"
20028   [(set_attr "type" "other")
20029    (set_attr "length" "2")])
20030
20031 (define_insn "*rdpmc_rex64"
20032   [(set (match_operand:DI 0 "register_operand" "=a")
20033         (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
20034                             UNSPECV_RDPMC))
20035   (set (match_operand:DI 1 "register_operand" "=d")
20036        (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
20037   "TARGET_64BIT"
20038   "rdpmc"
20039   [(set_attr "type" "other")
20040    (set_attr "length" "2")])
20041
20042 (define_expand "rdtsc"
20043   [(set (match_operand:DI 0 "register_operand" "")
20044         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
20045   ""
20046 {
20047   if (TARGET_64BIT)
20048     {
20049       rtvec vec = rtvec_alloc (2);
20050       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
20051       rtx upper = gen_reg_rtx (DImode);
20052       rtx lower = gen_reg_rtx (DImode);
20053       rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
20054                                          gen_rtvec (1, const0_rtx),
20055                                          UNSPECV_RDTSC);
20056       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
20057       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
20058       emit_insn (load);
20059       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
20060                                    NULL, 1, OPTAB_DIRECT);
20061       lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
20062                                    OPTAB_DIRECT);
20063       emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
20064       DONE;
20065     }
20066 })
20067
20068 (define_insn "*rdtsc"
20069   [(set (match_operand:DI 0 "register_operand" "=A")
20070         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
20071   "!TARGET_64BIT"
20072   "rdtsc"
20073   [(set_attr "type" "other")
20074    (set_attr "length" "2")])
20075
20076 (define_insn "*rdtsc_rex64"
20077   [(set (match_operand:DI 0 "register_operand" "=a")
20078         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
20079    (set (match_operand:DI 1 "register_operand" "=d")
20080         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
20081   "TARGET_64BIT"
20082   "rdtsc"
20083   [(set_attr "type" "other")
20084    (set_attr "length" "2")])
20085
20086 (define_expand "rdtscp"
20087   [(match_operand:DI 0 "register_operand" "")
20088    (match_operand:SI 1 "memory_operand" "")]
20089   ""
20090 {
20091   rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
20092                                     gen_rtvec (1, const0_rtx),
20093                                     UNSPECV_RDTSCP);
20094   rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
20095                                     gen_rtvec (1, const0_rtx),
20096                                     UNSPECV_RDTSCP);
20097   rtx reg = gen_reg_rtx (DImode);
20098   rtx tmp = gen_reg_rtx (SImode);
20099
20100   if (TARGET_64BIT)
20101     {
20102       rtvec vec = rtvec_alloc (3);
20103       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
20104       rtx upper = gen_reg_rtx (DImode);
20105       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
20106       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
20107       RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
20108       emit_insn (load);
20109       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
20110                                    NULL, 1, OPTAB_DIRECT);
20111       reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
20112                                  OPTAB_DIRECT);
20113     }
20114   else
20115     {
20116       rtvec vec = rtvec_alloc (2);
20117       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
20118       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
20119       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
20120       emit_insn (load);
20121     }
20122   emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
20123   emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
20124   DONE;
20125 })
20126
20127 (define_insn "*rdtscp"
20128   [(set (match_operand:DI 0 "register_operand" "=A")
20129         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
20130    (set (match_operand:SI 1 "register_operand" "=c")
20131         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
20132   "!TARGET_64BIT"
20133   "rdtscp"
20134   [(set_attr "type" "other")
20135    (set_attr "length" "3")])
20136
20137 (define_insn "*rdtscp_rex64"
20138   [(set (match_operand:DI 0 "register_operand" "=a")
20139         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
20140    (set (match_operand:DI 1 "register_operand" "=d")
20141         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
20142    (set (match_operand:SI 2 "register_operand" "=c")
20143         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
20144   "TARGET_64BIT"
20145   "rdtscp"
20146   [(set_attr "type" "other")
20147    (set_attr "length" "3")])
20148
20149 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
20150 ;;
20151 ;; LWP instructions
20152 ;;
20153 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
20154
20155 (define_expand "lwp_llwpcb"
20156   [(unspec_volatile [(match_operand 0 "register_operand" "r")]
20157                     UNSPECV_LLWP_INTRINSIC)]
20158   "TARGET_LWP"
20159   "")
20160
20161 (define_insn "*lwp_llwpcb<mode>1"
20162   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
20163                     UNSPECV_LLWP_INTRINSIC)]
20164   "TARGET_LWP"
20165   "llwpcb\t%0"
20166   [(set_attr "type" "lwp")
20167    (set_attr "mode" "<MODE>")
20168    (set_attr "length" "5")])
20169
20170 (define_expand "lwp_slwpcb"
20171   [(set (match_operand 0 "register_operand" "=r")
20172         (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
20173   "TARGET_LWP"
20174   {
20175     if (TARGET_64BIT)
20176       emit_insn (gen_lwp_slwpcbdi (operands[0]));
20177     else
20178       emit_insn (gen_lwp_slwpcbsi (operands[0]));
20179     DONE;
20180   })
20181
20182 (define_insn "lwp_slwpcb<mode>"
20183   [(set (match_operand:P 0 "register_operand" "=r")
20184         (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
20185   "TARGET_LWP"
20186   "slwpcb\t%0"
20187   [(set_attr "type" "lwp")
20188    (set_attr "mode" "<MODE>")
20189    (set_attr "length" "5")])
20190
20191 (define_expand "lwp_lwpval<mode>3"
20192   [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
20193                      (match_operand:SI 2 "nonimmediate_operand" "rm")
20194                      (match_operand:SI 3 "const_int_operand" "i")]
20195                     UNSPECV_LWPVAL_INTRINSIC)]
20196   "TARGET_LWP"
20197   "/* Avoid unused variable warning.  */
20198    (void) operand0;")
20199
20200 (define_insn "*lwp_lwpval<mode>3_1"
20201   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
20202                      (match_operand:SI 1 "nonimmediate_operand" "rm")
20203                      (match_operand:SI 2 "const_int_operand" "i")]
20204                     UNSPECV_LWPVAL_INTRINSIC)]
20205   "TARGET_LWP"
20206   "lwpval\t{%2, %1, %0|%0, %1, %2}"
20207   [(set_attr "type" "lwp")
20208    (set_attr "mode" "<MODE>")
20209    (set (attr "length")
20210         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
20211
20212 (define_expand "lwp_lwpins<mode>3"
20213   [(set (reg:CCC FLAGS_REG)
20214         (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
20215                               (match_operand:SI 2 "nonimmediate_operand" "rm")
20216                               (match_operand:SI 3 "const_int_operand" "i")]
20217                              UNSPECV_LWPINS_INTRINSIC))
20218    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
20219         (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
20220   "TARGET_LWP"
20221   "")
20222
20223 (define_insn "*lwp_lwpins<mode>3_1"
20224   [(set (reg:CCC FLAGS_REG)
20225         (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
20226                               (match_operand:SI 1 "nonimmediate_operand" "rm")
20227                               (match_operand:SI 2 "const_int_operand" "i")]
20228                              UNSPECV_LWPINS_INTRINSIC))]
20229   "TARGET_LWP"
20230   "lwpins\t{%2, %1, %0|%0, %1, %2}"
20231   [(set_attr "type" "lwp")
20232    (set_attr "mode" "<MODE>")
20233    (set (attr "length")
20234         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
20235
20236 (include "mmx.md")
20237 (include "sse.md")
20238 (include "sync.md")