OSDN Git Service

b8799960921cc86cff931a72962c0ae54d658161
[pf3gnuchains/gcc-fork.git] / gcc / config / i386 / i386.md
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
7 ;;
8 ;; This file is part of GCC.
9 ;;
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 3, or (at your option)
13 ;; any later version.
14 ;;
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 ;; GNU General Public License for more details.
19 ;;
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING3.  If not see
22 ;; <http://www.gnu.org/licenses/>.  */
23 ;;
24 ;; The original PO technology requires these to be ordered by speed,
25 ;; so that assigner will pick the fastest.
26 ;;
27 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
28 ;;
29 ;; The special asm out single letter directives following a '%' are:
30 ;; L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
31 ;; C -- print opcode suffix for set/cmov insn.
32 ;; c -- like C, but print reversed condition
33 ;; F,f -- likewise, but for floating-point.
34 ;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
35 ;;      otherwise nothing
36 ;; R -- print the prefix for register names.
37 ;; z -- print the opcode suffix for the size of the current operand.
38 ;; Z -- likewise, with special suffixes for x87 instructions.
39 ;; * -- print a star (in certain assembler syntax)
40 ;; A -- print an absolute memory reference.
41 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
42 ;; s -- print a shift double count, followed by the assemblers argument
43 ;;      delimiter.
44 ;; b -- print the QImode name of the register for the indicated operand.
45 ;;      %b0 would print %al if operands[0] is reg 0.
46 ;; w --  likewise, print the HImode name of the register.
47 ;; k --  likewise, print the SImode name of the register.
48 ;; q --  likewise, print the DImode name of the register.
49 ;; x --  likewise, print the V4SFmode name of the register.
50 ;; t --  likewise, print the V8SFmode name of the register.
51 ;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
52 ;; y -- print "st(0)" instead of "st" as a register.
53 ;; d -- print duplicated register operand for AVX instruction.
54 ;; D -- print condition for SSE cmp instruction.
55 ;; P -- if PIC, print an @PLT suffix.
56 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
57 ;; & -- print some in-use local-dynamic symbol name.
58 ;; H -- print a memory address offset by 8; used for sse high-parts
59 ;; Y -- print condition for XOP pcom* instruction.
60 ;; + -- print a branch hint as 'cs' or 'ds' prefix
61 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
62
63 ;; UNSPEC usage:
64
65 (define_constants
66   [; Relocation specifiers
67    (UNSPEC_GOT                  0)
68    (UNSPEC_GOTOFF               1)
69    (UNSPEC_GOTPCREL             2)
70    (UNSPEC_GOTTPOFF             3)
71    (UNSPEC_TPOFF                4)
72    (UNSPEC_NTPOFF               5)
73    (UNSPEC_DTPOFF               6)
74    (UNSPEC_GOTNTPOFF            7)
75    (UNSPEC_INDNTPOFF            8)
76    (UNSPEC_PLTOFF               9)
77    (UNSPEC_MACHOPIC_OFFSET      10)
78
79    ; Prologue support
80    (UNSPEC_STACK_ALLOC          11)
81    (UNSPEC_SET_GOT              12)
82    (UNSPEC_SSE_PROLOGUE_SAVE    13)
83    (UNSPEC_REG_SAVE             14)
84    (UNSPEC_DEF_CFA              15)
85    (UNSPEC_SET_RIP              16)
86    (UNSPEC_SET_GOT_OFFSET       17)
87    (UNSPEC_MEMORY_BLOCKAGE      18)
88
89    ; TLS support
90    (UNSPEC_TP                   20)
91    (UNSPEC_TLS_GD               21)
92    (UNSPEC_TLS_LD_BASE          22)
93    (UNSPEC_TLSDESC              23)
94
95    ; Other random patterns
96    (UNSPEC_SCAS                 30)
97    (UNSPEC_FNSTSW               31)
98    (UNSPEC_SAHF                 32)
99    (UNSPEC_FSTCW                33)
100    (UNSPEC_ADD_CARRY            34)
101    (UNSPEC_FLDCW                35)
102    (UNSPEC_REP                  36)
103    (UNSPEC_LD_MPIC              38)     ; load_macho_picbase
104    (UNSPEC_TRUNC_NOOP           39)
105
106    ; For SSE/MMX support:
107    (UNSPEC_FIX_NOTRUNC          40)
108    (UNSPEC_MASKMOV              41)
109    (UNSPEC_MOVMSK               42)
110    (UNSPEC_MOVNT                43)
111    (UNSPEC_MOVU                 44)
112    (UNSPEC_RCP                  45)
113    (UNSPEC_RSQRT                46)
114    (UNSPEC_SFENCE               47)
115    (UNSPEC_PFRCP                49)
116    (UNSPEC_PFRCPIT1             40)
117    (UNSPEC_PFRCPIT2             41)
118    (UNSPEC_PFRSQRT              42)
119    (UNSPEC_PFRSQIT1             43)
120    (UNSPEC_MFENCE               44)
121    (UNSPEC_LFENCE               45)
122    (UNSPEC_PSADBW               46)
123    (UNSPEC_LDDQU                47)
124    (UNSPEC_MS_TO_SYSV_CALL      48)
125
126    ; Generic math support
127    (UNSPEC_COPYSIGN             50)
128    (UNSPEC_IEEE_MIN             51)     ; not commutative
129    (UNSPEC_IEEE_MAX             52)     ; not commutative
130
131    ; x87 Floating point
132    (UNSPEC_SIN                  60)
133    (UNSPEC_COS                  61)
134    (UNSPEC_FPATAN               62)
135    (UNSPEC_FYL2X                63)
136    (UNSPEC_FYL2XP1              64)
137    (UNSPEC_FRNDINT              65)
138    (UNSPEC_FIST                 66)
139    (UNSPEC_F2XM1                67)
140    (UNSPEC_TAN                  68)
141    (UNSPEC_FXAM                 69)
142
143    ; x87 Rounding
144    (UNSPEC_FRNDINT_FLOOR        70)
145    (UNSPEC_FRNDINT_CEIL         71)
146    (UNSPEC_FRNDINT_TRUNC        72)
147    (UNSPEC_FRNDINT_MASK_PM      73)
148    (UNSPEC_FIST_FLOOR           74)
149    (UNSPEC_FIST_CEIL            75)
150
151    ; x87 Double output FP
152    (UNSPEC_SINCOS_COS           80)
153    (UNSPEC_SINCOS_SIN           81)
154    (UNSPEC_XTRACT_FRACT         84)
155    (UNSPEC_XTRACT_EXP           85)
156    (UNSPEC_FSCALE_FRACT         86)
157    (UNSPEC_FSCALE_EXP           87)
158    (UNSPEC_FPREM_F              88)
159    (UNSPEC_FPREM_U              89)
160    (UNSPEC_FPREM1_F             90)
161    (UNSPEC_FPREM1_U             91)
162
163    (UNSPEC_C2_FLAG              95)
164    (UNSPEC_FXAM_MEM             96)
165
166    ; SSP patterns
167    (UNSPEC_SP_SET               100)
168    (UNSPEC_SP_TEST              101)
169    (UNSPEC_SP_TLS_SET           102)
170    (UNSPEC_SP_TLS_TEST          103)
171
172    ; SSSE3
173    (UNSPEC_PSHUFB               120)
174    (UNSPEC_PSIGN                121)
175    (UNSPEC_PALIGNR              122)
176
177    ; For SSE4A support
178    (UNSPEC_EXTRQI               130)
179    (UNSPEC_EXTRQ                131)
180    (UNSPEC_INSERTQI             132)
181    (UNSPEC_INSERTQ              133)
182
183    ; For SSE4.1 support
184    (UNSPEC_BLENDV               134)
185    (UNSPEC_INSERTPS             135)
186    (UNSPEC_DP                   136)
187    (UNSPEC_MOVNTDQA             137)
188    (UNSPEC_MPSADBW              138)
189    (UNSPEC_PHMINPOSUW           139)
190    (UNSPEC_PTEST                140)
191    (UNSPEC_ROUND                141)
192
193    ; For SSE4.2 support
194    (UNSPEC_CRC32                143)
195    (UNSPEC_PCMPESTR             144)
196    (UNSPEC_PCMPISTR             145)
197
198    ; For FMA4 support
199    (UNSPEC_FMA4_INTRINSIC       150)
200    (UNSPEC_FMA4_FMADDSUB        151)
201    (UNSPEC_FMA4_FMSUBADD        152)
202    (UNSPEC_XOP_UNSIGNED_CMP     151)
203    (UNSPEC_XOP_TRUEFALSE        152)
204    (UNSPEC_XOP_PERMUTE          153)
205    (UNSPEC_FRCZ                 154)
206
207    ; For AES support
208    (UNSPEC_AESENC               159)
209    (UNSPEC_AESENCLAST           160)
210    (UNSPEC_AESDEC               161)
211    (UNSPEC_AESDECLAST           162)
212    (UNSPEC_AESIMC               163)
213    (UNSPEC_AESKEYGENASSIST      164)
214
215    ; For PCLMUL support
216    (UNSPEC_PCLMUL               165)
217
218    ; For AVX support
219    (UNSPEC_PCMP                 166)
220    (UNSPEC_VPERMIL              167)
221    (UNSPEC_VPERMIL2             168)
222    (UNSPEC_VPERMIL2F128         169)
223    (UNSPEC_MASKLOAD             170)
224    (UNSPEC_MASKSTORE            171)
225    (UNSPEC_CAST                 172)
226    (UNSPEC_VTESTP               173)
227   ])
228
229 (define_constants
230   [(UNSPECV_BLOCKAGE            0)
231    (UNSPECV_STACK_PROBE         1)
232    (UNSPECV_EMMS                2)
233    (UNSPECV_LDMXCSR             3)
234    (UNSPECV_STMXCSR             4)
235    (UNSPECV_FEMMS               5)
236    (UNSPECV_CLFLUSH             6)
237    (UNSPECV_ALIGN               7)
238    (UNSPECV_MONITOR             8)
239    (UNSPECV_MWAIT               9)
240    (UNSPECV_CMPXCHG             10)
241    (UNSPECV_XCHG                12)
242    (UNSPECV_LOCK                13)
243    (UNSPECV_PROLOGUE_USE        14)
244    (UNSPECV_CLD                 15)
245    (UNSPECV_VZEROALL            16)
246    (UNSPECV_VZEROUPPER          17)
247    (UNSPECV_RDTSC               18)
248    (UNSPECV_RDTSCP              19)
249    (UNSPECV_RDPMC               20)
250    (UNSPECV_VSWAPMOV            21)
251    (UNSPECV_LLWP_INTRINSIC      22)
252    (UNSPECV_SLWP_INTRINSIC      23)
253    (UNSPECV_LWPVAL_INTRINSIC    24)
254    (UNSPECV_LWPINS_INTRINSIC    25)
255   ])
256
257 ;; Constants to represent pcomtrue/pcomfalse variants
258 (define_constants
259   [(PCOM_FALSE                  0)
260    (PCOM_TRUE                   1)
261    (COM_FALSE_S                 2)
262    (COM_FALSE_P                 3)
263    (COM_TRUE_S                  4)
264    (COM_TRUE_P                  5)
265   ])
266
267 ;; Constants used in the XOP pperm instruction
268 (define_constants
269   [(PPERM_SRC                   0x00)   /* copy source */
270    (PPERM_INVERT                0x20)   /* invert source */
271    (PPERM_REVERSE               0x40)   /* bit reverse source */
272    (PPERM_REV_INV               0x60)   /* bit reverse & invert src */
273    (PPERM_ZERO                  0x80)   /* all 0's */
274    (PPERM_ONES                  0xa0)   /* all 1's */
275    (PPERM_SIGN                  0xc0)   /* propagate sign bit */
276    (PPERM_INV_SIGN              0xe0)   /* invert & propagate sign */
277    (PPERM_SRC1                  0x00)   /* use first source byte */
278    (PPERM_SRC2                  0x10)   /* use second source byte */
279    ])
280
281 ;; Registers by name.
282 (define_constants
283   [(AX_REG                       0)
284    (DX_REG                       1)
285    (CX_REG                       2)
286    (BX_REG                       3)
287    (SI_REG                       4)
288    (DI_REG                       5)
289    (BP_REG                       6)
290    (SP_REG                       7)
291    (ST0_REG                      8)
292    (ST1_REG                      9)
293    (ST2_REG                     10)
294    (ST3_REG                     11)
295    (ST4_REG                     12)
296    (ST5_REG                     13)
297    (ST6_REG                     14)
298    (ST7_REG                     15)
299    (FLAGS_REG                   17)
300    (FPSR_REG                    18)
301    (FPCR_REG                    19)
302    (XMM0_REG                    21)
303    (XMM1_REG                    22)
304    (XMM2_REG                    23)
305    (XMM3_REG                    24)
306    (XMM4_REG                    25)
307    (XMM5_REG                    26)
308    (XMM6_REG                    27)
309    (XMM7_REG                    28)
310    (MM0_REG                     29)
311    (MM1_REG                     30)
312    (MM2_REG                     31)
313    (MM3_REG                     32)
314    (MM4_REG                     33)
315    (MM5_REG                     34)
316    (MM6_REG                     35)
317    (MM7_REG                     36)
318    (R8_REG                      37)
319    (R9_REG                      38)
320    (R10_REG                     39)
321    (R11_REG                     40)
322    (R12_REG                     41)
323    (R13_REG                     42)
324    (XMM8_REG                    45)
325    (XMM9_REG                    46)
326    (XMM10_REG                   47)
327    (XMM11_REG                   48)
328    (XMM12_REG                   49)
329    (XMM13_REG                   50)
330    (XMM14_REG                   51)
331    (XMM15_REG                   52)
332   ])
333
334 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
335 ;; from i386.c.
336
337 ;; In C guard expressions, put expressions which may be compile-time
338 ;; constants first.  This allows for better optimization.  For
339 ;; example, write "TARGET_64BIT && reload_completed", not
340 ;; "reload_completed && TARGET_64BIT".
341
342 \f
343 ;; Processor type.
344 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,atom,
345                     generic64,amdfam10"
346   (const (symbol_ref "ix86_schedule")))
347
348 ;; A basic instruction type.  Refinements due to arguments to be
349 ;; provided in other attributes.
350 (define_attr "type"
351   "other,multi,
352    alu,alu1,negnot,imov,imovx,lea,
353    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
354    icmp,test,ibr,setcc,icmov,
355    push,pop,call,callv,leave,
356    str,bitmanip,
357    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
358    sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
359    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
360    ssemuladd,sse4arg,lwp,
361    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
362   (const_string "other"))
363
364 ;; Main data type used by the insn
365 (define_attr "mode"
366   "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
367   (const_string "unknown"))
368
369 ;; The CPU unit operations uses.
370 (define_attr "unit" "integer,i387,sse,mmx,unknown"
371   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
372            (const_string "i387")
373          (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
374                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
375                           ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
376            (const_string "sse")
377          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
378            (const_string "mmx")
379          (eq_attr "type" "other")
380            (const_string "unknown")]
381          (const_string "integer")))
382
383 ;; The (bounding maximum) length of an instruction immediate.
384 (define_attr "length_immediate" ""
385   (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
386                           bitmanip")
387            (const_int 0)
388          (eq_attr "unit" "i387,sse,mmx")
389            (const_int 0)
390          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
391                           imul,icmp,push,pop")
392            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
393          (eq_attr "type" "imov,test")
394            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
395          (eq_attr "type" "call")
396            (if_then_else (match_operand 0 "constant_call_address_operand" "")
397              (const_int 4)
398              (const_int 0))
399          (eq_attr "type" "callv")
400            (if_then_else (match_operand 1 "constant_call_address_operand" "")
401              (const_int 4)
402              (const_int 0))
403          ;; We don't know the size before shorten_branches.  Expect
404          ;; the instruction to fit for better scheduling.
405          (eq_attr "type" "ibr")
406            (const_int 1)
407          ]
408          (symbol_ref "/* Update immediate_length and other attributes! */
409                       gcc_unreachable (),1")))
410
411 ;; The (bounding maximum) length of an instruction address.
412 (define_attr "length_address" ""
413   (cond [(eq_attr "type" "str,other,multi,fxch")
414            (const_int 0)
415          (and (eq_attr "type" "call")
416               (match_operand 0 "constant_call_address_operand" ""))
417              (const_int 0)
418          (and (eq_attr "type" "callv")
419               (match_operand 1 "constant_call_address_operand" ""))
420              (const_int 0)
421          ]
422          (symbol_ref "ix86_attr_length_address_default (insn)")))
423
424 ;; Set when length prefix is used.
425 (define_attr "prefix_data16" ""
426   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
427            (const_int 0)
428          (eq_attr "mode" "HI")
429            (const_int 1)
430          (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
431            (const_int 1)
432         ]
433         (const_int 0)))
434
435 ;; Set when string REP prefix is used.
436 (define_attr "prefix_rep" ""
437   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
438            (const_int 0)
439          (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
440            (const_int 1)
441         ]
442         (const_int 0)))
443
444 ;; Set when 0f opcode prefix is used.
445 (define_attr "prefix_0f" ""
446   (if_then_else
447     (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
448          (eq_attr "unit" "sse,mmx"))
449     (const_int 1)
450     (const_int 0)))
451
452 ;; Set when REX opcode prefix is used.
453 (define_attr "prefix_rex" ""
454   (cond [(ne (symbol_ref "!TARGET_64BIT") (const_int 0))
455            (const_int 0)
456          (and (eq_attr "mode" "DI")
457               (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
458                    (eq_attr "unit" "!mmx")))
459            (const_int 1)
460          (and (eq_attr "mode" "QI")
461               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
462                   (const_int 0)))
463            (const_int 1)
464          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
465              (const_int 0))
466            (const_int 1)
467          (and (eq_attr "type" "imovx")
468               (match_operand:QI 1 "ext_QIreg_operand" ""))
469            (const_int 1)
470         ]
471         (const_int 0)))
472
473 ;; There are also additional prefixes in 3DNOW, SSSE3.
474 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
475 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
476 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
477 (define_attr "prefix_extra" ""
478   (cond [(eq_attr "type" "ssemuladd,sse4arg")
479            (const_int 2)
480          (eq_attr "type" "sseiadd1,ssecvt1")
481            (const_int 1)
482         ]
483         (const_int 0)))
484
485 ;; Prefix used: original, VEX or maybe VEX.
486 (define_attr "prefix" "orig,vex,maybe_vex"
487   (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
488     (const_string "vex")
489     (const_string "orig")))
490
491 ;; VEX W bit is used.
492 (define_attr "prefix_vex_w" "" (const_int 0))
493
494 ;; The length of VEX prefix
495 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
496 ;; 0f38/0f3a prefixes can't.  In i386.md 0f3[8a] is
497 ;; still prefix_0f 1, with prefix_extra 1.
498 (define_attr "length_vex" ""
499   (if_then_else (and (eq_attr "prefix_0f" "1")
500                      (eq_attr "prefix_extra" "0"))
501     (if_then_else (eq_attr "prefix_vex_w" "1")
502       (symbol_ref "ix86_attr_length_vex_default (insn, 1, 1)")
503       (symbol_ref "ix86_attr_length_vex_default (insn, 1, 0)"))
504     (if_then_else (eq_attr "prefix_vex_w" "1")
505       (symbol_ref "ix86_attr_length_vex_default (insn, 0, 1)")
506       (symbol_ref "ix86_attr_length_vex_default (insn, 0, 0)"))))
507
508 ;; Set when modrm byte is used.
509 (define_attr "modrm" ""
510   (cond [(eq_attr "type" "str,leave")
511            (const_int 0)
512          (eq_attr "unit" "i387")
513            (const_int 0)
514          (and (eq_attr "type" "incdec")
515               (and (eq (symbol_ref "TARGET_64BIT") (const_int 0))
516                    (ior (match_operand:SI 1 "register_operand" "")
517                         (match_operand:HI 1 "register_operand" ""))))
518            (const_int 0)
519          (and (eq_attr "type" "push")
520               (not (match_operand 1 "memory_operand" "")))
521            (const_int 0)
522          (and (eq_attr "type" "pop")
523               (not (match_operand 0 "memory_operand" "")))
524            (const_int 0)
525          (and (eq_attr "type" "imov")
526               (and (not (eq_attr "mode" "DI"))
527                    (ior (and (match_operand 0 "register_operand" "")
528                              (match_operand 1 "immediate_operand" ""))
529                         (ior (and (match_operand 0 "ax_reg_operand" "")
530                                   (match_operand 1 "memory_displacement_only_operand" ""))
531                              (and (match_operand 0 "memory_displacement_only_operand" "")
532                                   (match_operand 1 "ax_reg_operand" ""))))))
533            (const_int 0)
534          (and (eq_attr "type" "call")
535               (match_operand 0 "constant_call_address_operand" ""))
536              (const_int 0)
537          (and (eq_attr "type" "callv")
538               (match_operand 1 "constant_call_address_operand" ""))
539              (const_int 0)
540          (and (eq_attr "type" "alu,alu1,icmp,test")
541               (match_operand 0 "ax_reg_operand" ""))
542              (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
543          ]
544          (const_int 1)))
545
546 ;; The (bounding maximum) length of an instruction in bytes.
547 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
548 ;; Later we may want to split them and compute proper length as for
549 ;; other insns.
550 (define_attr "length" ""
551   (cond [(eq_attr "type" "other,multi,fistp,frndint")
552            (const_int 16)
553          (eq_attr "type" "fcmp")
554            (const_int 4)
555          (eq_attr "unit" "i387")
556            (plus (const_int 2)
557                  (plus (attr "prefix_data16")
558                        (attr "length_address")))
559          (ior (eq_attr "prefix" "vex")
560               (and (eq_attr "prefix" "maybe_vex")
561                     (ne (symbol_ref "TARGET_AVX") (const_int 0))))
562            (plus (attr "length_vex")
563                  (plus (attr "length_immediate")
564                        (plus (attr "modrm")
565                              (attr "length_address"))))]
566          (plus (plus (attr "modrm")
567                      (plus (attr "prefix_0f")
568                            (plus (attr "prefix_rex")
569                                  (plus (attr "prefix_extra")
570                                        (const_int 1)))))
571                (plus (attr "prefix_rep")
572                      (plus (attr "prefix_data16")
573                            (plus (attr "length_immediate")
574                                  (attr "length_address")))))))
575
576 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
577 ;; `store' if there is a simple memory reference therein, or `unknown'
578 ;; if the instruction is complex.
579
580 (define_attr "memory" "none,load,store,both,unknown"
581   (cond [(eq_attr "type" "other,multi,str,lwp")
582            (const_string "unknown")
583          (eq_attr "type" "lea,fcmov,fpspc")
584            (const_string "none")
585          (eq_attr "type" "fistp,leave")
586            (const_string "both")
587          (eq_attr "type" "frndint")
588            (const_string "load")
589          (eq_attr "type" "push")
590            (if_then_else (match_operand 1 "memory_operand" "")
591              (const_string "both")
592              (const_string "store"))
593          (eq_attr "type" "pop")
594            (if_then_else (match_operand 0 "memory_operand" "")
595              (const_string "both")
596              (const_string "load"))
597          (eq_attr "type" "setcc")
598            (if_then_else (match_operand 0 "memory_operand" "")
599              (const_string "store")
600              (const_string "none"))
601          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
602            (if_then_else (ior (match_operand 0 "memory_operand" "")
603                               (match_operand 1 "memory_operand" ""))
604              (const_string "load")
605              (const_string "none"))
606          (eq_attr "type" "ibr")
607            (if_then_else (match_operand 0 "memory_operand" "")
608              (const_string "load")
609              (const_string "none"))
610          (eq_attr "type" "call")
611            (if_then_else (match_operand 0 "constant_call_address_operand" "")
612              (const_string "none")
613              (const_string "load"))
614          (eq_attr "type" "callv")
615            (if_then_else (match_operand 1 "constant_call_address_operand" "")
616              (const_string "none")
617              (const_string "load"))
618          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
619               (match_operand 1 "memory_operand" ""))
620            (const_string "both")
621          (and (match_operand 0 "memory_operand" "")
622               (match_operand 1 "memory_operand" ""))
623            (const_string "both")
624          (match_operand 0 "memory_operand" "")
625            (const_string "store")
626          (match_operand 1 "memory_operand" "")
627            (const_string "load")
628          (and (eq_attr "type"
629                  "!alu1,negnot,ishift1,
630                    imov,imovx,icmp,test,bitmanip,
631                    fmov,fcmp,fsgn,
632                    sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
633                    sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
634               (match_operand 2 "memory_operand" ""))
635            (const_string "load")
636          (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
637               (match_operand 3 "memory_operand" ""))
638            (const_string "load")
639         ]
640         (const_string "none")))
641
642 ;; Indicates if an instruction has both an immediate and a displacement.
643
644 (define_attr "imm_disp" "false,true,unknown"
645   (cond [(eq_attr "type" "other,multi")
646            (const_string "unknown")
647          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
648               (and (match_operand 0 "memory_displacement_operand" "")
649                    (match_operand 1 "immediate_operand" "")))
650            (const_string "true")
651          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
652               (and (match_operand 0 "memory_displacement_operand" "")
653                    (match_operand 2 "immediate_operand" "")))
654            (const_string "true")
655         ]
656         (const_string "false")))
657
658 ;; Indicates if an FP operation has an integer source.
659
660 (define_attr "fp_int_src" "false,true"
661   (const_string "false"))
662
663 ;; Defines rounding mode of an FP operation.
664
665 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
666   (const_string "any"))
667
668 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
669 (define_attr "use_carry" "0,1" (const_string "0"))
670
671 ;; Define attribute to indicate unaligned ssemov insns
672 (define_attr "movu" "0,1" (const_string "0"))
673
674 ;; Describe a user's asm statement.
675 (define_asm_attributes
676   [(set_attr "length" "128")
677    (set_attr "type" "multi")])
678
679 ;; All integer comparison codes.
680 (define_code_iterator int_cond [ne eq ge gt le lt geu gtu leu ltu])
681
682 ;; All floating-point comparison codes.
683 (define_code_iterator fp_cond [unordered ordered
684                                uneq unge ungt unle unlt ltgt])
685
686 (define_code_iterator plusminus [plus minus])
687
688 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
689
690 ;; Base name for define_insn
691 (define_code_attr plusminus_insn
692   [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
693    (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
694
695 ;; Base name for insn mnemonic.
696 (define_code_attr plusminus_mnemonic
697   [(plus "add") (ss_plus "adds") (us_plus "addus")
698    (minus "sub") (ss_minus "subs") (us_minus "subus")])
699 (define_code_attr plusminus_carry_mnemonic
700   [(plus "adc") (minus "sbb")])
701
702 ;; Mark commutative operators as such in constraints.
703 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
704                         (minus "") (ss_minus "") (us_minus "")])
705
706 ;; Mapping of signed max and min
707 (define_code_iterator smaxmin [smax smin])
708
709 ;; Mapping of unsigned max and min
710 (define_code_iterator umaxmin [umax umin])
711
712 ;; Mapping of signed/unsigned max and min
713 (define_code_iterator maxmin [smax smin umax umin])
714
715 ;; Base name for integer and FP insn mnemonic
716 (define_code_attr maxminiprefix [(smax "maxs") (smin "mins")
717                                  (umax "maxu") (umin "minu")])
718 (define_code_attr maxminfprefix [(smax "max") (smin "min")])
719
720 ;; Mapping of logic operators
721 (define_code_iterator any_logic [and ior xor])
722 (define_code_iterator any_or [ior xor])
723
724 ;; Base name for insn mnemonic.
725 (define_code_attr logicprefix [(and "and") (ior "or") (xor "xor")])
726
727 ;; Mapping of shift-right operators
728 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
729
730 ;; Base name for define_insn
731 (define_code_attr shiftrt_insn [(lshiftrt "lshr") (ashiftrt "ashr")])
732
733 ;; Base name for insn mnemonic.
734 (define_code_attr shiftrt [(lshiftrt "shr") (ashiftrt "sar")])
735
736 ;; Mapping of rotate operators
737 (define_code_iterator any_rotate [rotate rotatert])
738
739 ;; Base name for define_insn
740 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
741
742 ;; Base name for insn mnemonic.
743 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
744
745 ;; Mapping of abs neg operators
746 (define_code_iterator absneg [abs neg])
747
748 ;; Base name for x87 insn mnemonic.
749 (define_code_attr absnegprefix [(abs "abs") (neg "chs")])
750
751 ;; Used in signed and unsigned widening multiplications.
752 (define_code_iterator any_extend [sign_extend zero_extend])
753
754 ;; Various insn prefixes for signed and unsigned operations.
755 (define_code_attr u [(sign_extend "") (zero_extend "u")
756                      (div "") (udiv "u")])
757 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
758
759 ;; Used in signed and unsigned divisions.
760 (define_code_iterator any_div [div udiv])
761
762 ;; Instruction prefix for signed and unsigned operations.
763 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")
764                              (div "i") (udiv "")])
765
766 ;; All single word integer modes.
767 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
768
769 ;; Single word integer modes without DImode.
770 (define_mode_iterator SWI124 [QI HI SI])
771
772 ;; Single word integer modes without QImode.
773 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
774
775 ;; Single word integer modes without QImode and HImode.
776 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
777
778 ;; All math-dependant single and double word integer modes.
779 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
780                              (HI "TARGET_HIMODE_MATH")
781                              SI DI (TI "TARGET_64BIT")])
782
783 ;; Math-dependant single word integer modes.
784 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
785                             (HI "TARGET_HIMODE_MATH")
786                             SI (DI "TARGET_64BIT")])
787
788 ;; Math-dependant single word integer modes without DImode.
789 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
790                                (HI "TARGET_HIMODE_MATH")
791                                SI])
792
793 ;; Math-dependant single word integer modes without QImode.
794 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
795                                SI (DI "TARGET_64BIT")])
796
797 ;; Double word integer modes.
798 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
799                            (TI "TARGET_64BIT")])
800
801 ;; Double word integer modes as mode attribute.
802 (define_mode_attr DWI [(SI "DI") (DI "TI")])
803 (define_mode_attr dwi [(SI "di") (DI "ti")])
804
805 ;; Half mode for double word integer modes.
806 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
807                             (DI "TARGET_64BIT")])
808
809 ;; Instruction suffix for integer modes.
810 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
811
812 ;; Register class for integer modes.
813 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
814
815 ;; Immediate operand constraint for integer modes.
816 (define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")])
817
818 ;; General operand constraint for word modes.
819 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "g") (DI "rme")])
820
821 ;; Immediate operand constraint for double integer modes.
822 (define_mode_attr di [(SI "iF") (DI "e")])
823
824 ;; Immediate operand constraint for shifts.
825 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
826
827 ;; General operand predicate for integer modes.
828 (define_mode_attr general_operand
829         [(QI "general_operand")
830          (HI "general_operand")
831          (SI "general_operand")
832          (DI "x86_64_general_operand")
833          (TI "x86_64_general_operand")])
834
835 ;; General sign/zero extend operand predicate for integer modes.
836 (define_mode_attr general_szext_operand
837         [(QI "general_operand")
838          (HI "general_operand")
839          (SI "general_operand")
840          (DI "x86_64_szext_general_operand")])
841
842 ;; Operand predicate for shifts.
843 (define_mode_attr shift_operand
844         [(QI "nonimmediate_operand")
845          (HI "nonimmediate_operand")
846          (SI "nonimmediate_operand")
847          (DI "shiftdi_operand")
848          (TI "register_operand")])
849
850 ;; Operand predicate for shift argument.
851 (define_mode_attr shift_immediate_operand
852         [(QI "const_1_to_31_operand")
853          (HI "const_1_to_31_operand")
854          (SI "const_1_to_31_operand")
855          (DI "const_1_to_63_operand")])
856
857 ;; Input operand predicate for arithmetic left shifts.
858 (define_mode_attr ashl_input_operand
859         [(QI "nonimmediate_operand")
860          (HI "nonimmediate_operand")
861          (SI "nonimmediate_operand")
862          (DI "ashldi_input_operand")
863          (TI "reg_or_pm1_operand")])
864
865 ;; SSE and x87 SFmode and DFmode floating point modes
866 (define_mode_iterator MODEF [SF DF])
867
868 ;; All x87 floating point modes
869 (define_mode_iterator X87MODEF [SF DF XF])
870
871 ;; All integer modes handled by x87 fisttp operator.
872 (define_mode_iterator X87MODEI [HI SI DI])
873
874 ;; All integer modes handled by integer x87 operators.
875 (define_mode_iterator X87MODEI12 [HI SI])
876
877 ;; All integer modes handled by SSE cvtts?2si* operators.
878 (define_mode_iterator SSEMODEI24 [SI DI])
879
880 ;; SSE asm suffix for floating point modes
881 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
882
883 ;; SSE vector mode corresponding to a scalar mode
884 (define_mode_attr ssevecmode
885   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
886
887 ;; Instruction suffix for REX 64bit operators.
888 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
889
890 ;; This mode iterator allows :P to be used for patterns that operate on
891 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
892 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
893 \f
894 ;; Scheduling descriptions
895
896 (include "pentium.md")
897 (include "ppro.md")
898 (include "k6.md")
899 (include "athlon.md")
900 (include "geode.md")
901 (include "atom.md")
902
903 \f
904 ;; Operand and operator predicates and constraints
905
906 (include "predicates.md")
907 (include "constraints.md")
908
909 \f
910 ;; Compare and branch/compare and store instructions.
911
912 (define_expand "cbranch<mode>4"
913   [(set (reg:CC FLAGS_REG)
914         (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
915                     (match_operand:SDWIM 2 "<general_operand>" "")))
916    (set (pc) (if_then_else
917                (match_operator 0 "comparison_operator"
918                 [(reg:CC FLAGS_REG) (const_int 0)])
919                (label_ref (match_operand 3 "" ""))
920                (pc)))]
921   ""
922 {
923   if (MEM_P (operands[1]) && MEM_P (operands[2]))
924     operands[1] = force_reg (<MODE>mode, operands[1]);
925   ix86_compare_op0 = operands[1];
926   ix86_compare_op1 = operands[2];
927   ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
928   DONE;
929 })
930
931 (define_expand "cstore<mode>4"
932   [(set (reg:CC FLAGS_REG)
933         (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
934                     (match_operand:SWIM 3 "<general_operand>" "")))
935    (set (match_operand:QI 0 "register_operand" "")
936         (match_operator 1 "comparison_operator"
937           [(reg:CC FLAGS_REG) (const_int 0)]))]
938   ""
939 {
940   if (MEM_P (operands[2]) && MEM_P (operands[3]))
941     operands[2] = force_reg (<MODE>mode, operands[2]);
942   ix86_compare_op0 = operands[2];
943   ix86_compare_op1 = operands[3];
944   ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
945   DONE;
946 })
947
948 (define_expand "cmp<mode>_1"
949   [(set (reg:CC FLAGS_REG)
950         (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
951                     (match_operand:SWI48 1 "<general_operand>" "")))]
952   ""
953   "")
954
955 (define_insn "*cmp<mode>_ccno_1"
956   [(set (reg FLAGS_REG)
957         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
958                  (match_operand:SWI 1 "const0_operand" "")))]
959   "ix86_match_ccmode (insn, CCNOmode)"
960   "@
961    test{<imodesuffix>}\t%0, %0
962    cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
963   [(set_attr "type" "test,icmp")
964    (set_attr "length_immediate" "0,1")
965    (set_attr "mode" "<MODE>")])
966
967 (define_insn "*cmp<mode>_1"
968   [(set (reg FLAGS_REG)
969         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
970                  (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
971   "ix86_match_ccmode (insn, CCmode)"
972   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
973   [(set_attr "type" "icmp")
974    (set_attr "mode" "<MODE>")])
975
976 (define_insn "*cmp<mode>_minus_1"
977   [(set (reg FLAGS_REG)
978         (compare
979           (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
980                      (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
981           (const_int 0)))]
982   "ix86_match_ccmode (insn, CCGOCmode)"
983   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
984   [(set_attr "type" "icmp")
985    (set_attr "mode" "<MODE>")])
986
987 (define_insn "*cmpqi_ext_1"
988   [(set (reg FLAGS_REG)
989         (compare
990           (match_operand:QI 0 "general_operand" "Qm")
991           (subreg:QI
992             (zero_extract:SI
993               (match_operand 1 "ext_register_operand" "Q")
994               (const_int 8)
995               (const_int 8)) 0)))]
996   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
997   "cmp{b}\t{%h1, %0|%0, %h1}"
998   [(set_attr "type" "icmp")
999    (set_attr "mode" "QI")])
1000
1001 (define_insn "*cmpqi_ext_1_rex64"
1002   [(set (reg FLAGS_REG)
1003         (compare
1004           (match_operand:QI 0 "register_operand" "Q")
1005           (subreg:QI
1006             (zero_extract:SI
1007               (match_operand 1 "ext_register_operand" "Q")
1008               (const_int 8)
1009               (const_int 8)) 0)))]
1010   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1011   "cmp{b}\t{%h1, %0|%0, %h1}"
1012   [(set_attr "type" "icmp")
1013    (set_attr "mode" "QI")])
1014
1015 (define_insn "*cmpqi_ext_2"
1016   [(set (reg FLAGS_REG)
1017         (compare
1018           (subreg:QI
1019             (zero_extract:SI
1020               (match_operand 0 "ext_register_operand" "Q")
1021               (const_int 8)
1022               (const_int 8)) 0)
1023           (match_operand:QI 1 "const0_operand" "")))]
1024   "ix86_match_ccmode (insn, CCNOmode)"
1025   "test{b}\t%h0, %h0"
1026   [(set_attr "type" "test")
1027    (set_attr "length_immediate" "0")
1028    (set_attr "mode" "QI")])
1029
1030 (define_expand "cmpqi_ext_3"
1031   [(set (reg:CC FLAGS_REG)
1032         (compare:CC
1033           (subreg:QI
1034             (zero_extract:SI
1035               (match_operand 0 "ext_register_operand" "")
1036               (const_int 8)
1037               (const_int 8)) 0)
1038           (match_operand:QI 1 "immediate_operand" "")))]
1039   ""
1040   "")
1041
1042 (define_insn "*cmpqi_ext_3_insn"
1043   [(set (reg FLAGS_REG)
1044         (compare
1045           (subreg:QI
1046             (zero_extract:SI
1047               (match_operand 0 "ext_register_operand" "Q")
1048               (const_int 8)
1049               (const_int 8)) 0)
1050           (match_operand:QI 1 "general_operand" "Qmn")))]
1051   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1052   "cmp{b}\t{%1, %h0|%h0, %1}"
1053   [(set_attr "type" "icmp")
1054    (set_attr "modrm" "1")
1055    (set_attr "mode" "QI")])
1056
1057 (define_insn "*cmpqi_ext_3_insn_rex64"
1058   [(set (reg FLAGS_REG)
1059         (compare
1060           (subreg:QI
1061             (zero_extract:SI
1062               (match_operand 0 "ext_register_operand" "Q")
1063               (const_int 8)
1064               (const_int 8)) 0)
1065           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1066   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1067   "cmp{b}\t{%1, %h0|%h0, %1}"
1068   [(set_attr "type" "icmp")
1069    (set_attr "modrm" "1")
1070    (set_attr "mode" "QI")])
1071
1072 (define_insn "*cmpqi_ext_4"
1073   [(set (reg FLAGS_REG)
1074         (compare
1075           (subreg:QI
1076             (zero_extract:SI
1077               (match_operand 0 "ext_register_operand" "Q")
1078               (const_int 8)
1079               (const_int 8)) 0)
1080           (subreg:QI
1081             (zero_extract:SI
1082               (match_operand 1 "ext_register_operand" "Q")
1083               (const_int 8)
1084               (const_int 8)) 0)))]
1085   "ix86_match_ccmode (insn, CCmode)"
1086   "cmp{b}\t{%h1, %h0|%h0, %h1}"
1087   [(set_attr "type" "icmp")
1088    (set_attr "mode" "QI")])
1089
1090 ;; These implement float point compares.
1091 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1092 ;; which would allow mix and match FP modes on the compares.  Which is what
1093 ;; the old patterns did, but with many more of them.
1094
1095 (define_expand "cbranchxf4"
1096   [(set (reg:CC FLAGS_REG)
1097         (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1098                     (match_operand:XF 2 "nonmemory_operand" "")))
1099    (set (pc) (if_then_else
1100               (match_operator 0 "ix86_fp_comparison_operator"
1101                [(reg:CC FLAGS_REG)
1102                 (const_int 0)])
1103               (label_ref (match_operand 3 "" ""))
1104               (pc)))]
1105   "TARGET_80387"
1106 {
1107   ix86_compare_op0 = operands[1];
1108   ix86_compare_op1 = operands[2];
1109   ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1110   DONE;
1111 })
1112
1113 (define_expand "cstorexf4"
1114   [(set (reg:CC FLAGS_REG)
1115         (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1116                     (match_operand:XF 3 "nonmemory_operand" "")))
1117    (set (match_operand:QI 0 "register_operand" "")
1118               (match_operator 1 "ix86_fp_comparison_operator"
1119                [(reg:CC FLAGS_REG)
1120                 (const_int 0)]))]
1121   "TARGET_80387"
1122 {
1123   ix86_compare_op0 = operands[2];
1124   ix86_compare_op1 = operands[3];
1125   ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1126   DONE;
1127 })
1128
1129 (define_expand "cbranch<mode>4"
1130   [(set (reg:CC FLAGS_REG)
1131         (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1132                     (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1133    (set (pc) (if_then_else
1134               (match_operator 0 "ix86_fp_comparison_operator"
1135                [(reg:CC FLAGS_REG)
1136                 (const_int 0)])
1137               (label_ref (match_operand 3 "" ""))
1138               (pc)))]
1139   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1140 {
1141   ix86_compare_op0 = operands[1];
1142   ix86_compare_op1 = operands[2];
1143   ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1144   DONE;
1145 })
1146
1147 (define_expand "cstore<mode>4"
1148   [(set (reg:CC FLAGS_REG)
1149         (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1150                     (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1151    (set (match_operand:QI 0 "register_operand" "")
1152               (match_operator 1 "ix86_fp_comparison_operator"
1153                [(reg:CC FLAGS_REG)
1154                 (const_int 0)]))]
1155   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1156 {
1157   ix86_compare_op0 = operands[2];
1158   ix86_compare_op1 = operands[3];
1159   ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1160   DONE;
1161 })
1162
1163 (define_expand "cbranchcc4"
1164   [(set (pc) (if_then_else
1165               (match_operator 0 "comparison_operator"
1166                [(match_operand 1 "flags_reg_operand" "")
1167                 (match_operand 2 "const0_operand" "")])
1168               (label_ref (match_operand 3 "" ""))
1169               (pc)))]
1170   ""
1171 {
1172   ix86_compare_op0 = operands[1];
1173   ix86_compare_op1 = operands[2];
1174   ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1175   DONE;
1176 })
1177
1178 (define_expand "cstorecc4"
1179   [(set (match_operand:QI 0 "register_operand" "")
1180               (match_operator 1 "comparison_operator"
1181                [(match_operand 2 "flags_reg_operand" "")
1182                 (match_operand 3 "const0_operand" "")]))]
1183   ""
1184 {
1185   ix86_compare_op0 = operands[2];
1186   ix86_compare_op1 = operands[3];
1187   ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1188   DONE;
1189 })
1190
1191
1192 ;; FP compares, step 1:
1193 ;; Set the FP condition codes.
1194 ;;
1195 ;; CCFPmode     compare with exceptions
1196 ;; CCFPUmode    compare with no exceptions
1197
1198 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1199 ;; used to manage the reg stack popping would not be preserved.
1200
1201 (define_insn "*cmpfp_0"
1202   [(set (match_operand:HI 0 "register_operand" "=a")
1203         (unspec:HI
1204           [(compare:CCFP
1205              (match_operand 1 "register_operand" "f")
1206              (match_operand 2 "const0_operand" ""))]
1207         UNSPEC_FNSTSW))]
1208   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1209    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1210   "* return output_fp_compare (insn, operands, 0, 0);"
1211   [(set_attr "type" "multi")
1212    (set_attr "unit" "i387")
1213    (set (attr "mode")
1214      (cond [(match_operand:SF 1 "" "")
1215               (const_string "SF")
1216             (match_operand:DF 1 "" "")
1217               (const_string "DF")
1218            ]
1219            (const_string "XF")))])
1220
1221 (define_insn_and_split "*cmpfp_0_cc"
1222   [(set (reg:CCFP FLAGS_REG)
1223         (compare:CCFP
1224           (match_operand 1 "register_operand" "f")
1225           (match_operand 2 "const0_operand" "")))
1226    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1227   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1228    && TARGET_SAHF && !TARGET_CMOVE
1229    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1230   "#"
1231   "&& reload_completed"
1232   [(set (match_dup 0)
1233         (unspec:HI
1234           [(compare:CCFP (match_dup 1)(match_dup 2))]
1235         UNSPEC_FNSTSW))
1236    (set (reg:CC FLAGS_REG)
1237         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1238   ""
1239   [(set_attr "type" "multi")
1240    (set_attr "unit" "i387")
1241    (set (attr "mode")
1242      (cond [(match_operand:SF 1 "" "")
1243               (const_string "SF")
1244             (match_operand:DF 1 "" "")
1245               (const_string "DF")
1246            ]
1247            (const_string "XF")))])
1248
1249 (define_insn "*cmpfp_xf"
1250   [(set (match_operand:HI 0 "register_operand" "=a")
1251         (unspec:HI
1252           [(compare:CCFP
1253              (match_operand:XF 1 "register_operand" "f")
1254              (match_operand:XF 2 "register_operand" "f"))]
1255           UNSPEC_FNSTSW))]
1256   "TARGET_80387"
1257   "* return output_fp_compare (insn, operands, 0, 0);"
1258   [(set_attr "type" "multi")
1259    (set_attr "unit" "i387")
1260    (set_attr "mode" "XF")])
1261
1262 (define_insn_and_split "*cmpfp_xf_cc"
1263   [(set (reg:CCFP FLAGS_REG)
1264         (compare:CCFP
1265           (match_operand:XF 1 "register_operand" "f")
1266           (match_operand:XF 2 "register_operand" "f")))
1267    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1268   "TARGET_80387
1269    && TARGET_SAHF && !TARGET_CMOVE"
1270   "#"
1271   "&& reload_completed"
1272   [(set (match_dup 0)
1273         (unspec:HI
1274           [(compare:CCFP (match_dup 1)(match_dup 2))]
1275         UNSPEC_FNSTSW))
1276    (set (reg:CC FLAGS_REG)
1277         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1278   ""
1279   [(set_attr "type" "multi")
1280    (set_attr "unit" "i387")
1281    (set_attr "mode" "XF")])
1282
1283 (define_insn "*cmpfp_<mode>"
1284   [(set (match_operand:HI 0 "register_operand" "=a")
1285         (unspec:HI
1286           [(compare:CCFP
1287              (match_operand:MODEF 1 "register_operand" "f")
1288              (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1289           UNSPEC_FNSTSW))]
1290   "TARGET_80387"
1291   "* return output_fp_compare (insn, operands, 0, 0);"
1292   [(set_attr "type" "multi")
1293    (set_attr "unit" "i387")
1294    (set_attr "mode" "<MODE>")])
1295
1296 (define_insn_and_split "*cmpfp_<mode>_cc"
1297   [(set (reg:CCFP FLAGS_REG)
1298         (compare:CCFP
1299           (match_operand:MODEF 1 "register_operand" "f")
1300           (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1301    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1302   "TARGET_80387
1303    && TARGET_SAHF && !TARGET_CMOVE"
1304   "#"
1305   "&& reload_completed"
1306   [(set (match_dup 0)
1307         (unspec:HI
1308           [(compare:CCFP (match_dup 1)(match_dup 2))]
1309         UNSPEC_FNSTSW))
1310    (set (reg:CC FLAGS_REG)
1311         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1312   ""
1313   [(set_attr "type" "multi")
1314    (set_attr "unit" "i387")
1315    (set_attr "mode" "<MODE>")])
1316
1317 (define_insn "*cmpfp_u"
1318   [(set (match_operand:HI 0 "register_operand" "=a")
1319         (unspec:HI
1320           [(compare:CCFPU
1321              (match_operand 1 "register_operand" "f")
1322              (match_operand 2 "register_operand" "f"))]
1323           UNSPEC_FNSTSW))]
1324   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1325    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1326   "* return output_fp_compare (insn, operands, 0, 1);"
1327   [(set_attr "type" "multi")
1328    (set_attr "unit" "i387")
1329    (set (attr "mode")
1330      (cond [(match_operand:SF 1 "" "")
1331               (const_string "SF")
1332             (match_operand:DF 1 "" "")
1333               (const_string "DF")
1334            ]
1335            (const_string "XF")))])
1336
1337 (define_insn_and_split "*cmpfp_u_cc"
1338   [(set (reg:CCFPU FLAGS_REG)
1339         (compare:CCFPU
1340           (match_operand 1 "register_operand" "f")
1341           (match_operand 2 "register_operand" "f")))
1342    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1343   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1344    && TARGET_SAHF && !TARGET_CMOVE
1345    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1346   "#"
1347   "&& reload_completed"
1348   [(set (match_dup 0)
1349         (unspec:HI
1350           [(compare:CCFPU (match_dup 1)(match_dup 2))]
1351         UNSPEC_FNSTSW))
1352    (set (reg:CC FLAGS_REG)
1353         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1354   ""
1355   [(set_attr "type" "multi")
1356    (set_attr "unit" "i387")
1357    (set (attr "mode")
1358      (cond [(match_operand:SF 1 "" "")
1359               (const_string "SF")
1360             (match_operand:DF 1 "" "")
1361               (const_string "DF")
1362            ]
1363            (const_string "XF")))])
1364
1365 (define_insn "*cmpfp_<mode>"
1366   [(set (match_operand:HI 0 "register_operand" "=a")
1367         (unspec:HI
1368           [(compare:CCFP
1369              (match_operand 1 "register_operand" "f")
1370              (match_operator 3 "float_operator"
1371                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1372           UNSPEC_FNSTSW))]
1373   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1374    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1375    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1376   "* return output_fp_compare (insn, operands, 0, 0);"
1377   [(set_attr "type" "multi")
1378    (set_attr "unit" "i387")
1379    (set_attr "fp_int_src" "true")
1380    (set_attr "mode" "<MODE>")])
1381
1382 (define_insn_and_split "*cmpfp_<mode>_cc"
1383   [(set (reg:CCFP FLAGS_REG)
1384         (compare:CCFP
1385           (match_operand 1 "register_operand" "f")
1386           (match_operator 3 "float_operator"
1387             [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1388    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1389   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1390    && TARGET_SAHF && !TARGET_CMOVE
1391    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1392    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1393   "#"
1394   "&& reload_completed"
1395   [(set (match_dup 0)
1396         (unspec:HI
1397           [(compare:CCFP
1398              (match_dup 1)
1399              (match_op_dup 3 [(match_dup 2)]))]
1400         UNSPEC_FNSTSW))
1401    (set (reg:CC FLAGS_REG)
1402         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1403   ""
1404   [(set_attr "type" "multi")
1405    (set_attr "unit" "i387")
1406    (set_attr "fp_int_src" "true")
1407    (set_attr "mode" "<MODE>")])
1408
1409 ;; FP compares, step 2
1410 ;; Move the fpsw to ax.
1411
1412 (define_insn "x86_fnstsw_1"
1413   [(set (match_operand:HI 0 "register_operand" "=a")
1414         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1415   "TARGET_80387"
1416   "fnstsw\t%0"
1417   [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1418    (set_attr "mode" "SI")
1419    (set_attr "unit" "i387")])
1420
1421 ;; FP compares, step 3
1422 ;; Get ax into flags, general case.
1423
1424 (define_insn "x86_sahf_1"
1425   [(set (reg:CC FLAGS_REG)
1426         (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1427                    UNSPEC_SAHF))]
1428   "TARGET_SAHF"
1429 {
1430 #ifdef HAVE_AS_IX86_SAHF
1431   return "sahf";
1432 #else
1433   return ASM_BYTE "0x9e";
1434 #endif
1435 }
1436   [(set_attr "length" "1")
1437    (set_attr "athlon_decode" "vector")
1438    (set_attr "amdfam10_decode" "direct")
1439    (set_attr "mode" "SI")])
1440
1441 ;; Pentium Pro can do steps 1 through 3 in one go.
1442 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1443 (define_insn "*cmpfp_i_mixed"
1444   [(set (reg:CCFP FLAGS_REG)
1445         (compare:CCFP (match_operand 0 "register_operand" "f,x")
1446                       (match_operand 1 "nonimmediate_operand" "f,xm")))]
1447   "TARGET_MIX_SSE_I387
1448    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1449    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1450   "* return output_fp_compare (insn, operands, 1, 0);"
1451   [(set_attr "type" "fcmp,ssecomi")
1452    (set_attr "prefix" "orig,maybe_vex")
1453    (set (attr "mode")
1454      (if_then_else (match_operand:SF 1 "" "")
1455         (const_string "SF")
1456         (const_string "DF")))
1457    (set (attr "prefix_rep")
1458         (if_then_else (eq_attr "type" "ssecomi")
1459                       (const_string "0")
1460                       (const_string "*")))
1461    (set (attr "prefix_data16")
1462         (cond [(eq_attr "type" "fcmp")
1463                  (const_string "*")
1464                (eq_attr "mode" "DF")
1465                  (const_string "1")
1466               ]
1467               (const_string "0")))
1468    (set_attr "athlon_decode" "vector")
1469    (set_attr "amdfam10_decode" "direct")])
1470
1471 (define_insn "*cmpfp_i_sse"
1472   [(set (reg:CCFP FLAGS_REG)
1473         (compare:CCFP (match_operand 0 "register_operand" "x")
1474                       (match_operand 1 "nonimmediate_operand" "xm")))]
1475   "TARGET_SSE_MATH
1476    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1477    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1478   "* return output_fp_compare (insn, operands, 1, 0);"
1479   [(set_attr "type" "ssecomi")
1480    (set_attr "prefix" "maybe_vex")
1481    (set (attr "mode")
1482      (if_then_else (match_operand:SF 1 "" "")
1483         (const_string "SF")
1484         (const_string "DF")))
1485    (set_attr "prefix_rep" "0")
1486    (set (attr "prefix_data16")
1487         (if_then_else (eq_attr "mode" "DF")
1488                       (const_string "1")
1489                       (const_string "0")))
1490    (set_attr "athlon_decode" "vector")
1491    (set_attr "amdfam10_decode" "direct")])
1492
1493 (define_insn "*cmpfp_i_i387"
1494   [(set (reg:CCFP FLAGS_REG)
1495         (compare:CCFP (match_operand 0 "register_operand" "f")
1496                       (match_operand 1 "register_operand" "f")))]
1497   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1498    && TARGET_CMOVE
1499    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1500    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1501   "* return output_fp_compare (insn, operands, 1, 0);"
1502   [(set_attr "type" "fcmp")
1503    (set (attr "mode")
1504      (cond [(match_operand:SF 1 "" "")
1505               (const_string "SF")
1506             (match_operand:DF 1 "" "")
1507               (const_string "DF")
1508            ]
1509            (const_string "XF")))
1510    (set_attr "athlon_decode" "vector")
1511    (set_attr "amdfam10_decode" "direct")])
1512
1513 (define_insn "*cmpfp_iu_mixed"
1514   [(set (reg:CCFPU FLAGS_REG)
1515         (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1516                        (match_operand 1 "nonimmediate_operand" "f,xm")))]
1517   "TARGET_MIX_SSE_I387
1518    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1519    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1520   "* return output_fp_compare (insn, operands, 1, 1);"
1521   [(set_attr "type" "fcmp,ssecomi")
1522    (set_attr "prefix" "orig,maybe_vex")
1523    (set (attr "mode")
1524      (if_then_else (match_operand:SF 1 "" "")
1525         (const_string "SF")
1526         (const_string "DF")))
1527    (set (attr "prefix_rep")
1528         (if_then_else (eq_attr "type" "ssecomi")
1529                       (const_string "0")
1530                       (const_string "*")))
1531    (set (attr "prefix_data16")
1532         (cond [(eq_attr "type" "fcmp")
1533                  (const_string "*")
1534                (eq_attr "mode" "DF")
1535                  (const_string "1")
1536               ]
1537               (const_string "0")))
1538    (set_attr "athlon_decode" "vector")
1539    (set_attr "amdfam10_decode" "direct")])
1540
1541 (define_insn "*cmpfp_iu_sse"
1542   [(set (reg:CCFPU FLAGS_REG)
1543         (compare:CCFPU (match_operand 0 "register_operand" "x")
1544                        (match_operand 1 "nonimmediate_operand" "xm")))]
1545   "TARGET_SSE_MATH
1546    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1547    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1548   "* return output_fp_compare (insn, operands, 1, 1);"
1549   [(set_attr "type" "ssecomi")
1550    (set_attr "prefix" "maybe_vex")
1551    (set (attr "mode")
1552      (if_then_else (match_operand:SF 1 "" "")
1553         (const_string "SF")
1554         (const_string "DF")))
1555    (set_attr "prefix_rep" "0")
1556    (set (attr "prefix_data16")
1557         (if_then_else (eq_attr "mode" "DF")
1558                       (const_string "1")
1559                       (const_string "0")))
1560    (set_attr "athlon_decode" "vector")
1561    (set_attr "amdfam10_decode" "direct")])
1562
1563 (define_insn "*cmpfp_iu_387"
1564   [(set (reg:CCFPU FLAGS_REG)
1565         (compare:CCFPU (match_operand 0 "register_operand" "f")
1566                        (match_operand 1 "register_operand" "f")))]
1567   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1568    && TARGET_CMOVE
1569    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1570    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1571   "* return output_fp_compare (insn, operands, 1, 1);"
1572   [(set_attr "type" "fcmp")
1573    (set (attr "mode")
1574      (cond [(match_operand:SF 1 "" "")
1575               (const_string "SF")
1576             (match_operand:DF 1 "" "")
1577               (const_string "DF")
1578            ]
1579            (const_string "XF")))
1580    (set_attr "athlon_decode" "vector")
1581    (set_attr "amdfam10_decode" "direct")])
1582 \f
1583 ;; Move instructions.
1584
1585 ;; General case of fullword move.
1586
1587 (define_expand "movsi"
1588   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1589         (match_operand:SI 1 "general_operand" ""))]
1590   ""
1591   "ix86_expand_move (SImode, operands); DONE;")
1592
1593 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1594 ;; general_operand.
1595 ;;
1596 ;; %%% We don't use a post-inc memory reference because x86 is not a
1597 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1598 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1599 ;; targets without our curiosities, and it is just as easy to represent
1600 ;; this differently.
1601
1602 (define_insn "*pushsi2"
1603   [(set (match_operand:SI 0 "push_operand" "=<")
1604         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1605   "!TARGET_64BIT"
1606   "push{l}\t%1"
1607   [(set_attr "type" "push")
1608    (set_attr "mode" "SI")])
1609
1610 ;; For 64BIT abi we always round up to 8 bytes.
1611 (define_insn "*pushsi2_rex64"
1612   [(set (match_operand:SI 0 "push_operand" "=X")
1613         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1614   "TARGET_64BIT"
1615   "push{q}\t%q1"
1616   [(set_attr "type" "push")
1617    (set_attr "mode" "SI")])
1618
1619 (define_insn "*pushsi2_prologue"
1620   [(set (match_operand:SI 0 "push_operand" "=<")
1621         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1622    (clobber (mem:BLK (scratch)))]
1623   "!TARGET_64BIT"
1624   "push{l}\t%1"
1625   [(set_attr "type" "push")
1626    (set_attr "mode" "SI")])
1627
1628 (define_insn "*popsi1_epilogue"
1629   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1630         (mem:SI (reg:SI SP_REG)))
1631    (set (reg:SI SP_REG)
1632         (plus:SI (reg:SI SP_REG) (const_int 4)))
1633    (clobber (mem:BLK (scratch)))]
1634   "!TARGET_64BIT"
1635   "pop{l}\t%0"
1636   [(set_attr "type" "pop")
1637    (set_attr "mode" "SI")])
1638
1639 (define_insn "popsi1"
1640   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1641         (mem:SI (reg:SI SP_REG)))
1642    (set (reg:SI SP_REG)
1643         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1644   "!TARGET_64BIT"
1645   "pop{l}\t%0"
1646   [(set_attr "type" "pop")
1647    (set_attr "mode" "SI")])
1648
1649 (define_insn "*movsi_xor"
1650   [(set (match_operand:SI 0 "register_operand" "=r")
1651         (match_operand:SI 1 "const0_operand" ""))
1652    (clobber (reg:CC FLAGS_REG))]
1653   "reload_completed"
1654   "xor{l}\t%0, %0"
1655   [(set_attr "type" "alu1")
1656    (set_attr "mode" "SI")
1657    (set_attr "length_immediate" "0")])
1658
1659 (define_insn "*movsi_or"
1660   [(set (match_operand:SI 0 "register_operand" "=r")
1661         (match_operand:SI 1 "immediate_operand" "i"))
1662    (clobber (reg:CC FLAGS_REG))]
1663   "reload_completed
1664    && operands[1] == constm1_rtx"
1665 {
1666   operands[1] = constm1_rtx;
1667   return "or{l}\t{%1, %0|%0, %1}";
1668 }
1669   [(set_attr "type" "alu1")
1670    (set_attr "mode" "SI")
1671    (set_attr "length_immediate" "1")])
1672
1673 (define_insn "*movsi_1"
1674   [(set (match_operand:SI 0 "nonimmediate_operand"
1675                         "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1676         (match_operand:SI 1 "general_operand"
1677                         "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r   ,m "))]
1678   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1679 {
1680   switch (get_attr_type (insn))
1681     {
1682     case TYPE_SSELOG1:
1683       if (get_attr_mode (insn) == MODE_TI)
1684         return "%vpxor\t%0, %d0";
1685       return "%vxorps\t%0, %d0";
1686
1687     case TYPE_SSEMOV:
1688       switch (get_attr_mode (insn))
1689         {
1690         case MODE_TI:
1691           return "%vmovdqa\t{%1, %0|%0, %1}";
1692         case MODE_V4SF:
1693           return "%vmovaps\t{%1, %0|%0, %1}";
1694         case MODE_SI:
1695           return "%vmovd\t{%1, %0|%0, %1}";
1696         case MODE_SF:
1697           return "%vmovss\t{%1, %0|%0, %1}";
1698         default:
1699           gcc_unreachable ();
1700         }
1701
1702     case TYPE_MMX:
1703       return "pxor\t%0, %0";
1704
1705     case TYPE_MMXMOV:
1706       if (get_attr_mode (insn) == MODE_DI)
1707         return "movq\t{%1, %0|%0, %1}";
1708       return "movd\t{%1, %0|%0, %1}";
1709
1710     case TYPE_LEA:
1711       return "lea{l}\t{%1, %0|%0, %1}";
1712
1713     default:
1714       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1715       return "mov{l}\t{%1, %0|%0, %1}";
1716     }
1717 }
1718   [(set (attr "type")
1719      (cond [(eq_attr "alternative" "2")
1720               (const_string "mmx")
1721             (eq_attr "alternative" "3,4,5")
1722               (const_string "mmxmov")
1723             (eq_attr "alternative" "6")
1724               (const_string "sselog1")
1725             (eq_attr "alternative" "7,8,9,10,11")
1726               (const_string "ssemov")
1727             (match_operand:DI 1 "pic_32bit_operand" "")
1728               (const_string "lea")
1729            ]
1730            (const_string "imov")))
1731    (set (attr "prefix")
1732      (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
1733        (const_string "orig")
1734        (const_string "maybe_vex")))
1735    (set (attr "prefix_data16")
1736      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
1737        (const_string "1")
1738        (const_string "*")))
1739    (set (attr "mode")
1740      (cond [(eq_attr "alternative" "2,3")
1741               (const_string "DI")
1742             (eq_attr "alternative" "6,7")
1743               (if_then_else
1744                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1745                 (const_string "V4SF")
1746                 (const_string "TI"))
1747             (and (eq_attr "alternative" "8,9,10,11")
1748                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1749               (const_string "SF")
1750            ]
1751            (const_string "SI")))])
1752
1753 ;; Stores and loads of ax to arbitrary constant address.
1754 ;; We fake an second form of instruction to force reload to load address
1755 ;; into register when rax is not available
1756 (define_insn "*movabssi_1_rex64"
1757   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1758         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1759   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1760   "@
1761    movabs{l}\t{%1, %P0|%P0, %1}
1762    mov{l}\t{%1, %a0|%a0, %1}"
1763   [(set_attr "type" "imov")
1764    (set_attr "modrm" "0,*")
1765    (set_attr "length_address" "8,0")
1766    (set_attr "length_immediate" "0,*")
1767    (set_attr "memory" "store")
1768    (set_attr "mode" "SI")])
1769
1770 (define_insn "*movabssi_2_rex64"
1771   [(set (match_operand:SI 0 "register_operand" "=a,r")
1772         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1773   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1774   "@
1775    movabs{l}\t{%P1, %0|%0, %P1}
1776    mov{l}\t{%a1, %0|%0, %a1}"
1777   [(set_attr "type" "imov")
1778    (set_attr "modrm" "0,*")
1779    (set_attr "length_address" "8,0")
1780    (set_attr "length_immediate" "0")
1781    (set_attr "memory" "load")
1782    (set_attr "mode" "SI")])
1783
1784 (define_insn "*swapsi"
1785   [(set (match_operand:SI 0 "register_operand" "+r")
1786         (match_operand:SI 1 "register_operand" "+r"))
1787    (set (match_dup 1)
1788         (match_dup 0))]
1789   ""
1790   "xchg{l}\t%1, %0"
1791   [(set_attr "type" "imov")
1792    (set_attr "mode" "SI")
1793    (set_attr "pent_pair" "np")
1794    (set_attr "athlon_decode" "vector")
1795    (set_attr "amdfam10_decode" "double")])
1796
1797 (define_expand "movhi"
1798   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1799         (match_operand:HI 1 "general_operand" ""))]
1800   ""
1801   "ix86_expand_move (HImode, operands); DONE;")
1802
1803 (define_insn "*pushhi2"
1804   [(set (match_operand:HI 0 "push_operand" "=X")
1805         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1806   "!TARGET_64BIT"
1807   "push{l}\t%k1"
1808   [(set_attr "type" "push")
1809    (set_attr "mode" "SI")])
1810
1811 ;; For 64BIT abi we always round up to 8 bytes.
1812 (define_insn "*pushhi2_rex64"
1813   [(set (match_operand:HI 0 "push_operand" "=X")
1814         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1815   "TARGET_64BIT"
1816   "push{q}\t%q1"
1817   [(set_attr "type" "push")
1818    (set_attr "mode" "DI")])
1819
1820 (define_insn "*movhi_1"
1821   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1822         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1823   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1824 {
1825   switch (get_attr_type (insn))
1826     {
1827     case TYPE_IMOVX:
1828       /* movzwl is faster than movw on p2 due to partial word stalls,
1829          though not as fast as an aligned movl.  */
1830       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1831     default:
1832       if (get_attr_mode (insn) == MODE_SI)
1833         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1834       else
1835         return "mov{w}\t{%1, %0|%0, %1}";
1836     }
1837 }
1838   [(set (attr "type")
1839      (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
1840               (const_string "imov")
1841             (and (eq_attr "alternative" "0")
1842                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1843                           (const_int 0))
1844                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1845                           (const_int 0))))
1846               (const_string "imov")
1847             (and (eq_attr "alternative" "1,2")
1848                  (match_operand:HI 1 "aligned_operand" ""))
1849               (const_string "imov")
1850             (and (ne (symbol_ref "TARGET_MOVX")
1851                      (const_int 0))
1852                  (eq_attr "alternative" "0,2"))
1853               (const_string "imovx")
1854            ]
1855            (const_string "imov")))
1856     (set (attr "mode")
1857       (cond [(eq_attr "type" "imovx")
1858                (const_string "SI")
1859              (and (eq_attr "alternative" "1,2")
1860                   (match_operand:HI 1 "aligned_operand" ""))
1861                (const_string "SI")
1862              (and (eq_attr "alternative" "0")
1863                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1864                            (const_int 0))
1865                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1866                            (const_int 0))))
1867                (const_string "SI")
1868             ]
1869             (const_string "HI")))])
1870
1871 ;; Stores and loads of ax to arbitrary constant address.
1872 ;; We fake an second form of instruction to force reload to load address
1873 ;; into register when rax is not available
1874 (define_insn "*movabshi_1_rex64"
1875   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1876         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1877   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1878   "@
1879    movabs{w}\t{%1, %P0|%P0, %1}
1880    mov{w}\t{%1, %a0|%a0, %1}"
1881   [(set_attr "type" "imov")
1882    (set_attr "modrm" "0,*")
1883    (set_attr "length_address" "8,0")
1884    (set_attr "length_immediate" "0,*")
1885    (set_attr "memory" "store")
1886    (set_attr "mode" "HI")])
1887
1888 (define_insn "*movabshi_2_rex64"
1889   [(set (match_operand:HI 0 "register_operand" "=a,r")
1890         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1891   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1892   "@
1893    movabs{w}\t{%P1, %0|%0, %P1}
1894    mov{w}\t{%a1, %0|%0, %a1}"
1895   [(set_attr "type" "imov")
1896    (set_attr "modrm" "0,*")
1897    (set_attr "length_address" "8,0")
1898    (set_attr "length_immediate" "0")
1899    (set_attr "memory" "load")
1900    (set_attr "mode" "HI")])
1901
1902 (define_insn "*swaphi_1"
1903   [(set (match_operand:HI 0 "register_operand" "+r")
1904         (match_operand:HI 1 "register_operand" "+r"))
1905    (set (match_dup 1)
1906         (match_dup 0))]
1907   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
1908   "xchg{l}\t%k1, %k0"
1909   [(set_attr "type" "imov")
1910    (set_attr "mode" "SI")
1911    (set_attr "pent_pair" "np")
1912    (set_attr "athlon_decode" "vector")
1913    (set_attr "amdfam10_decode" "double")])
1914
1915 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1916 (define_insn "*swaphi_2"
1917   [(set (match_operand:HI 0 "register_operand" "+r")
1918         (match_operand:HI 1 "register_operand" "+r"))
1919    (set (match_dup 1)
1920         (match_dup 0))]
1921   "TARGET_PARTIAL_REG_STALL"
1922   "xchg{w}\t%1, %0"
1923   [(set_attr "type" "imov")
1924    (set_attr "mode" "HI")
1925    (set_attr "pent_pair" "np")
1926    (set_attr "athlon_decode" "vector")])
1927
1928 (define_expand "movstricthi"
1929   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1930         (match_operand:HI 1 "general_operand" ""))]
1931   ""
1932 {
1933   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
1934     FAIL;
1935   /* Don't generate memory->memory moves, go through a register */
1936   if (MEM_P (operands[0]) && MEM_P (operands[1]))
1937     operands[1] = force_reg (HImode, operands[1]);
1938 })
1939
1940 (define_insn "*movstricthi_1"
1941   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1942         (match_operand:HI 1 "general_operand" "rn,m"))]
1943   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
1944    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1945   "mov{w}\t{%1, %0|%0, %1}"
1946   [(set_attr "type" "imov")
1947    (set_attr "mode" "HI")])
1948
1949 (define_insn "*movstricthi_xor"
1950   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1951         (match_operand:HI 1 "const0_operand" ""))
1952    (clobber (reg:CC FLAGS_REG))]
1953   "reload_completed"
1954   "xor{w}\t%0, %0"
1955   [(set_attr "type" "alu1")
1956    (set_attr "mode" "HI")
1957    (set_attr "length_immediate" "0")])
1958
1959 (define_expand "movqi"
1960   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1961         (match_operand:QI 1 "general_operand" ""))]
1962   ""
1963   "ix86_expand_move (QImode, operands); DONE;")
1964
1965 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1966 ;; "push a byte".  But actually we use pushl, which has the effect
1967 ;; of rounding the amount pushed up to a word.
1968
1969 (define_insn "*pushqi2"
1970   [(set (match_operand:QI 0 "push_operand" "=X")
1971         (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1972   "!TARGET_64BIT"
1973   "push{l}\t%k1"
1974   [(set_attr "type" "push")
1975    (set_attr "mode" "SI")])
1976
1977 ;; For 64BIT abi we always round up to 8 bytes.
1978 (define_insn "*pushqi2_rex64"
1979   [(set (match_operand:QI 0 "push_operand" "=X")
1980         (match_operand:QI 1 "nonmemory_no_elim_operand" "qn"))]
1981   "TARGET_64BIT"
1982   "push{q}\t%q1"
1983   [(set_attr "type" "push")
1984    (set_attr "mode" "DI")])
1985
1986 ;; Situation is quite tricky about when to choose full sized (SImode) move
1987 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1988 ;; partial register dependency machines (such as AMD Athlon), where QImode
1989 ;; moves issue extra dependency and for partial register stalls machines
1990 ;; that don't use QImode patterns (and QImode move cause stall on the next
1991 ;; instruction).
1992 ;;
1993 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1994 ;; register stall machines with, where we use QImode instructions, since
1995 ;; partial register stall can be caused there.  Then we use movzx.
1996 (define_insn "*movqi_1"
1997   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1998         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1999   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2000 {
2001   switch (get_attr_type (insn))
2002     {
2003     case TYPE_IMOVX:
2004       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2005       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2006     default:
2007       if (get_attr_mode (insn) == MODE_SI)
2008         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2009       else
2010         return "mov{b}\t{%1, %0|%0, %1}";
2011     }
2012 }
2013   [(set (attr "type")
2014      (cond [(and (eq_attr "alternative" "5")
2015                  (not (match_operand:QI 1 "aligned_operand" "")))
2016               (const_string "imovx")
2017             (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
2018               (const_string "imov")
2019             (and (eq_attr "alternative" "3")
2020                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2021                           (const_int 0))
2022                       (eq (symbol_ref "TARGET_QIMODE_MATH")
2023                           (const_int 0))))
2024               (const_string "imov")
2025             (eq_attr "alternative" "3,5")
2026               (const_string "imovx")
2027             (and (ne (symbol_ref "TARGET_MOVX")
2028                      (const_int 0))
2029                  (eq_attr "alternative" "2"))
2030               (const_string "imovx")
2031            ]
2032            (const_string "imov")))
2033    (set (attr "mode")
2034       (cond [(eq_attr "alternative" "3,4,5")
2035                (const_string "SI")
2036              (eq_attr "alternative" "6")
2037                (const_string "QI")
2038              (eq_attr "type" "imovx")
2039                (const_string "SI")
2040              (and (eq_attr "type" "imov")
2041                   (and (eq_attr "alternative" "0,1")
2042                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
2043                                 (const_int 0))
2044                             (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2045                                      (const_int 0))
2046                                  (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2047                                      (const_int 0))))))
2048                (const_string "SI")
2049              ;; Avoid partial register stalls when not using QImode arithmetic
2050              (and (eq_attr "type" "imov")
2051                   (and (eq_attr "alternative" "0,1")
2052                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
2053                                 (const_int 0))
2054                             (eq (symbol_ref "TARGET_QIMODE_MATH")
2055                                 (const_int 0)))))
2056                (const_string "SI")
2057            ]
2058            (const_string "QI")))])
2059
2060 (define_insn "*swapqi_1"
2061   [(set (match_operand:QI 0 "register_operand" "+r")
2062         (match_operand:QI 1 "register_operand" "+r"))
2063    (set (match_dup 1)
2064         (match_dup 0))]
2065   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2066   "xchg{l}\t%k1, %k0"
2067   [(set_attr "type" "imov")
2068    (set_attr "mode" "SI")
2069    (set_attr "pent_pair" "np")
2070    (set_attr "athlon_decode" "vector")
2071    (set_attr "amdfam10_decode" "vector")])
2072
2073 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
2074 (define_insn "*swapqi_2"
2075   [(set (match_operand:QI 0 "register_operand" "+q")
2076         (match_operand:QI 1 "register_operand" "+q"))
2077    (set (match_dup 1)
2078         (match_dup 0))]
2079   "TARGET_PARTIAL_REG_STALL"
2080   "xchg{b}\t%1, %0"
2081   [(set_attr "type" "imov")
2082    (set_attr "mode" "QI")
2083    (set_attr "pent_pair" "np")
2084    (set_attr "athlon_decode" "vector")])
2085
2086 (define_expand "movstrictqi"
2087   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
2088         (match_operand:QI 1 "general_operand" ""))]
2089   ""
2090 {
2091   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2092     FAIL;
2093   /* Don't generate memory->memory moves, go through a register.  */
2094   if (MEM_P (operands[0]) && MEM_P (operands[1]))
2095     operands[1] = force_reg (QImode, operands[1]);
2096 })
2097
2098 (define_insn "*movstrictqi_1"
2099   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
2100         (match_operand:QI 1 "general_operand" "*qn,m"))]
2101   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2102    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2103   "mov{b}\t{%1, %0|%0, %1}"
2104   [(set_attr "type" "imov")
2105    (set_attr "mode" "QI")])
2106
2107 (define_insn "*movstrictqi_xor"
2108   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
2109         (match_operand:QI 1 "const0_operand" ""))
2110    (clobber (reg:CC FLAGS_REG))]
2111   "reload_completed"
2112   "xor{b}\t%0, %0"
2113   [(set_attr "type" "alu1")
2114    (set_attr "mode" "QI")
2115    (set_attr "length_immediate" "0")])
2116
2117 (define_insn "*movsi_extv_1"
2118   [(set (match_operand:SI 0 "register_operand" "=R")
2119         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
2120                          (const_int 8)
2121                          (const_int 8)))]
2122   ""
2123   "movs{bl|x}\t{%h1, %0|%0, %h1}"
2124   [(set_attr "type" "imovx")
2125    (set_attr "mode" "SI")])
2126
2127 (define_insn "*movhi_extv_1"
2128   [(set (match_operand:HI 0 "register_operand" "=R")
2129         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
2130                          (const_int 8)
2131                          (const_int 8)))]
2132   ""
2133   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2134   [(set_attr "type" "imovx")
2135    (set_attr "mode" "SI")])
2136
2137 (define_insn "*movqi_extv_1"
2138   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2139         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2140                          (const_int 8)
2141                          (const_int 8)))]
2142   "!TARGET_64BIT"
2143 {
2144   switch (get_attr_type (insn))
2145     {
2146     case TYPE_IMOVX:
2147       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2148     default:
2149       return "mov{b}\t{%h1, %0|%0, %h1}";
2150     }
2151 }
2152   [(set (attr "type")
2153      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2154                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2155                              (ne (symbol_ref "TARGET_MOVX")
2156                                  (const_int 0))))
2157         (const_string "imovx")
2158         (const_string "imov")))
2159    (set (attr "mode")
2160      (if_then_else (eq_attr "type" "imovx")
2161         (const_string "SI")
2162         (const_string "QI")))])
2163
2164 (define_insn "*movqi_extv_1_rex64"
2165   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2166         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2167                          (const_int 8)
2168                          (const_int 8)))]
2169   "TARGET_64BIT"
2170 {
2171   switch (get_attr_type (insn))
2172     {
2173     case TYPE_IMOVX:
2174       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2175     default:
2176       return "mov{b}\t{%h1, %0|%0, %h1}";
2177     }
2178 }
2179   [(set (attr "type")
2180      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2181                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2182                              (ne (symbol_ref "TARGET_MOVX")
2183                                  (const_int 0))))
2184         (const_string "imovx")
2185         (const_string "imov")))
2186    (set (attr "mode")
2187      (if_then_else (eq_attr "type" "imovx")
2188         (const_string "SI")
2189         (const_string "QI")))])
2190
2191 ;; Stores and loads of ax to arbitrary constant address.
2192 ;; We fake an second form of instruction to force reload to load address
2193 ;; into register when rax is not available
2194 (define_insn "*movabsqi_1_rex64"
2195   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2196         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
2197   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2198   "@
2199    movabs{b}\t{%1, %P0|%P0, %1}
2200    mov{b}\t{%1, %a0|%a0, %1}"
2201   [(set_attr "type" "imov")
2202    (set_attr "modrm" "0,*")
2203    (set_attr "length_address" "8,0")
2204    (set_attr "length_immediate" "0,*")
2205    (set_attr "memory" "store")
2206    (set_attr "mode" "QI")])
2207
2208 (define_insn "*movabsqi_2_rex64"
2209   [(set (match_operand:QI 0 "register_operand" "=a,r")
2210         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2211   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2212   "@
2213    movabs{b}\t{%P1, %0|%0, %P1}
2214    mov{b}\t{%a1, %0|%0, %a1}"
2215   [(set_attr "type" "imov")
2216    (set_attr "modrm" "0,*")
2217    (set_attr "length_address" "8,0")
2218    (set_attr "length_immediate" "0")
2219    (set_attr "memory" "load")
2220    (set_attr "mode" "QI")])
2221
2222 (define_insn "*movdi_extzv_1"
2223   [(set (match_operand:DI 0 "register_operand" "=R")
2224         (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
2225                          (const_int 8)
2226                          (const_int 8)))]
2227   "TARGET_64BIT"
2228   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2229   [(set_attr "type" "imovx")
2230    (set_attr "mode" "SI")])
2231
2232 (define_insn "*movsi_extzv_1"
2233   [(set (match_operand:SI 0 "register_operand" "=R")
2234         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
2235                          (const_int 8)
2236                          (const_int 8)))]
2237   ""
2238   "movz{bl|x}\t{%h1, %0|%0, %h1}"
2239   [(set_attr "type" "imovx")
2240    (set_attr "mode" "SI")])
2241
2242 (define_insn "*movqi_extzv_2"
2243   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2244         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2245                                     (const_int 8)
2246                                     (const_int 8)) 0))]
2247   "!TARGET_64BIT"
2248 {
2249   switch (get_attr_type (insn))
2250     {
2251     case TYPE_IMOVX:
2252       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2253     default:
2254       return "mov{b}\t{%h1, %0|%0, %h1}";
2255     }
2256 }
2257   [(set (attr "type")
2258      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2259                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2260                              (ne (symbol_ref "TARGET_MOVX")
2261                                  (const_int 0))))
2262         (const_string "imovx")
2263         (const_string "imov")))
2264    (set (attr "mode")
2265      (if_then_else (eq_attr "type" "imovx")
2266         (const_string "SI")
2267         (const_string "QI")))])
2268
2269 (define_insn "*movqi_extzv_2_rex64"
2270   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2271         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2272                                     (const_int 8)
2273                                     (const_int 8)) 0))]
2274   "TARGET_64BIT"
2275 {
2276   switch (get_attr_type (insn))
2277     {
2278     case TYPE_IMOVX:
2279       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2280     default:
2281       return "mov{b}\t{%h1, %0|%0, %h1}";
2282     }
2283 }
2284   [(set (attr "type")
2285      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2286                         (ne (symbol_ref "TARGET_MOVX")
2287                             (const_int 0)))
2288         (const_string "imovx")
2289         (const_string "imov")))
2290    (set (attr "mode")
2291      (if_then_else (eq_attr "type" "imovx")
2292         (const_string "SI")
2293         (const_string "QI")))])
2294
2295 (define_insn "movsi_insv_1"
2296   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2297                          (const_int 8)
2298                          (const_int 8))
2299         (match_operand:SI 1 "general_operand" "Qmn"))]
2300   "!TARGET_64BIT"
2301   "mov{b}\t{%b1, %h0|%h0, %b1}"
2302   [(set_attr "type" "imov")
2303    (set_attr "mode" "QI")])
2304
2305 (define_insn "*movsi_insv_1_rex64"
2306   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2307                          (const_int 8)
2308                          (const_int 8))
2309         (match_operand:SI 1 "nonmemory_operand" "Qn"))]
2310   "TARGET_64BIT"
2311   "mov{b}\t{%b1, %h0|%h0, %b1}"
2312   [(set_attr "type" "imov")
2313    (set_attr "mode" "QI")])
2314
2315 (define_insn "movdi_insv_1_rex64"
2316   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
2317                          (const_int 8)
2318                          (const_int 8))
2319         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
2320   "TARGET_64BIT"
2321   "mov{b}\t{%b1, %h0|%h0, %b1}"
2322   [(set_attr "type" "imov")
2323    (set_attr "mode" "QI")])
2324
2325 (define_insn "*movqi_insv_2"
2326   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2327                          (const_int 8)
2328                          (const_int 8))
2329         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2330                      (const_int 8)))]
2331   ""
2332   "mov{b}\t{%h1, %h0|%h0, %h1}"
2333   [(set_attr "type" "imov")
2334    (set_attr "mode" "QI")])
2335
2336 (define_expand "movdi"
2337   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2338         (match_operand:DI 1 "general_operand" ""))]
2339   ""
2340   "ix86_expand_move (DImode, operands); DONE;")
2341
2342 (define_insn "*pushdi"
2343   [(set (match_operand:DI 0 "push_operand" "=<")
2344         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
2345   "!TARGET_64BIT"
2346   "#")
2347
2348 (define_insn "*pushdi2_rex64"
2349   [(set (match_operand:DI 0 "push_operand" "=<,!<")
2350         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
2351   "TARGET_64BIT"
2352   "@
2353    push{q}\t%1
2354    #"
2355   [(set_attr "type" "push,multi")
2356    (set_attr "mode" "DI")])
2357
2358 ;; Convert impossible pushes of immediate to existing instructions.
2359 ;; First try to get scratch register and go through it.  In case this
2360 ;; fails, push sign extended lower part first and then overwrite
2361 ;; upper part by 32bit move.
2362 (define_peephole2
2363   [(match_scratch:DI 2 "r")
2364    (set (match_operand:DI 0 "push_operand" "")
2365         (match_operand:DI 1 "immediate_operand" ""))]
2366   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2367    && !x86_64_immediate_operand (operands[1], DImode)"
2368   [(set (match_dup 2) (match_dup 1))
2369    (set (match_dup 0) (match_dup 2))]
2370   "")
2371
2372 ;; We need to define this as both peepholer and splitter for case
2373 ;; peephole2 pass is not run.
2374 ;; "&& 1" is needed to keep it from matching the previous pattern.
2375 (define_peephole2
2376   [(set (match_operand:DI 0 "push_operand" "")
2377         (match_operand:DI 1 "immediate_operand" ""))]
2378   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2379    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2380   [(set (match_dup 0) (match_dup 1))
2381    (set (match_dup 2) (match_dup 3))]
2382   "split_di (&operands[1], 1, &operands[2], &operands[3]);
2383    operands[1] = gen_lowpart (DImode, operands[2]);
2384    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2385                                                     GEN_INT (4)));
2386   ")
2387
2388 (define_split
2389   [(set (match_operand:DI 0 "push_operand" "")
2390         (match_operand:DI 1 "immediate_operand" ""))]
2391   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2392                     ? epilogue_completed : reload_completed)
2393    && !symbolic_operand (operands[1], DImode)
2394    && !x86_64_immediate_operand (operands[1], DImode)"
2395   [(set (match_dup 0) (match_dup 1))
2396    (set (match_dup 2) (match_dup 3))]
2397   "split_di (&operands[1], 1, &operands[2], &operands[3]);
2398    operands[1] = gen_lowpart (DImode, operands[2]);
2399    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2400                                                     GEN_INT (4)));
2401   ")
2402
2403 (define_insn "*pushdi2_prologue_rex64"
2404   [(set (match_operand:DI 0 "push_operand" "=<")
2405         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
2406    (clobber (mem:BLK (scratch)))]
2407   "TARGET_64BIT"
2408   "push{q}\t%1"
2409   [(set_attr "type" "push")
2410    (set_attr "mode" "DI")])
2411
2412 (define_insn "*popdi1_epilogue_rex64"
2413   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2414         (mem:DI (reg:DI SP_REG)))
2415    (set (reg:DI SP_REG)
2416         (plus:DI (reg:DI SP_REG) (const_int 8)))
2417    (clobber (mem:BLK (scratch)))]
2418   "TARGET_64BIT"
2419   "pop{q}\t%0"
2420   [(set_attr "type" "pop")
2421    (set_attr "mode" "DI")])
2422
2423 (define_insn "popdi1"
2424   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2425         (mem:DI (reg:DI SP_REG)))
2426    (set (reg:DI SP_REG)
2427         (plus:DI (reg:DI SP_REG) (const_int 8)))]
2428   "TARGET_64BIT"
2429   "pop{q}\t%0"
2430   [(set_attr "type" "pop")
2431    (set_attr "mode" "DI")])
2432
2433 (define_insn "*movdi_xor_rex64"
2434   [(set (match_operand:DI 0 "register_operand" "=r")
2435         (match_operand:DI 1 "const0_operand" ""))
2436    (clobber (reg:CC FLAGS_REG))]
2437   "TARGET_64BIT
2438    && reload_completed"
2439   "xor{l}\t%k0, %k0";
2440   [(set_attr "type" "alu1")
2441    (set_attr "mode" "SI")
2442    (set_attr "length_immediate" "0")])
2443
2444 (define_insn "*movdi_or_rex64"
2445   [(set (match_operand:DI 0 "register_operand" "=r")
2446         (match_operand:DI 1 "const_int_operand" "i"))
2447    (clobber (reg:CC FLAGS_REG))]
2448   "TARGET_64BIT
2449    && reload_completed
2450    && operands[1] == constm1_rtx"
2451 {
2452   operands[1] = constm1_rtx;
2453   return "or{q}\t{%1, %0|%0, %1}";
2454 }
2455   [(set_attr "type" "alu1")
2456    (set_attr "mode" "DI")
2457    (set_attr "length_immediate" "1")])
2458
2459 (define_insn "*movdi_2"
2460   [(set (match_operand:DI 0 "nonimmediate_operand"
2461                         "=r  ,o  ,*y,m*y,*y,*Y2,m  ,*Y2,*Y2,*x,m ,*x,*x")
2462         (match_operand:DI 1 "general_operand"
2463                         "riFo,riF,C ,*y ,m ,C  ,*Y2,*Y2,m  ,C ,*x,*x,m "))]
2464   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2465   "@
2466    #
2467    #
2468    pxor\t%0, %0
2469    movq\t{%1, %0|%0, %1}
2470    movq\t{%1, %0|%0, %1}
2471    %vpxor\t%0, %d0
2472    %vmovq\t{%1, %0|%0, %1}
2473    %vmovdqa\t{%1, %0|%0, %1}
2474    %vmovq\t{%1, %0|%0, %1}
2475    xorps\t%0, %0
2476    movlps\t{%1, %0|%0, %1}
2477    movaps\t{%1, %0|%0, %1}
2478    movlps\t{%1, %0|%0, %1}"
2479   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2480    (set (attr "prefix")
2481      (if_then_else (eq_attr "alternative" "5,6,7,8")
2482        (const_string "vex")
2483        (const_string "orig")))
2484    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2485
2486 (define_split
2487   [(set (match_operand:DI 0 "push_operand" "")
2488         (match_operand:DI 1 "general_operand" ""))]
2489   "!TARGET_64BIT && reload_completed
2490    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2491   [(const_int 0)]
2492   "ix86_split_long_move (operands); DONE;")
2493
2494 ;; %%% This multiword shite has got to go.
2495 (define_split
2496   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2497         (match_operand:DI 1 "general_operand" ""))]
2498   "!TARGET_64BIT && reload_completed
2499    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2500    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2501   [(const_int 0)]
2502   "ix86_split_long_move (operands); DONE;")
2503
2504 (define_insn "*movdi_1_rex64"
2505   [(set (match_operand:DI 0 "nonimmediate_operand"
2506           "=r,r  ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2507         (match_operand:DI 1 "general_operand"
2508           "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r   ,m  ,C ,*x,*Yi,*x,r  ,m ,*Ym,*x"))]
2509   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2510 {
2511   switch (get_attr_type (insn))
2512     {
2513     case TYPE_SSECVT:
2514       if (SSE_REG_P (operands[0]))
2515         return "movq2dq\t{%1, %0|%0, %1}";
2516       else
2517         return "movdq2q\t{%1, %0|%0, %1}";
2518
2519     case TYPE_SSEMOV:
2520       if (TARGET_AVX)
2521         {
2522           if (get_attr_mode (insn) == MODE_TI)
2523             return "vmovdqa\t{%1, %0|%0, %1}";
2524           else
2525             return "vmovq\t{%1, %0|%0, %1}";
2526         }
2527
2528       if (get_attr_mode (insn) == MODE_TI)
2529         return "movdqa\t{%1, %0|%0, %1}";
2530       /* FALLTHRU */
2531
2532     case TYPE_MMXMOV:
2533       /* Moves from and into integer register is done using movd
2534          opcode with REX prefix.  */
2535       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2536         return "movd\t{%1, %0|%0, %1}";
2537       return "movq\t{%1, %0|%0, %1}";
2538
2539     case TYPE_SSELOG1:
2540       return "%vpxor\t%0, %d0";
2541
2542     case TYPE_MMX:
2543       return "pxor\t%0, %0";
2544
2545     case TYPE_MULTI:
2546       return "#";
2547
2548     case TYPE_LEA:
2549       return "lea{q}\t{%a1, %0|%0, %a1}";
2550
2551     default:
2552       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2553       if (get_attr_mode (insn) == MODE_SI)
2554         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2555       else if (which_alternative == 2)
2556         return "movabs{q}\t{%1, %0|%0, %1}";
2557       else
2558         return "mov{q}\t{%1, %0|%0, %1}";
2559     }
2560 }
2561   [(set (attr "type")
2562      (cond [(eq_attr "alternative" "5")
2563               (const_string "mmx")
2564             (eq_attr "alternative" "6,7,8,9,10")
2565               (const_string "mmxmov")
2566             (eq_attr "alternative" "11")
2567               (const_string "sselog1")
2568             (eq_attr "alternative" "12,13,14,15,16")
2569               (const_string "ssemov")
2570             (eq_attr "alternative" "17,18")
2571               (const_string "ssecvt")
2572             (eq_attr "alternative" "4")
2573               (const_string "multi")
2574             (match_operand:DI 1 "pic_32bit_operand" "")
2575               (const_string "lea")
2576            ]
2577            (const_string "imov")))
2578    (set (attr "modrm")
2579      (if_then_else
2580        (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2581          (const_string "0")
2582          (const_string "*")))
2583    (set (attr "length_immediate")
2584      (if_then_else
2585        (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2586          (const_string "8")
2587          (const_string "*")))
2588    (set_attr "prefix_rex" "*,*,*,*,*,*,*,1,*,1,*,*,*,*,*,*,*,*,*")
2589    (set_attr "prefix_data16" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,1,*,*,*")
2590    (set (attr "prefix")
2591      (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
2592        (const_string "maybe_vex")
2593        (const_string "orig")))
2594    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2595
2596 ;; Stores and loads of ax to arbitrary constant address.
2597 ;; We fake an second form of instruction to force reload to load address
2598 ;; into register when rax is not available
2599 (define_insn "*movabsdi_1_rex64"
2600   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2601         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2602   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2603   "@
2604    movabs{q}\t{%1, %P0|%P0, %1}
2605    mov{q}\t{%1, %a0|%a0, %1}"
2606   [(set_attr "type" "imov")
2607    (set_attr "modrm" "0,*")
2608    (set_attr "length_address" "8,0")
2609    (set_attr "length_immediate" "0,*")
2610    (set_attr "memory" "store")
2611    (set_attr "mode" "DI")])
2612
2613 (define_insn "*movabsdi_2_rex64"
2614   [(set (match_operand:DI 0 "register_operand" "=a,r")
2615         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2616   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2617   "@
2618    movabs{q}\t{%P1, %0|%0, %P1}
2619    mov{q}\t{%a1, %0|%0, %a1}"
2620   [(set_attr "type" "imov")
2621    (set_attr "modrm" "0,*")
2622    (set_attr "length_address" "8,0")
2623    (set_attr "length_immediate" "0")
2624    (set_attr "memory" "load")
2625    (set_attr "mode" "DI")])
2626
2627 ;; Convert impossible stores of immediate to existing instructions.
2628 ;; First try to get scratch register and go through it.  In case this
2629 ;; fails, move by 32bit parts.
2630 (define_peephole2
2631   [(match_scratch:DI 2 "r")
2632    (set (match_operand:DI 0 "memory_operand" "")
2633         (match_operand:DI 1 "immediate_operand" ""))]
2634   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2635    && !x86_64_immediate_operand (operands[1], DImode)"
2636   [(set (match_dup 2) (match_dup 1))
2637    (set (match_dup 0) (match_dup 2))]
2638   "")
2639
2640 ;; We need to define this as both peepholer and splitter for case
2641 ;; peephole2 pass is not run.
2642 ;; "&& 1" is needed to keep it from matching the previous pattern.
2643 (define_peephole2
2644   [(set (match_operand:DI 0 "memory_operand" "")
2645         (match_operand:DI 1 "immediate_operand" ""))]
2646   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2647    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2648   [(set (match_dup 2) (match_dup 3))
2649    (set (match_dup 4) (match_dup 5))]
2650   "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2651
2652 (define_split
2653   [(set (match_operand:DI 0 "memory_operand" "")
2654         (match_operand:DI 1 "immediate_operand" ""))]
2655   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2656                     ? epilogue_completed : reload_completed)
2657    && !symbolic_operand (operands[1], DImode)
2658    && !x86_64_immediate_operand (operands[1], DImode)"
2659   [(set (match_dup 2) (match_dup 3))
2660    (set (match_dup 4) (match_dup 5))]
2661   "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2662
2663 (define_insn "*swapdi_rex64"
2664   [(set (match_operand:DI 0 "register_operand" "+r")
2665         (match_operand:DI 1 "register_operand" "+r"))
2666    (set (match_dup 1)
2667         (match_dup 0))]
2668   "TARGET_64BIT"
2669   "xchg{q}\t%1, %0"
2670   [(set_attr "type" "imov")
2671    (set_attr "mode" "DI")
2672    (set_attr "pent_pair" "np")
2673    (set_attr "athlon_decode" "vector")
2674    (set_attr "amdfam10_decode" "double")])
2675
2676 (define_expand "movoi"
2677   [(set (match_operand:OI 0 "nonimmediate_operand" "")
2678         (match_operand:OI 1 "general_operand" ""))]
2679   "TARGET_AVX"
2680   "ix86_expand_move (OImode, operands); DONE;")
2681
2682 (define_insn "*movoi_internal"
2683   [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
2684         (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
2685   "TARGET_AVX
2686    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2687 {
2688   switch (which_alternative)
2689     {
2690     case 0:
2691       return "vxorps\t%0, %0, %0";
2692     case 1:
2693     case 2:
2694       if (misaligned_operand (operands[0], OImode)
2695           || misaligned_operand (operands[1], OImode))
2696         return "vmovdqu\t{%1, %0|%0, %1}";
2697       else
2698         return "vmovdqa\t{%1, %0|%0, %1}";
2699     default:
2700       gcc_unreachable ();
2701     }
2702 }
2703   [(set_attr "type" "sselog1,ssemov,ssemov")
2704    (set_attr "prefix" "vex")
2705    (set_attr "mode" "OI")])
2706
2707 (define_expand "movti"
2708   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2709         (match_operand:TI 1 "nonimmediate_operand" ""))]
2710   "TARGET_SSE || TARGET_64BIT"
2711 {
2712   if (TARGET_64BIT)
2713     ix86_expand_move (TImode, operands);
2714   else if (push_operand (operands[0], TImode))
2715     ix86_expand_push (TImode, operands[1]);
2716   else
2717     ix86_expand_vector_move (TImode, operands);
2718   DONE;
2719 })
2720
2721 (define_insn "*movti_internal"
2722   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2723         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2724   "TARGET_SSE && !TARGET_64BIT
2725    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2726 {
2727   switch (which_alternative)
2728     {
2729     case 0:
2730       if (get_attr_mode (insn) == MODE_V4SF)
2731         return "%vxorps\t%0, %d0";
2732       else
2733         return "%vpxor\t%0, %d0";
2734     case 1:
2735     case 2:
2736       /* TDmode values are passed as TImode on the stack.  Moving them
2737          to stack may result in unaligned memory access.  */
2738       if (misaligned_operand (operands[0], TImode)
2739           || misaligned_operand (operands[1], TImode))
2740         {
2741           if (get_attr_mode (insn) == MODE_V4SF)
2742             return "%vmovups\t{%1, %0|%0, %1}";
2743          else
2744            return "%vmovdqu\t{%1, %0|%0, %1}";
2745         }
2746       else
2747         {
2748           if (get_attr_mode (insn) == MODE_V4SF)
2749             return "%vmovaps\t{%1, %0|%0, %1}";
2750          else
2751            return "%vmovdqa\t{%1, %0|%0, %1}";
2752         }
2753     default:
2754       gcc_unreachable ();
2755     }
2756 }
2757   [(set_attr "type" "sselog1,ssemov,ssemov")
2758    (set_attr "prefix" "maybe_vex")
2759    (set (attr "mode")
2760         (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2761                     (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0)))
2762                  (const_string "V4SF")
2763                (and (eq_attr "alternative" "2")
2764                     (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2765                         (const_int 0)))
2766                  (const_string "V4SF")]
2767               (const_string "TI")))])
2768
2769 (define_insn "*movti_rex64"
2770   [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
2771         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2772   "TARGET_64BIT
2773    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2774 {
2775   switch (which_alternative)
2776     {
2777     case 0:
2778     case 1:
2779       return "#";
2780     case 2:
2781       if (get_attr_mode (insn) == MODE_V4SF)
2782         return "%vxorps\t%0, %d0";
2783       else
2784         return "%vpxor\t%0, %d0";
2785     case 3:
2786     case 4:
2787       /* TDmode values are passed as TImode on the stack.  Moving them
2788          to stack may result in unaligned memory access.  */
2789       if (misaligned_operand (operands[0], TImode)
2790           || misaligned_operand (operands[1], TImode))
2791         {
2792           if (get_attr_mode (insn) == MODE_V4SF)
2793             return "%vmovups\t{%1, %0|%0, %1}";
2794          else
2795            return "%vmovdqu\t{%1, %0|%0, %1}";
2796         }
2797       else
2798         {
2799           if (get_attr_mode (insn) == MODE_V4SF)
2800             return "%vmovaps\t{%1, %0|%0, %1}";
2801          else
2802            return "%vmovdqa\t{%1, %0|%0, %1}";
2803         }
2804     default:
2805       gcc_unreachable ();
2806     }
2807 }
2808   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2809    (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
2810    (set (attr "mode")
2811         (cond [(eq_attr "alternative" "2,3")
2812                  (if_then_else
2813                    (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2814                        (const_int 0))
2815                    (const_string "V4SF")
2816                    (const_string "TI"))
2817                (eq_attr "alternative" "4")
2818                  (if_then_else
2819                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2820                             (const_int 0))
2821                         (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2822                             (const_int 0)))
2823                    (const_string "V4SF")
2824                    (const_string "TI"))]
2825                (const_string "DI")))])
2826
2827 (define_split
2828   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2829         (match_operand:TI 1 "general_operand" ""))]
2830   "reload_completed && !SSE_REG_P (operands[0])
2831    && !SSE_REG_P (operands[1])"
2832   [(const_int 0)]
2833   "ix86_split_long_move (operands); DONE;")
2834
2835 ;; This expands to what emit_move_complex would generate if we didn't
2836 ;; have a movti pattern.  Having this avoids problems with reload on
2837 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2838 ;; to have around all the time.
2839 (define_expand "movcdi"
2840   [(set (match_operand:CDI 0 "nonimmediate_operand" "")
2841         (match_operand:CDI 1 "general_operand" ""))]
2842   ""
2843 {
2844   if (push_operand (operands[0], CDImode))
2845     emit_move_complex_push (CDImode, operands[0], operands[1]);
2846   else
2847     emit_move_complex_parts (operands[0], operands[1]);
2848   DONE;
2849 })
2850
2851 (define_expand "movsf"
2852   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2853         (match_operand:SF 1 "general_operand" ""))]
2854   ""
2855   "ix86_expand_move (SFmode, operands); DONE;")
2856
2857 (define_insn "*pushsf"
2858   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2859         (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2860   "!TARGET_64BIT"
2861 {
2862   /* Anything else should be already split before reg-stack.  */
2863   gcc_assert (which_alternative == 1);
2864   return "push{l}\t%1";
2865 }
2866   [(set_attr "type" "multi,push,multi")
2867    (set_attr "unit" "i387,*,*")
2868    (set_attr "mode" "SF,SI,SF")])
2869
2870 (define_insn "*pushsf_rex64"
2871   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2872         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2873   "TARGET_64BIT"
2874 {
2875   /* Anything else should be already split before reg-stack.  */
2876   gcc_assert (which_alternative == 1);
2877   return "push{q}\t%q1";
2878 }
2879   [(set_attr "type" "multi,push,multi")
2880    (set_attr "unit" "i387,*,*")
2881    (set_attr "mode" "SF,DI,SF")])
2882
2883 (define_split
2884   [(set (match_operand:SF 0 "push_operand" "")
2885         (match_operand:SF 1 "memory_operand" ""))]
2886   "reload_completed
2887    && MEM_P (operands[1])
2888    && (operands[2] = find_constant_src (insn))"
2889   [(set (match_dup 0)
2890         (match_dup 2))])
2891
2892 ;; %%% Kill this when call knows how to work this out.
2893 (define_split
2894   [(set (match_operand:SF 0 "push_operand" "")
2895         (match_operand:SF 1 "any_fp_register_operand" ""))]
2896   "!TARGET_64BIT"
2897   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2898    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2899
2900 (define_split
2901   [(set (match_operand:SF 0 "push_operand" "")
2902         (match_operand:SF 1 "any_fp_register_operand" ""))]
2903   "TARGET_64BIT"
2904   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2905    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2906
2907 (define_insn "*movsf_1"
2908   [(set (match_operand:SF 0 "nonimmediate_operand"
2909           "=f,m,f,r  ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
2910         (match_operand:SF 1 "general_operand"
2911           "fm,f,G,rmF,Fr,C,x,xm,x,m  ,*y,*y ,r  ,Yi,r   ,*Ym"))]
2912   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2913    && (reload_in_progress || reload_completed
2914        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2915        || (!TARGET_SSE_MATH && optimize_function_for_size_p (cfun)
2916            && standard_80387_constant_p (operands[1]))
2917        || GET_CODE (operands[1]) != CONST_DOUBLE
2918        || memory_operand (operands[0], SFmode))"
2919 {
2920   switch (which_alternative)
2921     {
2922     case 0:
2923     case 1:
2924       return output_387_reg_move (insn, operands);
2925
2926     case 2:
2927       return standard_80387_constant_opcode (operands[1]);
2928
2929     case 3:
2930     case 4:
2931       return "mov{l}\t{%1, %0|%0, %1}";
2932     case 5:
2933       if (get_attr_mode (insn) == MODE_TI)
2934         return "%vpxor\t%0, %d0";
2935       else
2936         return "%vxorps\t%0, %d0";
2937     case 6:
2938       if (get_attr_mode (insn) == MODE_V4SF)
2939         return "%vmovaps\t{%1, %0|%0, %1}";
2940       else
2941         return "%vmovss\t{%1, %d0|%d0, %1}";
2942     case 7:
2943       if (TARGET_AVX)
2944         return REG_P (operands[1]) ? "vmovss\t{%1, %0, %0|%0, %0, %1}"
2945                                    : "vmovss\t{%1, %0|%0, %1}";
2946       else
2947         return "movss\t{%1, %0|%0, %1}";
2948     case 8:
2949       return "%vmovss\t{%1, %0|%0, %1}";
2950
2951     case 9: case 10: case 14: case 15:
2952       return "movd\t{%1, %0|%0, %1}";
2953     case 12: case 13:
2954       return "%vmovd\t{%1, %0|%0, %1}";
2955
2956     case 11:
2957       return "movq\t{%1, %0|%0, %1}";
2958
2959     default:
2960       gcc_unreachable ();
2961     }
2962 }
2963   [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2964    (set (attr "prefix")
2965      (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
2966        (const_string "maybe_vex")
2967        (const_string "orig")))
2968    (set (attr "mode")
2969         (cond [(eq_attr "alternative" "3,4,9,10")
2970                  (const_string "SI")
2971                (eq_attr "alternative" "5")
2972                  (if_then_else
2973                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2974                                  (const_int 0))
2975                              (ne (symbol_ref "TARGET_SSE2")
2976                                  (const_int 0)))
2977                         (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2978                             (const_int 0)))
2979                    (const_string "TI")
2980                    (const_string "V4SF"))
2981                /* For architectures resolving dependencies on
2982                   whole SSE registers use APS move to break dependency
2983                   chains, otherwise use short move to avoid extra work.
2984
2985                   Do the same for architectures resolving dependencies on
2986                   the parts.  While in DF mode it is better to always handle
2987                   just register parts, the SF mode is different due to lack
2988                   of instructions to load just part of the register.  It is
2989                   better to maintain the whole registers in single format
2990                   to avoid problems on using packed logical operations.  */
2991                (eq_attr "alternative" "6")
2992                  (if_then_else
2993                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2994                             (const_int 0))
2995                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2996                             (const_int 0)))
2997                    (const_string "V4SF")
2998                    (const_string "SF"))
2999                (eq_attr "alternative" "11")
3000                  (const_string "DI")]
3001                (const_string "SF")))])
3002
3003 (define_insn "*swapsf"
3004   [(set (match_operand:SF 0 "fp_register_operand" "+f")
3005         (match_operand:SF 1 "fp_register_operand" "+f"))
3006    (set (match_dup 1)
3007         (match_dup 0))]
3008   "reload_completed || TARGET_80387"
3009 {
3010   if (STACK_TOP_P (operands[0]))
3011     return "fxch\t%1";
3012   else
3013     return "fxch\t%0";
3014 }
3015   [(set_attr "type" "fxch")
3016    (set_attr "mode" "SF")])
3017
3018 (define_expand "movdf"
3019   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3020         (match_operand:DF 1 "general_operand" ""))]
3021   ""
3022   "ix86_expand_move (DFmode, operands); DONE;")
3023
3024 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3025 ;; Size of pushdf using integer instructions is 2+2*memory operand size
3026 ;; On the average, pushdf using integers can be still shorter.  Allow this
3027 ;; pattern for optimize_size too.
3028
3029 (define_insn "*pushdf_nointeger"
3030   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
3031         (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
3032   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
3033 {
3034   /* This insn should be already split before reg-stack.  */
3035   gcc_unreachable ();
3036 }
3037   [(set_attr "type" "multi")
3038    (set_attr "unit" "i387,*,*,*")
3039    (set_attr "mode" "DF,SI,SI,DF")])
3040
3041 (define_insn "*pushdf_integer"
3042   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
3043         (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
3044   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
3045 {
3046   /* This insn should be already split before reg-stack.  */
3047   gcc_unreachable ();
3048 }
3049   [(set_attr "type" "multi")
3050    (set_attr "unit" "i387,*,*")
3051    (set_attr "mode" "DF,SI,DF")])
3052
3053 ;; %%% Kill this when call knows how to work this out.
3054 (define_split
3055   [(set (match_operand:DF 0 "push_operand" "")
3056         (match_operand:DF 1 "any_fp_register_operand" ""))]
3057   "reload_completed"
3058   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3059    (set (mem:DF (reg:P SP_REG)) (match_dup 1))]
3060   "")
3061
3062 (define_split
3063   [(set (match_operand:DF 0 "push_operand" "")
3064         (match_operand:DF 1 "general_operand" ""))]
3065   "reload_completed"
3066   [(const_int 0)]
3067   "ix86_split_long_move (operands); DONE;")
3068
3069 ;; Moving is usually shorter when only FP registers are used. This separate
3070 ;; movdf pattern avoids the use of integer registers for FP operations
3071 ;; when optimizing for size.
3072
3073 (define_insn "*movdf_nointeger"
3074   [(set (match_operand:DF 0 "nonimmediate_operand"
3075                         "=f,m,f,*r  ,o  ,Y2*x,Y2*x,Y2*x ,m  ")
3076         (match_operand:DF 1 "general_operand"
3077                         "fm,f,G,*roF,*Fr,C   ,Y2*x,mY2*x,Y2*x"))]
3078   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3079    && ((optimize_function_for_size_p (cfun)
3080        || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
3081    && (reload_in_progress || reload_completed
3082        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3083        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3084            && optimize_function_for_size_p (cfun)
3085            && !memory_operand (operands[0], DFmode)
3086            && standard_80387_constant_p (operands[1]))
3087        || GET_CODE (operands[1]) != CONST_DOUBLE
3088        || ((optimize_function_for_size_p (cfun)
3089             || !TARGET_MEMORY_MISMATCH_STALL
3090             || reload_in_progress || reload_completed)
3091            && memory_operand (operands[0], DFmode)))"
3092 {
3093   switch (which_alternative)
3094     {
3095     case 0:
3096     case 1:
3097       return output_387_reg_move (insn, operands);
3098
3099     case 2:
3100       return standard_80387_constant_opcode (operands[1]);
3101
3102     case 3:
3103     case 4:
3104       return "#";
3105     case 5:
3106       switch (get_attr_mode (insn))
3107         {
3108         case MODE_V4SF:
3109           return "%vxorps\t%0, %d0";
3110         case MODE_V2DF:
3111           return "%vxorpd\t%0, %d0";
3112         case MODE_TI:
3113           return "%vpxor\t%0, %d0";
3114         default:
3115           gcc_unreachable ();
3116         }
3117     case 6:
3118     case 7:
3119     case 8:
3120       switch (get_attr_mode (insn))
3121         {
3122         case MODE_V4SF:
3123           return "%vmovaps\t{%1, %0|%0, %1}";
3124         case MODE_V2DF:
3125           return "%vmovapd\t{%1, %0|%0, %1}";
3126         case MODE_TI:
3127           return "%vmovdqa\t{%1, %0|%0, %1}";
3128         case MODE_DI:
3129           return "%vmovq\t{%1, %0|%0, %1}";
3130         case MODE_DF:
3131           if (TARGET_AVX)
3132             {
3133               if (REG_P (operands[0]) && REG_P (operands[1]))
3134                 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3135               else
3136                 return "vmovsd\t{%1, %0|%0, %1}";
3137             }
3138           else
3139             return "movsd\t{%1, %0|%0, %1}";
3140         case MODE_V1DF:
3141           if (TARGET_AVX)
3142             {
3143               if (REG_P (operands[0]))
3144                 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
3145               else
3146                 return "vmovlpd\t{%1, %0|%0, %1}";
3147             }
3148           else
3149             return "movlpd\t{%1, %0|%0, %1}";
3150         case MODE_V2SF:
3151           if (TARGET_AVX)
3152             {
3153               if (REG_P (operands[0]))
3154                 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
3155               else
3156                 return "vmovlps\t{%1, %0|%0, %1}";
3157             }
3158           else
3159             return "movlps\t{%1, %0|%0, %1}";
3160         default:
3161           gcc_unreachable ();
3162         }
3163
3164     default:
3165       gcc_unreachable ();
3166     }
3167 }
3168   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3169    (set (attr "prefix")
3170      (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3171        (const_string "orig")
3172        (const_string "maybe_vex")))
3173    (set (attr "prefix_data16")
3174      (if_then_else (eq_attr "mode" "V1DF")
3175        (const_string "1")
3176        (const_string "*")))
3177    (set (attr "mode")
3178         (cond [(eq_attr "alternative" "0,1,2")
3179                  (const_string "DF")
3180                (eq_attr "alternative" "3,4")
3181                  (const_string "SI")
3182
3183                /* For SSE1, we have many fewer alternatives.  */
3184                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3185                  (cond [(eq_attr "alternative" "5,6")
3186                           (const_string "V4SF")
3187                        ]
3188                    (const_string "V2SF"))
3189
3190                /* xorps is one byte shorter.  */
3191                (eq_attr "alternative" "5")
3192                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3193                             (const_int 0))
3194                           (const_string "V4SF")
3195                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3196                             (const_int 0))
3197                           (const_string "TI")
3198                        ]
3199                        (const_string "V2DF"))
3200
3201                /* For architectures resolving dependencies on
3202                   whole SSE registers use APD move to break dependency
3203                   chains, otherwise use short move to avoid extra work.
3204
3205                   movaps encodes one byte shorter.  */
3206                (eq_attr "alternative" "6")
3207                  (cond
3208                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3209                         (const_int 0))
3210                       (const_string "V4SF")
3211                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3212                         (const_int 0))
3213                       (const_string "V2DF")
3214                    ]
3215                    (const_string "DF"))
3216                /* For architectures resolving dependencies on register
3217                   parts we may avoid extra work to zero out upper part
3218                   of register.  */
3219                (eq_attr "alternative" "7")
3220                  (if_then_else
3221                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3222                        (const_int 0))
3223                    (const_string "V1DF")
3224                    (const_string "DF"))
3225               ]
3226               (const_string "DF")))])
3227
3228 (define_insn "*movdf_integer_rex64"
3229   [(set (match_operand:DF 0 "nonimmediate_operand"
3230                 "=f,m,f,r  ,m ,Y2*x,Y2*x,Y2*x,m   ,Yi,r ")
3231         (match_operand:DF 1 "general_operand"
3232                 "fm,f,G,rmF,Fr,C   ,Y2*x,m   ,Y2*x,r ,Yi"))]
3233   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3234    && (reload_in_progress || reload_completed
3235        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3236        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3237            && optimize_function_for_size_p (cfun)
3238            && standard_80387_constant_p (operands[1]))
3239        || GET_CODE (operands[1]) != CONST_DOUBLE
3240        || memory_operand (operands[0], DFmode))"
3241 {
3242   switch (which_alternative)
3243     {
3244     case 0:
3245     case 1:
3246       return output_387_reg_move (insn, operands);
3247
3248     case 2:
3249       return standard_80387_constant_opcode (operands[1]);
3250
3251     case 3:
3252     case 4:
3253       return "#";
3254
3255     case 5:
3256       switch (get_attr_mode (insn))
3257         {
3258         case MODE_V4SF:
3259           return "%vxorps\t%0, %d0";
3260         case MODE_V2DF:
3261           return "%vxorpd\t%0, %d0";
3262         case MODE_TI:
3263           return "%vpxor\t%0, %d0";
3264         default:
3265           gcc_unreachable ();
3266         }
3267     case 6:
3268     case 7:
3269     case 8:
3270       switch (get_attr_mode (insn))
3271         {
3272         case MODE_V4SF:
3273           return "%vmovaps\t{%1, %0|%0, %1}";
3274         case MODE_V2DF:
3275           return "%vmovapd\t{%1, %0|%0, %1}";
3276         case MODE_TI:
3277           return "%vmovdqa\t{%1, %0|%0, %1}";
3278         case MODE_DI:
3279           return "%vmovq\t{%1, %0|%0, %1}";
3280         case MODE_DF:
3281           if (TARGET_AVX)
3282             {
3283               if (REG_P (operands[0]) && REG_P (operands[1]))
3284                 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3285               else
3286                 return "vmovsd\t{%1, %0|%0, %1}";
3287             }
3288           else
3289             return "movsd\t{%1, %0|%0, %1}";
3290         case MODE_V1DF:
3291           return "%vmovlpd\t{%1, %d0|%d0, %1}";
3292         case MODE_V2SF:
3293           return "%vmovlps\t{%1, %d0|%d0, %1}";
3294         default:
3295           gcc_unreachable ();
3296         }
3297
3298     case 9:
3299     case 10:
3300     return "%vmovd\t{%1, %0|%0, %1}";
3301
3302     default:
3303       gcc_unreachable();
3304     }
3305 }
3306   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
3307    (set (attr "prefix")
3308      (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3309        (const_string "orig")
3310        (const_string "maybe_vex")))
3311    (set (attr "prefix_data16")
3312      (if_then_else (eq_attr "mode" "V1DF")
3313        (const_string "1")
3314        (const_string "*")))
3315    (set (attr "mode")
3316         (cond [(eq_attr "alternative" "0,1,2")
3317                  (const_string "DF")
3318                (eq_attr "alternative" "3,4,9,10")
3319                  (const_string "DI")
3320
3321                /* For SSE1, we have many fewer alternatives.  */
3322                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3323                  (cond [(eq_attr "alternative" "5,6")
3324                           (const_string "V4SF")
3325                        ]
3326                    (const_string "V2SF"))
3327
3328                /* xorps is one byte shorter.  */
3329                (eq_attr "alternative" "5")
3330                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3331                             (const_int 0))
3332                           (const_string "V4SF")
3333                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3334                             (const_int 0))
3335                           (const_string "TI")
3336                        ]
3337                        (const_string "V2DF"))
3338
3339                /* For architectures resolving dependencies on
3340                   whole SSE registers use APD move to break dependency
3341                   chains, otherwise use short move to avoid extra work.
3342
3343                   movaps encodes one byte shorter.  */
3344                (eq_attr "alternative" "6")
3345                  (cond
3346                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3347                         (const_int 0))
3348                       (const_string "V4SF")
3349                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3350                         (const_int 0))
3351                       (const_string "V2DF")
3352                    ]
3353                    (const_string "DF"))
3354                /* For architectures resolving dependencies on register
3355                   parts we may avoid extra work to zero out upper part
3356                   of register.  */
3357                (eq_attr "alternative" "7")
3358                  (if_then_else
3359                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3360                        (const_int 0))
3361                    (const_string "V1DF")
3362                    (const_string "DF"))
3363               ]
3364               (const_string "DF")))])
3365
3366 (define_insn "*movdf_integer"
3367   [(set (match_operand:DF 0 "nonimmediate_operand"
3368                 "=f,m,f,r  ,o ,Y2*x,Y2*x,Y2*x,m   ")
3369         (match_operand:DF 1 "general_operand"
3370                 "fm,f,G,roF,Fr,C   ,Y2*x,m   ,Y2*x"))]
3371   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3372    && optimize_function_for_speed_p (cfun)
3373    && TARGET_INTEGER_DFMODE_MOVES
3374    && (reload_in_progress || reload_completed
3375        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3376        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3377            && optimize_function_for_size_p (cfun)
3378            && standard_80387_constant_p (operands[1]))
3379        || GET_CODE (operands[1]) != CONST_DOUBLE
3380        || memory_operand (operands[0], DFmode))"
3381 {
3382   switch (which_alternative)
3383     {
3384     case 0:
3385     case 1:
3386       return output_387_reg_move (insn, operands);
3387
3388     case 2:
3389       return standard_80387_constant_opcode (operands[1]);
3390
3391     case 3:
3392     case 4:
3393       return "#";
3394
3395     case 5:
3396       switch (get_attr_mode (insn))
3397         {
3398         case MODE_V4SF:
3399           return "xorps\t%0, %0";
3400         case MODE_V2DF:
3401           return "xorpd\t%0, %0";
3402         case MODE_TI:
3403           return "pxor\t%0, %0";
3404         default:
3405           gcc_unreachable ();
3406         }
3407     case 6:
3408     case 7:
3409     case 8:
3410       switch (get_attr_mode (insn))
3411         {
3412         case MODE_V4SF:
3413           return "movaps\t{%1, %0|%0, %1}";
3414         case MODE_V2DF:
3415           return "movapd\t{%1, %0|%0, %1}";
3416         case MODE_TI:
3417           return "movdqa\t{%1, %0|%0, %1}";
3418         case MODE_DI:
3419           return "movq\t{%1, %0|%0, %1}";
3420         case MODE_DF:
3421           return "movsd\t{%1, %0|%0, %1}";
3422         case MODE_V1DF:
3423           return "movlpd\t{%1, %0|%0, %1}";
3424         case MODE_V2SF:
3425           return "movlps\t{%1, %0|%0, %1}";
3426         default:
3427           gcc_unreachable ();
3428         }
3429
3430     default:
3431       gcc_unreachable();
3432     }
3433 }
3434   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3435    (set (attr "prefix_data16")
3436      (if_then_else (eq_attr "mode" "V1DF")
3437        (const_string "1")
3438        (const_string "*")))
3439    (set (attr "mode")
3440         (cond [(eq_attr "alternative" "0,1,2")
3441                  (const_string "DF")
3442                (eq_attr "alternative" "3,4")
3443                  (const_string "SI")
3444
3445                /* For SSE1, we have many fewer alternatives.  */
3446                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3447                  (cond [(eq_attr "alternative" "5,6")
3448                           (const_string "V4SF")
3449                        ]
3450                    (const_string "V2SF"))
3451
3452                /* xorps is one byte shorter.  */
3453                (eq_attr "alternative" "5")
3454                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3455                             (const_int 0))
3456                           (const_string "V4SF")
3457                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3458                             (const_int 0))
3459                           (const_string "TI")
3460                        ]
3461                        (const_string "V2DF"))
3462
3463                /* For architectures resolving dependencies on
3464                   whole SSE registers use APD move to break dependency
3465                   chains, otherwise use short move to avoid extra work.
3466
3467                   movaps encodes one byte shorter.  */
3468                (eq_attr "alternative" "6")
3469                  (cond
3470                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3471                         (const_int 0))
3472                       (const_string "V4SF")
3473                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3474                         (const_int 0))
3475                       (const_string "V2DF")
3476                    ]
3477                    (const_string "DF"))
3478                /* For architectures resolving dependencies on register
3479                   parts we may avoid extra work to zero out upper part
3480                   of register.  */
3481                (eq_attr "alternative" "7")
3482                  (if_then_else
3483                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3484                        (const_int 0))
3485                    (const_string "V1DF")
3486                    (const_string "DF"))
3487               ]
3488               (const_string "DF")))])
3489
3490 (define_split
3491   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3492         (match_operand:DF 1 "general_operand" ""))]
3493   "reload_completed
3494    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3495    && ! (ANY_FP_REG_P (operands[0]) ||
3496          (GET_CODE (operands[0]) == SUBREG
3497           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3498    && ! (ANY_FP_REG_P (operands[1]) ||
3499          (GET_CODE (operands[1]) == SUBREG
3500           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3501   [(const_int 0)]
3502   "ix86_split_long_move (operands); DONE;")
3503
3504 (define_insn "*swapdf"
3505   [(set (match_operand:DF 0 "fp_register_operand" "+f")
3506         (match_operand:DF 1 "fp_register_operand" "+f"))
3507    (set (match_dup 1)
3508         (match_dup 0))]
3509   "reload_completed || TARGET_80387"
3510 {
3511   if (STACK_TOP_P (operands[0]))
3512     return "fxch\t%1";
3513   else
3514     return "fxch\t%0";
3515 }
3516   [(set_attr "type" "fxch")
3517    (set_attr "mode" "DF")])
3518
3519 (define_expand "movxf"
3520   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3521         (match_operand:XF 1 "general_operand" ""))]
3522   ""
3523   "ix86_expand_move (XFmode, operands); DONE;")
3524
3525 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3526 ;; Size of pushdf using integer instructions is 3+3*memory operand size
3527 ;; Pushing using integer instructions is longer except for constants
3528 ;; and direct memory references.
3529 ;; (assuming that any given constant is pushed only once, but this ought to be
3530 ;;  handled elsewhere).
3531
3532 (define_insn "*pushxf_nointeger"
3533   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
3534         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
3535   "optimize_function_for_size_p (cfun)"
3536 {
3537   /* This insn should be already split before reg-stack.  */
3538   gcc_unreachable ();
3539 }
3540   [(set_attr "type" "multi")
3541    (set_attr "unit" "i387,*,*")
3542    (set_attr "mode" "XF,SI,SI")])
3543
3544 (define_insn "*pushxf_integer"
3545   [(set (match_operand:XF 0 "push_operand" "=<,<")
3546         (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
3547   "optimize_function_for_speed_p (cfun)"
3548 {
3549   /* This insn should be already split before reg-stack.  */
3550   gcc_unreachable ();
3551 }
3552   [(set_attr "type" "multi")
3553    (set_attr "unit" "i387,*")
3554    (set_attr "mode" "XF,SI")])
3555
3556 (define_split
3557   [(set (match_operand 0 "push_operand" "")
3558         (match_operand 1 "general_operand" ""))]
3559   "reload_completed
3560    && (GET_MODE (operands[0]) == XFmode
3561        || GET_MODE (operands[0]) == DFmode)
3562    && !ANY_FP_REG_P (operands[1])"
3563   [(const_int 0)]
3564   "ix86_split_long_move (operands); DONE;")
3565
3566 (define_split
3567   [(set (match_operand:XF 0 "push_operand" "")
3568         (match_operand:XF 1 "any_fp_register_operand" ""))]
3569   ""
3570   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3571    (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
3572   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3573
3574 ;; Do not use integer registers when optimizing for size
3575 (define_insn "*movxf_nointeger"
3576   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3577         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3578   "optimize_function_for_size_p (cfun)
3579    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3580    && (reload_in_progress || reload_completed
3581        || standard_80387_constant_p (operands[1])
3582        || GET_CODE (operands[1]) != CONST_DOUBLE
3583        || memory_operand (operands[0], XFmode))"
3584 {
3585   switch (which_alternative)
3586     {
3587     case 0:
3588     case 1:
3589       return output_387_reg_move (insn, operands);
3590
3591     case 2:
3592       return standard_80387_constant_opcode (operands[1]);
3593
3594     case 3: case 4:
3595       return "#";
3596     default:
3597       gcc_unreachable ();
3598     }
3599 }
3600   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3601    (set_attr "mode" "XF,XF,XF,SI,SI")])
3602
3603 (define_insn "*movxf_integer"
3604   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
3605         (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
3606   "optimize_function_for_speed_p (cfun)
3607    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3608    && (reload_in_progress || reload_completed
3609        || GET_CODE (operands[1]) != CONST_DOUBLE
3610        || memory_operand (operands[0], XFmode))"
3611 {
3612   switch (which_alternative)
3613     {
3614     case 0:
3615     case 1:
3616       return output_387_reg_move (insn, operands);
3617
3618     case 2:
3619       return standard_80387_constant_opcode (operands[1]);
3620
3621     case 3: case 4:
3622       return "#";
3623
3624     default:
3625       gcc_unreachable ();
3626     }
3627 }
3628   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3629    (set_attr "mode" "XF,XF,XF,SI,SI")])
3630
3631 (define_expand "movtf"
3632   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3633         (match_operand:TF 1 "nonimmediate_operand" ""))]
3634   "TARGET_SSE2"
3635 {
3636   ix86_expand_move (TFmode, operands);
3637   DONE;
3638 })
3639
3640 (define_insn "*movtf_internal"
3641   [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
3642         (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
3643   "TARGET_SSE2
3644    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3645 {
3646   switch (which_alternative)
3647     {
3648     case 0:
3649     case 1:
3650       if (get_attr_mode (insn) == MODE_V4SF)
3651         return "%vmovaps\t{%1, %0|%0, %1}";
3652       else
3653         return "%vmovdqa\t{%1, %0|%0, %1}";
3654     case 2:
3655       if (get_attr_mode (insn) == MODE_V4SF)
3656         return "%vxorps\t%0, %d0";
3657       else
3658         return "%vpxor\t%0, %d0";
3659     case 3:
3660     case 4:
3661         return "#";
3662     default:
3663       gcc_unreachable ();
3664     }
3665 }
3666   [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
3667    (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
3668    (set (attr "mode")
3669         (cond [(eq_attr "alternative" "0,2")
3670                  (if_then_else
3671                    (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3672                        (const_int 0))
3673                    (const_string "V4SF")
3674                    (const_string "TI"))
3675                (eq_attr "alternative" "1")
3676                  (if_then_else
3677                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3678                             (const_int 0))
3679                         (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3680                             (const_int 0)))
3681                    (const_string "V4SF")
3682                    (const_string "TI"))]
3683                (const_string "DI")))])
3684
3685 (define_insn "*pushtf_sse"
3686   [(set (match_operand:TF 0 "push_operand" "=<,<,<")
3687         (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
3688   "TARGET_SSE2"
3689 {
3690   /* This insn should be already split before reg-stack.  */
3691   gcc_unreachable ();
3692 }
3693   [(set_attr "type" "multi")
3694    (set_attr "unit" "sse,*,*")
3695    (set_attr "mode" "TF,SI,SI")])
3696
3697 (define_split
3698   [(set (match_operand:TF 0 "push_operand" "")
3699         (match_operand:TF 1 "general_operand" ""))]
3700   "TARGET_SSE2 && reload_completed
3701    && !SSE_REG_P (operands[1])"
3702   [(const_int 0)]
3703   "ix86_split_long_move (operands); DONE;")
3704
3705 (define_split
3706   [(set (match_operand:TF 0 "push_operand" "")
3707         (match_operand:TF 1 "any_fp_register_operand" ""))]
3708   "TARGET_SSE2"
3709   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3710    (set (mem:TF (reg:P SP_REG)) (match_dup 1))]
3711   "")
3712
3713 (define_split
3714   [(set (match_operand 0 "nonimmediate_operand" "")
3715         (match_operand 1 "general_operand" ""))]
3716   "reload_completed
3717    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3718    && GET_MODE (operands[0]) == XFmode
3719    && ! (ANY_FP_REG_P (operands[0]) ||
3720          (GET_CODE (operands[0]) == SUBREG
3721           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3722    && ! (ANY_FP_REG_P (operands[1]) ||
3723          (GET_CODE (operands[1]) == SUBREG
3724           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3725   [(const_int 0)]
3726   "ix86_split_long_move (operands); DONE;")
3727
3728 (define_split
3729   [(set (match_operand 0 "register_operand" "")
3730         (match_operand 1 "memory_operand" ""))]
3731   "reload_completed
3732    && MEM_P (operands[1])
3733    && (GET_MODE (operands[0]) == TFmode
3734        || GET_MODE (operands[0]) == XFmode
3735        || GET_MODE (operands[0]) == SFmode
3736        || GET_MODE (operands[0]) == DFmode)
3737    && (operands[2] = find_constant_src (insn))"
3738   [(set (match_dup 0) (match_dup 2))]
3739 {
3740   rtx c = operands[2];
3741   rtx r = operands[0];
3742
3743   if (GET_CODE (r) == SUBREG)
3744     r = SUBREG_REG (r);
3745
3746   if (SSE_REG_P (r))
3747     {
3748       if (!standard_sse_constant_p (c))
3749         FAIL;
3750     }
3751   else if (FP_REG_P (r))
3752     {
3753       if (!standard_80387_constant_p (c))
3754         FAIL;
3755     }
3756   else if (MMX_REG_P (r))
3757     FAIL;
3758 })
3759
3760 (define_split
3761   [(set (match_operand 0 "register_operand" "")
3762         (float_extend (match_operand 1 "memory_operand" "")))]
3763   "reload_completed
3764    && MEM_P (operands[1])
3765    && (GET_MODE (operands[0]) == TFmode
3766        || GET_MODE (operands[0]) == XFmode
3767        || GET_MODE (operands[0]) == SFmode
3768        || GET_MODE (operands[0]) == DFmode)
3769    && (operands[2] = find_constant_src (insn))"
3770   [(set (match_dup 0) (match_dup 2))]
3771 {
3772   rtx c = operands[2];
3773   rtx r = operands[0];
3774
3775   if (GET_CODE (r) == SUBREG)
3776     r = SUBREG_REG (r);
3777
3778   if (SSE_REG_P (r))
3779     {
3780       if (!standard_sse_constant_p (c))
3781         FAIL;
3782     }
3783   else if (FP_REG_P (r))
3784     {
3785       if (!standard_80387_constant_p (c))
3786         FAIL;
3787     }
3788   else if (MMX_REG_P (r))
3789     FAIL;
3790 })
3791
3792 (define_insn "swapxf"
3793   [(set (match_operand:XF 0 "register_operand" "+f")
3794         (match_operand:XF 1 "register_operand" "+f"))
3795    (set (match_dup 1)
3796         (match_dup 0))]
3797   "TARGET_80387"
3798 {
3799   if (STACK_TOP_P (operands[0]))
3800     return "fxch\t%1";
3801   else
3802     return "fxch\t%0";
3803 }
3804   [(set_attr "type" "fxch")
3805    (set_attr "mode" "XF")])
3806
3807 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3808 (define_split
3809   [(set (match_operand:X87MODEF 0 "register_operand" "")
3810         (match_operand:X87MODEF 1 "immediate_operand" ""))]
3811   "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3812    && (standard_80387_constant_p (operands[1]) == 8
3813        || standard_80387_constant_p (operands[1]) == 9)"
3814   [(set (match_dup 0)(match_dup 1))
3815    (set (match_dup 0)
3816         (neg:X87MODEF (match_dup 0)))]
3817 {
3818   REAL_VALUE_TYPE r;
3819
3820   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3821   if (real_isnegzero (&r))
3822     operands[1] = CONST0_RTX (<MODE>mode);
3823   else
3824     operands[1] = CONST1_RTX (<MODE>mode);
3825 })
3826
3827 (define_split
3828   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3829         (match_operand:TF 1 "general_operand" ""))]
3830   "reload_completed
3831    && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
3832   [(const_int 0)]
3833   "ix86_split_long_move (operands); DONE;")
3834 \f
3835 ;; Zero extension instructions
3836
3837 (define_expand "zero_extendhisi2"
3838   [(set (match_operand:SI 0 "register_operand" "")
3839      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3840   ""
3841 {
3842   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3843     {
3844       operands[1] = force_reg (HImode, operands[1]);
3845       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3846       DONE;
3847     }
3848 })
3849
3850 (define_insn "zero_extendhisi2_and"
3851   [(set (match_operand:SI 0 "register_operand" "=r")
3852      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3853    (clobber (reg:CC FLAGS_REG))]
3854   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3855   "#"
3856   [(set_attr "type" "alu1")
3857    (set_attr "mode" "SI")])
3858
3859 (define_split
3860   [(set (match_operand:SI 0 "register_operand" "")
3861         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3862    (clobber (reg:CC FLAGS_REG))]
3863   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND
3864    && optimize_function_for_speed_p (cfun)"
3865   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3866               (clobber (reg:CC FLAGS_REG))])]
3867   "")
3868
3869 (define_insn "*zero_extendhisi2_movzwl"
3870   [(set (match_operand:SI 0 "register_operand" "=r")
3871      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3872   "!TARGET_ZERO_EXTEND_WITH_AND
3873    || optimize_function_for_size_p (cfun)"
3874   "movz{wl|x}\t{%1, %0|%0, %1}"
3875   [(set_attr "type" "imovx")
3876    (set_attr "mode" "SI")])
3877
3878 (define_expand "zero_extendqihi2"
3879   [(parallel
3880     [(set (match_operand:HI 0 "register_operand" "")
3881        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3882      (clobber (reg:CC FLAGS_REG))])]
3883   ""
3884   "")
3885
3886 (define_insn "*zero_extendqihi2_and"
3887   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3888      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3889    (clobber (reg:CC FLAGS_REG))]
3890   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3891   "#"
3892   [(set_attr "type" "alu1")
3893    (set_attr "mode" "HI")])
3894
3895 (define_insn "*zero_extendqihi2_movzbw_and"
3896   [(set (match_operand:HI 0 "register_operand" "=r,r")
3897      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3898    (clobber (reg:CC FLAGS_REG))]
3899   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3900   "#"
3901   [(set_attr "type" "imovx,alu1")
3902    (set_attr "mode" "HI")])
3903
3904 ; zero extend to SImode here to avoid partial register stalls
3905 (define_insn "*zero_extendqihi2_movzbl"
3906   [(set (match_operand:HI 0 "register_operand" "=r")
3907      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3908   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3909    && reload_completed"
3910   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3911   [(set_attr "type" "imovx")
3912    (set_attr "mode" "SI")])
3913
3914 ;; For the movzbw case strip only the clobber
3915 (define_split
3916   [(set (match_operand:HI 0 "register_operand" "")
3917         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3918    (clobber (reg:CC FLAGS_REG))]
3919   "reload_completed
3920    && (!TARGET_ZERO_EXTEND_WITH_AND
3921        || optimize_function_for_size_p (cfun))
3922    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3923   [(set (match_operand:HI 0 "register_operand" "")
3924         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3925
3926 ;; When source and destination does not overlap, clear destination
3927 ;; first and then do the movb
3928 (define_split
3929   [(set (match_operand:HI 0 "register_operand" "")
3930         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3931    (clobber (reg:CC FLAGS_REG))]
3932   "reload_completed
3933    && ANY_QI_REG_P (operands[0])
3934    && (TARGET_ZERO_EXTEND_WITH_AND
3935        && optimize_function_for_speed_p (cfun))
3936    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3937   [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3938 {
3939   operands[2] = gen_lowpart (QImode, operands[0]);
3940   ix86_expand_clear (operands[0]);
3941 })
3942
3943 ;; Rest is handled by single and.
3944 (define_split
3945   [(set (match_operand:HI 0 "register_operand" "")
3946         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3947    (clobber (reg:CC FLAGS_REG))]
3948   "reload_completed
3949    && true_regnum (operands[0]) == true_regnum (operands[1])"
3950   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3951               (clobber (reg:CC FLAGS_REG))])]
3952   "")
3953
3954 (define_expand "zero_extendqisi2"
3955   [(parallel
3956     [(set (match_operand:SI 0 "register_operand" "")
3957        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3958      (clobber (reg:CC FLAGS_REG))])]
3959   ""
3960   "")
3961
3962 (define_insn "*zero_extendqisi2_and"
3963   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3964      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3965    (clobber (reg:CC FLAGS_REG))]
3966   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3967   "#"
3968   [(set_attr "type" "alu1")
3969    (set_attr "mode" "SI")])
3970
3971 (define_insn "*zero_extendqisi2_movzbl_and"
3972   [(set (match_operand:SI 0 "register_operand" "=r,r")
3973      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3974    (clobber (reg:CC FLAGS_REG))]
3975   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3976   "#"
3977   [(set_attr "type" "imovx,alu1")
3978    (set_attr "mode" "SI")])
3979
3980 (define_insn "*zero_extendqisi2_movzbl"
3981   [(set (match_operand:SI 0 "register_operand" "=r")
3982      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3983   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3984    && reload_completed"
3985   "movz{bl|x}\t{%1, %0|%0, %1}"
3986   [(set_attr "type" "imovx")
3987    (set_attr "mode" "SI")])
3988
3989 ;; For the movzbl case strip only the clobber
3990 (define_split
3991   [(set (match_operand:SI 0 "register_operand" "")
3992         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3993    (clobber (reg:CC FLAGS_REG))]
3994   "reload_completed
3995    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3996    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3997   [(set (match_dup 0)
3998         (zero_extend:SI (match_dup 1)))])
3999
4000 ;; When source and destination does not overlap, clear destination
4001 ;; first and then do the movb
4002 (define_split
4003   [(set (match_operand:SI 0 "register_operand" "")
4004         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
4005    (clobber (reg:CC FLAGS_REG))]
4006   "reload_completed
4007    && ANY_QI_REG_P (operands[0])
4008    && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
4009    && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
4010    && !reg_overlap_mentioned_p (operands[0], operands[1])"
4011   [(set (strict_low_part (match_dup 2)) (match_dup 1))]
4012 {
4013   operands[2] = gen_lowpart (QImode, operands[0]);
4014   ix86_expand_clear (operands[0]);
4015 })
4016
4017 ;; Rest is handled by single and.
4018 (define_split
4019   [(set (match_operand:SI 0 "register_operand" "")
4020         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
4021    (clobber (reg:CC FLAGS_REG))]
4022   "reload_completed
4023    && true_regnum (operands[0]) == true_regnum (operands[1])"
4024   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
4025               (clobber (reg:CC FLAGS_REG))])]
4026   "")
4027
4028 ;; %%% Kill me once multi-word ops are sane.
4029 (define_expand "zero_extendsidi2"
4030   [(set (match_operand:DI 0 "register_operand" "")
4031      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
4032   ""
4033 {
4034   if (!TARGET_64BIT)
4035     {
4036       emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
4037       DONE;
4038     }
4039 })
4040
4041 (define_insn "zero_extendsidi2_32"
4042   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
4043         (zero_extend:DI
4044          (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r   ,m  ,r   ,m")))
4045    (clobber (reg:CC FLAGS_REG))]
4046   "!TARGET_64BIT"
4047   "@
4048    #
4049    #
4050    #
4051    movd\t{%1, %0|%0, %1}
4052    movd\t{%1, %0|%0, %1}
4053    %vmovd\t{%1, %0|%0, %1}
4054    %vmovd\t{%1, %0|%0, %1}"
4055   [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
4056    (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
4057    (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
4058
4059 (define_insn "zero_extendsidi2_rex64"
4060   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
4061      (zero_extend:DI
4062        (match_operand:SI 1 "nonimmediate_operand"  "rm,0,r   ,m  ,r   ,m")))]
4063   "TARGET_64BIT"
4064   "@
4065    mov\t{%k1, %k0|%k0, %k1}
4066    #
4067    movd\t{%1, %0|%0, %1}
4068    movd\t{%1, %0|%0, %1}
4069    %vmovd\t{%1, %0|%0, %1}
4070    %vmovd\t{%1, %0|%0, %1}"
4071   [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
4072    (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
4073    (set_attr "prefix_0f" "0,*,*,*,*,*")
4074    (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
4075
4076 (define_split
4077   [(set (match_operand:DI 0 "memory_operand" "")
4078      (zero_extend:DI (match_dup 0)))]
4079   "TARGET_64BIT"
4080   [(set (match_dup 4) (const_int 0))]
4081   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4082
4083 (define_split
4084   [(set (match_operand:DI 0 "register_operand" "")
4085         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
4086    (clobber (reg:CC FLAGS_REG))]
4087   "!TARGET_64BIT && reload_completed
4088    && true_regnum (operands[0]) == true_regnum (operands[1])"
4089   [(set (match_dup 4) (const_int 0))]
4090   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4091
4092 (define_split
4093   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4094         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
4095    (clobber (reg:CC FLAGS_REG))]
4096   "!TARGET_64BIT && reload_completed
4097    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
4098   [(set (match_dup 3) (match_dup 1))
4099    (set (match_dup 4) (const_int 0))]
4100   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4101
4102 (define_insn "zero_extendhidi2"
4103   [(set (match_operand:DI 0 "register_operand" "=r")
4104      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
4105   "TARGET_64BIT"
4106   "movz{wl|x}\t{%1, %k0|%k0, %1}"
4107   [(set_attr "type" "imovx")
4108    (set_attr "mode" "SI")])
4109
4110 (define_insn "zero_extendqidi2"
4111   [(set (match_operand:DI 0 "register_operand" "=r")
4112      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
4113   "TARGET_64BIT"
4114   "movz{bl|x}\t{%1, %k0|%k0, %1}"
4115   [(set_attr "type" "imovx")
4116    (set_attr "mode" "SI")])
4117 \f
4118 ;; Sign extension instructions
4119
4120 (define_expand "extendsidi2"
4121   [(parallel [(set (match_operand:DI 0 "register_operand" "")
4122                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4123               (clobber (reg:CC FLAGS_REG))
4124               (clobber (match_scratch:SI 2 ""))])]
4125   ""
4126 {
4127   if (TARGET_64BIT)
4128     {
4129       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
4130       DONE;
4131     }
4132 })
4133
4134 (define_insn "*extendsidi2_1"
4135   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
4136         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
4137    (clobber (reg:CC FLAGS_REG))
4138    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
4139   "!TARGET_64BIT"
4140   "#")
4141
4142 (define_insn "extendsidi2_rex64"
4143   [(set (match_operand:DI 0 "register_operand" "=*a,r")
4144         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
4145   "TARGET_64BIT"
4146   "@
4147    {cltq|cdqe}
4148    movs{lq|x}\t{%1, %0|%0, %1}"
4149   [(set_attr "type" "imovx")
4150    (set_attr "mode" "DI")
4151    (set_attr "prefix_0f" "0")
4152    (set_attr "modrm" "0,1")])
4153
4154 (define_insn "extendhidi2"
4155   [(set (match_operand:DI 0 "register_operand" "=r")
4156         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
4157   "TARGET_64BIT"
4158   "movs{wq|x}\t{%1, %0|%0, %1}"
4159   [(set_attr "type" "imovx")
4160    (set_attr "mode" "DI")])
4161
4162 (define_insn "extendqidi2"
4163   [(set (match_operand:DI 0 "register_operand" "=r")
4164         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4165   "TARGET_64BIT"
4166   "movs{bq|x}\t{%1, %0|%0, %1}"
4167    [(set_attr "type" "imovx")
4168     (set_attr "mode" "DI")])
4169
4170 ;; Extend to memory case when source register does die.
4171 (define_split
4172   [(set (match_operand:DI 0 "memory_operand" "")
4173         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4174    (clobber (reg:CC FLAGS_REG))
4175    (clobber (match_operand:SI 2 "register_operand" ""))]
4176   "(reload_completed
4177     && dead_or_set_p (insn, operands[1])
4178     && !reg_mentioned_p (operands[1], operands[0]))"
4179   [(set (match_dup 3) (match_dup 1))
4180    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4181               (clobber (reg:CC FLAGS_REG))])
4182    (set (match_dup 4) (match_dup 1))]
4183   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4184
4185 ;; Extend to memory case when source register does not die.
4186 (define_split
4187   [(set (match_operand:DI 0 "memory_operand" "")
4188         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4189    (clobber (reg:CC FLAGS_REG))
4190    (clobber (match_operand:SI 2 "register_operand" ""))]
4191   "reload_completed"
4192   [(const_int 0)]
4193 {
4194   split_di (&operands[0], 1, &operands[3], &operands[4]);
4195
4196   emit_move_insn (operands[3], operands[1]);
4197
4198   /* Generate a cltd if possible and doing so it profitable.  */
4199   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4200       && true_regnum (operands[1]) == AX_REG
4201       && true_regnum (operands[2]) == DX_REG)
4202     {
4203       emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
4204     }
4205   else
4206     {
4207       emit_move_insn (operands[2], operands[1]);
4208       emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
4209     }
4210   emit_move_insn (operands[4], operands[2]);
4211   DONE;
4212 })
4213
4214 ;; Extend to register case.  Optimize case where source and destination
4215 ;; registers match and cases where we can use cltd.
4216 (define_split
4217   [(set (match_operand:DI 0 "register_operand" "")
4218         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4219    (clobber (reg:CC FLAGS_REG))
4220    (clobber (match_scratch:SI 2 ""))]
4221   "reload_completed"
4222   [(const_int 0)]
4223 {
4224   split_di (&operands[0], 1, &operands[3], &operands[4]);
4225
4226   if (true_regnum (operands[3]) != true_regnum (operands[1]))
4227     emit_move_insn (operands[3], operands[1]);
4228
4229   /* Generate a cltd if possible and doing so it profitable.  */
4230   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4231       && true_regnum (operands[3]) == AX_REG
4232       && true_regnum (operands[4]) == DX_REG)
4233     {
4234       emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
4235       DONE;
4236     }
4237
4238   if (true_regnum (operands[4]) != true_regnum (operands[1]))
4239     emit_move_insn (operands[4], operands[1]);
4240
4241   emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
4242   DONE;
4243 })
4244
4245 (define_insn "extendhisi2"
4246   [(set (match_operand:SI 0 "register_operand" "=*a,r")
4247         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4248   ""
4249 {
4250   switch (get_attr_prefix_0f (insn))
4251     {
4252     case 0:
4253       return "{cwtl|cwde}";
4254     default:
4255       return "movs{wl|x}\t{%1, %0|%0, %1}";
4256     }
4257 }
4258   [(set_attr "type" "imovx")
4259    (set_attr "mode" "SI")
4260    (set (attr "prefix_0f")
4261      ;; movsx is short decodable while cwtl is vector decoded.
4262      (if_then_else (and (eq_attr "cpu" "!k6")
4263                         (eq_attr "alternative" "0"))
4264         (const_string "0")
4265         (const_string "1")))
4266    (set (attr "modrm")
4267      (if_then_else (eq_attr "prefix_0f" "0")
4268         (const_string "0")
4269         (const_string "1")))])
4270
4271 (define_insn "*extendhisi2_zext"
4272   [(set (match_operand:DI 0 "register_operand" "=*a,r")
4273         (zero_extend:DI
4274           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4275   "TARGET_64BIT"
4276 {
4277   switch (get_attr_prefix_0f (insn))
4278     {
4279     case 0:
4280       return "{cwtl|cwde}";
4281     default:
4282       return "movs{wl|x}\t{%1, %k0|%k0, %1}";
4283     }
4284 }
4285   [(set_attr "type" "imovx")
4286    (set_attr "mode" "SI")
4287    (set (attr "prefix_0f")
4288      ;; movsx is short decodable while cwtl is vector decoded.
4289      (if_then_else (and (eq_attr "cpu" "!k6")
4290                         (eq_attr "alternative" "0"))
4291         (const_string "0")
4292         (const_string "1")))
4293    (set (attr "modrm")
4294      (if_then_else (eq_attr "prefix_0f" "0")
4295         (const_string "0")
4296         (const_string "1")))])
4297
4298 (define_insn "extendqihi2"
4299   [(set (match_operand:HI 0 "register_operand" "=*a,r")
4300         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4301   ""
4302 {
4303   switch (get_attr_prefix_0f (insn))
4304     {
4305     case 0:
4306       return "{cbtw|cbw}";
4307     default:
4308       return "movs{bw|x}\t{%1, %0|%0, %1}";
4309     }
4310 }
4311   [(set_attr "type" "imovx")
4312    (set_attr "mode" "HI")
4313    (set (attr "prefix_0f")
4314      ;; movsx is short decodable while cwtl is vector decoded.
4315      (if_then_else (and (eq_attr "cpu" "!k6")
4316                         (eq_attr "alternative" "0"))
4317         (const_string "0")
4318         (const_string "1")))
4319    (set (attr "modrm")
4320      (if_then_else (eq_attr "prefix_0f" "0")
4321         (const_string "0")
4322         (const_string "1")))])
4323
4324 (define_insn "extendqisi2"
4325   [(set (match_operand:SI 0 "register_operand" "=r")
4326         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4327   ""
4328   "movs{bl|x}\t{%1, %0|%0, %1}"
4329    [(set_attr "type" "imovx")
4330     (set_attr "mode" "SI")])
4331
4332 (define_insn "*extendqisi2_zext"
4333   [(set (match_operand:DI 0 "register_operand" "=r")
4334         (zero_extend:DI
4335           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4336   "TARGET_64BIT"
4337   "movs{bl|x}\t{%1, %k0|%k0, %1}"
4338    [(set_attr "type" "imovx")
4339     (set_attr "mode" "SI")])
4340 \f
4341 ;; Conversions between float and double.
4342
4343 ;; These are all no-ops in the model used for the 80387.  So just
4344 ;; emit moves.
4345
4346 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4347 (define_insn "*dummy_extendsfdf2"
4348   [(set (match_operand:DF 0 "push_operand" "=<")
4349         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY2")))]
4350   "0"
4351   "#")
4352
4353 (define_split
4354   [(set (match_operand:DF 0 "push_operand" "")
4355         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
4356   ""
4357   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4358    (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4359
4360 (define_insn "*dummy_extendsfxf2"
4361   [(set (match_operand:XF 0 "push_operand" "=<")
4362         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
4363   "0"
4364   "#")
4365
4366 (define_split
4367   [(set (match_operand:XF 0 "push_operand" "")
4368         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
4369   ""
4370   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4371    (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4372   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4373
4374 (define_split
4375   [(set (match_operand:XF 0 "push_operand" "")
4376         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
4377   ""
4378   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4379    (set (mem:DF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4380   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4381
4382 (define_expand "extendsfdf2"
4383   [(set (match_operand:DF 0 "nonimmediate_operand" "")
4384         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
4385   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4386 {
4387   /* ??? Needed for compress_float_constant since all fp constants
4388      are LEGITIMATE_CONSTANT_P.  */
4389   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4390     {
4391       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4392           && standard_80387_constant_p (operands[1]) > 0)
4393         {
4394           operands[1] = simplify_const_unary_operation
4395             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4396           emit_move_insn_1 (operands[0], operands[1]);
4397           DONE;
4398         }
4399       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4400     }
4401 })
4402
4403 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4404    cvtss2sd:
4405       unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4406       cvtps2pd xmm2,xmm1
4407    We do the conversion post reload to avoid producing of 128bit spills
4408    that might lead to ICE on 32bit target.  The sequence unlikely combine
4409    anyway.  */
4410 (define_split
4411   [(set (match_operand:DF 0 "register_operand" "")
4412         (float_extend:DF
4413           (match_operand:SF 1 "nonimmediate_operand" "")))]
4414   "TARGET_USE_VECTOR_FP_CONVERTS
4415    && optimize_insn_for_speed_p ()
4416    && reload_completed && SSE_REG_P (operands[0])"
4417    [(set (match_dup 2)
4418          (float_extend:V2DF
4419            (vec_select:V2SF
4420              (match_dup 3)
4421              (parallel [(const_int 0) (const_int 1)]))))]
4422 {
4423   operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4424   operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4425   /* Use movss for loading from memory, unpcklps reg, reg for registers.
4426      Try to avoid move when unpacking can be done in source.  */
4427   if (REG_P (operands[1]))
4428     {
4429       /* If it is unsafe to overwrite upper half of source, we need
4430          to move to destination and unpack there.  */
4431       if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4432            || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4433           && true_regnum (operands[0]) != true_regnum (operands[1]))
4434         {
4435           rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4436           emit_move_insn (tmp, operands[1]);
4437         }
4438       else
4439         operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4440       emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4441                                              operands[3]));
4442     }
4443   else
4444     emit_insn (gen_vec_setv4sf_0 (operands[3],
4445                                   CONST0_RTX (V4SFmode), operands[1]));
4446 })
4447
4448 (define_insn "*extendsfdf2_mixed"
4449   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4450         (float_extend:DF
4451           (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4452   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4453 {
4454   switch (which_alternative)
4455     {
4456     case 0:
4457     case 1:
4458       return output_387_reg_move (insn, operands);
4459
4460     case 2:
4461       return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4462
4463     default:
4464       gcc_unreachable ();
4465     }
4466 }
4467   [(set_attr "type" "fmov,fmov,ssecvt")
4468    (set_attr "prefix" "orig,orig,maybe_vex")
4469    (set_attr "mode" "SF,XF,DF")])
4470
4471 (define_insn "*extendsfdf2_sse"
4472   [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4473         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4474   "TARGET_SSE2 && TARGET_SSE_MATH"
4475   "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4476   [(set_attr "type" "ssecvt")
4477    (set_attr "prefix" "maybe_vex")
4478    (set_attr "mode" "DF")])
4479
4480 (define_insn "*extendsfdf2_i387"
4481   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4482         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4483   "TARGET_80387"
4484   "* return output_387_reg_move (insn, operands);"
4485   [(set_attr "type" "fmov")
4486    (set_attr "mode" "SF,XF")])
4487
4488 (define_expand "extend<mode>xf2"
4489   [(set (match_operand:XF 0 "nonimmediate_operand" "")
4490         (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4491   "TARGET_80387"
4492 {
4493   /* ??? Needed for compress_float_constant since all fp constants
4494      are LEGITIMATE_CONSTANT_P.  */
4495   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4496     {
4497       if (standard_80387_constant_p (operands[1]) > 0)
4498         {
4499           operands[1] = simplify_const_unary_operation
4500             (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4501           emit_move_insn_1 (operands[0], operands[1]);
4502           DONE;
4503         }
4504       operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4505     }
4506 })
4507
4508 (define_insn "*extend<mode>xf2_i387"
4509   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4510         (float_extend:XF
4511           (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4512   "TARGET_80387"
4513   "* return output_387_reg_move (insn, operands);"
4514   [(set_attr "type" "fmov")
4515    (set_attr "mode" "<MODE>,XF")])
4516
4517 ;; %%% This seems bad bad news.
4518 ;; This cannot output into an f-reg because there is no way to be sure
4519 ;; of truncating in that case.  Otherwise this is just like a simple move
4520 ;; insn.  So we pretend we can output to a reg in order to get better
4521 ;; register preferencing, but we really use a stack slot.
4522
4523 ;; Conversion from DFmode to SFmode.
4524
4525 (define_expand "truncdfsf2"
4526   [(set (match_operand:SF 0 "nonimmediate_operand" "")
4527         (float_truncate:SF
4528           (match_operand:DF 1 "nonimmediate_operand" "")))]
4529   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4530 {
4531   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4532     ;
4533   else if (flag_unsafe_math_optimizations)
4534     ;
4535   else
4536     {
4537       enum ix86_stack_slot slot = (virtuals_instantiated
4538                                    ? SLOT_TEMP
4539                                    : SLOT_VIRTUAL);
4540       rtx temp = assign_386_stack_local (SFmode, slot);
4541       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4542       DONE;
4543     }
4544 })
4545
4546 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4547    cvtsd2ss:
4548       unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4549       cvtpd2ps xmm2,xmm1
4550    We do the conversion post reload to avoid producing of 128bit spills
4551    that might lead to ICE on 32bit target.  The sequence unlikely combine
4552    anyway.  */
4553 (define_split
4554   [(set (match_operand:SF 0 "register_operand" "")
4555         (float_truncate:SF
4556           (match_operand:DF 1 "nonimmediate_operand" "")))]
4557   "TARGET_USE_VECTOR_FP_CONVERTS
4558    && optimize_insn_for_speed_p ()
4559    && reload_completed && SSE_REG_P (operands[0])"
4560    [(set (match_dup 2)
4561          (vec_concat:V4SF
4562            (float_truncate:V2SF
4563              (match_dup 4))
4564            (match_dup 3)))]
4565 {
4566   operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4567   operands[3] = CONST0_RTX (V2SFmode);
4568   operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4569   /* Use movsd for loading from memory, unpcklpd for registers.
4570      Try to avoid move when unpacking can be done in source, or SSE3
4571      movddup is available.  */
4572   if (REG_P (operands[1]))
4573     {
4574       if (!TARGET_SSE3
4575           && true_regnum (operands[0]) != true_regnum (operands[1])
4576           && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4577               || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4578         {
4579           rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4580           emit_move_insn (tmp, operands[1]);
4581           operands[1] = tmp;
4582         }
4583       else if (!TARGET_SSE3)
4584         operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4585       emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4586     }
4587   else
4588     emit_insn (gen_sse2_loadlpd (operands[4],
4589                                  CONST0_RTX (V2DFmode), operands[1]));
4590 })
4591
4592 (define_expand "truncdfsf2_with_temp"
4593   [(parallel [(set (match_operand:SF 0 "" "")
4594                    (float_truncate:SF (match_operand:DF 1 "" "")))
4595               (clobber (match_operand:SF 2 "" ""))])]
4596   "")
4597
4598 (define_insn "*truncdfsf_fast_mixed"
4599   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm,x")
4600         (float_truncate:SF
4601           (match_operand:DF 1 "nonimmediate_operand" "f  ,xm")))]
4602   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4603 {
4604   switch (which_alternative)
4605     {
4606     case 0:
4607       return output_387_reg_move (insn, operands);
4608     case 1:
4609       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4610     default:
4611       gcc_unreachable ();
4612     }
4613 }
4614   [(set_attr "type" "fmov,ssecvt")
4615    (set_attr "prefix" "orig,maybe_vex")
4616    (set_attr "mode" "SF")])
4617
4618 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4619 ;; because nothing we do here is unsafe.
4620 (define_insn "*truncdfsf_fast_sse"
4621   [(set (match_operand:SF 0 "nonimmediate_operand"   "=x")
4622         (float_truncate:SF
4623           (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4624   "TARGET_SSE2 && TARGET_SSE_MATH"
4625   "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4626   [(set_attr "type" "ssecvt")
4627    (set_attr "prefix" "maybe_vex")
4628    (set_attr "mode" "SF")])
4629
4630 (define_insn "*truncdfsf_fast_i387"
4631   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
4632         (float_truncate:SF
4633           (match_operand:DF 1 "nonimmediate_operand" "f")))]
4634   "TARGET_80387 && flag_unsafe_math_optimizations"
4635   "* return output_387_reg_move (insn, operands);"
4636   [(set_attr "type" "fmov")
4637    (set_attr "mode" "SF")])
4638
4639 (define_insn "*truncdfsf_mixed"
4640   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,Y2 ,?f,?x,?*r")
4641         (float_truncate:SF
4642           (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4643    (clobber (match_operand:SF 2 "memory_operand"     "=X,X  ,m ,m ,m"))]
4644   "TARGET_MIX_SSE_I387"
4645 {
4646   switch (which_alternative)
4647     {
4648     case 0:
4649       return output_387_reg_move (insn, operands);
4650     case 1:
4651       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4652
4653     default:
4654       return "#";
4655     }
4656 }
4657   [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4658    (set_attr "unit" "*,*,i387,i387,i387")
4659    (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4660    (set_attr "mode" "SF")])
4661
4662 (define_insn "*truncdfsf_i387"
4663   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?f,?x,?*r")
4664         (float_truncate:SF
4665           (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4666    (clobber (match_operand:SF 2 "memory_operand"     "=X,m ,m ,m"))]
4667   "TARGET_80387"
4668 {
4669   switch (which_alternative)
4670     {
4671     case 0:
4672       return output_387_reg_move (insn, operands);
4673
4674     default:
4675       return "#";
4676     }
4677 }
4678   [(set_attr "type" "fmov,multi,multi,multi")
4679    (set_attr "unit" "*,i387,i387,i387")
4680    (set_attr "mode" "SF")])
4681
4682 (define_insn "*truncdfsf2_i387_1"
4683   [(set (match_operand:SF 0 "memory_operand" "=m")
4684         (float_truncate:SF
4685           (match_operand:DF 1 "register_operand" "f")))]
4686   "TARGET_80387
4687    && !(TARGET_SSE2 && TARGET_SSE_MATH)
4688    && !TARGET_MIX_SSE_I387"
4689   "* return output_387_reg_move (insn, operands);"
4690   [(set_attr "type" "fmov")
4691    (set_attr "mode" "SF")])
4692
4693 (define_split
4694   [(set (match_operand:SF 0 "register_operand" "")
4695         (float_truncate:SF
4696          (match_operand:DF 1 "fp_register_operand" "")))
4697    (clobber (match_operand 2 "" ""))]
4698   "reload_completed"
4699   [(set (match_dup 2) (match_dup 1))
4700    (set (match_dup 0) (match_dup 2))]
4701 {
4702   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4703 })
4704
4705 ;; Conversion from XFmode to {SF,DF}mode
4706
4707 (define_expand "truncxf<mode>2"
4708   [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4709                    (float_truncate:MODEF
4710                      (match_operand:XF 1 "register_operand" "")))
4711               (clobber (match_dup 2))])]
4712   "TARGET_80387"
4713 {
4714   if (flag_unsafe_math_optimizations)
4715     {
4716       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4717       emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4718       if (reg != operands[0])
4719         emit_move_insn (operands[0], reg);
4720       DONE;
4721     }
4722   else
4723     {
4724      enum ix86_stack_slot slot = (virtuals_instantiated
4725                                   ? SLOT_TEMP
4726                                   : SLOT_VIRTUAL);
4727       operands[2] = assign_386_stack_local (<MODE>mode, slot);
4728     }
4729 })
4730
4731 (define_insn "*truncxfsf2_mixed"
4732   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4733         (float_truncate:SF
4734           (match_operand:XF 1 "register_operand"   "f ,f ,f ,f")))
4735    (clobber (match_operand:SF 2 "memory_operand"   "=X,m ,m ,m"))]
4736   "TARGET_80387"
4737 {
4738   gcc_assert (!which_alternative);
4739   return output_387_reg_move (insn, operands);
4740 }
4741   [(set_attr "type" "fmov,multi,multi,multi")
4742    (set_attr "unit" "*,i387,i387,i387")
4743    (set_attr "mode" "SF")])
4744
4745 (define_insn "*truncxfdf2_mixed"
4746   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4747         (float_truncate:DF
4748           (match_operand:XF 1 "register_operand"   "f ,f ,f  ,f")))
4749    (clobber (match_operand:DF 2 "memory_operand"   "=X,m ,m  ,m"))]
4750   "TARGET_80387"
4751 {
4752   gcc_assert (!which_alternative);
4753   return output_387_reg_move (insn, operands);
4754 }
4755   [(set_attr "type" "fmov,multi,multi,multi")
4756    (set_attr "unit" "*,i387,i387,i387")
4757    (set_attr "mode" "DF")])
4758
4759 (define_insn "truncxf<mode>2_i387_noop"
4760   [(set (match_operand:MODEF 0 "register_operand" "=f")
4761         (float_truncate:MODEF
4762           (match_operand:XF 1 "register_operand" "f")))]
4763   "TARGET_80387 && flag_unsafe_math_optimizations"
4764   "* return output_387_reg_move (insn, operands);"
4765   [(set_attr "type" "fmov")
4766    (set_attr "mode" "<MODE>")])
4767
4768 (define_insn "*truncxf<mode>2_i387"
4769   [(set (match_operand:MODEF 0 "memory_operand" "=m")
4770         (float_truncate:MODEF
4771           (match_operand:XF 1 "register_operand" "f")))]
4772   "TARGET_80387"
4773   "* return output_387_reg_move (insn, operands);"
4774   [(set_attr "type" "fmov")
4775    (set_attr "mode" "<MODE>")])
4776
4777 (define_split
4778   [(set (match_operand:MODEF 0 "register_operand" "")
4779         (float_truncate:MODEF
4780           (match_operand:XF 1 "register_operand" "")))
4781    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4782   "TARGET_80387 && reload_completed"
4783   [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4784    (set (match_dup 0) (match_dup 2))]
4785   "")
4786
4787 (define_split
4788   [(set (match_operand:MODEF 0 "memory_operand" "")
4789         (float_truncate:MODEF
4790           (match_operand:XF 1 "register_operand" "")))
4791    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4792   "TARGET_80387"
4793   [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]
4794   "")
4795 \f
4796 ;; Signed conversion to DImode.
4797
4798 (define_expand "fix_truncxfdi2"
4799   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4800                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4801               (clobber (reg:CC FLAGS_REG))])]
4802   "TARGET_80387"
4803 {
4804   if (TARGET_FISTTP)
4805    {
4806      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4807      DONE;
4808    }
4809 })
4810
4811 (define_expand "fix_trunc<mode>di2"
4812   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4813                    (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4814               (clobber (reg:CC FLAGS_REG))])]
4815   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4816 {
4817   if (TARGET_FISTTP
4818       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4819    {
4820      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4821      DONE;
4822    }
4823   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4824    {
4825      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4826      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4827      if (out != operands[0])
4828         emit_move_insn (operands[0], out);
4829      DONE;
4830    }
4831 })
4832
4833 ;; Signed conversion to SImode.
4834
4835 (define_expand "fix_truncxfsi2"
4836   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4837                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4838               (clobber (reg:CC FLAGS_REG))])]
4839   "TARGET_80387"
4840 {
4841   if (TARGET_FISTTP)
4842    {
4843      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4844      DONE;
4845    }
4846 })
4847
4848 (define_expand "fix_trunc<mode>si2"
4849   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4850                    (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4851               (clobber (reg:CC FLAGS_REG))])]
4852   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4853 {
4854   if (TARGET_FISTTP
4855       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4856    {
4857      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4858      DONE;
4859    }
4860   if (SSE_FLOAT_MODE_P (<MODE>mode))
4861    {
4862      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4863      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4864      if (out != operands[0])
4865         emit_move_insn (operands[0], out);
4866      DONE;
4867    }
4868 })
4869
4870 ;; Signed conversion to HImode.
4871
4872 (define_expand "fix_trunc<mode>hi2"
4873   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4874                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4875               (clobber (reg:CC FLAGS_REG))])]
4876   "TARGET_80387
4877    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4878 {
4879   if (TARGET_FISTTP)
4880    {
4881      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4882      DONE;
4883    }
4884 })
4885
4886 ;; Unsigned conversion to SImode.
4887
4888 (define_expand "fixuns_trunc<mode>si2"
4889   [(parallel
4890     [(set (match_operand:SI 0 "register_operand" "")
4891           (unsigned_fix:SI
4892             (match_operand:MODEF 1 "nonimmediate_operand" "")))
4893      (use (match_dup 2))
4894      (clobber (match_scratch:<ssevecmode> 3 ""))
4895      (clobber (match_scratch:<ssevecmode> 4 ""))])]
4896   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4897 {
4898   enum machine_mode mode = <MODE>mode;
4899   enum machine_mode vecmode = <ssevecmode>mode;
4900   REAL_VALUE_TYPE TWO31r;
4901   rtx two31;
4902
4903   if (optimize_insn_for_size_p ())
4904     FAIL;
4905
4906   real_ldexp (&TWO31r, &dconst1, 31);
4907   two31 = const_double_from_real_value (TWO31r, mode);
4908   two31 = ix86_build_const_vector (mode, true, two31);
4909   operands[2] = force_reg (vecmode, two31);
4910 })
4911
4912 (define_insn_and_split "*fixuns_trunc<mode>_1"
4913   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4914         (unsigned_fix:SI
4915           (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4916    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
4917    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4918    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4919   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4920    && optimize_function_for_speed_p (cfun)"
4921   "#"
4922   "&& reload_completed"
4923   [(const_int 0)]
4924 {
4925   ix86_split_convert_uns_si_sse (operands);
4926   DONE;
4927 })
4928
4929 ;; Unsigned conversion to HImode.
4930 ;; Without these patterns, we'll try the unsigned SI conversion which
4931 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4932
4933 (define_expand "fixuns_trunc<mode>hi2"
4934   [(set (match_dup 2)
4935         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4936    (set (match_operand:HI 0 "nonimmediate_operand" "")
4937         (subreg:HI (match_dup 2) 0))]
4938   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4939   "operands[2] = gen_reg_rtx (SImode);")
4940
4941 ;; When SSE is available, it is always faster to use it!
4942 (define_insn "fix_trunc<mode>di_sse"
4943   [(set (match_operand:DI 0 "register_operand" "=r,r")
4944         (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4945   "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4946    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4947   "%vcvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4948   [(set_attr "type" "sseicvt")
4949    (set_attr "prefix" "maybe_vex")
4950    (set_attr "prefix_rex" "1")
4951    (set_attr "mode" "<MODE>")
4952    (set_attr "athlon_decode" "double,vector")
4953    (set_attr "amdfam10_decode" "double,double")])
4954
4955 (define_insn "fix_trunc<mode>si_sse"
4956   [(set (match_operand:SI 0 "register_operand" "=r,r")
4957         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4958   "SSE_FLOAT_MODE_P (<MODE>mode)
4959    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4960   "%vcvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4961   [(set_attr "type" "sseicvt")
4962    (set_attr "prefix" "maybe_vex")
4963    (set_attr "mode" "<MODE>")
4964    (set_attr "athlon_decode" "double,vector")
4965    (set_attr "amdfam10_decode" "double,double")])
4966
4967 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4968 (define_peephole2
4969   [(set (match_operand:MODEF 0 "register_operand" "")
4970         (match_operand:MODEF 1 "memory_operand" ""))
4971    (set (match_operand:SSEMODEI24 2 "register_operand" "")
4972         (fix:SSEMODEI24 (match_dup 0)))]
4973   "TARGET_SHORTEN_X87_SSE
4974    && peep2_reg_dead_p (2, operands[0])"
4975   [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4976   "")
4977
4978 ;; Avoid vector decoded forms of the instruction.
4979 (define_peephole2
4980   [(match_scratch:DF 2 "Y2")
4981    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4982         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4983   "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4984   [(set (match_dup 2) (match_dup 1))
4985    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4986   "")
4987
4988 (define_peephole2
4989   [(match_scratch:SF 2 "x")
4990    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4991         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4992   "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4993   [(set (match_dup 2) (match_dup 1))
4994    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4995   "")
4996
4997 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4998   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4999         (fix:X87MODEI (match_operand 1 "register_operand" "")))]
5000   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5001    && TARGET_FISTTP
5002    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5003          && (TARGET_64BIT || <MODE>mode != DImode))
5004         && TARGET_SSE_MATH)
5005    && can_create_pseudo_p ()"
5006   "#"
5007   "&& 1"
5008   [(const_int 0)]
5009 {
5010   if (memory_operand (operands[0], VOIDmode))
5011     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
5012   else
5013     {
5014       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
5015       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
5016                                                             operands[1],
5017                                                             operands[2]));
5018     }
5019   DONE;
5020 }
5021   [(set_attr "type" "fisttp")
5022    (set_attr "mode" "<MODE>")])
5023
5024 (define_insn "fix_trunc<mode>_i387_fisttp"
5025   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
5026         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
5027    (clobber (match_scratch:XF 2 "=&1f"))]
5028   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5029    && TARGET_FISTTP
5030    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5031          && (TARGET_64BIT || <MODE>mode != DImode))
5032         && TARGET_SSE_MATH)"
5033   "* return output_fix_trunc (insn, operands, 1);"
5034   [(set_attr "type" "fisttp")
5035    (set_attr "mode" "<MODE>")])
5036
5037 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
5038   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
5039         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
5040    (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
5041    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
5042   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5043    && TARGET_FISTTP
5044    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5045         && (TARGET_64BIT || <MODE>mode != DImode))
5046         && TARGET_SSE_MATH)"
5047   "#"
5048   [(set_attr "type" "fisttp")
5049    (set_attr "mode" "<MODE>")])
5050
5051 (define_split
5052   [(set (match_operand:X87MODEI 0 "register_operand" "")
5053         (fix:X87MODEI (match_operand 1 "register_operand" "")))
5054    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
5055    (clobber (match_scratch 3 ""))]
5056   "reload_completed"
5057   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
5058               (clobber (match_dup 3))])
5059    (set (match_dup 0) (match_dup 2))]
5060   "")
5061
5062 (define_split
5063   [(set (match_operand:X87MODEI 0 "memory_operand" "")
5064         (fix:X87MODEI (match_operand 1 "register_operand" "")))
5065    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
5066    (clobber (match_scratch 3 ""))]
5067   "reload_completed"
5068   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
5069               (clobber (match_dup 3))])]
5070   "")
5071
5072 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
5073 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
5074 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
5075 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
5076 ;; function in i386.c.
5077 (define_insn_and_split "*fix_trunc<mode>_i387_1"
5078   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
5079         (fix:X87MODEI (match_operand 1 "register_operand" "")))
5080    (clobber (reg:CC FLAGS_REG))]
5081   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5082    && !TARGET_FISTTP
5083    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5084          && (TARGET_64BIT || <MODE>mode != DImode))
5085    && can_create_pseudo_p ()"
5086   "#"
5087   "&& 1"
5088   [(const_int 0)]
5089 {
5090   ix86_optimize_mode_switching[I387_TRUNC] = 1;
5091
5092   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
5093   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
5094   if (memory_operand (operands[0], VOIDmode))
5095     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
5096                                          operands[2], operands[3]));
5097   else
5098     {
5099       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
5100       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
5101                                                      operands[2], operands[3],
5102                                                      operands[4]));
5103     }
5104   DONE;
5105 }
5106   [(set_attr "type" "fistp")
5107    (set_attr "i387_cw" "trunc")
5108    (set_attr "mode" "<MODE>")])
5109
5110 (define_insn "fix_truncdi_i387"
5111   [(set (match_operand:DI 0 "memory_operand" "=m")
5112         (fix:DI (match_operand 1 "register_operand" "f")))
5113    (use (match_operand:HI 2 "memory_operand" "m"))
5114    (use (match_operand:HI 3 "memory_operand" "m"))
5115    (clobber (match_scratch:XF 4 "=&1f"))]
5116   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5117    && !TARGET_FISTTP
5118    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5119   "* return output_fix_trunc (insn, operands, 0);"
5120   [(set_attr "type" "fistp")
5121    (set_attr "i387_cw" "trunc")
5122    (set_attr "mode" "DI")])
5123
5124 (define_insn "fix_truncdi_i387_with_temp"
5125   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
5126         (fix:DI (match_operand 1 "register_operand" "f,f")))
5127    (use (match_operand:HI 2 "memory_operand" "m,m"))
5128    (use (match_operand:HI 3 "memory_operand" "m,m"))
5129    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
5130    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
5131   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5132    && !TARGET_FISTTP
5133    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5134   "#"
5135   [(set_attr "type" "fistp")
5136    (set_attr "i387_cw" "trunc")
5137    (set_attr "mode" "DI")])
5138
5139 (define_split
5140   [(set (match_operand:DI 0 "register_operand" "")
5141         (fix:DI (match_operand 1 "register_operand" "")))
5142    (use (match_operand:HI 2 "memory_operand" ""))
5143    (use (match_operand:HI 3 "memory_operand" ""))
5144    (clobber (match_operand:DI 4 "memory_operand" ""))
5145    (clobber (match_scratch 5 ""))]
5146   "reload_completed"
5147   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
5148               (use (match_dup 2))
5149               (use (match_dup 3))
5150               (clobber (match_dup 5))])
5151    (set (match_dup 0) (match_dup 4))]
5152   "")
5153
5154 (define_split
5155   [(set (match_operand:DI 0 "memory_operand" "")
5156         (fix:DI (match_operand 1 "register_operand" "")))
5157    (use (match_operand:HI 2 "memory_operand" ""))
5158    (use (match_operand:HI 3 "memory_operand" ""))
5159    (clobber (match_operand:DI 4 "memory_operand" ""))
5160    (clobber (match_scratch 5 ""))]
5161   "reload_completed"
5162   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
5163               (use (match_dup 2))
5164               (use (match_dup 3))
5165               (clobber (match_dup 5))])]
5166   "")
5167
5168 (define_insn "fix_trunc<mode>_i387"
5169   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
5170         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
5171    (use (match_operand:HI 2 "memory_operand" "m"))
5172    (use (match_operand:HI 3 "memory_operand" "m"))]
5173   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5174    && !TARGET_FISTTP
5175    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5176   "* return output_fix_trunc (insn, operands, 0);"
5177   [(set_attr "type" "fistp")
5178    (set_attr "i387_cw" "trunc")
5179    (set_attr "mode" "<MODE>")])
5180
5181 (define_insn "fix_trunc<mode>_i387_with_temp"
5182   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
5183         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
5184    (use (match_operand:HI 2 "memory_operand" "m,m"))
5185    (use (match_operand:HI 3 "memory_operand" "m,m"))
5186    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
5187   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5188    && !TARGET_FISTTP
5189    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5190   "#"
5191   [(set_attr "type" "fistp")
5192    (set_attr "i387_cw" "trunc")
5193    (set_attr "mode" "<MODE>")])
5194
5195 (define_split
5196   [(set (match_operand:X87MODEI12 0 "register_operand" "")
5197         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5198    (use (match_operand:HI 2 "memory_operand" ""))
5199    (use (match_operand:HI 3 "memory_operand" ""))
5200    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5201   "reload_completed"
5202   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
5203               (use (match_dup 2))
5204               (use (match_dup 3))])
5205    (set (match_dup 0) (match_dup 4))]
5206   "")
5207
5208 (define_split
5209   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
5210         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5211    (use (match_operand:HI 2 "memory_operand" ""))
5212    (use (match_operand:HI 3 "memory_operand" ""))
5213    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5214   "reload_completed"
5215   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
5216               (use (match_dup 2))
5217               (use (match_dup 3))])]
5218   "")
5219
5220 (define_insn "x86_fnstcw_1"
5221   [(set (match_operand:HI 0 "memory_operand" "=m")
5222         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
5223   "TARGET_80387"
5224   "fnstcw\t%0"
5225   [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5226    (set_attr "mode" "HI")
5227    (set_attr "unit" "i387")])
5228
5229 (define_insn "x86_fldcw_1"
5230   [(set (reg:HI FPCR_REG)
5231         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
5232   "TARGET_80387"
5233   "fldcw\t%0"
5234   [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5235    (set_attr "mode" "HI")
5236    (set_attr "unit" "i387")
5237    (set_attr "athlon_decode" "vector")
5238    (set_attr "amdfam10_decode" "vector")])
5239 \f
5240 ;; Conversion between fixed point and floating point.
5241
5242 ;; Even though we only accept memory inputs, the backend _really_
5243 ;; wants to be able to do this between registers.
5244
5245 (define_expand "floathi<mode>2"
5246   [(set (match_operand:X87MODEF 0 "register_operand" "")
5247         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
5248   "TARGET_80387
5249    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5250        || TARGET_MIX_SSE_I387)"
5251   "")
5252
5253 ;; Pre-reload splitter to add memory clobber to the pattern.
5254 (define_insn_and_split "*floathi<mode>2_1"
5255   [(set (match_operand:X87MODEF 0 "register_operand" "")
5256         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
5257   "TARGET_80387
5258    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5259        || TARGET_MIX_SSE_I387)
5260    && can_create_pseudo_p ()"
5261   "#"
5262   "&& 1"
5263   [(parallel [(set (match_dup 0)
5264               (float:X87MODEF (match_dup 1)))
5265    (clobber (match_dup 2))])]
5266   "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
5267
5268 (define_insn "*floathi<mode>2_i387_with_temp"
5269   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5270         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
5271   (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
5272   "TARGET_80387
5273    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5274        || TARGET_MIX_SSE_I387)"
5275   "#"
5276   [(set_attr "type" "fmov,multi")
5277    (set_attr "mode" "<MODE>")
5278    (set_attr "unit" "*,i387")
5279    (set_attr "fp_int_src" "true")])
5280
5281 (define_insn "*floathi<mode>2_i387"
5282   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5283         (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
5284   "TARGET_80387
5285    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5286        || TARGET_MIX_SSE_I387)"
5287   "fild%Z1\t%1"
5288   [(set_attr "type" "fmov")
5289    (set_attr "mode" "<MODE>")
5290    (set_attr "fp_int_src" "true")])
5291
5292 (define_split
5293   [(set (match_operand:X87MODEF 0 "register_operand" "")
5294         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
5295    (clobber (match_operand:HI 2 "memory_operand" ""))]
5296   "TARGET_80387
5297    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5298        || TARGET_MIX_SSE_I387)
5299    && reload_completed"
5300   [(set (match_dup 2) (match_dup 1))
5301    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5302   "")
5303
5304 (define_split
5305   [(set (match_operand:X87MODEF 0 "register_operand" "")
5306         (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
5307    (clobber (match_operand:HI 2 "memory_operand" ""))]
5308    "TARGET_80387
5309     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5310         || TARGET_MIX_SSE_I387)
5311     && reload_completed"
5312   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5313   "")
5314
5315 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
5316   [(set (match_operand:X87MODEF 0 "register_operand" "")
5317         (float:X87MODEF
5318           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
5319   "TARGET_80387
5320    || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5321        && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
5322 {
5323   if (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5324         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5325       && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode))
5326     {
5327       rtx reg = gen_reg_rtx (XFmode);
5328       rtx insn;
5329
5330       emit_insn (gen_float<SSEMODEI24:mode>xf2 (reg, operands[1]));
5331
5332       if (<X87MODEF:MODE>mode == SFmode)
5333         insn = gen_truncxfsf2 (operands[0], reg);
5334       else if (<X87MODEF:MODE>mode == DFmode)
5335         insn = gen_truncxfdf2 (operands[0], reg);
5336       else
5337         gcc_unreachable ();
5338
5339       emit_insn (insn);
5340       DONE;
5341     }
5342 })
5343
5344 ;; Pre-reload splitter to add memory clobber to the pattern.
5345 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
5346   [(set (match_operand:X87MODEF 0 "register_operand" "")
5347         (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
5348   "((TARGET_80387
5349      && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5350      && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5351            && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5352          || TARGET_MIX_SSE_I387))
5353     || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5354         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
5355         && ((<SSEMODEI24:MODE>mode == SImode
5356              && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
5357              && optimize_function_for_speed_p (cfun)
5358              && flag_trapping_math)
5359             || !(TARGET_INTER_UNIT_CONVERSIONS
5360                  || optimize_function_for_size_p (cfun)))))
5361    && can_create_pseudo_p ()"
5362   "#"
5363   "&& 1"
5364   [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
5365               (clobber (match_dup 2))])]
5366 {
5367   operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
5368
5369   /* Avoid store forwarding (partial memory) stall penalty
5370      by passing DImode value through XMM registers.  */
5371   if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
5372       && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5373       && optimize_function_for_speed_p (cfun))
5374     {
5375       emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
5376                                                             operands[1],
5377                                                             operands[2]));
5378       DONE;
5379     }
5380 })
5381
5382 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
5383   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
5384         (float:MODEF
5385           (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
5386    (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
5387   "TARGET_SSE2 && TARGET_MIX_SSE_I387
5388    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5389   "#"
5390   [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
5391    (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
5392    (set_attr "unit" "*,i387,*,*,*")
5393    (set_attr "athlon_decode" "*,*,double,direct,double")
5394    (set_attr "amdfam10_decode" "*,*,vector,double,double")
5395    (set_attr "fp_int_src" "true")])
5396
5397 (define_insn "*floatsi<mode>2_vector_mixed"
5398   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5399         (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
5400   "TARGET_SSE2 && TARGET_MIX_SSE_I387
5401    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5402   "@
5403    fild%Z1\t%1
5404    #"
5405   [(set_attr "type" "fmov,sseicvt")
5406    (set_attr "mode" "<MODE>,<ssevecmode>")
5407    (set_attr "unit" "i387,*")
5408    (set_attr "athlon_decode" "*,direct")
5409    (set_attr "amdfam10_decode" "*,double")
5410    (set_attr "fp_int_src" "true")])
5411
5412 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
5413   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
5414         (float:MODEF
5415           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
5416   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
5417   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5418    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
5419   "#"
5420   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5421    (set_attr "mode" "<MODEF:MODE>")
5422    (set_attr "unit" "*,i387,*,*")
5423    (set_attr "athlon_decode" "*,*,double,direct")
5424    (set_attr "amdfam10_decode" "*,*,vector,double")
5425    (set_attr "fp_int_src" "true")])
5426
5427 (define_split
5428   [(set (match_operand:MODEF 0 "register_operand" "")
5429         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5430    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5431   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5432    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5433    && TARGET_INTER_UNIT_CONVERSIONS
5434    && reload_completed
5435    && (SSE_REG_P (operands[0])
5436        || (GET_CODE (operands[0]) == SUBREG
5437            && SSE_REG_P (operands[0])))"
5438   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5439   "")
5440
5441 (define_split
5442   [(set (match_operand:MODEF 0 "register_operand" "")
5443         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5444    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5445   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5446    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5447    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5448    && reload_completed
5449    && (SSE_REG_P (operands[0])
5450        || (GET_CODE (operands[0]) == SUBREG
5451            && SSE_REG_P (operands[0])))"
5452   [(set (match_dup 2) (match_dup 1))
5453    (set (match_dup 0) (float:MODEF (match_dup 2)))]
5454   "")
5455
5456 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5457   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5458         (float:MODEF
5459           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
5460   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5461    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5462    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5463   "@
5464    fild%Z1\t%1
5465    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
5466    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5467   [(set_attr "type" "fmov,sseicvt,sseicvt")
5468    (set_attr "prefix" "orig,maybe_vex,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 "unit" "i387,*,*")
5477    (set_attr "athlon_decode" "*,double,direct")
5478    (set_attr "amdfam10_decode" "*,vector,double")
5479    (set_attr "fp_int_src" "true")])
5480
5481 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5482   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5483         (float:MODEF
5484           (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5485   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5486    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5487    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5488   "@
5489    fild%Z1\t%1
5490    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5491   [(set_attr "type" "fmov,sseicvt")
5492    (set_attr "prefix" "orig,maybe_vex")
5493    (set_attr "mode" "<MODEF:MODE>")
5494    (set (attr "prefix_rex")
5495      (if_then_else
5496        (and (eq_attr "prefix" "maybe_vex")
5497             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5498        (const_string "1")
5499        (const_string "*")))
5500    (set_attr "athlon_decode" "*,direct")
5501    (set_attr "amdfam10_decode" "*,double")
5502    (set_attr "fp_int_src" "true")])
5503
5504 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5505   [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5506         (float:MODEF
5507           (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5508    (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5509   "TARGET_SSE2 && TARGET_SSE_MATH
5510    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5511   "#"
5512   [(set_attr "type" "sseicvt")
5513    (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5514    (set_attr "athlon_decode" "double,direct,double")
5515    (set_attr "amdfam10_decode" "vector,double,double")
5516    (set_attr "fp_int_src" "true")])
5517
5518 (define_insn "*floatsi<mode>2_vector_sse"
5519   [(set (match_operand:MODEF 0 "register_operand" "=x")
5520         (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5521   "TARGET_SSE2 && TARGET_SSE_MATH
5522    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5523   "#"
5524   [(set_attr "type" "sseicvt")
5525    (set_attr "mode" "<MODE>")
5526    (set_attr "athlon_decode" "direct")
5527    (set_attr "amdfam10_decode" "double")
5528    (set_attr "fp_int_src" "true")])
5529
5530 (define_split
5531   [(set (match_operand:MODEF 0 "register_operand" "")
5532         (float:MODEF (match_operand:SI 1 "register_operand" "")))
5533    (clobber (match_operand:SI 2 "memory_operand" ""))]
5534   "TARGET_SSE2 && TARGET_SSE_MATH
5535    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5536    && reload_completed
5537    && (SSE_REG_P (operands[0])
5538        || (GET_CODE (operands[0]) == SUBREG
5539            && SSE_REG_P (operands[0])))"
5540   [(const_int 0)]
5541 {
5542   rtx op1 = operands[1];
5543
5544   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5545                                      <MODE>mode, 0);
5546   if (GET_CODE (op1) == SUBREG)
5547     op1 = SUBREG_REG (op1);
5548
5549   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5550     {
5551       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5552       emit_insn (gen_sse2_loadld (operands[4],
5553                                   CONST0_RTX (V4SImode), operands[1]));
5554     }
5555   /* We can ignore possible trapping value in the
5556      high part of SSE register for non-trapping math. */
5557   else if (SSE_REG_P (op1) && !flag_trapping_math)
5558     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5559   else
5560     {
5561       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5562       emit_move_insn (operands[2], operands[1]);
5563       emit_insn (gen_sse2_loadld (operands[4],
5564                                   CONST0_RTX (V4SImode), operands[2]));
5565     }
5566   emit_insn
5567     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5568   DONE;
5569 })
5570
5571 (define_split
5572   [(set (match_operand:MODEF 0 "register_operand" "")
5573         (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5574    (clobber (match_operand:SI 2 "memory_operand" ""))]
5575   "TARGET_SSE2 && TARGET_SSE_MATH
5576    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5577    && reload_completed
5578    && (SSE_REG_P (operands[0])
5579        || (GET_CODE (operands[0]) == SUBREG
5580            && SSE_REG_P (operands[0])))"
5581   [(const_int 0)]
5582 {
5583   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5584                                      <MODE>mode, 0);
5585   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5586
5587   emit_insn (gen_sse2_loadld (operands[4],
5588                               CONST0_RTX (V4SImode), operands[1]));
5589   emit_insn
5590     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5591   DONE;
5592 })
5593
5594 (define_split
5595   [(set (match_operand:MODEF 0 "register_operand" "")
5596         (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5597   "TARGET_SSE2 && TARGET_SSE_MATH
5598    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5599    && reload_completed
5600    && (SSE_REG_P (operands[0])
5601        || (GET_CODE (operands[0]) == SUBREG
5602            && SSE_REG_P (operands[0])))"
5603   [(const_int 0)]
5604 {
5605   rtx op1 = operands[1];
5606
5607   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5608                                      <MODE>mode, 0);
5609   if (GET_CODE (op1) == SUBREG)
5610     op1 = SUBREG_REG (op1);
5611
5612   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5613     {
5614       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5615       emit_insn (gen_sse2_loadld (operands[4],
5616                                   CONST0_RTX (V4SImode), operands[1]));
5617     }
5618   /* We can ignore possible trapping value in the
5619      high part of SSE register for non-trapping math. */
5620   else if (SSE_REG_P (op1) && !flag_trapping_math)
5621     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5622   else
5623     gcc_unreachable ();
5624   emit_insn
5625     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5626   DONE;
5627 })
5628
5629 (define_split
5630   [(set (match_operand:MODEF 0 "register_operand" "")
5631         (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5632   "TARGET_SSE2 && TARGET_SSE_MATH
5633    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5634    && reload_completed
5635    && (SSE_REG_P (operands[0])
5636        || (GET_CODE (operands[0]) == SUBREG
5637            && SSE_REG_P (operands[0])))"
5638   [(const_int 0)]
5639 {
5640   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5641                                      <MODE>mode, 0);
5642   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5643
5644   emit_insn (gen_sse2_loadld (operands[4],
5645                               CONST0_RTX (V4SImode), operands[1]));
5646   emit_insn
5647     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5648   DONE;
5649 })
5650
5651 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5652   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5653         (float:MODEF
5654           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5655   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5656   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5657    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5658   "#"
5659   [(set_attr "type" "sseicvt")
5660    (set_attr "mode" "<MODEF:MODE>")
5661    (set_attr "athlon_decode" "double,direct")
5662    (set_attr "amdfam10_decode" "vector,double")
5663    (set_attr "fp_int_src" "true")])
5664
5665 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5666   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5667         (float:MODEF
5668           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5669   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5670    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5671    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5672   "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5673   [(set_attr "type" "sseicvt")
5674    (set_attr "prefix" "maybe_vex")
5675    (set_attr "mode" "<MODEF:MODE>")
5676    (set (attr "prefix_rex")
5677      (if_then_else
5678        (and (eq_attr "prefix" "maybe_vex")
5679             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5680        (const_string "1")
5681        (const_string "*")))
5682    (set_attr "athlon_decode" "double,direct")
5683    (set_attr "amdfam10_decode" "vector,double")
5684    (set_attr "fp_int_src" "true")])
5685
5686 (define_split
5687   [(set (match_operand:MODEF 0 "register_operand" "")
5688         (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5689    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5690   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5691    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5692    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5693    && reload_completed
5694    && (SSE_REG_P (operands[0])
5695        || (GET_CODE (operands[0]) == SUBREG
5696            && SSE_REG_P (operands[0])))"
5697   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5698   "")
5699
5700 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5701   [(set (match_operand:MODEF 0 "register_operand" "=x")
5702         (float:MODEF
5703           (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5704   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5705    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5706    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5707   "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5708   [(set_attr "type" "sseicvt")
5709    (set_attr "prefix" "maybe_vex")
5710    (set_attr "mode" "<MODEF:MODE>")
5711    (set (attr "prefix_rex")
5712      (if_then_else
5713        (and (eq_attr "prefix" "maybe_vex")
5714             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5715        (const_string "1")
5716        (const_string "*")))
5717    (set_attr "athlon_decode" "direct")
5718    (set_attr "amdfam10_decode" "double")
5719    (set_attr "fp_int_src" "true")])
5720
5721 (define_split
5722   [(set (match_operand:MODEF 0 "register_operand" "")
5723         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5724    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5725   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5726    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5727    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5728    && reload_completed
5729    && (SSE_REG_P (operands[0])
5730        || (GET_CODE (operands[0]) == SUBREG
5731            && SSE_REG_P (operands[0])))"
5732   [(set (match_dup 2) (match_dup 1))
5733    (set (match_dup 0) (float:MODEF (match_dup 2)))]
5734   "")
5735
5736 (define_split
5737   [(set (match_operand:MODEF 0 "register_operand" "")
5738         (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5739    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5740   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5741    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5742    && reload_completed
5743    && (SSE_REG_P (operands[0])
5744        || (GET_CODE (operands[0]) == SUBREG
5745            && SSE_REG_P (operands[0])))"
5746   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5747   "")
5748
5749 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5750   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5751         (float:X87MODEF
5752           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5753   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5754   "TARGET_80387
5755    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5756   "@
5757    fild%Z1\t%1
5758    #"
5759   [(set_attr "type" "fmov,multi")
5760    (set_attr "mode" "<X87MODEF:MODE>")
5761    (set_attr "unit" "*,i387")
5762    (set_attr "fp_int_src" "true")])
5763
5764 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5765   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5766         (float:X87MODEF
5767           (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5768   "TARGET_80387
5769    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5770   "fild%Z1\t%1"
5771   [(set_attr "type" "fmov")
5772    (set_attr "mode" "<X87MODEF:MODE>")
5773    (set_attr "fp_int_src" "true")])
5774
5775 (define_split
5776   [(set (match_operand:X87MODEF 0 "register_operand" "")
5777         (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5778    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5779   "TARGET_80387
5780    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5781    && reload_completed
5782    && FP_REG_P (operands[0])"
5783   [(set (match_dup 2) (match_dup 1))
5784    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5785   "")
5786
5787 (define_split
5788   [(set (match_operand:X87MODEF 0 "register_operand" "")
5789         (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5790    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5791   "TARGET_80387
5792    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5793    && reload_completed
5794    && FP_REG_P (operands[0])"
5795   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5796   "")
5797
5798 ;; Avoid store forwarding (partial memory) stall penalty
5799 ;; by passing DImode value through XMM registers.  */
5800
5801 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5802   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5803         (float:X87MODEF
5804           (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5805    (clobber (match_scratch:V4SI 3 "=X,x"))
5806    (clobber (match_scratch:V4SI 4 "=X,x"))
5807    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5808   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5809    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5810    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5811   "#"
5812   [(set_attr "type" "multi")
5813    (set_attr "mode" "<X87MODEF:MODE>")
5814    (set_attr "unit" "i387")
5815    (set_attr "fp_int_src" "true")])
5816
5817 (define_split
5818   [(set (match_operand:X87MODEF 0 "register_operand" "")
5819         (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5820    (clobber (match_scratch:V4SI 3 ""))
5821    (clobber (match_scratch:V4SI 4 ""))
5822    (clobber (match_operand:DI 2 "memory_operand" ""))]
5823   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5824    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5825    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5826    && reload_completed
5827    && FP_REG_P (operands[0])"
5828   [(set (match_dup 2) (match_dup 3))
5829    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5830 {
5831   /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5832      Assemble the 64-bit DImode value in an xmm register.  */
5833   emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5834                               gen_rtx_SUBREG (SImode, operands[1], 0)));
5835   emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5836                               gen_rtx_SUBREG (SImode, operands[1], 4)));
5837   emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5838                                          operands[4]));
5839
5840   operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5841 })
5842
5843 (define_split
5844   [(set (match_operand:X87MODEF 0 "register_operand" "")
5845         (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5846    (clobber (match_scratch:V4SI 3 ""))
5847    (clobber (match_scratch:V4SI 4 ""))
5848    (clobber (match_operand:DI 2 "memory_operand" ""))]
5849   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5850    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5851    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5852    && reload_completed
5853    && FP_REG_P (operands[0])"
5854   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5855   "")
5856
5857 ;; Avoid store forwarding (partial memory) stall penalty by extending
5858 ;; SImode value to DImode through XMM register instead of pushing two
5859 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5860 ;; targets benefit from this optimization. Also note that fild
5861 ;; loads from memory only.
5862
5863 (define_insn "*floatunssi<mode>2_1"
5864   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5865         (unsigned_float:X87MODEF
5866           (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5867    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5868    (clobber (match_scratch:SI 3 "=X,x"))]
5869   "!TARGET_64BIT
5870    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5871    && TARGET_SSE"
5872   "#"
5873   [(set_attr "type" "multi")
5874    (set_attr "mode" "<MODE>")])
5875
5876 (define_split
5877   [(set (match_operand:X87MODEF 0 "register_operand" "")
5878         (unsigned_float:X87MODEF
5879           (match_operand:SI 1 "register_operand" "")))
5880    (clobber (match_operand:DI 2 "memory_operand" ""))
5881    (clobber (match_scratch:SI 3 ""))]
5882   "!TARGET_64BIT
5883    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5884    && TARGET_SSE
5885    && reload_completed"
5886   [(set (match_dup 2) (match_dup 1))
5887    (set (match_dup 0)
5888         (float:X87MODEF (match_dup 2)))]
5889   "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5890
5891 (define_split
5892   [(set (match_operand:X87MODEF 0 "register_operand" "")
5893         (unsigned_float:X87MODEF
5894           (match_operand:SI 1 "memory_operand" "")))
5895    (clobber (match_operand:DI 2 "memory_operand" ""))
5896    (clobber (match_scratch:SI 3 ""))]
5897   "!TARGET_64BIT
5898    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5899    && TARGET_SSE
5900    && reload_completed"
5901   [(set (match_dup 2) (match_dup 3))
5902    (set (match_dup 0)
5903         (float:X87MODEF (match_dup 2)))]
5904 {
5905   emit_move_insn (operands[3], operands[1]);
5906   operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5907 })
5908
5909 (define_expand "floatunssi<mode>2"
5910   [(parallel
5911      [(set (match_operand:X87MODEF 0 "register_operand" "")
5912            (unsigned_float:X87MODEF
5913              (match_operand:SI 1 "nonimmediate_operand" "")))
5914       (clobber (match_dup 2))
5915       (clobber (match_scratch:SI 3 ""))])]
5916   "!TARGET_64BIT
5917    && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5918         && TARGET_SSE)
5919        || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5920 {
5921   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5922     {
5923       ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5924       DONE;
5925     }
5926   else
5927     {
5928       enum ix86_stack_slot slot = (virtuals_instantiated
5929                                    ? SLOT_TEMP
5930                                    : SLOT_VIRTUAL);
5931       operands[2] = assign_386_stack_local (DImode, slot);
5932     }
5933 })
5934
5935 (define_expand "floatunsdisf2"
5936   [(use (match_operand:SF 0 "register_operand" ""))
5937    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5938   "TARGET_64BIT && TARGET_SSE_MATH"
5939   "x86_emit_floatuns (operands); DONE;")
5940
5941 (define_expand "floatunsdidf2"
5942   [(use (match_operand:DF 0 "register_operand" ""))
5943    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5944   "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5945    && TARGET_SSE2 && TARGET_SSE_MATH"
5946 {
5947   if (TARGET_64BIT)
5948     x86_emit_floatuns (operands);
5949   else
5950     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5951   DONE;
5952 })
5953 \f
5954 ;; Add instructions
5955
5956 (define_expand "add<mode>3"
5957   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5958         (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5959                     (match_operand:SDWIM 2 "<general_operand>" "")))]
5960   ""
5961   "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5962
5963 (define_insn_and_split "*add<dwi>3_doubleword"
5964   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5965         (plus:<DWI>
5966           (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5967           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5968    (clobber (reg:CC FLAGS_REG))]
5969   "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5970   "#"
5971   "reload_completed"
5972   [(parallel [(set (reg:CC FLAGS_REG)
5973                    (unspec:CC [(match_dup 1) (match_dup 2)]
5974                               UNSPEC_ADD_CARRY))
5975               (set (match_dup 0)
5976                    (plus:DWIH (match_dup 1) (match_dup 2)))])
5977    (parallel [(set (match_dup 3)
5978                    (plus:DWIH
5979                      (match_dup 4)
5980                      (plus:DWIH
5981                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5982                        (match_dup 5))))
5983               (clobber (reg:CC FLAGS_REG))])]
5984   "split_<dwi> (&operands[0], 3, &operands[0], &operands[3]);")
5985
5986 (define_insn "*add<mode>3_cc"
5987   [(set (reg:CC FLAGS_REG)
5988         (unspec:CC
5989           [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5990            (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5991           UNSPEC_ADD_CARRY))
5992    (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5993         (plus:SWI48 (match_dup 1) (match_dup 2)))]
5994   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5995   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5996   [(set_attr "type" "alu")
5997    (set_attr "mode" "<MODE>")])
5998
5999 (define_insn "addqi3_cc"
6000   [(set (reg:CC FLAGS_REG)
6001         (unspec:CC
6002           [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
6003            (match_operand:QI 2 "general_operand" "qn,qm")]
6004           UNSPEC_ADD_CARRY))
6005    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6006         (plus:QI (match_dup 1) (match_dup 2)))]
6007   "ix86_binary_operator_ok (PLUS, QImode, operands)"
6008   "add{b}\t{%2, %0|%0, %2}"
6009   [(set_attr "type" "alu")
6010    (set_attr "mode" "QI")])
6011
6012 (define_insn "*lea_1"
6013   [(set (match_operand:DWIH 0 "register_operand" "=r")
6014         (match_operand:DWIH 1 "no_seg_address_operand" "p"))]
6015   ""
6016   "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
6017   [(set_attr "type" "lea")
6018    (set_attr "mode" "<MODE>")])
6019
6020 (define_insn "*lea_2"
6021   [(set (match_operand:SI 0 "register_operand" "=r")
6022         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
6023   "TARGET_64BIT"
6024   "lea{l}\t{%a1, %0|%0, %a1}"
6025   [(set_attr "type" "lea")
6026    (set_attr "mode" "SI")])
6027
6028 (define_insn "*lea_2_zext"
6029   [(set (match_operand:DI 0 "register_operand" "=r")
6030         (zero_extend:DI
6031           (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
6032   "TARGET_64BIT"
6033   "lea{l}\t{%a1, %k0|%k0, %a1}"
6034   [(set_attr "type" "lea")
6035    (set_attr "mode" "SI")])
6036
6037 (define_insn "*add<mode>_1"
6038   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
6039         (plus:SWI48
6040           (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
6041           (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,0,l<i>")))
6042    (clobber (reg:CC FLAGS_REG))]
6043   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6044 {
6045   switch (get_attr_type (insn))
6046     {
6047     case TYPE_LEA:
6048       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6049       return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
6050
6051     case TYPE_INCDEC:
6052       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6053       if (operands[2] == const1_rtx)
6054         return "inc{<imodesuffix>}\t%0";
6055       else
6056         {
6057           gcc_assert (operands[2] == constm1_rtx);
6058           return "dec{<imodesuffix>}\t%0";
6059         }
6060
6061     default:
6062       /* Use add as much as possible to replace lea for AGU optimization. */
6063       if (which_alternative == 2 && TARGET_OPT_AGU)
6064         return "add{<imodesuffix>}\t{%1, %0|%0, %1}";
6065         
6066       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6067       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6068         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6069
6070       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6071     }
6072 }
6073   [(set (attr "type")
6074      (cond [(and (eq_attr "alternative" "2") 
6075                  (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
6076               (const_string "lea")
6077             (eq_attr "alternative" "3")
6078               (const_string "lea")
6079             ; Current assemblers are broken and do not allow @GOTOFF in
6080             ; ought but a memory context.
6081             (match_operand:SWI48 2 "pic_symbolic_operand" "")
6082               (const_string "lea")
6083             (match_operand:SWI48 2 "incdec_operand" "")
6084               (const_string "incdec")
6085            ]
6086            (const_string "alu")))
6087    (set (attr "length_immediate")
6088       (if_then_else
6089         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6090         (const_string "1")
6091         (const_string "*")))
6092    (set_attr "mode" "<MODE>")])
6093
6094 ;; It may seem that nonimmediate operand is proper one for operand 1.
6095 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6096 ;; we take care in ix86_binary_operator_ok to not allow two memory
6097 ;; operands so proper swapping will be done in reload.  This allow
6098 ;; patterns constructed from addsi_1 to match.
6099
6100 (define_insn "*addsi_1_zext"
6101   [(set (match_operand:DI 0 "register_operand" "=r,r")
6102         (zero_extend:DI
6103           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6104                    (match_operand:SI 2 "general_operand" "g,li"))))
6105    (clobber (reg:CC FLAGS_REG))]
6106   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6107 {
6108   switch (get_attr_type (insn))
6109     {
6110     case TYPE_LEA:
6111       operands[2] = XEXP (SET_SRC (XVECEXP (PATTERN (insn), 0, 0)), 0);
6112       return "lea{l}\t{%a2, %k0|%k0, %a2}";
6113
6114     case TYPE_INCDEC:
6115       if (operands[2] == const1_rtx)
6116         return "inc{l}\t%k0";
6117       else
6118         {
6119           gcc_assert (operands[2] == constm1_rtx);
6120           return "dec{l}\t%k0";
6121         }
6122
6123     default:
6124       if (x86_maybe_negate_const_int (&operands[2], SImode))
6125         return "sub{l}\t{%2, %k0|%k0, %2}";
6126
6127       return "add{l}\t{%2, %k0|%k0, %2}";
6128     }
6129 }
6130   [(set (attr "type")
6131      (cond [(eq_attr "alternative" "1")
6132               (const_string "lea")
6133             ; Current assemblers are broken and do not allow @GOTOFF in
6134             ; ought but a memory context.
6135             (match_operand:SI 2 "pic_symbolic_operand" "")
6136               (const_string "lea")
6137             (match_operand:SI 2 "incdec_operand" "")
6138               (const_string "incdec")
6139            ]
6140            (const_string "alu")))
6141    (set (attr "length_immediate")
6142       (if_then_else
6143         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6144         (const_string "1")
6145         (const_string "*")))
6146    (set_attr "mode" "SI")])
6147
6148 (define_insn "*addhi_1"
6149   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6150         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6151                  (match_operand:HI 2 "general_operand" "rn,rm")))
6152    (clobber (reg:CC FLAGS_REG))]
6153   "TARGET_PARTIAL_REG_STALL
6154    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6155 {
6156   switch (get_attr_type (insn))
6157     {
6158     case TYPE_INCDEC:
6159       if (operands[2] == const1_rtx)
6160         return "inc{w}\t%0";
6161       else
6162         {
6163           gcc_assert (operands[2] == constm1_rtx);
6164           return "dec{w}\t%0";
6165         }
6166
6167     default:
6168       if (x86_maybe_negate_const_int (&operands[2], HImode))
6169         return "sub{w}\t{%2, %0|%0, %2}";
6170
6171       return "add{w}\t{%2, %0|%0, %2}";
6172     }
6173 }
6174   [(set (attr "type")
6175      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6176         (const_string "incdec")
6177         (const_string "alu")))
6178    (set (attr "length_immediate")
6179       (if_then_else
6180         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6181         (const_string "1")
6182         (const_string "*")))
6183    (set_attr "mode" "HI")])
6184
6185 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6186 ;; type optimizations enabled by define-splits.  This is not important
6187 ;; for PII, and in fact harmful because of partial register stalls.
6188
6189 (define_insn "*addhi_1_lea"
6190   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6191         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6192                  (match_operand:HI 2 "general_operand" "rn,rm,ln")))
6193    (clobber (reg:CC FLAGS_REG))]
6194   "!TARGET_PARTIAL_REG_STALL
6195    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6196 {
6197   switch (get_attr_type (insn))
6198     {
6199     case TYPE_LEA:
6200       return "#";
6201     case TYPE_INCDEC:
6202       if (operands[2] == const1_rtx)
6203         return "inc{w}\t%0";
6204       else
6205         {
6206           gcc_assert (operands[2] == constm1_rtx);
6207           return "dec{w}\t%0";
6208         }
6209
6210     default:
6211       if (x86_maybe_negate_const_int (&operands[2], HImode))
6212         return "sub{w}\t{%2, %0|%0, %2}";
6213
6214       return "add{w}\t{%2, %0|%0, %2}";
6215     }
6216 }
6217   [(set (attr "type")
6218      (if_then_else (eq_attr "alternative" "2")
6219         (const_string "lea")
6220         (if_then_else (match_operand:HI 2 "incdec_operand" "")
6221            (const_string "incdec")
6222            (const_string "alu"))))
6223    (set (attr "length_immediate")
6224       (if_then_else
6225         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6226         (const_string "1")
6227         (const_string "*")))
6228    (set_attr "mode" "HI,HI,SI")])
6229
6230 (define_insn "*addqi_1"
6231   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6232         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6233                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6234    (clobber (reg:CC FLAGS_REG))]
6235   "TARGET_PARTIAL_REG_STALL
6236    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6237 {
6238   int widen = (which_alternative == 2);
6239   switch (get_attr_type (insn))
6240     {
6241     case TYPE_INCDEC:
6242       if (operands[2] == const1_rtx)
6243         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6244       else
6245         {
6246           gcc_assert (operands[2] == constm1_rtx);
6247           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6248         }
6249
6250     default:
6251       if (x86_maybe_negate_const_int (&operands[2], QImode))
6252         {
6253           if (widen)
6254             return "sub{l}\t{%2, %k0|%k0, %2}";
6255           else
6256             return "sub{b}\t{%2, %0|%0, %2}";
6257         }
6258       if (widen)
6259         return "add{l}\t{%k2, %k0|%k0, %k2}";
6260       else
6261         return "add{b}\t{%2, %0|%0, %2}";
6262     }
6263 }
6264   [(set (attr "type")
6265      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6266         (const_string "incdec")
6267         (const_string "alu")))
6268    (set (attr "length_immediate")
6269       (if_then_else
6270         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6271         (const_string "1")
6272         (const_string "*")))
6273    (set_attr "mode" "QI,QI,SI")])
6274
6275 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6276 (define_insn "*addqi_1_lea"
6277   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6278         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6279                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6280    (clobber (reg:CC FLAGS_REG))]
6281   "!TARGET_PARTIAL_REG_STALL
6282    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6283 {
6284   int widen = (which_alternative == 2);
6285   switch (get_attr_type (insn))
6286     {
6287     case TYPE_LEA:
6288       return "#";
6289     case TYPE_INCDEC:
6290       if (operands[2] == const1_rtx)
6291         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6292       else
6293         {
6294           gcc_assert (operands[2] == constm1_rtx);
6295           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6296         }
6297
6298     default:
6299       if (x86_maybe_negate_const_int (&operands[2], QImode))
6300         {
6301           if (widen)
6302             return "sub{l}\t{%2, %k0|%k0, %2}";
6303           else
6304             return "sub{b}\t{%2, %0|%0, %2}";
6305         }
6306       if (widen)
6307         return "add{l}\t{%k2, %k0|%k0, %k2}";
6308       else
6309         return "add{b}\t{%2, %0|%0, %2}";
6310     }
6311 }
6312   [(set (attr "type")
6313      (if_then_else (eq_attr "alternative" "3")
6314         (const_string "lea")
6315         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6316            (const_string "incdec")
6317            (const_string "alu"))))
6318    (set (attr "length_immediate")
6319       (if_then_else
6320         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6321         (const_string "1")
6322         (const_string "*")))
6323    (set_attr "mode" "QI,QI,SI,SI")])
6324
6325 (define_insn "*addqi_1_slp"
6326   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6327         (plus:QI (match_dup 0)
6328                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6329    (clobber (reg:CC FLAGS_REG))]
6330   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6331    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6332 {
6333   switch (get_attr_type (insn))
6334     {
6335     case TYPE_INCDEC:
6336       if (operands[1] == const1_rtx)
6337         return "inc{b}\t%0";
6338       else
6339         {
6340           gcc_assert (operands[1] == constm1_rtx);
6341           return "dec{b}\t%0";
6342         }
6343
6344     default:
6345       if (x86_maybe_negate_const_int (&operands[1], QImode))
6346         return "sub{b}\t{%1, %0|%0, %1}";
6347
6348       return "add{b}\t{%1, %0|%0, %1}";
6349     }
6350 }
6351   [(set (attr "type")
6352      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6353         (const_string "incdec")
6354         (const_string "alu1")))
6355    (set (attr "memory")
6356      (if_then_else (match_operand 1 "memory_operand" "")
6357         (const_string "load")
6358         (const_string "none")))
6359    (set_attr "mode" "QI")])
6360
6361 (define_insn "*add<mode>_2"
6362   [(set (reg FLAGS_REG)
6363         (compare
6364           (plus:SWI48
6365             (match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
6366             (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>"))
6367           (const_int 0)))
6368    (set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm")
6369         (plus:SWI48 (match_dup 1) (match_dup 2)))]
6370   "ix86_match_ccmode (insn, CCGOCmode)
6371    && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
6372    /* Current assemblers are broken and do not allow @GOTOFF in
6373       ought but a memory context.  */
6374    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6375 {
6376   switch (get_attr_type (insn))
6377     {
6378     case TYPE_INCDEC:
6379       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6380       if (operands[2] == const1_rtx)
6381         return "inc{<imodesuffix>}\t%0";
6382       else
6383         {
6384           gcc_assert (operands[2] == constm1_rtx);
6385           return "dec{<imodesuffix>}\t%0";
6386         }
6387
6388     default:
6389       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6390       /* ???? In DImode, we ought to handle there the 32bit case too
6391          - do we need new constraint?  */
6392       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6393         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6394
6395       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6396     }
6397 }
6398   [(set (attr "type")
6399      (if_then_else (match_operand:SWI48 2 "incdec_operand" "")
6400         (const_string "incdec")
6401         (const_string "alu")))
6402    (set (attr "length_immediate")
6403       (if_then_else
6404         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6405         (const_string "1")
6406         (const_string "*")))
6407    (set_attr "mode" "<MODE>")])
6408
6409 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6410 (define_insn "*addsi_2_zext"
6411   [(set (reg FLAGS_REG)
6412         (compare
6413           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6414                    (match_operand:SI 2 "general_operand" "g"))
6415           (const_int 0)))
6416    (set (match_operand:DI 0 "register_operand" "=r")
6417         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6418   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6419    && ix86_binary_operator_ok (PLUS, SImode, operands)
6420    /* Current assemblers are broken and do not allow @GOTOFF in
6421       ought but a memory context.  */
6422    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6423 {
6424   switch (get_attr_type (insn))
6425     {
6426     case TYPE_INCDEC:
6427       if (operands[2] == const1_rtx)
6428         return "inc{l}\t%k0";
6429       else
6430         {
6431           gcc_assert (operands[2] == constm1_rtx);
6432           return "dec{l}\t%k0";
6433         }
6434
6435     default:
6436       if (x86_maybe_negate_const_int (&operands[2], SImode))
6437         return "sub{l}\t{%2, %k0|%k0, %2}";
6438
6439       return "add{l}\t{%2, %k0|%k0, %2}";
6440     }
6441 }
6442   [(set (attr "type")
6443      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6444         (const_string "incdec")
6445         (const_string "alu")))
6446    (set (attr "length_immediate")
6447       (if_then_else
6448         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6449         (const_string "1")
6450         (const_string "*")))
6451    (set_attr "mode" "SI")])
6452
6453 (define_insn "*addhi_2"
6454   [(set (reg FLAGS_REG)
6455         (compare
6456           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6457                    (match_operand:HI 2 "general_operand" "rmn,rn"))
6458           (const_int 0)))
6459    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6460         (plus:HI (match_dup 1) (match_dup 2)))]
6461   "ix86_match_ccmode (insn, CCGOCmode)
6462    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6463 {
6464   switch (get_attr_type (insn))
6465     {
6466     case TYPE_INCDEC:
6467       if (operands[2] == const1_rtx)
6468         return "inc{w}\t%0";
6469       else
6470         {
6471           gcc_assert (operands[2] == constm1_rtx);
6472           return "dec{w}\t%0";
6473         }
6474
6475     default:
6476       if (x86_maybe_negate_const_int (&operands[2], HImode))
6477         return "sub{w}\t{%2, %0|%0, %2}";
6478
6479       return "add{w}\t{%2, %0|%0, %2}";
6480     }
6481 }
6482   [(set (attr "type")
6483      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6484         (const_string "incdec")
6485         (const_string "alu")))
6486    (set (attr "length_immediate")
6487       (if_then_else
6488         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6489         (const_string "1")
6490         (const_string "*")))
6491    (set_attr "mode" "HI")])
6492
6493 (define_insn "*addqi_2"
6494   [(set (reg FLAGS_REG)
6495         (compare
6496           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6497                    (match_operand:QI 2 "general_operand" "qmn,qn"))
6498           (const_int 0)))
6499    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6500         (plus:QI (match_dup 1) (match_dup 2)))]
6501   "ix86_match_ccmode (insn, CCGOCmode)
6502    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6503 {
6504   switch (get_attr_type (insn))
6505     {
6506     case TYPE_INCDEC:
6507       if (operands[2] == const1_rtx)
6508         return "inc{b}\t%0";
6509       else
6510         {
6511           gcc_assert (operands[2] == constm1_rtx
6512                       || (CONST_INT_P (operands[2])
6513                           && INTVAL (operands[2]) == 255));
6514           return "dec{b}\t%0";
6515         }
6516
6517     default:
6518       if (x86_maybe_negate_const_int (&operands[2], QImode))
6519         return "sub{b}\t{%2, %0|%0, %2}";
6520
6521       return "add{b}\t{%2, %0|%0, %2}";
6522     }
6523 }
6524   [(set (attr "type")
6525      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6526         (const_string "incdec")
6527         (const_string "alu")))
6528    (set_attr "mode" "QI")])
6529
6530 (define_insn "*add<mode>_3"
6531   [(set (reg FLAGS_REG)
6532         (compare
6533           (neg:SWI48 (match_operand:SWI48 2 "<general_operand>" "<g>"))
6534           (match_operand:SWI48 1 "nonimmediate_operand" "%0")))
6535    (clobber (match_scratch:SWI48 0 "=r"))]
6536   "ix86_match_ccmode (insn, CCZmode)
6537    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6538    /* Current assemblers are broken and do not allow @GOTOFF in
6539       ought but a memory context.  */
6540    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6541 {
6542   switch (get_attr_type (insn))
6543     {
6544     case TYPE_INCDEC:
6545       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6546       if (operands[2] == const1_rtx)
6547         return "inc{<imodesuffix>}\t%0";
6548       else
6549         {
6550           gcc_assert (operands[2] == constm1_rtx);
6551           return "dec{<imodesuffix>}\t%0";
6552         }
6553
6554     default:
6555       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6556       /* ???? In DImode, we ought to handle there the 32bit case too
6557          - do we need new constraint?  */
6558       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6559         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6560
6561       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6562     }
6563 }
6564   [(set (attr "type")
6565      (if_then_else (match_operand:SWI48 2 "incdec_operand" "")
6566         (const_string "incdec")
6567         (const_string "alu")))
6568    (set (attr "length_immediate")
6569       (if_then_else
6570         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6571         (const_string "1")
6572         (const_string "*")))
6573    (set_attr "mode" "<MODE>")])
6574
6575 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6576 (define_insn "*addsi_3_zext"
6577   [(set (reg FLAGS_REG)
6578         (compare
6579           (neg:SI (match_operand:SI 2 "general_operand" "g"))
6580           (match_operand:SI 1 "nonimmediate_operand" "%0")))
6581    (set (match_operand:DI 0 "register_operand" "=r")
6582         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6583   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6584    && ix86_binary_operator_ok (PLUS, SImode, operands)
6585    /* Current assemblers are broken and do not allow @GOTOFF in
6586       ought but a memory context.  */
6587    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6588 {
6589   switch (get_attr_type (insn))
6590     {
6591     case TYPE_INCDEC:
6592       if (operands[2] == const1_rtx)
6593         return "inc{l}\t%k0";
6594       else
6595         {
6596           gcc_assert (operands[2] == constm1_rtx);
6597           return "dec{l}\t%k0";
6598         }
6599
6600     default:
6601       if (x86_maybe_negate_const_int (&operands[2], SImode))
6602         return "sub{l}\t{%2, %k0|%k0, %2}";
6603
6604       return "add{l}\t{%2, %k0|%k0, %2}";
6605     }
6606 }
6607   [(set (attr "type")
6608      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6609         (const_string "incdec")
6610         (const_string "alu")))
6611    (set (attr "length_immediate")
6612       (if_then_else
6613         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6614         (const_string "1")
6615         (const_string "*")))
6616    (set_attr "mode" "SI")])
6617
6618 (define_insn "*addhi_3"
6619   [(set (reg FLAGS_REG)
6620         (compare
6621           (neg:HI (match_operand:HI 2 "general_operand" "rmn"))
6622           (match_operand:HI 1 "nonimmediate_operand" "%0")))
6623    (clobber (match_scratch:HI 0 "=r"))]
6624   "ix86_match_ccmode (insn, CCZmode)
6625    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6626 {
6627   switch (get_attr_type (insn))
6628     {
6629     case TYPE_INCDEC:
6630       if (operands[2] == const1_rtx)
6631         return "inc{w}\t%0";
6632       else
6633         {
6634           gcc_assert (operands[2] == constm1_rtx);
6635           return "dec{w}\t%0";
6636         }
6637
6638     default:
6639       if (x86_maybe_negate_const_int (&operands[2], HImode))
6640         return "sub{w}\t{%2, %0|%0, %2}";
6641
6642       return "add{w}\t{%2, %0|%0, %2}";
6643     }
6644 }
6645   [(set (attr "type")
6646      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6647         (const_string "incdec")
6648         (const_string "alu")))
6649    (set (attr "length_immediate")
6650       (if_then_else
6651         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6652         (const_string "1")
6653         (const_string "*")))
6654    (set_attr "mode" "HI")])
6655
6656 (define_insn "*addqi_3"
6657   [(set (reg FLAGS_REG)
6658         (compare
6659           (neg:QI (match_operand:QI 2 "general_operand" "qmn"))
6660           (match_operand:QI 1 "nonimmediate_operand" "%0")))
6661    (clobber (match_scratch:QI 0 "=q"))]
6662   "ix86_match_ccmode (insn, CCZmode)
6663    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6664 {
6665   switch (get_attr_type (insn))
6666     {
6667     case TYPE_INCDEC:
6668       if (operands[2] == const1_rtx)
6669         return "inc{b}\t%0";
6670       else
6671         {
6672           gcc_assert (operands[2] == constm1_rtx
6673                       || (CONST_INT_P (operands[2])
6674                           && INTVAL (operands[2]) == 255));
6675           return "dec{b}\t%0";
6676         }
6677
6678     default:
6679       if (x86_maybe_negate_const_int (&operands[2], QImode))
6680         return "sub{b}\t{%2, %0|%0, %2}";
6681
6682       return "add{b}\t{%2, %0|%0, %2}";
6683     }
6684 }
6685   [(set (attr "type")
6686      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6687         (const_string "incdec")
6688         (const_string "alu")))
6689    (set_attr "mode" "QI")])
6690
6691 ; For comparisons against 1, -1 and 128, we may generate better code
6692 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6693 ; is matched then.  We can't accept general immediate, because for
6694 ; case of overflows,  the result is messed up.
6695 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6696 ; only for comparisons not depending on it.
6697
6698 (define_insn "*adddi_4"
6699   [(set (reg FLAGS_REG)
6700         (compare
6701           (match_operand:DI 1 "nonimmediate_operand" "0")
6702           (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6703    (clobber (match_scratch:DI 0 "=rm"))]
6704   "TARGET_64BIT
6705    && ix86_match_ccmode (insn, CCGCmode)"
6706 {
6707   switch (get_attr_type (insn))
6708     {
6709     case TYPE_INCDEC:
6710       if (operands[2] == constm1_rtx)
6711         return "inc{q}\t%0";
6712       else
6713         {
6714           gcc_assert (operands[2] == const1_rtx);
6715           return "dec{q}\t%0";
6716         }
6717
6718     default:
6719       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6720       if (x86_maybe_negate_const_int (&operands[2], DImode))
6721         return "add{q}\t{%2, %0|%0, %2}";
6722
6723       return "sub{q}\t{%2, %0|%0, %2}";
6724     }
6725 }
6726   [(set (attr "type")
6727      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6728         (const_string "incdec")
6729         (const_string "alu")))
6730    (set (attr "length_immediate")
6731       (if_then_else
6732         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6733         (const_string "1")
6734         (const_string "*")))
6735    (set_attr "mode" "DI")])
6736
6737 ; For comparisons against 1, -1 and 128, we may generate better code
6738 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6739 ; is matched then.  We can't accept general immediate, because for
6740 ; case of overflows,  the result is messed up.
6741 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6742 ; only for comparisons not depending on it.
6743
6744 (define_insn "*addsi_4"
6745   [(set (reg FLAGS_REG)
6746         (compare
6747           (match_operand:SI 1 "nonimmediate_operand" "0")
6748           (match_operand:SI 2 "const_int_operand" "n")))
6749    (clobber (match_scratch:SI 0 "=rm"))]
6750   "ix86_match_ccmode (insn, CCGCmode)"
6751 {
6752   switch (get_attr_type (insn))
6753     {
6754     case TYPE_INCDEC:
6755       if (operands[2] == constm1_rtx)
6756         return "inc{l}\t%0";
6757       else
6758         {
6759           gcc_assert (operands[2] == const1_rtx);
6760           return "dec{l}\t%0";
6761         }
6762
6763     default:
6764       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6765       if (x86_maybe_negate_const_int (&operands[2], SImode))
6766         return "add{l}\t{%2, %0|%0, %2}";
6767
6768       return "sub{l}\t{%2, %0|%0, %2}";
6769     }
6770 }
6771   [(set (attr "type")
6772      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6773         (const_string "incdec")
6774         (const_string "alu")))
6775    (set (attr "length_immediate")
6776       (if_then_else
6777         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6778         (const_string "1")
6779         (const_string "*")))
6780    (set_attr "mode" "SI")])
6781
6782 ; See comments above addsi_4 for details.
6783
6784 (define_insn "*addhi_4"
6785   [(set (reg FLAGS_REG)
6786         (compare
6787           (match_operand:HI 1 "nonimmediate_operand" "0")
6788           (match_operand:HI 2 "const_int_operand" "n")))
6789    (clobber (match_scratch:HI 0 "=rm"))]
6790   "ix86_match_ccmode (insn, CCGCmode)"
6791 {
6792   switch (get_attr_type (insn))
6793     {
6794     case TYPE_INCDEC:
6795       if (operands[2] == constm1_rtx)
6796         return "inc{w}\t%0";
6797       else
6798         {
6799           gcc_assert (operands[2] == const1_rtx);
6800           return "dec{w}\t%0";
6801         }
6802
6803     default:
6804       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6805       if (x86_maybe_negate_const_int (&operands[2], HImode))
6806         return "add{w}\t{%2, %0|%0, %2}";
6807
6808       return "sub{w}\t{%2, %0|%0, %2}";
6809     }
6810 }
6811   [(set (attr "type")
6812      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6813         (const_string "incdec")
6814         (const_string "alu")))
6815    (set (attr "length_immediate")
6816       (if_then_else
6817         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6818         (const_string "1")
6819         (const_string "*")))
6820    (set_attr "mode" "HI")])
6821
6822 ; See comments above addsi_4 for details.
6823
6824 (define_insn "*addqi_4"
6825   [(set (reg FLAGS_REG)
6826         (compare
6827           (match_operand:QI 1 "nonimmediate_operand" "0")
6828           (match_operand:QI 2 "const_int_operand" "n")))
6829    (clobber (match_scratch:QI 0 "=qm"))]
6830   "ix86_match_ccmode (insn, CCGCmode)"
6831 {
6832   switch (get_attr_type (insn))
6833     {
6834     case TYPE_INCDEC:
6835       if (operands[2] == constm1_rtx
6836           || (CONST_INT_P (operands[2])
6837               && INTVAL (operands[2]) == 255))
6838         return "inc{b}\t%0";
6839       else
6840         {
6841           gcc_assert (operands[2] == const1_rtx);
6842           return "dec{b}\t%0";
6843         }
6844
6845     default:
6846       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6847       if (x86_maybe_negate_const_int (&operands[2], QImode))
6848         return "add{b}\t{%2, %0|%0, %2}";
6849
6850       return "sub{b}\t{%2, %0|%0, %2}";
6851     }
6852 }
6853   [(set (attr "type")
6854      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6855         (const_string "incdec")
6856         (const_string "alu")))
6857    (set_attr "mode" "QI")])
6858
6859 (define_insn "*add<mode>_5"
6860   [(set (reg FLAGS_REG)
6861         (compare
6862           (plus:SWI48
6863             (match_operand:SWI48 1 "nonimmediate_operand" "%0")
6864             (match_operand:SWI48 2 "<general_operand>" "<g>"))
6865           (const_int 0)))
6866    (clobber (match_scratch:SWI48 0 "=r"))]
6867   "ix86_match_ccmode (insn, CCGOCmode)
6868    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6869    /* Current assemblers are broken and do not allow @GOTOFF in
6870       ought but a memory context.  */
6871    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6872 {
6873   switch (get_attr_type (insn))
6874     {
6875     case TYPE_INCDEC:
6876       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6877       if (operands[2] == const1_rtx)
6878         return "inc{<imodesuffix>}\t%0";
6879       else
6880         {
6881           gcc_assert (operands[2] == constm1_rtx);
6882           return "dec{<imodesuffix>}\t%0";
6883         }
6884
6885     default:
6886       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6887       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6888         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6889
6890       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6891     }
6892 }
6893   [(set (attr "type")
6894      (if_then_else (match_operand:SWI48 2 "incdec_operand" "")
6895         (const_string "incdec")
6896         (const_string "alu")))
6897    (set (attr "length_immediate")
6898       (if_then_else
6899         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6900         (const_string "1")
6901         (const_string "*")))
6902    (set_attr "mode" "<MODE>")])
6903
6904 (define_insn "*addhi_5"
6905   [(set (reg FLAGS_REG)
6906         (compare
6907           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6908                    (match_operand:HI 2 "general_operand" "rmn"))
6909           (const_int 0)))
6910    (clobber (match_scratch:HI 0 "=r"))]
6911   "ix86_match_ccmode (insn, CCGOCmode)
6912    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6913 {
6914   switch (get_attr_type (insn))
6915     {
6916     case TYPE_INCDEC:
6917       if (operands[2] == const1_rtx)
6918         return "inc{w}\t%0";
6919       else
6920         {
6921           gcc_assert (operands[2] == constm1_rtx);
6922           return "dec{w}\t%0";
6923         }
6924
6925     default:
6926       if (x86_maybe_negate_const_int (&operands[2], HImode))
6927         return "sub{w}\t{%2, %0|%0, %2}";
6928
6929       return "add{w}\t{%2, %0|%0, %2}";
6930     }
6931 }
6932   [(set (attr "type")
6933      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6934         (const_string "incdec")
6935         (const_string "alu")))
6936    (set (attr "length_immediate")
6937       (if_then_else
6938         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6939         (const_string "1")
6940         (const_string "*")))
6941    (set_attr "mode" "HI")])
6942
6943 (define_insn "*addqi_5"
6944   [(set (reg FLAGS_REG)
6945         (compare
6946           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6947                    (match_operand:QI 2 "general_operand" "qmn"))
6948           (const_int 0)))
6949    (clobber (match_scratch:QI 0 "=q"))]
6950   "ix86_match_ccmode (insn, CCGOCmode)
6951    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6952 {
6953   switch (get_attr_type (insn))
6954     {
6955     case TYPE_INCDEC:
6956       if (operands[2] == const1_rtx)
6957         return "inc{b}\t%0";
6958       else
6959         {
6960           gcc_assert (operands[2] == constm1_rtx
6961                       || (CONST_INT_P (operands[2])
6962                           && INTVAL (operands[2]) == 255));
6963           return "dec{b}\t%0";
6964         }
6965
6966     default:
6967       if (x86_maybe_negate_const_int (&operands[2], QImode))
6968         return "sub{b}\t{%2, %0|%0, %2}";
6969
6970       return "add{b}\t{%2, %0|%0, %2}";
6971     }
6972 }
6973   [(set (attr "type")
6974      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6975         (const_string "incdec")
6976         (const_string "alu")))
6977    (set_attr "mode" "QI")])
6978
6979 (define_insn "*addqi_ext_1_rex64"
6980   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6981                          (const_int 8)
6982                          (const_int 8))
6983         (plus:SI
6984           (zero_extract:SI
6985             (match_operand 1 "ext_register_operand" "0")
6986             (const_int 8)
6987             (const_int 8))
6988           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6989    (clobber (reg:CC FLAGS_REG))]
6990   "TARGET_64BIT"
6991 {
6992   switch (get_attr_type (insn))
6993     {
6994     case TYPE_INCDEC:
6995       if (operands[2] == const1_rtx)
6996         return "inc{b}\t%h0";
6997       else
6998         {
6999           gcc_assert (operands[2] == constm1_rtx
7000                       || (CONST_INT_P (operands[2])
7001                           && INTVAL (operands[2]) == 255));
7002           return "dec{b}\t%h0";
7003         }
7004
7005     default:
7006       return "add{b}\t{%2, %h0|%h0, %2}";
7007     }
7008 }
7009   [(set (attr "type")
7010      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7011         (const_string "incdec")
7012         (const_string "alu")))
7013    (set_attr "modrm" "1")
7014    (set_attr "mode" "QI")])
7015
7016 (define_insn "addqi_ext_1"
7017   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7018                          (const_int 8)
7019                          (const_int 8))
7020         (plus:SI
7021           (zero_extract:SI
7022             (match_operand 1 "ext_register_operand" "0")
7023             (const_int 8)
7024             (const_int 8))
7025           (match_operand:QI 2 "general_operand" "Qmn")))
7026    (clobber (reg:CC FLAGS_REG))]
7027   "!TARGET_64BIT"
7028 {
7029   switch (get_attr_type (insn))
7030     {
7031     case TYPE_INCDEC:
7032       if (operands[2] == const1_rtx)
7033         return "inc{b}\t%h0";
7034       else
7035         {
7036           gcc_assert (operands[2] == constm1_rtx
7037                       || (CONST_INT_P (operands[2])
7038                           && INTVAL (operands[2]) == 255));
7039           return "dec{b}\t%h0";
7040         }
7041
7042     default:
7043       return "add{b}\t{%2, %h0|%h0, %2}";
7044     }
7045 }
7046   [(set (attr "type")
7047      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7048         (const_string "incdec")
7049         (const_string "alu")))
7050    (set_attr "modrm" "1")
7051    (set_attr "mode" "QI")])
7052
7053 (define_insn "*addqi_ext_2"
7054   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7055                          (const_int 8)
7056                          (const_int 8))
7057         (plus:SI
7058           (zero_extract:SI
7059             (match_operand 1 "ext_register_operand" "%0")
7060             (const_int 8)
7061             (const_int 8))
7062           (zero_extract:SI
7063             (match_operand 2 "ext_register_operand" "Q")
7064             (const_int 8)
7065             (const_int 8))))
7066    (clobber (reg:CC FLAGS_REG))]
7067   ""
7068   "add{b}\t{%h2, %h0|%h0, %h2}"
7069   [(set_attr "type" "alu")
7070    (set_attr "mode" "QI")])
7071
7072 ;; The lea patterns for non-Pmodes needs to be matched by
7073 ;; several insns converted to real lea by splitters.
7074
7075 (define_insn_and_split "*lea_general_1"
7076   [(set (match_operand 0 "register_operand" "=r")
7077         (plus (plus (match_operand 1 "index_register_operand" "l")
7078                     (match_operand 2 "register_operand" "r"))
7079               (match_operand 3 "immediate_operand" "i")))]
7080   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
7081     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
7082    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7083    && GET_MODE (operands[0]) == GET_MODE (operands[1])
7084    && GET_MODE (operands[0]) == GET_MODE (operands[2])
7085    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
7086        || GET_MODE (operands[3]) == VOIDmode)"
7087   "#"
7088   "&& reload_completed"
7089   [(const_int 0)]
7090 {
7091   rtx pat;
7092   operands[0] = gen_lowpart (SImode, operands[0]);
7093   operands[1] = gen_lowpart (Pmode, operands[1]);
7094   operands[2] = gen_lowpart (Pmode, operands[2]);
7095   operands[3] = gen_lowpart (Pmode, operands[3]);
7096   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
7097                       operands[3]);
7098   if (Pmode != SImode)
7099     pat = gen_rtx_SUBREG (SImode, pat, 0);
7100   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7101   DONE;
7102 }
7103   [(set_attr "type" "lea")
7104    (set_attr "mode" "SI")])
7105
7106 (define_insn_and_split "*lea_general_1_zext"
7107   [(set (match_operand:DI 0 "register_operand" "=r")
7108         (zero_extend:DI
7109           (plus:SI (plus:SI
7110                      (match_operand:SI 1 "index_register_operand" "l")
7111                      (match_operand:SI 2 "register_operand" "r"))
7112                    (match_operand:SI 3 "immediate_operand" "i"))))]
7113   "TARGET_64BIT"
7114   "#"
7115   "&& reload_completed"
7116   [(set (match_dup 0)
7117         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
7118                                                      (match_dup 2))
7119                                             (match_dup 3)) 0)))]
7120 {
7121   operands[1] = gen_lowpart (Pmode, operands[1]);
7122   operands[2] = gen_lowpart (Pmode, operands[2]);
7123   operands[3] = gen_lowpart (Pmode, operands[3]);
7124 }
7125   [(set_attr "type" "lea")
7126    (set_attr "mode" "SI")])
7127
7128 (define_insn_and_split "*lea_general_2"
7129   [(set (match_operand 0 "register_operand" "=r")
7130         (plus (mult (match_operand 1 "index_register_operand" "l")
7131                     (match_operand 2 "const248_operand" "i"))
7132               (match_operand 3 "nonmemory_operand" "ri")))]
7133   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
7134     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
7135    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7136    && GET_MODE (operands[0]) == GET_MODE (operands[1])
7137    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
7138        || GET_MODE (operands[3]) == VOIDmode)"
7139   "#"
7140   "&& reload_completed"
7141   [(const_int 0)]
7142 {
7143   rtx pat;
7144   operands[0] = gen_lowpart (SImode, operands[0]);
7145   operands[1] = gen_lowpart (Pmode, operands[1]);
7146   operands[3] = gen_lowpart (Pmode, operands[3]);
7147   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
7148                       operands[3]);
7149   if (Pmode != SImode)
7150     pat = gen_rtx_SUBREG (SImode, pat, 0);
7151   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7152   DONE;
7153 }
7154   [(set_attr "type" "lea")
7155    (set_attr "mode" "SI")])
7156
7157 (define_insn_and_split "*lea_general_2_zext"
7158   [(set (match_operand:DI 0 "register_operand" "=r")
7159         (zero_extend:DI
7160           (plus:SI (mult:SI
7161                      (match_operand:SI 1 "index_register_operand" "l")
7162                      (match_operand:SI 2 "const248_operand" "n"))
7163                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
7164   "TARGET_64BIT"
7165   "#"
7166   "&& reload_completed"
7167   [(set (match_dup 0)
7168         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
7169                                                      (match_dup 2))
7170                                             (match_dup 3)) 0)))]
7171 {
7172   operands[1] = gen_lowpart (Pmode, operands[1]);
7173   operands[3] = gen_lowpart (Pmode, operands[3]);
7174 }
7175   [(set_attr "type" "lea")
7176    (set_attr "mode" "SI")])
7177
7178 (define_insn_and_split "*lea_general_3"
7179   [(set (match_operand 0 "register_operand" "=r")
7180         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
7181                           (match_operand 2 "const248_operand" "i"))
7182                     (match_operand 3 "register_operand" "r"))
7183               (match_operand 4 "immediate_operand" "i")))]
7184   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
7185     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
7186    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7187    && GET_MODE (operands[0]) == GET_MODE (operands[1])
7188    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
7189   "#"
7190   "&& reload_completed"
7191   [(const_int 0)]
7192 {
7193   rtx pat;
7194   operands[0] = gen_lowpart (SImode, operands[0]);
7195   operands[1] = gen_lowpart (Pmode, operands[1]);
7196   operands[3] = gen_lowpart (Pmode, operands[3]);
7197   operands[4] = gen_lowpart (Pmode, operands[4]);
7198   pat = gen_rtx_PLUS (Pmode,
7199                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
7200                                                          operands[2]),
7201                                     operands[3]),
7202                       operands[4]);
7203   if (Pmode != SImode)
7204     pat = gen_rtx_SUBREG (SImode, pat, 0);
7205   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7206   DONE;
7207 }
7208   [(set_attr "type" "lea")
7209    (set_attr "mode" "SI")])
7210
7211 (define_insn_and_split "*lea_general_3_zext"
7212   [(set (match_operand:DI 0 "register_operand" "=r")
7213         (zero_extend:DI
7214           (plus:SI (plus:SI
7215                      (mult:SI
7216                        (match_operand:SI 1 "index_register_operand" "l")
7217                        (match_operand:SI 2 "const248_operand" "n"))
7218                      (match_operand:SI 3 "register_operand" "r"))
7219                    (match_operand:SI 4 "immediate_operand" "i"))))]
7220   "TARGET_64BIT"
7221   "#"
7222   "&& reload_completed"
7223   [(set (match_dup 0)
7224         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
7225                                                               (match_dup 2))
7226                                                      (match_dup 3))
7227                                             (match_dup 4)) 0)))]
7228 {
7229   operands[1] = gen_lowpart (Pmode, operands[1]);
7230   operands[3] = gen_lowpart (Pmode, operands[3]);
7231   operands[4] = gen_lowpart (Pmode, operands[4]);
7232 }
7233   [(set_attr "type" "lea")
7234    (set_attr "mode" "SI")])
7235
7236 ;; Convert lea to the lea pattern to avoid flags dependency.
7237 (define_split
7238   [(set (match_operand:DI 0 "register_operand" "")
7239         (plus:DI (match_operand:DI 1 "register_operand" "")
7240                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
7241    (clobber (reg:CC FLAGS_REG))]
7242   "TARGET_64BIT && reload_completed 
7243    && ix86_lea_for_add_ok (PLUS, insn, operands)"
7244   [(set (match_dup 0)
7245         (plus:DI (match_dup 1)
7246                  (match_dup 2)))]
7247   "")
7248
7249 ;; Convert lea to the lea pattern to avoid flags dependency.
7250 (define_split
7251   [(set (match_operand 0 "register_operand" "")
7252         (plus (match_operand 1 "register_operand" "")
7253               (match_operand 2 "nonmemory_operand" "")))
7254    (clobber (reg:CC FLAGS_REG))]
7255   "reload_completed && ix86_lea_for_add_ok (PLUS, insn, operands)" 
7256   [(const_int 0)]
7257 {
7258   rtx pat;
7259   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
7260      may confuse gen_lowpart.  */
7261   if (GET_MODE (operands[0]) != Pmode)
7262     {
7263       operands[1] = gen_lowpart (Pmode, operands[1]);
7264       operands[2] = gen_lowpart (Pmode, operands[2]);
7265     }
7266   operands[0] = gen_lowpart (SImode, operands[0]);
7267   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
7268   if (Pmode != SImode)
7269     pat = gen_rtx_SUBREG (SImode, pat, 0);
7270   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7271   DONE;
7272 })
7273
7274 ;; Convert lea to the lea pattern to avoid flags dependency.
7275 (define_split
7276   [(set (match_operand:DI 0 "register_operand" "")
7277         (zero_extend:DI
7278           (plus:SI (match_operand:SI 1 "register_operand" "")
7279                    (match_operand:SI 2 "nonmemory_operand" ""))))
7280    (clobber (reg:CC FLAGS_REG))]
7281   "TARGET_64BIT && reload_completed
7282    && true_regnum (operands[0]) != true_regnum (operands[1])"
7283   [(set (match_dup 0)
7284         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
7285 {
7286   operands[1] = gen_lowpart (Pmode, operands[1]);
7287   operands[2] = gen_lowpart (Pmode, operands[2]);
7288 })
7289 \f
7290 ;; Subtract instructions
7291
7292 (define_expand "sub<mode>3"
7293   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
7294         (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
7295                      (match_operand:SDWIM 2 "<general_operand>" "")))]
7296   ""
7297   "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
7298
7299 (define_insn_and_split "*sub<dwi>3_doubleword"
7300   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
7301         (minus:<DWI>
7302           (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
7303           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
7304    (clobber (reg:CC FLAGS_REG))]
7305   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7306   "#"
7307   "reload_completed"
7308   [(parallel [(set (reg:CC FLAGS_REG)
7309                    (compare:CC (match_dup 1) (match_dup 2)))
7310               (set (match_dup 0)
7311                    (minus:DWIH (match_dup 1) (match_dup 2)))])
7312    (parallel [(set (match_dup 3)
7313                    (minus:DWIH
7314                      (match_dup 4)
7315                      (plus:DWIH
7316                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7317                        (match_dup 5))))
7318               (clobber (reg:CC FLAGS_REG))])]
7319   "split_<dwi> (&operands[0], 3, &operands[0], &operands[3]);")
7320
7321 (define_insn "*sub<mode>_1"
7322   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7323         (minus:SWI
7324           (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7325           (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
7326    (clobber (reg:CC FLAGS_REG))]
7327   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7328   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7329   [(set_attr "type" "alu")
7330    (set_attr "mode" "<MODE>")])
7331
7332 (define_insn "*subsi_1_zext"
7333   [(set (match_operand:DI 0 "register_operand" "=r")
7334         (zero_extend:DI
7335           (minus:SI (match_operand:SI 1 "register_operand" "0")
7336                     (match_operand:SI 2 "general_operand" "g"))))
7337    (clobber (reg:CC FLAGS_REG))]
7338   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7339   "sub{l}\t{%2, %k0|%k0, %2}"
7340   [(set_attr "type" "alu")
7341    (set_attr "mode" "SI")])
7342
7343 (define_insn "*subqi_1_slp"
7344   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7345         (minus:QI (match_dup 0)
7346                   (match_operand:QI 1 "general_operand" "qn,qm")))
7347    (clobber (reg:CC FLAGS_REG))]
7348   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7349    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7350   "sub{b}\t{%1, %0|%0, %1}"
7351   [(set_attr "type" "alu1")
7352    (set_attr "mode" "QI")])
7353
7354 (define_insn "*sub<mode>_2"
7355   [(set (reg FLAGS_REG)
7356         (compare
7357           (minus:SWI
7358             (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7359             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
7360           (const_int 0)))
7361    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7362         (minus:SWI (match_dup 1) (match_dup 2)))]
7363   "ix86_match_ccmode (insn, CCGOCmode)
7364    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7365   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7366   [(set_attr "type" "alu")
7367    (set_attr "mode" "<MODE>")])
7368
7369 (define_insn "*subsi_2_zext"
7370   [(set (reg FLAGS_REG)
7371         (compare
7372           (minus:SI (match_operand:SI 1 "register_operand" "0")
7373                     (match_operand:SI 2 "general_operand" "g"))
7374           (const_int 0)))
7375    (set (match_operand:DI 0 "register_operand" "=r")
7376         (zero_extend:DI
7377           (minus:SI (match_dup 1)
7378                     (match_dup 2))))]
7379   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7380    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7381   "sub{l}\t{%2, %k0|%k0, %2}"
7382   [(set_attr "type" "alu")
7383    (set_attr "mode" "SI")])
7384
7385 (define_insn "*sub<mode>_3"
7386   [(set (reg FLAGS_REG)
7387         (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7388                  (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
7389    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7390         (minus:SWI (match_dup 1) (match_dup 2)))]
7391   "ix86_match_ccmode (insn, CCmode)
7392    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7393   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7394   [(set_attr "type" "alu")
7395    (set_attr "mode" "<MODE>")])
7396
7397 (define_insn "*subsi_3_zext"
7398   [(set (reg FLAGS_REG)
7399         (compare (match_operand:SI 1 "register_operand" "0")
7400                  (match_operand:SI 2 "general_operand" "g")))
7401    (set (match_operand:DI 0 "register_operand" "=r")
7402         (zero_extend:DI
7403           (minus:SI (match_dup 1)
7404                     (match_dup 2))))]
7405   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7406    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7407   "sub{l}\t{%2, %1|%1, %2}"
7408   [(set_attr "type" "alu")
7409    (set_attr "mode" "SI")])
7410 \f
7411 ;; Add with carry and subtract with borrow
7412
7413 (define_expand "<plusminus_insn><mode>3_carry"
7414   [(parallel
7415     [(set (match_operand:SWI 0 "nonimmediate_operand" "")
7416           (plusminus:SWI
7417             (match_operand:SWI 1 "nonimmediate_operand" "")
7418             (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
7419                        [(match_operand 3 "flags_reg_operand" "")
7420                         (const_int 0)])
7421                       (match_operand:SWI 2 "<general_operand>" ""))))
7422      (clobber (reg:CC FLAGS_REG))])]
7423   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
7424   "")
7425
7426 (define_insn "*<plusminus_insn><mode>3_carry"
7427   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7428         (plusminus:SWI
7429           (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
7430           (plus:SWI
7431             (match_operator 3 "ix86_carry_flag_operator"
7432              [(reg FLAGS_REG) (const_int 0)])
7433             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
7434    (clobber (reg:CC FLAGS_REG))]
7435   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7436   "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
7437   [(set_attr "type" "alu")
7438    (set_attr "use_carry" "1")
7439    (set_attr "pent_pair" "pu")
7440    (set_attr "mode" "<MODE>")])
7441
7442 (define_insn "*addsi3_carry_zext"
7443   [(set (match_operand:DI 0 "register_operand" "=r")
7444         (zero_extend:DI
7445           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7446                    (plus:SI (match_operator 3 "ix86_carry_flag_operator"
7447                              [(reg FLAGS_REG) (const_int 0)])
7448                             (match_operand:SI 2 "general_operand" "g")))))
7449    (clobber (reg:CC FLAGS_REG))]
7450   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
7451   "adc{l}\t{%2, %k0|%k0, %2}"
7452   [(set_attr "type" "alu")
7453    (set_attr "use_carry" "1")
7454    (set_attr "pent_pair" "pu")
7455    (set_attr "mode" "SI")])
7456
7457 (define_insn "*subsi3_carry_zext"
7458   [(set (match_operand:DI 0 "register_operand" "=r")
7459         (zero_extend:DI
7460           (minus:SI (match_operand:SI 1 "register_operand" "0")
7461                     (plus:SI (match_operator 3 "ix86_carry_flag_operator"
7462                               [(reg FLAGS_REG) (const_int 0)])
7463                              (match_operand:SI 2 "general_operand" "g")))))
7464    (clobber (reg:CC FLAGS_REG))]
7465   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7466   "sbb{l}\t{%2, %k0|%k0, %2}"
7467   [(set_attr "type" "alu")
7468    (set_attr "pent_pair" "pu")
7469    (set_attr "mode" "SI")])
7470 \f
7471 ;; Overflow setting add and subtract instructions
7472
7473 (define_insn "*add<mode>3_cconly_overflow"
7474   [(set (reg:CCC FLAGS_REG)
7475         (compare:CCC
7476           (plus:SWI
7477             (match_operand:SWI 1 "nonimmediate_operand" "%0")
7478             (match_operand:SWI 2 "<general_operand>" "<r><i>m"))
7479           (match_dup 1)))
7480    (clobber (match_scratch:SWI 0 "=<r>"))]
7481   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7482   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7483   [(set_attr "type" "alu")
7484    (set_attr "mode" "<MODE>")])
7485
7486 (define_insn "*sub<mode>3_cconly_overflow"
7487   [(set (reg:CCC FLAGS_REG)
7488         (compare:CCC
7489           (minus:SWI
7490             (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
7491             (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
7492           (match_dup 0)))]
7493   ""
7494   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
7495   [(set_attr "type" "icmp")
7496    (set_attr "mode" "<MODE>")])
7497
7498 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
7499   [(set (reg:CCC FLAGS_REG)
7500         (compare:CCC
7501             (plusminus:SWI
7502                 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
7503                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
7504             (match_dup 1)))
7505    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7506         (plusminus:SWI (match_dup 1) (match_dup 2)))]
7507   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
7508   "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
7509   [(set_attr "type" "alu")
7510    (set_attr "mode" "<MODE>")])
7511
7512 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
7513   [(set (reg:CCC FLAGS_REG)
7514         (compare:CCC
7515           (plusminus:SI
7516             (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
7517             (match_operand:SI 2 "general_operand" "g"))
7518           (match_dup 1)))
7519    (set (match_operand:DI 0 "register_operand" "=r")
7520         (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
7521   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
7522   "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
7523   [(set_attr "type" "alu")
7524    (set_attr "mode" "SI")])
7525
7526 ;; The patterns that match these are at the end of this file.
7527
7528 (define_expand "<plusminus_insn>xf3"
7529   [(set (match_operand:XF 0 "register_operand" "")
7530         (plusminus:XF
7531           (match_operand:XF 1 "register_operand" "")
7532           (match_operand:XF 2 "register_operand" "")))]
7533   "TARGET_80387"
7534   "")
7535
7536 (define_expand "<plusminus_insn><mode>3"
7537   [(set (match_operand:MODEF 0 "register_operand" "")
7538         (plusminus:MODEF
7539           (match_operand:MODEF 1 "register_operand" "")
7540           (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7541   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7542     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7543   "")
7544 \f
7545 ;; Multiply instructions
7546
7547 (define_expand "mul<mode>3"
7548   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7549                    (mult:SWIM248
7550                      (match_operand:SWIM248 1 "register_operand" "")
7551                      (match_operand:SWIM248 2 "<general_operand>" "")))
7552               (clobber (reg:CC FLAGS_REG))])]
7553   ""
7554   "")
7555
7556 (define_expand "mulqi3"
7557   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7558                    (mult:QI
7559                      (match_operand:QI 1 "register_operand" "")
7560                      (match_operand:QI 2 "nonimmediate_operand" "")))
7561               (clobber (reg:CC FLAGS_REG))])]
7562   "TARGET_QIMODE_MATH"
7563   "")
7564
7565 ;; On AMDFAM10
7566 ;; IMUL reg32/64, reg32/64, imm8        Direct
7567 ;; IMUL reg32/64, mem32/64, imm8        VectorPath
7568 ;; IMUL reg32/64, reg32/64, imm32       Direct
7569 ;; IMUL reg32/64, mem32/64, imm32       VectorPath
7570 ;; IMUL reg32/64, reg32/64              Direct
7571 ;; IMUL reg32/64, mem32/64              Direct
7572
7573 (define_insn "*mul<mode>3_1"
7574   [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
7575         (mult:SWI48
7576           (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
7577           (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
7578    (clobber (reg:CC FLAGS_REG))]
7579   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7580   "@
7581    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7582    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7583    imul{<imodesuffix>}\t{%2, %0|%0, %2}"
7584   [(set_attr "type" "imul")
7585    (set_attr "prefix_0f" "0,0,1")
7586    (set (attr "athlon_decode")
7587         (cond [(eq_attr "cpu" "athlon")
7588                   (const_string "vector")
7589                (eq_attr "alternative" "1")
7590                   (const_string "vector")
7591                (and (eq_attr "alternative" "2")
7592                     (match_operand 1 "memory_operand" ""))
7593                   (const_string "vector")]
7594               (const_string "direct")))
7595    (set (attr "amdfam10_decode")
7596         (cond [(and (eq_attr "alternative" "0,1")
7597                     (match_operand 1 "memory_operand" ""))
7598                   (const_string "vector")]
7599               (const_string "direct")))
7600    (set_attr "mode" "<MODE>")])
7601
7602 (define_insn "*mulsi3_1_zext"
7603   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7604         (zero_extend:DI
7605           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7606                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
7607    (clobber (reg:CC FLAGS_REG))]
7608   "TARGET_64BIT
7609    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7610   "@
7611    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7612    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7613    imul{l}\t{%2, %k0|%k0, %2}"
7614   [(set_attr "type" "imul")
7615    (set_attr "prefix_0f" "0,0,1")
7616    (set (attr "athlon_decode")
7617         (cond [(eq_attr "cpu" "athlon")
7618                   (const_string "vector")
7619                (eq_attr "alternative" "1")
7620                   (const_string "vector")
7621                (and (eq_attr "alternative" "2")
7622                     (match_operand 1 "memory_operand" ""))
7623                   (const_string "vector")]
7624               (const_string "direct")))
7625    (set (attr "amdfam10_decode")
7626         (cond [(and (eq_attr "alternative" "0,1")
7627                     (match_operand 1 "memory_operand" ""))
7628                   (const_string "vector")]
7629               (const_string "direct")))
7630    (set_attr "mode" "SI")])
7631
7632 ;; On AMDFAM10
7633 ;; IMUL reg16, reg16, imm8      VectorPath
7634 ;; IMUL reg16, mem16, imm8      VectorPath
7635 ;; IMUL reg16, reg16, imm16     VectorPath
7636 ;; IMUL reg16, mem16, imm16     VectorPath
7637 ;; IMUL reg16, reg16            Direct
7638 ;; IMUL reg16, mem16            Direct
7639
7640 (define_insn "*mulhi3_1"
7641   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7642         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7643                  (match_operand:HI 2 "general_operand" "K,n,mr")))
7644    (clobber (reg:CC FLAGS_REG))]
7645   "TARGET_HIMODE_MATH
7646    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7647   "@
7648    imul{w}\t{%2, %1, %0|%0, %1, %2}
7649    imul{w}\t{%2, %1, %0|%0, %1, %2}
7650    imul{w}\t{%2, %0|%0, %2}"
7651   [(set_attr "type" "imul")
7652    (set_attr "prefix_0f" "0,0,1")
7653    (set (attr "athlon_decode")
7654         (cond [(eq_attr "cpu" "athlon")
7655                   (const_string "vector")
7656                (eq_attr "alternative" "1,2")
7657                   (const_string "vector")]
7658               (const_string "direct")))
7659    (set (attr "amdfam10_decode")
7660         (cond [(eq_attr "alternative" "0,1")
7661                   (const_string "vector")]
7662               (const_string "direct")))
7663    (set_attr "mode" "HI")])
7664
7665 ;;On AMDFAM10
7666 ;; MUL reg8     Direct
7667 ;; MUL mem8     Direct
7668
7669 (define_insn "*mulqi3_1"
7670   [(set (match_operand:QI 0 "register_operand" "=a")
7671         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7672                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7673    (clobber (reg:CC FLAGS_REG))]
7674   "TARGET_QIMODE_MATH
7675    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7676   "mul{b}\t%2"
7677   [(set_attr "type" "imul")
7678    (set_attr "length_immediate" "0")
7679    (set (attr "athlon_decode")
7680      (if_then_else (eq_attr "cpu" "athlon")
7681         (const_string "vector")
7682         (const_string "direct")))
7683    (set_attr "amdfam10_decode" "direct")
7684    (set_attr "mode" "QI")])
7685
7686 (define_expand "<u>mul<mode><dwi>3"
7687   [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
7688                    (mult:<DWI>
7689                      (any_extend:<DWI>
7690                        (match_operand:DWIH 1 "nonimmediate_operand" ""))
7691                      (any_extend:<DWI>
7692                        (match_operand:DWIH 2 "register_operand" ""))))
7693               (clobber (reg:CC FLAGS_REG))])]
7694   ""
7695   "")
7696
7697 (define_expand "<u>mulqihi3"
7698   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7699                    (mult:HI
7700                      (any_extend:HI
7701                        (match_operand:QI 1 "nonimmediate_operand" ""))
7702                      (any_extend:HI
7703                        (match_operand:QI 2 "register_operand" ""))))
7704               (clobber (reg:CC FLAGS_REG))])]
7705   "TARGET_QIMODE_MATH"
7706   "")
7707
7708 (define_insn "*<u>mul<mode><dwi>3_1"
7709   [(set (match_operand:<DWI> 0 "register_operand" "=A")
7710         (mult:<DWI>
7711           (any_extend:<DWI>
7712             (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
7713           (any_extend:<DWI>
7714             (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7715    (clobber (reg:CC FLAGS_REG))]
7716   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7717   "<sgnprefix>mul{<imodesuffix>}\t%2"
7718   [(set_attr "type" "imul")
7719    (set_attr "length_immediate" "0")
7720    (set (attr "athlon_decode")
7721      (if_then_else (eq_attr "cpu" "athlon")
7722         (const_string "vector")
7723         (const_string "double")))
7724    (set_attr "amdfam10_decode" "double")
7725    (set_attr "mode" "<MODE>")])
7726
7727 (define_insn "*<u>mulqihi3_1"
7728   [(set (match_operand:HI 0 "register_operand" "=a")
7729         (mult:HI
7730           (any_extend:HI
7731             (match_operand:QI 1 "nonimmediate_operand" "%0"))
7732           (any_extend:HI
7733             (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7734    (clobber (reg:CC FLAGS_REG))]
7735   "TARGET_QIMODE_MATH
7736    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7737   "<sgnprefix>mul{b}\t%2"
7738   [(set_attr "type" "imul")
7739    (set_attr "length_immediate" "0")
7740    (set (attr "athlon_decode")
7741      (if_then_else (eq_attr "cpu" "athlon")
7742         (const_string "vector")
7743         (const_string "direct")))
7744    (set_attr "amdfam10_decode" "direct")
7745    (set_attr "mode" "QI")])
7746
7747 (define_expand "<s>mul<mode>3_highpart"
7748   [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
7749                    (truncate:SWI48
7750                      (lshiftrt:<DWI>
7751                        (mult:<DWI>
7752                          (any_extend:<DWI>
7753                            (match_operand:SWI48 1 "nonimmediate_operand" ""))
7754                          (any_extend:<DWI>
7755                            (match_operand:SWI48 2 "register_operand" "")))
7756                        (match_dup 4))))
7757               (clobber (match_scratch:SWI48 3 ""))
7758               (clobber (reg:CC FLAGS_REG))])]
7759   ""
7760   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7761
7762 (define_insn "*<s>muldi3_highpart_1"
7763   [(set (match_operand:DI 0 "register_operand" "=d")
7764         (truncate:DI
7765           (lshiftrt:TI
7766             (mult:TI
7767               (any_extend:TI
7768                 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7769               (any_extend:TI
7770                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7771             (const_int 64))))
7772    (clobber (match_scratch:DI 3 "=1"))
7773    (clobber (reg:CC FLAGS_REG))]
7774   "TARGET_64BIT
7775    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7776   "<sgnprefix>mul{q}\t%2"
7777   [(set_attr "type" "imul")
7778    (set_attr "length_immediate" "0")
7779    (set (attr "athlon_decode")
7780      (if_then_else (eq_attr "cpu" "athlon")
7781         (const_string "vector")
7782         (const_string "double")))
7783    (set_attr "amdfam10_decode" "double")
7784    (set_attr "mode" "DI")])
7785
7786 (define_insn "*<s>mulsi3_highpart_1"
7787   [(set (match_operand:SI 0 "register_operand" "=d")
7788         (truncate:SI
7789           (lshiftrt:DI
7790             (mult:DI
7791               (any_extend:DI
7792                 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7793               (any_extend:DI
7794                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7795             (const_int 32))))
7796    (clobber (match_scratch:SI 3 "=1"))
7797    (clobber (reg:CC FLAGS_REG))]
7798   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7799   "<sgnprefix>mul{l}\t%2"
7800   [(set_attr "type" "imul")
7801    (set_attr "length_immediate" "0")
7802    (set (attr "athlon_decode")
7803      (if_then_else (eq_attr "cpu" "athlon")
7804         (const_string "vector")
7805         (const_string "double")))
7806    (set_attr "amdfam10_decode" "double")
7807    (set_attr "mode" "SI")])
7808
7809 (define_insn "*<s>mulsi3_highpart_zext"
7810   [(set (match_operand:DI 0 "register_operand" "=d")
7811         (zero_extend:DI (truncate:SI
7812           (lshiftrt:DI
7813             (mult:DI (any_extend:DI
7814                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7815                      (any_extend:DI
7816                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7817             (const_int 32)))))
7818    (clobber (match_scratch:SI 3 "=1"))
7819    (clobber (reg:CC FLAGS_REG))]
7820   "TARGET_64BIT
7821    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7822   "<sgnprefix>mul{l}\t%2"
7823   [(set_attr "type" "imul")
7824    (set_attr "length_immediate" "0")
7825    (set (attr "athlon_decode")
7826      (if_then_else (eq_attr "cpu" "athlon")
7827         (const_string "vector")
7828         (const_string "double")))
7829    (set_attr "amdfam10_decode" "double")
7830    (set_attr "mode" "SI")])
7831
7832 ;; The patterns that match these are at the end of this file.
7833
7834 (define_expand "mulxf3"
7835   [(set (match_operand:XF 0 "register_operand" "")
7836         (mult:XF (match_operand:XF 1 "register_operand" "")
7837                  (match_operand:XF 2 "register_operand" "")))]
7838   "TARGET_80387"
7839   "")
7840
7841 (define_expand "mul<mode>3"
7842   [(set (match_operand:MODEF 0 "register_operand" "")
7843         (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
7844                     (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7845   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7846     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7847   "")
7848 \f
7849 ;; Divide instructions
7850
7851 (define_insn "<u>divqi3"
7852   [(set (match_operand:QI 0 "register_operand" "=a")
7853         (any_div:QI
7854           (match_operand:HI 1 "register_operand" "0")
7855           (match_operand:QI 2 "nonimmediate_operand" "qm")))
7856    (clobber (reg:CC FLAGS_REG))]
7857   "TARGET_QIMODE_MATH"
7858   "<sgnprefix>div{b}\t%2"
7859   [(set_attr "type" "idiv")
7860    (set_attr "mode" "QI")])
7861
7862 ;; The patterns that match these are at the end of this file.
7863
7864 (define_expand "divxf3"
7865   [(set (match_operand:XF 0 "register_operand" "")
7866         (div:XF (match_operand:XF 1 "register_operand" "")
7867                 (match_operand:XF 2 "register_operand" "")))]
7868   "TARGET_80387"
7869   "")
7870
7871 (define_expand "divdf3"
7872   [(set (match_operand:DF 0 "register_operand" "")
7873         (div:DF (match_operand:DF 1 "register_operand" "")
7874                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7875    "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7876     || (TARGET_SSE2 && TARGET_SSE_MATH)"
7877    "")
7878
7879 (define_expand "divsf3"
7880   [(set (match_operand:SF 0 "register_operand" "")
7881         (div:SF (match_operand:SF 1 "register_operand" "")
7882                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7883   "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7884     || TARGET_SSE_MATH"
7885 {
7886   if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
7887       && flag_finite_math_only && !flag_trapping_math
7888       && flag_unsafe_math_optimizations)
7889     {
7890       ix86_emit_swdivsf (operands[0], operands[1],
7891                          operands[2], SFmode);
7892       DONE;
7893     }
7894 })
7895 \f
7896 ;; Divmod instructions.
7897
7898 (define_expand "divmod<mode>4"
7899   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7900                    (div:SWIM248
7901                      (match_operand:SWIM248 1 "register_operand" "")
7902                      (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7903               (set (match_operand:SWIM248 3 "register_operand" "")
7904                    (mod:SWIM248 (match_dup 1) (match_dup 2)))
7905               (clobber (reg:CC FLAGS_REG))])]
7906   ""
7907   "")
7908
7909 (define_insn_and_split "*divmod<mode>4"
7910   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7911         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7912                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7913    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7914         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7915    (clobber (reg:CC FLAGS_REG))]
7916   ""
7917   "#"
7918   "&& reload_completed"
7919   [(parallel [(set (match_dup 1)
7920                    (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7921               (clobber (reg:CC FLAGS_REG))])
7922    (parallel [(set (match_dup 0)
7923                    (div:SWIM248 (match_dup 2) (match_dup 3)))
7924               (set (match_dup 1)
7925                    (mod:SWIM248 (match_dup 2) (match_dup 3)))
7926               (use (match_dup 1))
7927               (clobber (reg:CC FLAGS_REG))])]
7928 {
7929   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - 1);
7930
7931   if (<MODE>mode != HImode
7932       && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7933     operands[4] = operands[2];
7934   else
7935     {
7936       /* Avoid use of cltd in favor of a mov+shift.  */
7937       emit_move_insn (operands[1], operands[2]);
7938       operands[4] = operands[1];
7939     }
7940 }
7941   [(set_attr "type" "multi")
7942    (set_attr "mode" "<MODE>")])
7943
7944 (define_insn "*divmod<mode>4_noext"
7945   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7946         (div: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         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7950    (use (match_operand:SWIM248 4 "register_operand" "1"))
7951    (clobber (reg:CC FLAGS_REG))]
7952   ""
7953   "idiv{<imodesuffix>}\t%3"
7954   [(set_attr "type" "idiv")
7955    (set_attr "mode" "<MODE>")])
7956
7957 (define_expand "udivmod<mode>4"
7958   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7959                    (udiv:SWIM248
7960                      (match_operand:SWIM248 1 "register_operand" "")
7961                      (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7962               (set (match_operand:SWIM248 3 "register_operand" "")
7963                    (umod:SWIM248 (match_dup 1) (match_dup 2)))
7964               (clobber (reg:CC FLAGS_REG))])]
7965   ""
7966   "")
7967
7968 (define_insn_and_split "*udivmod<mode>4"
7969   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7970         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7971                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7972    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7973         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7974    (clobber (reg:CC FLAGS_REG))]
7975   ""
7976   "#"
7977   "&& reload_completed"
7978   [(set (match_dup 1) (const_int 0))
7979    (parallel [(set (match_dup 0)
7980                    (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7981               (set (match_dup 1)
7982                    (umod:SWIM248 (match_dup 2) (match_dup 3)))
7983               (use (match_dup 1))
7984               (clobber (reg:CC FLAGS_REG))])]
7985   ""
7986   [(set_attr "type" "multi")
7987    (set_attr "mode" "<MODE>")])
7988
7989 (define_insn "*udivmod<mode>4_noext"
7990   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7991         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7992                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7993    (set (match_operand:SWIM248 1 "register_operand" "=d")
7994         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7995    (use (match_operand:SWIM248 4 "register_operand" "1"))
7996    (clobber (reg:CC FLAGS_REG))]
7997   ""
7998   "div{<imodesuffix>}\t%3"
7999   [(set_attr "type" "idiv")
8000    (set_attr "mode" "<MODE>")])
8001
8002 ;; We cannot use div/idiv for double division, because it causes
8003 ;; "division by zero" on the overflow and that's not what we expect
8004 ;; from truncate.  Because true (non truncating) double division is
8005 ;; never generated, we can't create this insn anyway.
8006 ;
8007 ;(define_insn ""
8008 ;  [(set (match_operand:SI 0 "register_operand" "=a")
8009 ;       (truncate:SI
8010 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
8011 ;                  (zero_extend:DI
8012 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8013 ;   (set (match_operand:SI 3 "register_operand" "=d")
8014 ;       (truncate:SI
8015 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8016 ;   (clobber (reg:CC FLAGS_REG))]
8017 ;  ""
8018 ;  "div{l}\t{%2, %0|%0, %2}"
8019 ;  [(set_attr "type" "idiv")])
8020 \f
8021 ;;- Logical AND instructions
8022
8023 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8024 ;; Note that this excludes ah.
8025
8026 (define_expand "testsi_ccno_1"
8027   [(set (reg:CCNO FLAGS_REG)
8028         (compare:CCNO
8029           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8030                   (match_operand:SI 1 "nonmemory_operand" ""))
8031           (const_int 0)))]
8032   ""
8033   "")
8034
8035 (define_expand "testqi_ccz_1"
8036   [(set (reg:CCZ FLAGS_REG)
8037         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8038                              (match_operand:QI 1 "nonmemory_operand" ""))
8039                  (const_int 0)))]
8040   ""
8041   "")
8042
8043 (define_insn "*testdi_1"
8044   [(set (reg FLAGS_REG)
8045         (compare
8046          (and:DI
8047           (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8048           (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8049          (const_int 0)))]
8050   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8051    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8052   "@
8053    test{l}\t{%k1, %k0|%k0, %k1}
8054    test{l}\t{%k1, %k0|%k0, %k1}
8055    test{q}\t{%1, %0|%0, %1}
8056    test{q}\t{%1, %0|%0, %1}
8057    test{q}\t{%1, %0|%0, %1}"
8058   [(set_attr "type" "test")
8059    (set_attr "modrm" "0,1,0,1,1")
8060    (set_attr "mode" "SI,SI,DI,DI,DI")])
8061
8062 (define_insn "*testqi_1_maybe_si"
8063   [(set (reg FLAGS_REG)
8064         (compare
8065           (and:QI
8066             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8067             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8068           (const_int 0)))]
8069    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8070     && ix86_match_ccmode (insn,
8071                          CONST_INT_P (operands[1])
8072                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8073 {
8074   if (which_alternative == 3)
8075     {
8076       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8077         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8078       return "test{l}\t{%1, %k0|%k0, %1}";
8079     }
8080   return "test{b}\t{%1, %0|%0, %1}";
8081 }
8082   [(set_attr "type" "test")
8083    (set_attr "modrm" "0,1,1,1")
8084    (set_attr "mode" "QI,QI,QI,SI")
8085    (set_attr "pent_pair" "uv,np,uv,np")])
8086
8087 (define_insn "*test<mode>_1"
8088   [(set (reg FLAGS_REG)
8089         (compare
8090          (and:SWI124
8091           (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
8092           (match_operand:SWI124 1 "general_operand" "<i>,<i>,<r><i>"))
8093          (const_int 0)))]
8094   "ix86_match_ccmode (insn, CCNOmode)
8095    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8096   "test{<imodesuffix>}\t{%1, %0|%0, %1}"
8097   [(set_attr "type" "test")
8098    (set_attr "modrm" "0,1,1")
8099    (set_attr "mode" "<MODE>")
8100    (set_attr "pent_pair" "uv,np,uv")])
8101
8102 (define_expand "testqi_ext_ccno_0"
8103   [(set (reg:CCNO FLAGS_REG)
8104         (compare:CCNO
8105           (and:SI
8106             (zero_extract:SI
8107               (match_operand 0 "ext_register_operand" "")
8108               (const_int 8)
8109               (const_int 8))
8110             (match_operand 1 "const_int_operand" ""))
8111           (const_int 0)))]
8112   ""
8113   "")
8114
8115 (define_insn "*testqi_ext_0"
8116   [(set (reg FLAGS_REG)
8117         (compare
8118           (and:SI
8119             (zero_extract:SI
8120               (match_operand 0 "ext_register_operand" "Q")
8121               (const_int 8)
8122               (const_int 8))
8123             (match_operand 1 "const_int_operand" "n"))
8124           (const_int 0)))]
8125   "ix86_match_ccmode (insn, CCNOmode)"
8126   "test{b}\t{%1, %h0|%h0, %1}"
8127   [(set_attr "type" "test")
8128    (set_attr "mode" "QI")
8129    (set_attr "length_immediate" "1")
8130    (set_attr "modrm" "1")
8131    (set_attr "pent_pair" "np")])
8132
8133 (define_insn "*testqi_ext_1_rex64"
8134   [(set (reg FLAGS_REG)
8135         (compare
8136           (and:SI
8137             (zero_extract:SI
8138               (match_operand 0 "ext_register_operand" "Q")
8139               (const_int 8)
8140               (const_int 8))
8141             (zero_extend:SI
8142               (match_operand:QI 1 "register_operand" "Q")))
8143           (const_int 0)))]
8144   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8145   "test{b}\t{%1, %h0|%h0, %1}"
8146   [(set_attr "type" "test")
8147    (set_attr "mode" "QI")])
8148
8149 (define_insn "*testqi_ext_1"
8150   [(set (reg FLAGS_REG)
8151         (compare
8152           (and:SI
8153             (zero_extract:SI
8154               (match_operand 0 "ext_register_operand" "Q")
8155               (const_int 8)
8156               (const_int 8))
8157             (zero_extend:SI
8158               (match_operand:QI 1 "general_operand" "Qm")))
8159           (const_int 0)))]
8160   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8161   "test{b}\t{%1, %h0|%h0, %1}"
8162   [(set_attr "type" "test")
8163    (set_attr "mode" "QI")])
8164
8165 (define_insn "*testqi_ext_2"
8166   [(set (reg FLAGS_REG)
8167         (compare
8168           (and:SI
8169             (zero_extract:SI
8170               (match_operand 0 "ext_register_operand" "Q")
8171               (const_int 8)
8172               (const_int 8))
8173             (zero_extract:SI
8174               (match_operand 1 "ext_register_operand" "Q")
8175               (const_int 8)
8176               (const_int 8)))
8177           (const_int 0)))]
8178   "ix86_match_ccmode (insn, CCNOmode)"
8179   "test{b}\t{%h1, %h0|%h0, %h1}"
8180   [(set_attr "type" "test")
8181    (set_attr "mode" "QI")])
8182
8183 (define_insn "*testqi_ext_3_rex64"
8184   [(set (reg FLAGS_REG)
8185         (compare (zero_extract:DI
8186                    (match_operand 0 "nonimmediate_operand" "rm")
8187                    (match_operand:DI 1 "const_int_operand" "")
8188                    (match_operand:DI 2 "const_int_operand" ""))
8189                  (const_int 0)))]
8190   "TARGET_64BIT
8191    && ix86_match_ccmode (insn, CCNOmode)
8192    && INTVAL (operands[1]) > 0
8193    && INTVAL (operands[2]) >= 0
8194    /* Ensure that resulting mask is zero or sign extended operand.  */
8195    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8196        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8197            && INTVAL (operands[1]) > 32))
8198    && (GET_MODE (operands[0]) == SImode
8199        || GET_MODE (operands[0]) == DImode
8200        || GET_MODE (operands[0]) == HImode
8201        || GET_MODE (operands[0]) == QImode)"
8202   "#")
8203
8204 ;; Combine likes to form bit extractions for some tests.  Humor it.
8205 (define_insn "*testqi_ext_3"
8206   [(set (reg FLAGS_REG)
8207         (compare (zero_extract:SI
8208                    (match_operand 0 "nonimmediate_operand" "rm")
8209                    (match_operand:SI 1 "const_int_operand" "")
8210                    (match_operand:SI 2 "const_int_operand" ""))
8211                  (const_int 0)))]
8212   "ix86_match_ccmode (insn, CCNOmode)
8213    && INTVAL (operands[1]) > 0
8214    && INTVAL (operands[2]) >= 0
8215    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8216    && (GET_MODE (operands[0]) == SImode
8217        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8218        || GET_MODE (operands[0]) == HImode
8219        || GET_MODE (operands[0]) == QImode)"
8220   "#")
8221
8222 (define_split
8223   [(set (match_operand 0 "flags_reg_operand" "")
8224         (match_operator 1 "compare_operator"
8225           [(zero_extract
8226              (match_operand 2 "nonimmediate_operand" "")
8227              (match_operand 3 "const_int_operand" "")
8228              (match_operand 4 "const_int_operand" ""))
8229            (const_int 0)]))]
8230   "ix86_match_ccmode (insn, CCNOmode)"
8231   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8232 {
8233   rtx val = operands[2];
8234   HOST_WIDE_INT len = INTVAL (operands[3]);
8235   HOST_WIDE_INT pos = INTVAL (operands[4]);
8236   HOST_WIDE_INT mask;
8237   enum machine_mode mode, submode;
8238
8239   mode = GET_MODE (val);
8240   if (MEM_P (val))
8241     {
8242       /* ??? Combine likes to put non-volatile mem extractions in QImode
8243          no matter the size of the test.  So find a mode that works.  */
8244       if (! MEM_VOLATILE_P (val))
8245         {
8246           mode = smallest_mode_for_size (pos + len, MODE_INT);
8247           val = adjust_address (val, mode, 0);
8248         }
8249     }
8250   else if (GET_CODE (val) == SUBREG
8251            && (submode = GET_MODE (SUBREG_REG (val)),
8252                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8253            && pos + len <= GET_MODE_BITSIZE (submode)
8254            && GET_MODE_CLASS (submode) == MODE_INT)
8255     {
8256       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
8257       mode = submode;
8258       val = SUBREG_REG (val);
8259     }
8260   else if (mode == HImode && pos + len <= 8)
8261     {
8262       /* Small HImode tests can be converted to QImode.  */
8263       mode = QImode;
8264       val = gen_lowpart (QImode, val);
8265     }
8266
8267   if (len == HOST_BITS_PER_WIDE_INT)
8268     mask = -1;
8269   else
8270     mask = ((HOST_WIDE_INT)1 << len) - 1;
8271   mask <<= pos;
8272
8273   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8274 })
8275
8276 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8277 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8278 ;; this is relatively important trick.
8279 ;; Do the conversion only post-reload to avoid limiting of the register class
8280 ;; to QI regs.
8281 (define_split
8282   [(set (match_operand 0 "flags_reg_operand" "")
8283         (match_operator 1 "compare_operator"
8284           [(and (match_operand 2 "register_operand" "")
8285                 (match_operand 3 "const_int_operand" ""))
8286            (const_int 0)]))]
8287    "reload_completed
8288     && QI_REG_P (operands[2])
8289     && GET_MODE (operands[2]) != QImode
8290     && ((ix86_match_ccmode (insn, CCZmode)
8291          && !(INTVAL (operands[3]) & ~(255 << 8)))
8292         || (ix86_match_ccmode (insn, CCNOmode)
8293             && !(INTVAL (operands[3]) & ~(127 << 8))))"
8294   [(set (match_dup 0)
8295         (match_op_dup 1
8296           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8297                    (match_dup 3))
8298            (const_int 0)]))]
8299   "operands[2] = gen_lowpart (SImode, operands[2]);
8300    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8301
8302 (define_split
8303   [(set (match_operand 0 "flags_reg_operand" "")
8304         (match_operator 1 "compare_operator"
8305           [(and (match_operand 2 "nonimmediate_operand" "")
8306                 (match_operand 3 "const_int_operand" ""))
8307            (const_int 0)]))]
8308    "reload_completed
8309     && GET_MODE (operands[2]) != QImode
8310     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8311     && ((ix86_match_ccmode (insn, CCZmode)
8312          && !(INTVAL (operands[3]) & ~255))
8313         || (ix86_match_ccmode (insn, CCNOmode)
8314             && !(INTVAL (operands[3]) & ~127)))"
8315   [(set (match_dup 0)
8316         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8317                          (const_int 0)]))]
8318   "operands[2] = gen_lowpart (QImode, operands[2]);
8319    operands[3] = gen_lowpart (QImode, operands[3]);")
8320
8321 ;; %%% This used to optimize known byte-wide and operations to memory,
8322 ;; and sometimes to QImode registers.  If this is considered useful,
8323 ;; it should be done with splitters.
8324
8325 (define_expand "and<mode>3"
8326   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8327         (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8328                   (match_operand:SWIM 2 "<general_szext_operand>" "")))]
8329   ""
8330   "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
8331
8332 (define_insn "*anddi_1"
8333   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8334         (and:DI
8335          (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8336          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8337    (clobber (reg:CC FLAGS_REG))]
8338   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8339 {
8340   switch (get_attr_type (insn))
8341     {
8342     case TYPE_IMOVX:
8343       {
8344         enum machine_mode mode;
8345
8346         gcc_assert (CONST_INT_P (operands[2]));
8347         if (INTVAL (operands[2]) == 0xff)
8348           mode = QImode;
8349         else
8350           {
8351             gcc_assert (INTVAL (operands[2]) == 0xffff);
8352             mode = HImode;
8353           }
8354
8355         operands[1] = gen_lowpart (mode, operands[1]);
8356         if (mode == QImode)
8357           return "movz{bl|x}\t{%1, %k0|%k0, %1}";
8358         else
8359           return "movz{wl|x}\t{%1, %k0|%k0, %1}";
8360       }
8361
8362     default:
8363       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8364       if (get_attr_mode (insn) == MODE_SI)
8365         return "and{l}\t{%k2, %k0|%k0, %k2}";
8366       else
8367         return "and{q}\t{%2, %0|%0, %2}";
8368     }
8369 }
8370   [(set_attr "type" "alu,alu,alu,imovx")
8371    (set_attr "length_immediate" "*,*,*,0")
8372    (set (attr "prefix_rex")
8373      (if_then_else
8374        (and (eq_attr "type" "imovx")
8375             (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
8376                  (match_operand 1 "ext_QIreg_nomode_operand" "")))
8377        (const_string "1")
8378        (const_string "*")))
8379    (set_attr "mode" "SI,DI,DI,SI")])
8380
8381 (define_insn "*andsi_1"
8382   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8383         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8384                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8385    (clobber (reg:CC FLAGS_REG))]
8386   "ix86_binary_operator_ok (AND, SImode, operands)"
8387 {
8388   switch (get_attr_type (insn))
8389     {
8390     case TYPE_IMOVX:
8391       {
8392         enum machine_mode mode;
8393
8394         gcc_assert (CONST_INT_P (operands[2]));
8395         if (INTVAL (operands[2]) == 0xff)
8396           mode = QImode;
8397         else
8398           {
8399             gcc_assert (INTVAL (operands[2]) == 0xffff);
8400             mode = HImode;
8401           }
8402
8403         operands[1] = gen_lowpart (mode, operands[1]);
8404         if (mode == QImode)
8405           return "movz{bl|x}\t{%1, %0|%0, %1}";
8406         else
8407           return "movz{wl|x}\t{%1, %0|%0, %1}";
8408       }
8409
8410     default:
8411       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8412       return "and{l}\t{%2, %0|%0, %2}";
8413     }
8414 }
8415   [(set_attr "type" "alu,alu,imovx")
8416    (set (attr "prefix_rex")
8417      (if_then_else
8418        (and (eq_attr "type" "imovx")
8419             (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
8420                  (match_operand 1 "ext_QIreg_nomode_operand" "")))
8421        (const_string "1")
8422        (const_string "*")))
8423    (set_attr "length_immediate" "*,*,0")
8424    (set_attr "mode" "SI")])
8425
8426 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8427 (define_insn "*andsi_1_zext"
8428   [(set (match_operand:DI 0 "register_operand" "=r")
8429         (zero_extend:DI
8430           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8431                   (match_operand:SI 2 "general_operand" "g"))))
8432    (clobber (reg:CC FLAGS_REG))]
8433   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8434   "and{l}\t{%2, %k0|%k0, %2}"
8435   [(set_attr "type" "alu")
8436    (set_attr "mode" "SI")])
8437
8438 (define_insn "*andhi_1"
8439   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8440         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8441                 (match_operand:HI 2 "general_operand" "rn,rm,L")))
8442    (clobber (reg:CC FLAGS_REG))]
8443   "ix86_binary_operator_ok (AND, HImode, operands)"
8444 {
8445   switch (get_attr_type (insn))
8446     {
8447     case TYPE_IMOVX:
8448       gcc_assert (CONST_INT_P (operands[2]));
8449       gcc_assert (INTVAL (operands[2]) == 0xff);
8450       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8451
8452     default:
8453       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8454
8455       return "and{w}\t{%2, %0|%0, %2}";
8456     }
8457 }
8458   [(set_attr "type" "alu,alu,imovx")
8459    (set_attr "length_immediate" "*,*,0")
8460    (set (attr "prefix_rex")
8461      (if_then_else
8462        (and (eq_attr "type" "imovx")
8463             (match_operand 1 "ext_QIreg_nomode_operand" ""))
8464        (const_string "1")
8465        (const_string "*")))
8466    (set_attr "mode" "HI,HI,SI")])
8467
8468 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8469 (define_insn "*andqi_1"
8470   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8471         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8472                 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
8473    (clobber (reg:CC FLAGS_REG))]
8474   "ix86_binary_operator_ok (AND, QImode, operands)"
8475   "@
8476    and{b}\t{%2, %0|%0, %2}
8477    and{b}\t{%2, %0|%0, %2}
8478    and{l}\t{%k2, %k0|%k0, %k2}"
8479   [(set_attr "type" "alu")
8480    (set_attr "mode" "QI,QI,SI")])
8481
8482 (define_insn "*andqi_1_slp"
8483   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8484         (and:QI (match_dup 0)
8485                 (match_operand:QI 1 "general_operand" "qn,qmn")))
8486    (clobber (reg:CC FLAGS_REG))]
8487   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8488    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8489   "and{b}\t{%1, %0|%0, %1}"
8490   [(set_attr "type" "alu1")
8491    (set_attr "mode" "QI")])
8492
8493 (define_split
8494   [(set (match_operand 0 "register_operand" "")
8495         (and (match_dup 0)
8496              (const_int -65536)))
8497    (clobber (reg:CC FLAGS_REG))]
8498   "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
8499     || optimize_function_for_size_p (cfun)"
8500   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8501   "operands[1] = gen_lowpart (HImode, operands[0]);")
8502
8503 (define_split
8504   [(set (match_operand 0 "ext_register_operand" "")
8505         (and (match_dup 0)
8506              (const_int -256)))
8507    (clobber (reg:CC FLAGS_REG))]
8508   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8509    && reload_completed"
8510   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8511   "operands[1] = gen_lowpart (QImode, operands[0]);")
8512
8513 (define_split
8514   [(set (match_operand 0 "ext_register_operand" "")
8515         (and (match_dup 0)
8516              (const_int -65281)))
8517    (clobber (reg:CC FLAGS_REG))]
8518   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8519    && reload_completed"
8520   [(parallel [(set (zero_extract:SI (match_dup 0)
8521                                     (const_int 8)
8522                                     (const_int 8))
8523                    (xor:SI
8524                      (zero_extract:SI (match_dup 0)
8525                                       (const_int 8)
8526                                       (const_int 8))
8527                      (zero_extract:SI (match_dup 0)
8528                                       (const_int 8)
8529                                       (const_int 8))))
8530               (clobber (reg:CC FLAGS_REG))])]
8531   "operands[0] = gen_lowpart (SImode, operands[0]);")
8532
8533 (define_insn "*anddi_2"
8534   [(set (reg FLAGS_REG)
8535         (compare
8536          (and:DI
8537           (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8538           (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8539          (const_int 0)))
8540    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8541         (and:DI (match_dup 1) (match_dup 2)))]
8542   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8543    && ix86_binary_operator_ok (AND, DImode, operands)"
8544   "@
8545    and{l}\t{%k2, %k0|%k0, %k2}
8546    and{q}\t{%2, %0|%0, %2}
8547    and{q}\t{%2, %0|%0, %2}"
8548   [(set_attr "type" "alu")
8549    (set_attr "mode" "SI,DI,DI")])
8550
8551 (define_insn "*andqi_2_maybe_si"
8552   [(set (reg FLAGS_REG)
8553         (compare (and:QI
8554                   (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8555                   (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8556                  (const_int 0)))
8557    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8558         (and:QI (match_dup 1) (match_dup 2)))]
8559   "ix86_binary_operator_ok (AND, QImode, operands)
8560    && ix86_match_ccmode (insn,
8561                          CONST_INT_P (operands[2])
8562                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8563 {
8564   if (which_alternative == 2)
8565     {
8566       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8567         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8568       return "and{l}\t{%2, %k0|%k0, %2}";
8569     }
8570   return "and{b}\t{%2, %0|%0, %2}";
8571 }
8572   [(set_attr "type" "alu")
8573    (set_attr "mode" "QI,QI,SI")])
8574
8575 (define_insn "*and<mode>_2"
8576   [(set (reg FLAGS_REG)
8577         (compare (and:SWI124
8578                   (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8579                   (match_operand:SWI124 2 "general_operand" "<g>,<r><i>"))
8580                  (const_int 0)))
8581    (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8582         (and:SWI124 (match_dup 1) (match_dup 2)))]
8583   "ix86_match_ccmode (insn, CCNOmode)
8584    && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8585   "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8586   [(set_attr "type" "alu")
8587    (set_attr "mode" "<MODE>")])
8588
8589 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8590 (define_insn "*andsi_2_zext"
8591   [(set (reg FLAGS_REG)
8592         (compare (and:SI
8593                   (match_operand:SI 1 "nonimmediate_operand" "%0")
8594                   (match_operand:SI 2 "general_operand" "g"))
8595                  (const_int 0)))
8596    (set (match_operand:DI 0 "register_operand" "=r")
8597         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8598   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8599    && ix86_binary_operator_ok (AND, SImode, operands)"
8600   "and{l}\t{%2, %k0|%k0, %2}"
8601   [(set_attr "type" "alu")
8602    (set_attr "mode" "SI")])
8603
8604 (define_insn "*andqi_2_slp"
8605   [(set (reg FLAGS_REG)
8606         (compare (and:QI
8607                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8608                    (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8609                  (const_int 0)))
8610    (set (strict_low_part (match_dup 0))
8611         (and:QI (match_dup 0) (match_dup 1)))]
8612   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8613    && ix86_match_ccmode (insn, CCNOmode)
8614    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8615   "and{b}\t{%1, %0|%0, %1}"
8616   [(set_attr "type" "alu1")
8617    (set_attr "mode" "QI")])
8618
8619 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8620 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8621 ;; for a QImode operand, which of course failed.
8622 (define_insn "andqi_ext_0"
8623   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8624                          (const_int 8)
8625                          (const_int 8))
8626         (and:SI
8627           (zero_extract:SI
8628             (match_operand 1 "ext_register_operand" "0")
8629             (const_int 8)
8630             (const_int 8))
8631           (match_operand 2 "const_int_operand" "n")))
8632    (clobber (reg:CC FLAGS_REG))]
8633   ""
8634   "and{b}\t{%2, %h0|%h0, %2}"
8635   [(set_attr "type" "alu")
8636    (set_attr "length_immediate" "1")
8637    (set_attr "modrm" "1")
8638    (set_attr "mode" "QI")])
8639
8640 ;; Generated by peephole translating test to and.  This shows up
8641 ;; often in fp comparisons.
8642 (define_insn "*andqi_ext_0_cc"
8643   [(set (reg FLAGS_REG)
8644         (compare
8645           (and:SI
8646             (zero_extract:SI
8647               (match_operand 1 "ext_register_operand" "0")
8648               (const_int 8)
8649               (const_int 8))
8650             (match_operand 2 "const_int_operand" "n"))
8651           (const_int 0)))
8652    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8653                          (const_int 8)
8654                          (const_int 8))
8655         (and:SI
8656           (zero_extract:SI
8657             (match_dup 1)
8658             (const_int 8)
8659             (const_int 8))
8660           (match_dup 2)))]
8661   "ix86_match_ccmode (insn, CCNOmode)"
8662   "and{b}\t{%2, %h0|%h0, %2}"
8663   [(set_attr "type" "alu")
8664    (set_attr "length_immediate" "1")
8665    (set_attr "modrm" "1")
8666    (set_attr "mode" "QI")])
8667
8668 (define_insn "*andqi_ext_1_rex64"
8669   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8670                          (const_int 8)
8671                          (const_int 8))
8672         (and:SI
8673           (zero_extract:SI
8674             (match_operand 1 "ext_register_operand" "0")
8675             (const_int 8)
8676             (const_int 8))
8677           (zero_extend:SI
8678             (match_operand 2 "ext_register_operand" "Q"))))
8679    (clobber (reg:CC FLAGS_REG))]
8680   "TARGET_64BIT"
8681   "and{b}\t{%2, %h0|%h0, %2}"
8682   [(set_attr "type" "alu")
8683    (set_attr "length_immediate" "0")
8684    (set_attr "mode" "QI")])
8685
8686 (define_insn "*andqi_ext_1"
8687   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8688                          (const_int 8)
8689                          (const_int 8))
8690         (and:SI
8691           (zero_extract:SI
8692             (match_operand 1 "ext_register_operand" "0")
8693             (const_int 8)
8694             (const_int 8))
8695           (zero_extend:SI
8696             (match_operand:QI 2 "general_operand" "Qm"))))
8697    (clobber (reg:CC FLAGS_REG))]
8698   "!TARGET_64BIT"
8699   "and{b}\t{%2, %h0|%h0, %2}"
8700   [(set_attr "type" "alu")
8701    (set_attr "length_immediate" "0")
8702    (set_attr "mode" "QI")])
8703
8704 (define_insn "*andqi_ext_2"
8705   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8706                          (const_int 8)
8707                          (const_int 8))
8708         (and:SI
8709           (zero_extract:SI
8710             (match_operand 1 "ext_register_operand" "%0")
8711             (const_int 8)
8712             (const_int 8))
8713           (zero_extract:SI
8714             (match_operand 2 "ext_register_operand" "Q")
8715             (const_int 8)
8716             (const_int 8))))
8717    (clobber (reg:CC FLAGS_REG))]
8718   ""
8719   "and{b}\t{%h2, %h0|%h0, %h2}"
8720   [(set_attr "type" "alu")
8721    (set_attr "length_immediate" "0")
8722    (set_attr "mode" "QI")])
8723
8724 ;; Convert wide AND instructions with immediate operand to shorter QImode
8725 ;; equivalents when possible.
8726 ;; Don't do the splitting with memory operands, since it introduces risk
8727 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8728 ;; for size, but that can (should?) be handled by generic code instead.
8729 (define_split
8730   [(set (match_operand 0 "register_operand" "")
8731         (and (match_operand 1 "register_operand" "")
8732              (match_operand 2 "const_int_operand" "")))
8733    (clobber (reg:CC FLAGS_REG))]
8734    "reload_completed
8735     && QI_REG_P (operands[0])
8736     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8737     && !(~INTVAL (operands[2]) & ~(255 << 8))
8738     && GET_MODE (operands[0]) != QImode"
8739   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8740                    (and:SI (zero_extract:SI (match_dup 1)
8741                                             (const_int 8) (const_int 8))
8742                            (match_dup 2)))
8743               (clobber (reg:CC FLAGS_REG))])]
8744   "operands[0] = gen_lowpart (SImode, operands[0]);
8745    operands[1] = gen_lowpart (SImode, operands[1]);
8746    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8747
8748 ;; Since AND can be encoded with sign extended immediate, this is only
8749 ;; profitable when 7th bit is not set.
8750 (define_split
8751   [(set (match_operand 0 "register_operand" "")
8752         (and (match_operand 1 "general_operand" "")
8753              (match_operand 2 "const_int_operand" "")))
8754    (clobber (reg:CC FLAGS_REG))]
8755    "reload_completed
8756     && ANY_QI_REG_P (operands[0])
8757     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8758     && !(~INTVAL (operands[2]) & ~255)
8759     && !(INTVAL (operands[2]) & 128)
8760     && GET_MODE (operands[0]) != QImode"
8761   [(parallel [(set (strict_low_part (match_dup 0))
8762                    (and:QI (match_dup 1)
8763                            (match_dup 2)))
8764               (clobber (reg:CC FLAGS_REG))])]
8765   "operands[0] = gen_lowpart (QImode, operands[0]);
8766    operands[1] = gen_lowpart (QImode, operands[1]);
8767    operands[2] = gen_lowpart (QImode, operands[2]);")
8768 \f
8769 ;; Logical inclusive and exclusive OR instructions
8770
8771 ;; %%% This used to optimize known byte-wide and operations to memory.
8772 ;; If this is considered useful, it should be done with splitters.
8773
8774 (define_expand "<code><mode>3"
8775   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8776         (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8777                      (match_operand:SWIM 2 "<general_operand>" "")))]
8778   ""
8779   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8780
8781 (define_insn "*<code><mode>_1"
8782   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8783         (any_or:SWI248
8784          (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8785          (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8786    (clobber (reg:CC FLAGS_REG))]
8787   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8788   "<logicprefix>{<imodesuffix>}\t{%2, %0|%0, %2}"
8789   [(set_attr "type" "alu")
8790    (set_attr "mode" "<MODE>")])
8791
8792 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8793 (define_insn "*<code>qi_1"
8794   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8795         (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8796                    (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8797    (clobber (reg:CC FLAGS_REG))]
8798   "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8799   "@
8800    <logicprefix>{b}\t{%2, %0|%0, %2}
8801    <logicprefix>{b}\t{%2, %0|%0, %2}
8802    <logicprefix>{l}\t{%k2, %k0|%k0, %k2}"
8803   [(set_attr "type" "alu")
8804    (set_attr "mode" "QI,QI,SI")])
8805
8806 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8807 (define_insn "*<code>si_1_zext"
8808   [(set (match_operand:DI 0 "register_operand" "=r")
8809         (zero_extend:DI
8810          (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8811                     (match_operand:SI 2 "general_operand" "g"))))
8812    (clobber (reg:CC FLAGS_REG))]
8813   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8814   "<logicprefix>{l}\t{%2, %k0|%k0, %2}"
8815   [(set_attr "type" "alu")
8816    (set_attr "mode" "SI")])
8817
8818 (define_insn "*<code>si_1_zext_imm"
8819   [(set (match_operand:DI 0 "register_operand" "=r")
8820         (any_or:DI
8821          (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8822          (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8823    (clobber (reg:CC FLAGS_REG))]
8824   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8825   "<logicprefix>{l}\t{%2, %k0|%k0, %2}"
8826   [(set_attr "type" "alu")
8827    (set_attr "mode" "SI")])
8828
8829 (define_insn "*<code>qi_1_slp"
8830   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8831         (any_or:QI (match_dup 0)
8832                    (match_operand:QI 1 "general_operand" "qmn,qn")))
8833    (clobber (reg:CC FLAGS_REG))]
8834   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8835    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8836   "<logicprefix>{b}\t{%1, %0|%0, %1}"
8837   [(set_attr "type" "alu1")
8838    (set_attr "mode" "QI")])
8839
8840 (define_insn "*<code><mode>_2"
8841   [(set (reg FLAGS_REG)
8842         (compare (any_or:SWI
8843                   (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8844                   (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8845                  (const_int 0)))
8846    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8847         (any_or:SWI (match_dup 1) (match_dup 2)))]
8848   "ix86_match_ccmode (insn, CCNOmode)
8849    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8850   "<logicprefix>{<imodesuffix>}\t{%2, %0|%0, %2}"
8851   [(set_attr "type" "alu")
8852    (set_attr "mode" "<MODE>")])
8853
8854 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8855 ;; ??? Special case for immediate operand is missing - it is tricky.
8856 (define_insn "*<code>si_2_zext"
8857   [(set (reg FLAGS_REG)
8858         (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8859                             (match_operand:SI 2 "general_operand" "g"))
8860                  (const_int 0)))
8861    (set (match_operand:DI 0 "register_operand" "=r")
8862         (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8863   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8864    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8865   "<logicprefix>{l}\t{%2, %k0|%k0, %2}"
8866   [(set_attr "type" "alu")
8867    (set_attr "mode" "SI")])
8868
8869 (define_insn "*<code>si_2_zext_imm"
8870   [(set (reg FLAGS_REG)
8871         (compare (any_or:SI
8872                   (match_operand:SI 1 "nonimmediate_operand" "%0")
8873                   (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8874                  (const_int 0)))
8875    (set (match_operand:DI 0 "register_operand" "=r")
8876         (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8877   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8878    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8879   "<logicprefix>{l}\t{%2, %k0|%k0, %2}"
8880   [(set_attr "type" "alu")
8881    (set_attr "mode" "SI")])
8882
8883 (define_insn "*<code>qi_2_slp"
8884   [(set (reg FLAGS_REG)
8885         (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8886                             (match_operand:QI 1 "general_operand" "qmn,qn"))
8887                  (const_int 0)))
8888    (set (strict_low_part (match_dup 0))
8889         (any_or:QI (match_dup 0) (match_dup 1)))]
8890   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8891    && ix86_match_ccmode (insn, CCNOmode)
8892    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8893   "<logicprefix>{b}\t{%1, %0|%0, %1}"
8894   [(set_attr "type" "alu1")
8895    (set_attr "mode" "QI")])
8896
8897 (define_insn "*<code><mode>_3"
8898   [(set (reg FLAGS_REG)
8899         (compare (any_or:SWI
8900                   (match_operand:SWI 1 "nonimmediate_operand" "%0")
8901                   (match_operand:SWI 2 "<general_operand>" "<g>"))
8902                  (const_int 0)))
8903    (clobber (match_scratch:SWI 0 "=<r>"))]
8904   "ix86_match_ccmode (insn, CCNOmode)
8905    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8906   "<logicprefix>{<imodesuffix>}\t{%2, %0|%0, %2}"
8907   [(set_attr "type" "alu")
8908    (set_attr "mode" "<MODE>")])
8909
8910 (define_insn "*<code>qi_ext_0"
8911   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8912                          (const_int 8)
8913                          (const_int 8))
8914         (any_or:SI
8915           (zero_extract:SI
8916             (match_operand 1 "ext_register_operand" "0")
8917             (const_int 8)
8918             (const_int 8))
8919           (match_operand 2 "const_int_operand" "n")))
8920    (clobber (reg:CC FLAGS_REG))]
8921   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8922   "<logicprefix>{b}\t{%2, %h0|%h0, %2}"
8923   [(set_attr "type" "alu")
8924    (set_attr "length_immediate" "1")
8925    (set_attr "modrm" "1")
8926    (set_attr "mode" "QI")])
8927
8928 (define_insn "*<code>qi_ext_1_rex64"
8929   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8930                          (const_int 8)
8931                          (const_int 8))
8932         (any_or:SI
8933           (zero_extract:SI
8934             (match_operand 1 "ext_register_operand" "0")
8935             (const_int 8)
8936             (const_int 8))
8937           (zero_extend:SI
8938             (match_operand 2 "ext_register_operand" "Q"))))
8939    (clobber (reg:CC FLAGS_REG))]
8940   "TARGET_64BIT
8941    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8942   "<logicprefix>{b}\t{%2, %h0|%h0, %2}"
8943   [(set_attr "type" "alu")
8944    (set_attr "length_immediate" "0")
8945    (set_attr "mode" "QI")])
8946
8947 (define_insn "*<code>qi_ext_1"
8948   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8949                          (const_int 8)
8950                          (const_int 8))
8951         (any_or:SI
8952           (zero_extract:SI
8953             (match_operand 1 "ext_register_operand" "0")
8954             (const_int 8)
8955             (const_int 8))
8956           (zero_extend:SI
8957             (match_operand:QI 2 "general_operand" "Qm"))))
8958    (clobber (reg:CC FLAGS_REG))]
8959   "!TARGET_64BIT
8960    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8961   "<logicprefix>{b}\t{%2, %h0|%h0, %2}"
8962   [(set_attr "type" "alu")
8963    (set_attr "length_immediate" "0")
8964    (set_attr "mode" "QI")])
8965
8966 (define_insn "*<code>qi_ext_2"
8967   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8968                          (const_int 8)
8969                          (const_int 8))
8970         (any_or:SI
8971           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8972                            (const_int 8)
8973                            (const_int 8))
8974           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8975                            (const_int 8)
8976                            (const_int 8))))
8977    (clobber (reg:CC FLAGS_REG))]
8978   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8979   "<logicprefix>{b}\t{%h2, %h0|%h0, %h2}"
8980   [(set_attr "type" "alu")
8981    (set_attr "length_immediate" "0")
8982    (set_attr "mode" "QI")])
8983
8984 (define_split
8985   [(set (match_operand 0 "register_operand" "")
8986         (any_or (match_operand 1 "register_operand" "")
8987                 (match_operand 2 "const_int_operand" "")))
8988    (clobber (reg:CC FLAGS_REG))]
8989    "reload_completed
8990     && QI_REG_P (operands[0])
8991     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8992     && !(INTVAL (operands[2]) & ~(255 << 8))
8993     && GET_MODE (operands[0]) != QImode"
8994   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8995                    (any_or:SI (zero_extract:SI (match_dup 1)
8996                                                (const_int 8) (const_int 8))
8997                               (match_dup 2)))
8998               (clobber (reg:CC FLAGS_REG))])]
8999   "operands[0] = gen_lowpart (SImode, operands[0]);
9000    operands[1] = gen_lowpart (SImode, operands[1]);
9001    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9002
9003 ;; Since OR can be encoded with sign extended immediate, this is only
9004 ;; profitable when 7th bit is set.
9005 (define_split
9006   [(set (match_operand 0 "register_operand" "")
9007         (any_or (match_operand 1 "general_operand" "")
9008                 (match_operand 2 "const_int_operand" "")))
9009    (clobber (reg:CC FLAGS_REG))]
9010    "reload_completed
9011     && ANY_QI_REG_P (operands[0])
9012     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9013     && !(INTVAL (operands[2]) & ~255)
9014     && (INTVAL (operands[2]) & 128)
9015     && GET_MODE (operands[0]) != QImode"
9016   [(parallel [(set (strict_low_part (match_dup 0))
9017                    (any_or:QI (match_dup 1)
9018                               (match_dup 2)))
9019               (clobber (reg:CC FLAGS_REG))])]
9020   "operands[0] = gen_lowpart (QImode, operands[0]);
9021    operands[1] = gen_lowpart (QImode, operands[1]);
9022    operands[2] = gen_lowpart (QImode, operands[2]);")
9023
9024 (define_expand "xorqi_cc_ext_1"
9025   [(parallel [
9026      (set (reg:CCNO FLAGS_REG)
9027           (compare:CCNO
9028             (xor:SI
9029               (zero_extract:SI
9030                 (match_operand 1 "ext_register_operand" "")
9031                 (const_int 8)
9032                 (const_int 8))
9033               (match_operand:QI 2 "general_operand" ""))
9034             (const_int 0)))
9035      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9036                            (const_int 8)
9037                            (const_int 8))
9038           (xor:SI
9039             (zero_extract:SI
9040              (match_dup 1)
9041              (const_int 8)
9042              (const_int 8))
9043             (match_dup 2)))])]
9044   ""
9045   "")
9046
9047 (define_insn "*xorqi_cc_ext_1_rex64"
9048   [(set (reg FLAGS_REG)
9049         (compare
9050           (xor:SI
9051             (zero_extract:SI
9052               (match_operand 1 "ext_register_operand" "0")
9053               (const_int 8)
9054               (const_int 8))
9055             (match_operand:QI 2 "nonmemory_operand" "Qn"))
9056           (const_int 0)))
9057    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9058                          (const_int 8)
9059                          (const_int 8))
9060         (xor:SI
9061           (zero_extract:SI
9062            (match_dup 1)
9063            (const_int 8)
9064            (const_int 8))
9065           (match_dup 2)))]
9066   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9067   "xor{b}\t{%2, %h0|%h0, %2}"
9068   [(set_attr "type" "alu")
9069    (set_attr "modrm" "1")
9070    (set_attr "mode" "QI")])
9071
9072 (define_insn "*xorqi_cc_ext_1"
9073   [(set (reg FLAGS_REG)
9074         (compare
9075           (xor:SI
9076             (zero_extract:SI
9077               (match_operand 1 "ext_register_operand" "0")
9078               (const_int 8)
9079               (const_int 8))
9080             (match_operand:QI 2 "general_operand" "qmn"))
9081           (const_int 0)))
9082    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9083                          (const_int 8)
9084                          (const_int 8))
9085         (xor:SI
9086           (zero_extract:SI
9087            (match_dup 1)
9088            (const_int 8)
9089            (const_int 8))
9090           (match_dup 2)))]
9091   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9092   "xor{b}\t{%2, %h0|%h0, %2}"
9093   [(set_attr "type" "alu")
9094    (set_attr "modrm" "1")
9095    (set_attr "mode" "QI")])
9096 \f
9097 ;; Negation instructions
9098
9099 (define_expand "neg<mode>2"
9100   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
9101         (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
9102   ""
9103   "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
9104
9105 (define_insn_and_split "*neg<dwi>2_doubleword"
9106   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
9107         (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
9108    (clobber (reg:CC FLAGS_REG))]
9109   "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
9110   "#"
9111   "reload_completed"
9112   [(parallel
9113     [(set (reg:CCZ FLAGS_REG)
9114           (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
9115      (set (match_dup 0) (neg:DWIH (match_dup 1)))])
9116    (parallel
9117     [(set (match_dup 2)
9118           (plus:DWIH (match_dup 3)
9119                      (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
9120                                 (const_int 0))))
9121      (clobber (reg:CC FLAGS_REG))])
9122    (parallel
9123     [(set (match_dup 2)
9124           (neg:DWIH (match_dup 2)))
9125      (clobber (reg:CC FLAGS_REG))])]
9126   "split_<dwi> (&operands[0], 2, &operands[0], &operands[2]);")
9127
9128 (define_insn "*neg<mode>2_1"
9129   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9130         (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
9131    (clobber (reg:CC FLAGS_REG))]
9132   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9133   "neg{<imodesuffix>}\t%0"
9134   [(set_attr "type" "negnot")
9135    (set_attr "mode" "<MODE>")])
9136
9137 ;; Combine is quite creative about this pattern.
9138 (define_insn "*negsi2_1_zext"
9139   [(set (match_operand:DI 0 "register_operand" "=r")
9140         (lshiftrt:DI
9141           (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9142                              (const_int 32)))
9143         (const_int 32)))
9144    (clobber (reg:CC FLAGS_REG))]
9145   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9146   "neg{l}\t%k0"
9147   [(set_attr "type" "negnot")
9148    (set_attr "mode" "SI")])
9149
9150 ;; The problem with neg is that it does not perform (compare x 0),
9151 ;; it really performs (compare 0 x), which leaves us with the zero
9152 ;; flag being the only useful item.
9153
9154 (define_insn "*neg<mode>2_cmpz"
9155   [(set (reg:CCZ FLAGS_REG)
9156         (compare:CCZ
9157           (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9158                    (const_int 0)))
9159    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9160         (neg:SWI (match_dup 1)))]
9161   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9162   "neg{<imodesuffix>}\t%0"
9163   [(set_attr "type" "negnot")
9164    (set_attr "mode" "<MODE>")])
9165
9166 (define_insn "*negsi2_cmpz_zext"
9167   [(set (reg:CCZ FLAGS_REG)
9168         (compare:CCZ
9169           (lshiftrt:DI
9170             (neg:DI (ashift:DI
9171                       (match_operand:DI 1 "register_operand" "0")
9172                       (const_int 32)))
9173             (const_int 32))
9174           (const_int 0)))
9175    (set (match_operand:DI 0 "register_operand" "=r")
9176         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9177                                         (const_int 32)))
9178                      (const_int 32)))]
9179   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9180   "neg{l}\t%k0"
9181   [(set_attr "type" "negnot")
9182    (set_attr "mode" "SI")])
9183
9184 ;; Changing of sign for FP values is doable using integer unit too.
9185
9186 (define_expand "<code><mode>2"
9187   [(set (match_operand:X87MODEF 0 "register_operand" "")
9188         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
9189   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9190   "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
9191
9192 (define_insn "*absneg<mode>2_mixed"
9193   [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
9194         (match_operator:MODEF 3 "absneg_operator"
9195           [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
9196    (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
9197    (clobber (reg:CC FLAGS_REG))]
9198   "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
9199   "#")
9200
9201 (define_insn "*absneg<mode>2_sse"
9202   [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
9203         (match_operator:MODEF 3 "absneg_operator"
9204           [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
9205    (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
9206    (clobber (reg:CC FLAGS_REG))]
9207   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
9208   "#")
9209
9210 (define_insn "*absneg<mode>2_i387"
9211   [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
9212         (match_operator:X87MODEF 3 "absneg_operator"
9213           [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
9214    (use (match_operand 2 "" ""))
9215    (clobber (reg:CC FLAGS_REG))]
9216   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9217   "#")
9218
9219 (define_expand "<code>tf2"
9220   [(set (match_operand:TF 0 "register_operand" "")
9221         (absneg:TF (match_operand:TF 1 "register_operand" "")))]
9222   "TARGET_SSE2"
9223   "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
9224
9225 (define_insn "*absnegtf2_sse"
9226   [(set (match_operand:TF 0 "register_operand" "=x,x")
9227         (match_operator:TF 3 "absneg_operator"
9228           [(match_operand:TF 1 "register_operand" "0,x")]))
9229    (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
9230    (clobber (reg:CC FLAGS_REG))]
9231   "TARGET_SSE2"
9232   "#")
9233
9234 ;; Splitters for fp abs and neg.
9235
9236 (define_split
9237   [(set (match_operand 0 "fp_register_operand" "")
9238         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9239    (use (match_operand 2 "" ""))
9240    (clobber (reg:CC FLAGS_REG))]
9241   "reload_completed"
9242   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9243
9244 (define_split
9245   [(set (match_operand 0 "register_operand" "")
9246         (match_operator 3 "absneg_operator"
9247           [(match_operand 1 "register_operand" "")]))
9248    (use (match_operand 2 "nonimmediate_operand" ""))
9249    (clobber (reg:CC FLAGS_REG))]
9250   "reload_completed && SSE_REG_P (operands[0])"
9251   [(set (match_dup 0) (match_dup 3))]
9252 {
9253   enum machine_mode mode = GET_MODE (operands[0]);
9254   enum machine_mode vmode = GET_MODE (operands[2]);
9255   rtx tmp;
9256
9257   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9258   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9259   if (operands_match_p (operands[0], operands[2]))
9260     {
9261       tmp = operands[1];
9262       operands[1] = operands[2];
9263       operands[2] = tmp;
9264     }
9265   if (GET_CODE (operands[3]) == ABS)
9266     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9267   else
9268     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9269   operands[3] = tmp;
9270 })
9271
9272 (define_split
9273   [(set (match_operand:SF 0 "register_operand" "")
9274         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9275    (use (match_operand:V4SF 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   operands[0] = gen_lowpart (SImode, operands[0]);
9283   if (GET_CODE (operands[1]) == ABS)
9284     {
9285       tmp = gen_int_mode (0x7fffffff, SImode);
9286       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9287     }
9288   else
9289     {
9290       tmp = gen_int_mode (0x80000000, SImode);
9291       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9292     }
9293   operands[1] = tmp;
9294 })
9295
9296 (define_split
9297   [(set (match_operand:DF 0 "register_operand" "")
9298         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9299    (use (match_operand 2 "" ""))
9300    (clobber (reg:CC FLAGS_REG))]
9301   "reload_completed"
9302   [(parallel [(set (match_dup 0) (match_dup 1))
9303               (clobber (reg:CC FLAGS_REG))])]
9304 {
9305   rtx tmp;
9306   if (TARGET_64BIT)
9307     {
9308       tmp = gen_lowpart (DImode, operands[0]);
9309       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9310       operands[0] = tmp;
9311
9312       if (GET_CODE (operands[1]) == ABS)
9313         tmp = const0_rtx;
9314       else
9315         tmp = gen_rtx_NOT (DImode, tmp);
9316     }
9317   else
9318     {
9319       operands[0] = gen_highpart (SImode, operands[0]);
9320       if (GET_CODE (operands[1]) == ABS)
9321         {
9322           tmp = gen_int_mode (0x7fffffff, SImode);
9323           tmp = gen_rtx_AND (SImode, operands[0], tmp);
9324         }
9325       else
9326         {
9327           tmp = gen_int_mode (0x80000000, SImode);
9328           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9329         }
9330     }
9331   operands[1] = tmp;
9332 })
9333
9334 (define_split
9335   [(set (match_operand:XF 0 "register_operand" "")
9336         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9337    (use (match_operand 2 "" ""))
9338    (clobber (reg:CC FLAGS_REG))]
9339   "reload_completed"
9340   [(parallel [(set (match_dup 0) (match_dup 1))
9341               (clobber (reg:CC FLAGS_REG))])]
9342 {
9343   rtx tmp;
9344   operands[0] = gen_rtx_REG (SImode,
9345                              true_regnum (operands[0])
9346                              + (TARGET_64BIT ? 1 : 2));
9347   if (GET_CODE (operands[1]) == ABS)
9348     {
9349       tmp = GEN_INT (0x7fff);
9350       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9351     }
9352   else
9353     {
9354       tmp = GEN_INT (0x8000);
9355       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9356     }
9357   operands[1] = tmp;
9358 })
9359
9360 ;; Conditionalize these after reload. If they match before reload, we
9361 ;; lose the clobber and ability to use integer instructions.
9362
9363 (define_insn "*<code><mode>2_1"
9364   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
9365         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
9366   "TARGET_80387
9367    && (reload_completed
9368        || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
9369   "f<absnegprefix>"
9370   [(set_attr "type" "fsgn")
9371    (set_attr "mode" "<MODE>")])
9372
9373 (define_insn "*<code>extendsfdf2"
9374   [(set (match_operand:DF 0 "register_operand" "=f")
9375         (absneg:DF (float_extend:DF
9376                      (match_operand:SF 1 "register_operand" "0"))))]
9377   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9378   "f<absnegprefix>"
9379   [(set_attr "type" "fsgn")
9380    (set_attr "mode" "DF")])
9381
9382 (define_insn "*<code>extendsfxf2"
9383   [(set (match_operand:XF 0 "register_operand" "=f")
9384         (absneg:XF (float_extend:XF
9385                      (match_operand:SF 1 "register_operand" "0"))))]
9386   "TARGET_80387"
9387   "f<absnegprefix>"
9388   [(set_attr "type" "fsgn")
9389    (set_attr "mode" "XF")])
9390
9391 (define_insn "*<code>extenddfxf2"
9392   [(set (match_operand:XF 0 "register_operand" "=f")
9393         (absneg:XF (float_extend:XF
9394                       (match_operand:DF 1 "register_operand" "0"))))]
9395   "TARGET_80387"
9396   "f<absnegprefix>"
9397   [(set_attr "type" "fsgn")
9398    (set_attr "mode" "XF")])
9399
9400 ;; Copysign instructions
9401
9402 (define_mode_iterator CSGNMODE [SF DF TF])
9403 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
9404
9405 (define_expand "copysign<mode>3"
9406   [(match_operand:CSGNMODE 0 "register_operand" "")
9407    (match_operand:CSGNMODE 1 "nonmemory_operand" "")
9408    (match_operand:CSGNMODE 2 "register_operand" "")]
9409   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9410    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
9411 {
9412   ix86_expand_copysign (operands);
9413   DONE;
9414 })
9415
9416 (define_insn_and_split "copysign<mode>3_const"
9417   [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
9418         (unspec:CSGNMODE
9419           [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
9420            (match_operand:CSGNMODE 2 "register_operand" "0")
9421            (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
9422           UNSPEC_COPYSIGN))]
9423   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9424    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
9425   "#"
9426   "&& reload_completed"
9427   [(const_int 0)]
9428 {
9429   ix86_split_copysign_const (operands);
9430   DONE;
9431 })
9432
9433 (define_insn "copysign<mode>3_var"
9434   [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
9435         (unspec:CSGNMODE
9436           [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
9437            (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
9438            (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
9439            (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
9440           UNSPEC_COPYSIGN))
9441    (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
9442   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9443    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
9444   "#")
9445
9446 (define_split
9447   [(set (match_operand:CSGNMODE 0 "register_operand" "")
9448         (unspec:CSGNMODE
9449           [(match_operand:CSGNMODE 2 "register_operand" "")
9450            (match_operand:CSGNMODE 3 "register_operand" "")
9451            (match_operand:<CSGNVMODE> 4 "" "")
9452            (match_operand:<CSGNVMODE> 5 "" "")]
9453           UNSPEC_COPYSIGN))
9454    (clobber (match_scratch:<CSGNVMODE> 1 ""))]
9455   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9456     || (TARGET_SSE2 && (<MODE>mode == TFmode)))
9457    && reload_completed"
9458   [(const_int 0)]
9459 {
9460   ix86_split_copysign_var (operands);
9461   DONE;
9462 })
9463 \f
9464 ;; One complement instructions
9465
9466 (define_expand "one_cmpl<mode>2"
9467   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
9468         (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
9469   ""
9470   "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
9471
9472 (define_insn "*one_cmpl<mode>2_1"
9473   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
9474         (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
9475   "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9476   "not{<imodesuffix>}\t%0"
9477   [(set_attr "type" "negnot")
9478    (set_attr "mode" "<MODE>")])
9479
9480 ;; %%% Potential partial reg stall on alternative 1.  What to do?
9481 (define_insn "*one_cmplqi2_1"
9482   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9483         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
9484   "ix86_unary_operator_ok (NOT, QImode, operands)"
9485   "@
9486    not{b}\t%0
9487    not{l}\t%k0"
9488   [(set_attr "type" "negnot")
9489    (set_attr "mode" "QI,SI")])
9490
9491 ;; ??? Currently never generated - xor is used instead.
9492 (define_insn "*one_cmplsi2_1_zext"
9493   [(set (match_operand:DI 0 "register_operand" "=r")
9494         (zero_extend:DI
9495           (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9496   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9497   "not{l}\t%k0"
9498   [(set_attr "type" "negnot")
9499    (set_attr "mode" "SI")])
9500
9501 (define_insn "*one_cmpl<mode>2_2"
9502   [(set (reg FLAGS_REG)
9503         (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9504                  (const_int 0)))
9505    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9506         (not:SWI (match_dup 1)))]
9507   "ix86_match_ccmode (insn, CCNOmode)
9508    && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9509   "#"
9510   [(set_attr "type" "alu1")
9511    (set_attr "mode" "<MODE>")])
9512
9513 (define_split
9514   [(set (match_operand 0 "flags_reg_operand" "")
9515         (match_operator 2 "compare_operator"
9516           [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
9517            (const_int 0)]))
9518    (set (match_operand:SWI 1 "nonimmediate_operand" "")
9519         (not:SWI (match_dup 3)))]
9520   "ix86_match_ccmode (insn, CCNOmode)"
9521   [(parallel [(set (match_dup 0)
9522                    (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9523                                     (const_int 0)]))
9524               (set (match_dup 1)
9525                    (xor:SWI (match_dup 3) (const_int -1)))])]
9526   "")
9527
9528 ;; ??? Currently never generated - xor is used instead.
9529 (define_insn "*one_cmplsi2_2_zext"
9530   [(set (reg FLAGS_REG)
9531         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9532                  (const_int 0)))
9533    (set (match_operand:DI 0 "register_operand" "=r")
9534         (zero_extend:DI (not:SI (match_dup 1))))]
9535   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9536    && ix86_unary_operator_ok (NOT, SImode, operands)"
9537   "#"
9538   [(set_attr "type" "alu1")
9539    (set_attr "mode" "SI")])
9540
9541 (define_split
9542   [(set (match_operand 0 "flags_reg_operand" "")
9543         (match_operator 2 "compare_operator"
9544           [(not:SI (match_operand:SI 3 "register_operand" ""))
9545            (const_int 0)]))
9546    (set (match_operand:DI 1 "register_operand" "")
9547         (zero_extend:DI (not:SI (match_dup 3))))]
9548   "ix86_match_ccmode (insn, CCNOmode)"
9549   [(parallel [(set (match_dup 0)
9550                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9551                                     (const_int 0)]))
9552               (set (match_dup 1)
9553                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
9554   "")
9555 \f
9556 ;; Shift instructions
9557
9558 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9559 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
9560 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9561 ;; from the assembler input.
9562 ;;
9563 ;; This instruction shifts the target reg/mem as usual, but instead of
9564 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
9565 ;; is a left shift double, bits are taken from the high order bits of
9566 ;; reg, else if the insn is a shift right double, bits are taken from the
9567 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
9568 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9569 ;;
9570 ;; Since sh[lr]d does not change the `reg' operand, that is done
9571 ;; separately, making all shifts emit pairs of shift double and normal
9572 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
9573 ;; support a 63 bit shift, each shift where the count is in a reg expands
9574 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9575 ;;
9576 ;; If the shift count is a constant, we need never emit more than one
9577 ;; shift pair, instead using moves and sign extension for counts greater
9578 ;; than 31.
9579
9580 (define_expand "ashl<mode>3"
9581   [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9582         (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
9583                       (match_operand:QI 2 "nonmemory_operand" "")))]
9584   ""
9585   "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9586
9587 (define_insn "*ashl<mode>3_doubleword"
9588   [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9589         (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9590                     (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9591    (clobber (reg:CC FLAGS_REG))]
9592   ""
9593   "#"
9594   [(set_attr "type" "multi")])
9595
9596 (define_split
9597   [(set (match_operand:DWI 0 "register_operand" "")
9598         (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
9599                     (match_operand:QI 2 "nonmemory_operand" "")))
9600    (clobber (reg:CC FLAGS_REG))]
9601   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9602   [(const_int 0)]
9603   "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9604
9605 ;; By default we don't ask for a scratch register, because when DWImode
9606 ;; values are manipulated, registers are already at a premium.  But if
9607 ;; we have one handy, we won't turn it away.
9608
9609 (define_peephole2
9610   [(match_scratch:DWIH 3 "r")
9611    (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9612                    (ashift:<DWI>
9613                      (match_operand:<DWI> 1 "nonmemory_operand" "")
9614                      (match_operand:QI 2 "nonmemory_operand" "")))
9615               (clobber (reg:CC FLAGS_REG))])
9616    (match_dup 3)]
9617   "TARGET_CMOVE"
9618   [(const_int 0)]
9619   "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9620
9621 (define_insn "x86_64_shld"
9622   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9623         (ior:DI (ashift:DI (match_dup 0)
9624                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
9625                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9626                   (minus:QI (const_int 64) (match_dup 2)))))
9627    (clobber (reg:CC FLAGS_REG))]
9628   "TARGET_64BIT"
9629   "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9630   [(set_attr "type" "ishift")
9631    (set_attr "prefix_0f" "1")
9632    (set_attr "mode" "DI")
9633    (set_attr "athlon_decode" "vector")
9634    (set_attr "amdfam10_decode" "vector")])
9635
9636 (define_insn "x86_shld"
9637   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9638         (ior:SI (ashift:SI (match_dup 0)
9639                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
9640                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9641                   (minus:QI (const_int 32) (match_dup 2)))))
9642    (clobber (reg:CC FLAGS_REG))]
9643   ""
9644   "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9645   [(set_attr "type" "ishift")
9646    (set_attr "prefix_0f" "1")
9647    (set_attr "mode" "SI")
9648    (set_attr "pent_pair" "np")
9649    (set_attr "athlon_decode" "vector")
9650    (set_attr "amdfam10_decode" "vector")])
9651
9652 (define_expand "x86_shift<mode>_adj_1"
9653   [(set (reg:CCZ FLAGS_REG)
9654         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
9655                              (match_dup 4))
9656                      (const_int 0)))
9657    (set (match_operand:SWI48 0 "register_operand" "")
9658         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9659                             (match_operand:SWI48 1 "register_operand" "")
9660                             (match_dup 0)))
9661    (set (match_dup 1)
9662         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9663                             (match_operand:SWI48 3 "register_operand" "r")
9664                             (match_dup 1)))]
9665   "TARGET_CMOVE"
9666   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9667
9668 (define_expand "x86_shift<mode>_adj_2"
9669   [(use (match_operand:SWI48 0 "register_operand" ""))
9670    (use (match_operand:SWI48 1 "register_operand" ""))
9671    (use (match_operand:QI 2 "register_operand" ""))]
9672   ""
9673 {
9674   rtx label = gen_label_rtx ();
9675   rtx tmp;
9676
9677   emit_insn (gen_testqi_ccz_1 (operands[2],
9678                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9679
9680   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9681   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9682   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9683                               gen_rtx_LABEL_REF (VOIDmode, label),
9684                               pc_rtx);
9685   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9686   JUMP_LABEL (tmp) = label;
9687
9688   emit_move_insn (operands[0], operands[1]);
9689   ix86_expand_clear (operands[1]);
9690
9691   emit_label (label);
9692   LABEL_NUSES (label) = 1;
9693
9694   DONE;
9695 })
9696
9697 (define_insn "*ashl<mode>3_1"
9698   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9699         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l")
9700                       (match_operand:QI 2 "nonmemory_operand" "c<S>,M")))
9701    (clobber (reg:CC FLAGS_REG))]
9702   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9703 {
9704   switch (get_attr_type (insn))
9705     {
9706     case TYPE_LEA:
9707       return "#";
9708
9709     case TYPE_ALU:
9710       gcc_assert (operands[2] == const1_rtx);
9711       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9712       return "add{<imodesuffix>}\t%0, %0";
9713
9714     default:
9715       if (operands[2] == const1_rtx
9716           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9717         return "sal{<imodesuffix>}\t%0";
9718       else
9719         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9720     }
9721 }
9722   [(set (attr "type")
9723      (cond [(eq_attr "alternative" "1")
9724               (const_string "lea")
9725             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9726                           (const_int 0))
9727                       (match_operand 0 "register_operand" ""))
9728                  (match_operand 2 "const1_operand" ""))
9729               (const_string "alu")
9730            ]
9731            (const_string "ishift")))
9732    (set (attr "length_immediate")
9733      (if_then_else
9734        (ior (eq_attr "type" "alu")
9735             (and (eq_attr "type" "ishift")
9736                  (and (match_operand 2 "const1_operand" "")
9737                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9738                           (const_int 0)))))
9739        (const_string "0")
9740        (const_string "*")))
9741    (set_attr "mode" "<MODE>")])
9742
9743 (define_insn "*ashlsi3_1_zext"
9744   [(set (match_operand:DI 0 "register_operand" "=r,r")
9745         (zero_extend:DI
9746           (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
9747                      (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
9748    (clobber (reg:CC FLAGS_REG))]
9749   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9750 {
9751   switch (get_attr_type (insn))
9752     {
9753     case TYPE_LEA:
9754       return "#";
9755
9756     case TYPE_ALU:
9757       gcc_assert (operands[2] == const1_rtx);
9758       return "add{l}\t%k0, %k0";
9759
9760     default:
9761       if (operands[2] == const1_rtx
9762           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9763         return "sal{l}\t%k0";
9764       else
9765         return "sal{l}\t{%2, %k0|%k0, %2}";
9766     }
9767 }
9768   [(set (attr "type")
9769      (cond [(eq_attr "alternative" "1")
9770               (const_string "lea")
9771             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9772                      (const_int 0))
9773                  (match_operand 2 "const1_operand" ""))
9774               (const_string "alu")
9775            ]
9776            (const_string "ishift")))
9777    (set (attr "length_immediate")
9778      (if_then_else
9779        (ior (eq_attr "type" "alu")
9780             (and (eq_attr "type" "ishift")
9781                  (and (match_operand 2 "const1_operand" "")
9782                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9783                           (const_int 0)))))
9784        (const_string "0")
9785        (const_string "*")))
9786    (set_attr "mode" "SI")])
9787
9788 (define_insn "*ashlhi3_1"
9789   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9790         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
9791                    (match_operand:QI 2 "nonmemory_operand" "cI")))
9792    (clobber (reg:CC FLAGS_REG))]
9793   "TARGET_PARTIAL_REG_STALL
9794    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9795 {
9796   switch (get_attr_type (insn))
9797     {
9798     case TYPE_ALU:
9799       gcc_assert (operands[2] == const1_rtx);
9800       return "add{w}\t%0, %0";
9801
9802     default:
9803       if (operands[2] == const1_rtx
9804           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9805         return "sal{w}\t%0";
9806       else
9807         return "sal{w}\t{%2, %0|%0, %2}";
9808     }
9809 }
9810   [(set (attr "type")
9811      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9812                           (const_int 0))
9813                       (match_operand 0 "register_operand" ""))
9814                  (match_operand 2 "const1_operand" ""))
9815               (const_string "alu")
9816            ]
9817            (const_string "ishift")))
9818    (set (attr "length_immediate")
9819      (if_then_else
9820        (ior (eq_attr "type" "alu")
9821             (and (eq_attr "type" "ishift")
9822                  (and (match_operand 2 "const1_operand" "")
9823                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9824                           (const_int 0)))))
9825        (const_string "0")
9826        (const_string "*")))
9827    (set_attr "mode" "HI")])
9828
9829 (define_insn "*ashlhi3_1_lea"
9830   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
9831         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9832                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9833    (clobber (reg:CC FLAGS_REG))]
9834   "!TARGET_PARTIAL_REG_STALL
9835    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9836 {
9837   switch (get_attr_type (insn))
9838     {
9839     case TYPE_LEA:
9840       return "#";
9841
9842     case TYPE_ALU:
9843       gcc_assert (operands[2] == const1_rtx);
9844       return "add{w}\t%0, %0";
9845
9846     default:
9847       if (operands[2] == const1_rtx
9848           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9849         return "sal{w}\t%0";
9850       else
9851         return "sal{w}\t{%2, %0|%0, %2}";
9852     }
9853 }
9854   [(set (attr "type")
9855      (cond [(eq_attr "alternative" "1")
9856               (const_string "lea")
9857             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9858                           (const_int 0))
9859                       (match_operand 0 "register_operand" ""))
9860                  (match_operand 2 "const1_operand" ""))
9861               (const_string "alu")
9862            ]
9863            (const_string "ishift")))
9864    (set (attr "length_immediate")
9865      (if_then_else
9866        (ior (eq_attr "type" "alu")
9867             (and (eq_attr "type" "ishift")
9868                  (and (match_operand 2 "const1_operand" "")
9869                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9870                           (const_int 0)))))
9871        (const_string "0")
9872        (const_string "*")))
9873    (set_attr "mode" "HI,SI")])
9874
9875 (define_insn "*ashlqi3_1"
9876   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9877         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
9878                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
9879    (clobber (reg:CC FLAGS_REG))]
9880   "TARGET_PARTIAL_REG_STALL
9881    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9882 {
9883   switch (get_attr_type (insn))
9884     {
9885     case TYPE_ALU:
9886       gcc_assert (operands[2] == const1_rtx);
9887       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9888         return "add{l}\t%k0, %k0";
9889       else
9890         return "add{b}\t%0, %0";
9891
9892     default:
9893       if (operands[2] == const1_rtx
9894           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9895         {
9896           if (get_attr_mode (insn) == MODE_SI)
9897             return "sal{l}\t%k0";
9898           else
9899             return "sal{b}\t%0";
9900         }
9901       else
9902         {
9903           if (get_attr_mode (insn) == MODE_SI)
9904             return "sal{l}\t{%2, %k0|%k0, %2}";
9905           else
9906             return "sal{b}\t{%2, %0|%0, %2}";
9907         }
9908     }
9909 }
9910   [(set (attr "type")
9911      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9912                           (const_int 0))
9913                       (match_operand 0 "register_operand" ""))
9914                  (match_operand 2 "const1_operand" ""))
9915               (const_string "alu")
9916            ]
9917            (const_string "ishift")))
9918    (set (attr "length_immediate")
9919      (if_then_else
9920        (ior (eq_attr "type" "alu")
9921             (and (eq_attr "type" "ishift")
9922                  (and (match_operand 2 "const1_operand" "")
9923                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9924                           (const_int 0)))))
9925        (const_string "0")
9926        (const_string "*")))
9927    (set_attr "mode" "QI,SI")])
9928
9929 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9930 (define_insn "*ashlqi3_1_lea"
9931   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
9932         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9933                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9934    (clobber (reg:CC FLAGS_REG))]
9935   "!TARGET_PARTIAL_REG_STALL
9936    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9937 {
9938   switch (get_attr_type (insn))
9939     {
9940     case TYPE_LEA:
9941       return "#";
9942
9943     case TYPE_ALU:
9944       gcc_assert (operands[2] == const1_rtx);
9945       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9946         return "add{l}\t%k0, %k0";
9947       else
9948         return "add{b}\t%0, %0";
9949
9950     default:
9951       if (operands[2] == const1_rtx
9952           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9953         {
9954           if (get_attr_mode (insn) == MODE_SI)
9955             return "sal{l}\t%k0";
9956           else
9957             return "sal{b}\t%0";
9958         }
9959       else
9960         {
9961           if (get_attr_mode (insn) == MODE_SI)
9962             return "sal{l}\t{%2, %k0|%k0, %2}";
9963           else
9964             return "sal{b}\t{%2, %0|%0, %2}";
9965         }
9966     }
9967 }
9968   [(set (attr "type")
9969      (cond [(eq_attr "alternative" "2")
9970               (const_string "lea")
9971             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9972                           (const_int 0))
9973                       (match_operand 0 "register_operand" ""))
9974                  (match_operand 2 "const1_operand" ""))
9975               (const_string "alu")
9976            ]
9977            (const_string "ishift")))
9978    (set (attr "length_immediate")
9979      (if_then_else
9980        (ior (eq_attr "type" "alu")
9981             (and (eq_attr "type" "ishift")
9982                  (and (match_operand 2 "const1_operand" "")
9983                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9984                           (const_int 0)))))
9985        (const_string "0")
9986        (const_string "*")))
9987    (set_attr "mode" "QI,SI,SI")])
9988
9989 ;; Convert lea to the lea pattern to avoid flags dependency.
9990 (define_split
9991   [(set (match_operand:DI 0 "register_operand" "")
9992         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
9993                    (match_operand:QI 2 "const_int_operand" "")))
9994    (clobber (reg:CC FLAGS_REG))]
9995   "TARGET_64BIT && reload_completed
9996    && true_regnum (operands[0]) != true_regnum (operands[1])"
9997   [(set (match_dup 0)
9998         (mult:DI (match_dup 1)
9999                  (match_dup 2)))]
10000   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10001
10002 ;; Convert lea to the lea pattern to avoid flags dependency.
10003 (define_split
10004   [(set (match_operand 0 "register_operand" "")
10005         (ashift (match_operand 1 "index_register_operand" "")
10006                 (match_operand:QI 2 "const_int_operand" "")))
10007    (clobber (reg:CC FLAGS_REG))]
10008   "reload_completed
10009    && true_regnum (operands[0]) != true_regnum (operands[1])
10010    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10011   [(const_int 0)]
10012 {
10013   rtx pat;
10014   enum machine_mode mode = GET_MODE (operands[0]);
10015
10016   if (GET_MODE_SIZE (mode) < 4)
10017     operands[0] = gen_lowpart (SImode, operands[0]);
10018   if (mode != Pmode)
10019     operands[1] = gen_lowpart (Pmode, operands[1]);
10020   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10021
10022   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10023   if (Pmode != SImode)
10024     pat = gen_rtx_SUBREG (SImode, pat, 0);
10025   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10026   DONE;
10027 })
10028
10029 ;; Rare case of shifting RSP is handled by generating move and shift
10030 (define_split
10031   [(set (match_operand 0 "register_operand" "")
10032         (ashift (match_operand 1 "register_operand" "")
10033                 (match_operand:QI 2 "const_int_operand" "")))
10034    (clobber (reg:CC FLAGS_REG))]
10035   "reload_completed
10036    && true_regnum (operands[0]) != true_regnum (operands[1])"
10037   [(const_int 0)]
10038 {
10039   rtx pat, clob;
10040   emit_move_insn (operands[0], operands[1]);
10041   pat = gen_rtx_SET (VOIDmode, operands[0],
10042                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
10043                                      operands[0], operands[2]));
10044   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10045   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10046   DONE;
10047 })
10048
10049 ;; Convert lea to the lea pattern to avoid flags dependency.
10050 (define_split
10051   [(set (match_operand:DI 0 "register_operand" "")
10052         (zero_extend:DI
10053           (ashift:SI (match_operand:SI 1 "register_operand" "")
10054                      (match_operand:QI 2 "const_int_operand" ""))))
10055    (clobber (reg:CC FLAGS_REG))]
10056   "TARGET_64BIT && reload_completed
10057    && true_regnum (operands[0]) != true_regnum (operands[1])"
10058   [(set (match_dup 0)
10059         (zero_extend:DI (subreg:SI (mult:SI (match_dup 1) (match_dup 2)) 0)))]
10060 {
10061   operands[1] = gen_lowpart (Pmode, operands[1]);
10062   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10063 })
10064
10065 ;; This pattern can't accept a variable shift count, since shifts by
10066 ;; zero don't affect the flags.  We assume that shifts by constant
10067 ;; zero are optimized away.
10068 (define_insn "*ashl<mode>3_cmp"
10069   [(set (reg FLAGS_REG)
10070         (compare
10071           (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10072                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10073           (const_int 0)))
10074    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10075         (ashift:SWI (match_dup 1) (match_dup 2)))]
10076   "(optimize_function_for_size_p (cfun)
10077     || !TARGET_PARTIAL_FLAG_REG_STALL
10078     || (operands[2] == const1_rtx
10079         && (TARGET_SHIFT1
10080             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
10081    && ix86_match_ccmode (insn, CCGOCmode)
10082    && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
10083 {
10084   switch (get_attr_type (insn))
10085     {
10086     case TYPE_ALU:
10087       gcc_assert (operands[2] == const1_rtx);
10088       return "add{<imodesuffix>}\t%0, %0";
10089
10090     default:
10091       if (operands[2] == const1_rtx
10092           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10093         return "sal{<imodesuffix>}\t%0";
10094       else
10095         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10096     }
10097 }
10098   [(set (attr "type")
10099      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10100                           (const_int 0))
10101                       (match_operand 0 "register_operand" ""))
10102                  (match_operand 2 "const1_operand" ""))
10103               (const_string "alu")
10104            ]
10105            (const_string "ishift")))
10106    (set (attr "length_immediate")
10107      (if_then_else
10108        (ior (eq_attr "type" "alu")
10109             (and (eq_attr "type" "ishift")
10110                  (and (match_operand 2 "const1_operand" "")
10111                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10112                           (const_int 0)))))
10113        (const_string "0")
10114        (const_string "*")))
10115    (set_attr "mode" "<MODE>")])
10116
10117 (define_insn "*ashlsi3_cmp_zext"
10118   [(set (reg FLAGS_REG)
10119         (compare
10120           (ashift:SI (match_operand:SI 1 "register_operand" "0")
10121                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10122           (const_int 0)))
10123    (set (match_operand:DI 0 "register_operand" "=r")
10124         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10125   "TARGET_64BIT
10126    && (optimize_function_for_size_p (cfun)
10127        || !TARGET_PARTIAL_FLAG_REG_STALL
10128        || (operands[2] == const1_rtx
10129            && (TARGET_SHIFT1
10130                || TARGET_DOUBLE_WITH_ADD)))
10131    && ix86_match_ccmode (insn, CCGOCmode)
10132    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10133 {
10134   switch (get_attr_type (insn))
10135     {
10136     case TYPE_ALU:
10137       gcc_assert (operands[2] == const1_rtx);
10138       return "add{l}\t%k0, %k0";
10139
10140     default:
10141       if (operands[2] == const1_rtx
10142           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10143         return "sal{l}\t%k0";
10144       else
10145         return "sal{l}\t{%2, %k0|%k0, %2}";
10146     }
10147 }
10148   [(set (attr "type")
10149      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10150                      (const_int 0))
10151                  (match_operand 2 "const1_operand" ""))
10152               (const_string "alu")
10153            ]
10154            (const_string "ishift")))
10155    (set (attr "length_immediate")
10156      (if_then_else
10157        (ior (eq_attr "type" "alu")
10158             (and (eq_attr "type" "ishift")
10159                  (and (match_operand 2 "const1_operand" "")
10160                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10161                           (const_int 0)))))
10162        (const_string "0")
10163        (const_string "*")))
10164    (set_attr "mode" "SI")])
10165
10166 (define_insn "*ashl<mode>3_cconly"
10167   [(set (reg FLAGS_REG)
10168         (compare
10169           (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10170                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10171           (const_int 0)))
10172    (clobber (match_scratch:SWI 0 "=<r>"))]
10173   "(optimize_function_for_size_p (cfun)
10174     || !TARGET_PARTIAL_FLAG_REG_STALL
10175     || (operands[2] == const1_rtx
10176         && (TARGET_SHIFT1
10177             || TARGET_DOUBLE_WITH_ADD)))
10178    && ix86_match_ccmode (insn, CCGOCmode)
10179    && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
10180 {
10181   switch (get_attr_type (insn))
10182     {
10183     case TYPE_ALU:
10184       gcc_assert (operands[2] == const1_rtx);
10185       return "add{<imodesuffix>}\t%0, %0";
10186
10187     default:
10188       if (operands[2] == const1_rtx
10189           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10190         return "sal{<imodesuffix>}\t%0";
10191       else
10192         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10193     }
10194 }
10195   [(set (attr "type")
10196      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10197                           (const_int 0))
10198                       (match_operand 0 "register_operand" ""))
10199                  (match_operand 2 "const1_operand" ""))
10200               (const_string "alu")
10201            ]
10202            (const_string "ishift")))
10203    (set (attr "length_immediate")
10204      (if_then_else
10205        (ior (eq_attr "type" "alu")
10206             (and (eq_attr "type" "ishift")
10207                  (and (match_operand 2 "const1_operand" "")
10208                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10209                           (const_int 0)))))
10210        (const_string "0")
10211        (const_string "*")))
10212    (set_attr "mode" "<MODE>")])
10213
10214 ;; See comment above `ashl<mode>3' about how this works.
10215
10216 (define_expand "<shiftrt_insn><mode>3"
10217   [(set (match_operand:SDWIM 0 "<shift_operand>" "")
10218         (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
10219                            (match_operand:QI 2 "nonmemory_operand" "")))]
10220   ""
10221   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10222
10223 (define_insn_and_split "*<shiftrt_insn><mode>3_doubleword"
10224   [(set (match_operand:DWI 0 "register_operand" "=r")
10225         (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
10226                          (match_operand:QI 2 "nonmemory_operand" "<S>c")))
10227    (clobber (reg:CC FLAGS_REG))]
10228   ""
10229   "#"
10230   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
10231   [(const_int 0)]
10232   "ix86_split_<shiftrt_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
10233   [(set_attr "type" "multi")])
10234
10235 ;; By default we don't ask for a scratch register, because when DWImode
10236 ;; values are manipulated, registers are already at a premium.  But if
10237 ;; we have one handy, we won't turn it away.
10238
10239 (define_peephole2
10240   [(match_scratch:DWIH 3 "r")
10241    (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
10242                    (any_shiftrt:<DWI>
10243                      (match_operand:<DWI> 1 "register_operand" "")
10244                      (match_operand:QI 2 "nonmemory_operand" "")))
10245               (clobber (reg:CC FLAGS_REG))])
10246    (match_dup 3)]
10247   "TARGET_CMOVE"
10248   [(const_int 0)]
10249   "ix86_split_<shiftrt_insn> (operands, operands[3], <DWI>mode); DONE;")
10250
10251 (define_insn "x86_64_shrd"
10252   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
10253         (ior:DI (ashiftrt:DI (match_dup 0)
10254                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
10255                 (ashift:DI (match_operand:DI 1 "register_operand" "r")
10256                   (minus:QI (const_int 64) (match_dup 2)))))
10257    (clobber (reg:CC FLAGS_REG))]
10258   "TARGET_64BIT"
10259   "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
10260   [(set_attr "type" "ishift")
10261    (set_attr "prefix_0f" "1")
10262    (set_attr "mode" "DI")
10263    (set_attr "athlon_decode" "vector")
10264    (set_attr "amdfam10_decode" "vector")])
10265
10266 (define_insn "x86_shrd"
10267   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
10268         (ior:SI (ashiftrt:SI (match_dup 0)
10269                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
10270                 (ashift:SI (match_operand:SI 1 "register_operand" "r")
10271                   (minus:QI (const_int 32) (match_dup 2)))))
10272    (clobber (reg:CC FLAGS_REG))]
10273   ""
10274   "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
10275   [(set_attr "type" "ishift")
10276    (set_attr "prefix_0f" "1")
10277    (set_attr "pent_pair" "np")
10278    (set_attr "mode" "SI")])
10279
10280 (define_insn "ashrdi3_cvt"
10281   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
10282         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
10283                      (match_operand:QI 2 "const_int_operand" "")))
10284    (clobber (reg:CC FLAGS_REG))]
10285   "TARGET_64BIT && INTVAL (operands[2]) == 63
10286    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10287    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10288   "@
10289    {cqto|cqo}
10290    sar{q}\t{%2, %0|%0, %2}"
10291   [(set_attr "type" "imovx,ishift")
10292    (set_attr "prefix_0f" "0,*")
10293    (set_attr "length_immediate" "0,*")
10294    (set_attr "modrm" "0,1")
10295    (set_attr "mode" "DI")])
10296
10297 (define_insn "ashrsi3_cvt"
10298   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
10299         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
10300                      (match_operand:QI 2 "const_int_operand" "")))
10301    (clobber (reg:CC FLAGS_REG))]
10302   "INTVAL (operands[2]) == 31
10303    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10304    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10305   "@
10306    {cltd|cdq}
10307    sar{l}\t{%2, %0|%0, %2}"
10308   [(set_attr "type" "imovx,ishift")
10309    (set_attr "prefix_0f" "0,*")
10310    (set_attr "length_immediate" "0,*")
10311    (set_attr "modrm" "0,1")
10312    (set_attr "mode" "SI")])
10313
10314 (define_insn "*ashrsi3_cvt_zext"
10315   [(set (match_operand:DI 0 "register_operand" "=*d,r")
10316         (zero_extend:DI
10317           (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
10318                        (match_operand:QI 2 "const_int_operand" ""))))
10319    (clobber (reg:CC FLAGS_REG))]
10320   "TARGET_64BIT && INTVAL (operands[2]) == 31
10321    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10322    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10323   "@
10324    {cltd|cdq}
10325    sar{l}\t{%2, %k0|%k0, %2}"
10326   [(set_attr "type" "imovx,ishift")
10327    (set_attr "prefix_0f" "0,*")
10328    (set_attr "length_immediate" "0,*")
10329    (set_attr "modrm" "0,1")
10330    (set_attr "mode" "SI")])
10331
10332 (define_expand "x86_shift<mode>_adj_3"
10333   [(use (match_operand:SWI48 0 "register_operand" ""))
10334    (use (match_operand:SWI48 1 "register_operand" ""))
10335    (use (match_operand:QI 2 "register_operand" ""))]
10336   ""
10337 {
10338   rtx label = gen_label_rtx ();
10339   rtx tmp;
10340
10341   emit_insn (gen_testqi_ccz_1 (operands[2],
10342                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
10343
10344   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10345   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10346   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10347                               gen_rtx_LABEL_REF (VOIDmode, label),
10348                               pc_rtx);
10349   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10350   JUMP_LABEL (tmp) = label;
10351
10352   emit_move_insn (operands[0], operands[1]);
10353   emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
10354                                   GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
10355   emit_label (label);
10356   LABEL_NUSES (label) = 1;
10357
10358   DONE;
10359 })
10360
10361 (define_insn "*<shiftrt_insn><mode>3_1"
10362   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10363         (any_shiftrt:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10364                          (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10365    (clobber (reg:CC FLAGS_REG))]
10366   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10367 {
10368   if (operands[2] == const1_rtx
10369       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10370     return "<shiftrt>{<imodesuffix>}\t%0";
10371   else
10372     return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
10373 }
10374   [(set_attr "type" "ishift")
10375    (set (attr "length_immediate")
10376      (if_then_else
10377        (and (match_operand 2 "const1_operand" "")
10378             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10379                 (const_int 0)))
10380        (const_string "0")
10381        (const_string "*")))
10382    (set_attr "mode" "<MODE>")])
10383
10384 (define_insn "*<shiftrt_insn>si3_1_zext"
10385   [(set (match_operand:DI 0 "register_operand" "=r")
10386         (zero_extend:DI
10387           (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10388                           (match_operand:QI 2 "nonmemory_operand" "cI"))))
10389    (clobber (reg:CC FLAGS_REG))]
10390   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10391 {
10392   if (operands[2] == const1_rtx
10393       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10394     return "<shiftrt>{l}\t%k0";
10395   else
10396     return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
10397 }
10398   [(set_attr "type" "ishift")
10399    (set (attr "length_immediate")
10400      (if_then_else
10401        (and (match_operand 2 "const1_operand" "")
10402             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10403                 (const_int 0)))
10404        (const_string "0")
10405        (const_string "*")))
10406    (set_attr "mode" "SI")])
10407
10408 (define_insn "*<shiftrt_insn>qi3_1_slp"
10409   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10410         (any_shiftrt:QI (match_dup 0)
10411                         (match_operand:QI 1 "nonmemory_operand" "cI")))
10412    (clobber (reg:CC FLAGS_REG))]
10413   "(optimize_function_for_size_p (cfun)
10414     || !TARGET_PARTIAL_REG_STALL
10415     || (operands[1] == const1_rtx
10416         && TARGET_SHIFT1))"
10417 {
10418   if (operands[1] == const1_rtx
10419       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10420     return "<shiftrt>{b}\t%0";
10421   else
10422     return "<shiftrt>{b}\t{%1, %0|%0, %1}";
10423 }
10424   [(set_attr "type" "ishift1")
10425    (set (attr "length_immediate")
10426      (if_then_else
10427        (and (match_operand 1 "const1_operand" "")
10428             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10429                 (const_int 0)))
10430        (const_string "0")
10431        (const_string "*")))
10432    (set_attr "mode" "QI")])
10433
10434 ;; This pattern can't accept a variable shift count, since shifts by
10435 ;; zero don't affect the flags.  We assume that shifts by constant
10436 ;; zero are optimized away.
10437 (define_insn "*<shiftrt_insn><mode>3_cmp"
10438   [(set (reg FLAGS_REG)
10439         (compare
10440           (any_shiftrt:SWI
10441             (match_operand:SWI 1 "nonimmediate_operand" "0")
10442             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10443           (const_int 0)))
10444    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10445         (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
10446   "(optimize_function_for_size_p (cfun)
10447     || !TARGET_PARTIAL_FLAG_REG_STALL
10448     || (operands[2] == const1_rtx
10449         && TARGET_SHIFT1))
10450    && ix86_match_ccmode (insn, CCGOCmode)
10451    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10452 {
10453   if (operands[2] == const1_rtx
10454       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10455     return "<shiftrt>{<imodesuffix>}\t%0";
10456   else
10457     return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
10458 }
10459   [(set_attr "type" "ishift")
10460    (set (attr "length_immediate")
10461      (if_then_else
10462        (and (match_operand 2 "const1_operand" "")
10463             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10464                 (const_int 0)))
10465        (const_string "0")
10466        (const_string "*")))
10467    (set_attr "mode" "<MODE>")])
10468
10469 (define_insn "*<shiftrt_insn>si3_cmp_zext"
10470   [(set (reg FLAGS_REG)
10471         (compare
10472           (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10473                           (match_operand:QI 2 "const_1_to_31_operand" "I"))
10474           (const_int 0)))
10475    (set (match_operand:DI 0 "register_operand" "=r")
10476         (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10477   "TARGET_64BIT
10478    && (optimize_function_for_size_p (cfun)
10479        || !TARGET_PARTIAL_FLAG_REG_STALL
10480        || (operands[2] == const1_rtx
10481            && TARGET_SHIFT1))
10482    && ix86_match_ccmode (insn, CCGOCmode)
10483    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10484 {
10485   if (operands[2] == const1_rtx
10486       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10487     return "<shiftrt>{l}\t%k0";
10488   else
10489     return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
10490 }
10491   [(set_attr "type" "ishift")
10492    (set (attr "length_immediate")
10493      (if_then_else
10494        (and (match_operand 2 "const1_operand" "")
10495             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10496                 (const_int 0)))
10497        (const_string "0")
10498        (const_string "*")))
10499    (set_attr "mode" "SI")])
10500
10501 (define_insn "*<shiftrt_insn><mode>3_cconly"
10502   [(set (reg FLAGS_REG)
10503         (compare
10504           (any_shiftrt:SWI
10505             (match_operand:SWI 1 "nonimmediate_operand" "0")
10506             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10507           (const_int 0)))
10508    (clobber (match_scratch:SWI 0 "=<r>"))]
10509   "(optimize_function_for_size_p (cfun)
10510     || !TARGET_PARTIAL_FLAG_REG_STALL
10511     || (operands[2] == const1_rtx
10512         && TARGET_SHIFT1))
10513    && ix86_match_ccmode (insn, CCGOCmode)
10514    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10515 {
10516   if (operands[2] == const1_rtx
10517       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10518     return "<shiftrt>{<imodesuffix>}\t%0";
10519   else
10520     return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
10521 }
10522   [(set_attr "type" "ishift")
10523    (set (attr "length_immediate")
10524      (if_then_else
10525        (and (match_operand 2 "const1_operand" "")
10526             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10527                 (const_int 0)))
10528        (const_string "0")
10529        (const_string "*")))
10530    (set_attr "mode" "<MODE>")])
10531 \f
10532 ;; Rotate instructions
10533
10534 (define_expand "<rotate_insn>ti3"
10535   [(set (match_operand:TI 0 "register_operand" "")
10536         (any_rotate:TI (match_operand:TI 1 "register_operand" "")
10537                        (match_operand:QI 2 "nonmemory_operand" "")))]
10538   "TARGET_64BIT"
10539 {
10540   if (const_1_to_63_operand (operands[2], VOIDmode))
10541     emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10542                 (operands[0], operands[1], operands[2]));
10543   else
10544     FAIL;
10545
10546   DONE;
10547 })
10548
10549 (define_expand "<rotate_insn>di3"
10550   [(set (match_operand:DI 0 "shiftdi_operand" "")
10551         (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
10552                        (match_operand:QI 2 "nonmemory_operand" "")))]
10553  ""
10554 {
10555   if (TARGET_64BIT)
10556     ix86_expand_binary_operator (<CODE>, DImode, operands);
10557   else if (const_1_to_31_operand (operands[2], VOIDmode))
10558     emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10559                 (operands[0], operands[1], operands[2]));
10560   else
10561     FAIL;
10562
10563   DONE;
10564 })
10565
10566 (define_expand "<rotate_insn><mode>3"
10567   [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
10568         (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
10569                             (match_operand:QI 2 "nonmemory_operand" "")))]
10570   ""
10571   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10572
10573 ;; Implement rotation using two double-precision
10574 ;; shift instructions and a scratch register.
10575
10576 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10577  [(set (match_operand:<DWI> 0 "register_operand" "=r")
10578        (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10579                      (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10580   (clobber (reg:CC FLAGS_REG))
10581   (clobber (match_scratch:DWIH 3 "=&r"))]
10582  ""
10583  "#"
10584  "reload_completed"
10585  [(set (match_dup 3) (match_dup 4))
10586   (parallel
10587    [(set (match_dup 4)
10588          (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10589                    (lshiftrt:DWIH (match_dup 5)
10590                                   (minus:QI (match_dup 6) (match_dup 2)))))
10591     (clobber (reg:CC FLAGS_REG))])
10592   (parallel
10593    [(set (match_dup 5)
10594          (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10595                    (lshiftrt:DWIH (match_dup 3)
10596                                   (minus:QI (match_dup 6) (match_dup 2)))))
10597     (clobber (reg:CC FLAGS_REG))])]
10598 {
10599   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10600
10601   split_<dwi> (&operands[0], 1, &operands[4], &operands[5]);
10602 })
10603
10604 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10605  [(set (match_operand:<DWI> 0 "register_operand" "=r")
10606        (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10607                        (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10608   (clobber (reg:CC FLAGS_REG))
10609   (clobber (match_scratch:DWIH 3 "=&r"))]
10610  ""
10611  "#"
10612  "reload_completed"
10613  [(set (match_dup 3) (match_dup 4))
10614   (parallel
10615    [(set (match_dup 4)
10616          (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10617                    (ashift:DWIH (match_dup 5)
10618                                 (minus:QI (match_dup 6) (match_dup 2)))))
10619     (clobber (reg:CC FLAGS_REG))])
10620   (parallel
10621    [(set (match_dup 5)
10622          (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10623                    (ashift:DWIH (match_dup 3)
10624                                 (minus:QI (match_dup 6) (match_dup 2)))))
10625     (clobber (reg:CC FLAGS_REG))])]
10626 {
10627   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10628
10629   split_<dwi> (&operands[0], 1, &operands[4], &operands[5]);
10630 })
10631
10632 (define_insn "*<rotate_insn><mode>3_1"
10633   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10634         (any_rotate:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10635                         (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10636    (clobber (reg:CC FLAGS_REG))]
10637   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10638 {
10639   if (operands[2] == const1_rtx
10640       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10641     return "<rotate>{<imodesuffix>}\t%0";
10642   else
10643     return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10644 }
10645   [(set_attr "type" "rotate")
10646    (set (attr "length_immediate")
10647      (if_then_else
10648        (and (match_operand 2 "const1_operand" "")
10649             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10650                 (const_int 0)))
10651        (const_string "0")
10652        (const_string "*")))
10653    (set_attr "mode" "<MODE>")])
10654
10655 (define_insn "*<rotate_insn>si3_1_zext"
10656   [(set (match_operand:DI 0 "register_operand" "=r")
10657         (zero_extend:DI
10658           (any_rotate:SI (match_operand:SI 1 "register_operand" "0")
10659                          (match_operand:QI 2 "nonmemory_operand" "cI"))))
10660    (clobber (reg:CC FLAGS_REG))]
10661   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10662 {
10663     if (operands[2] == const1_rtx
10664         && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10665     return "<rotate>{l}\t%k0";
10666   else
10667     return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10668 }
10669   [(set_attr "type" "rotate")
10670    (set (attr "length_immediate")
10671      (if_then_else
10672        (and (match_operand 2 "const1_operand" "")
10673             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10674                 (const_int 0)))
10675        (const_string "0")
10676        (const_string "*")))
10677    (set_attr "mode" "SI")])
10678
10679 (define_insn "*<rotate_insn>qi3_1_slp"
10680   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10681         (any_rotate:QI (match_dup 0)
10682                        (match_operand:QI 1 "nonmemory_operand" "cI")))
10683    (clobber (reg:CC FLAGS_REG))]
10684   "(optimize_function_for_size_p (cfun)
10685     || !TARGET_PARTIAL_REG_STALL
10686     || (operands[1] == const1_rtx
10687         && TARGET_SHIFT1))"
10688 {
10689   if (operands[1] == const1_rtx
10690       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10691     return "<rotate>{b}\t%0";
10692   else
10693     return "<rotate>{b}\t{%1, %0|%0, %1}";
10694 }
10695   [(set_attr "type" "rotate1")
10696    (set (attr "length_immediate")
10697      (if_then_else
10698        (and (match_operand 1 "const1_operand" "")
10699             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10700                 (const_int 0)))
10701        (const_string "0")
10702        (const_string "*")))
10703    (set_attr "mode" "QI")])
10704
10705 (define_split
10706  [(set (match_operand:HI 0 "register_operand" "")
10707        (any_rotate:HI (match_dup 0) (const_int 8)))
10708   (clobber (reg:CC FLAGS_REG))]
10709  "reload_completed
10710   && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10711  [(parallel [(set (strict_low_part (match_dup 0))
10712                   (bswap:HI (match_dup 0)))
10713              (clobber (reg:CC FLAGS_REG))])]
10714  "")
10715 \f
10716 ;; Bit set / bit test instructions
10717
10718 (define_expand "extv"
10719   [(set (match_operand:SI 0 "register_operand" "")
10720         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10721                          (match_operand:SI 2 "const8_operand" "")
10722                          (match_operand:SI 3 "const8_operand" "")))]
10723   ""
10724 {
10725   /* Handle extractions from %ah et al.  */
10726   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10727     FAIL;
10728
10729   /* From mips.md: extract_bit_field doesn't verify that our source
10730      matches the predicate, so check it again here.  */
10731   if (! ext_register_operand (operands[1], VOIDmode))
10732     FAIL;
10733 })
10734
10735 (define_expand "extzv"
10736   [(set (match_operand:SI 0 "register_operand" "")
10737         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10738                          (match_operand:SI 2 "const8_operand" "")
10739                          (match_operand:SI 3 "const8_operand" "")))]
10740   ""
10741 {
10742   /* Handle extractions from %ah et al.  */
10743   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10744     FAIL;
10745
10746   /* From mips.md: extract_bit_field doesn't verify that our source
10747      matches the predicate, so check it again here.  */
10748   if (! ext_register_operand (operands[1], VOIDmode))
10749     FAIL;
10750 })
10751
10752 (define_expand "insv"
10753   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
10754                       (match_operand 1 "const8_operand" "")
10755                       (match_operand 2 "const8_operand" ""))
10756         (match_operand 3 "register_operand" ""))]
10757   ""
10758 {
10759   /* Handle insertions to %ah et al.  */
10760   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10761     FAIL;
10762
10763   /* From mips.md: insert_bit_field doesn't verify that our source
10764      matches the predicate, so check it again here.  */
10765   if (! ext_register_operand (operands[0], VOIDmode))
10766     FAIL;
10767
10768   if (TARGET_64BIT)
10769     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
10770   else
10771     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
10772
10773   DONE;
10774 })
10775
10776 ;; %%% bts, btr, btc, bt.
10777 ;; In general these instructions are *slow* when applied to memory,
10778 ;; since they enforce atomic operation.  When applied to registers,
10779 ;; it depends on the cpu implementation.  They're never faster than
10780 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10781 ;; no point.  But in 64-bit, we can't hold the relevant immediates
10782 ;; within the instruction itself, so operating on bits in the high
10783 ;; 32-bits of a register becomes easier.
10784 ;;
10785 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
10786 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10787 ;; negdf respectively, so they can never be disabled entirely.
10788
10789 (define_insn "*btsq"
10790   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10791                          (const_int 1)
10792                          (match_operand:DI 1 "const_0_to_63_operand" ""))
10793         (const_int 1))
10794    (clobber (reg:CC FLAGS_REG))]
10795   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10796   "bts{q}\t{%1, %0|%0, %1}"
10797   [(set_attr "type" "alu1")
10798    (set_attr "prefix_0f" "1")
10799    (set_attr "mode" "DI")])
10800
10801 (define_insn "*btrq"
10802   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10803                          (const_int 1)
10804                          (match_operand:DI 1 "const_0_to_63_operand" ""))
10805         (const_int 0))
10806    (clobber (reg:CC FLAGS_REG))]
10807   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10808   "btr{q}\t{%1, %0|%0, %1}"
10809   [(set_attr "type" "alu1")
10810    (set_attr "prefix_0f" "1")
10811    (set_attr "mode" "DI")])
10812
10813 (define_insn "*btcq"
10814   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10815                          (const_int 1)
10816                          (match_operand:DI 1 "const_0_to_63_operand" ""))
10817         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10818    (clobber (reg:CC FLAGS_REG))]
10819   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10820   "btc{q}\t{%1, %0|%0, %1}"
10821   [(set_attr "type" "alu1")
10822    (set_attr "prefix_0f" "1")
10823    (set_attr "mode" "DI")])
10824
10825 ;; Allow Nocona to avoid these instructions if a register is available.
10826
10827 (define_peephole2
10828   [(match_scratch:DI 2 "r")
10829    (parallel [(set (zero_extract:DI
10830                      (match_operand:DI 0 "register_operand" "")
10831                      (const_int 1)
10832                      (match_operand:DI 1 "const_0_to_63_operand" ""))
10833                    (const_int 1))
10834               (clobber (reg:CC FLAGS_REG))])]
10835   "TARGET_64BIT && !TARGET_USE_BT"
10836   [(const_int 0)]
10837 {
10838   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10839   rtx op1;
10840
10841   if (HOST_BITS_PER_WIDE_INT >= 64)
10842     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10843   else if (i < HOST_BITS_PER_WIDE_INT)
10844     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10845   else
10846     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10847
10848   op1 = immed_double_const (lo, hi, DImode);
10849   if (i >= 31)
10850     {
10851       emit_move_insn (operands[2], op1);
10852       op1 = operands[2];
10853     }
10854
10855   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10856   DONE;
10857 })
10858
10859 (define_peephole2
10860   [(match_scratch:DI 2 "r")
10861    (parallel [(set (zero_extract:DI
10862                      (match_operand:DI 0 "register_operand" "")
10863                      (const_int 1)
10864                      (match_operand:DI 1 "const_0_to_63_operand" ""))
10865                    (const_int 0))
10866               (clobber (reg:CC FLAGS_REG))])]
10867   "TARGET_64BIT && !TARGET_USE_BT"
10868   [(const_int 0)]
10869 {
10870   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10871   rtx op1;
10872
10873   if (HOST_BITS_PER_WIDE_INT >= 64)
10874     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10875   else if (i < HOST_BITS_PER_WIDE_INT)
10876     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10877   else
10878     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10879
10880   op1 = immed_double_const (~lo, ~hi, DImode);
10881   if (i >= 32)
10882     {
10883       emit_move_insn (operands[2], op1);
10884       op1 = operands[2];
10885     }
10886
10887   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10888   DONE;
10889 })
10890
10891 (define_peephole2
10892   [(match_scratch:DI 2 "r")
10893    (parallel [(set (zero_extract:DI
10894                      (match_operand:DI 0 "register_operand" "")
10895                      (const_int 1)
10896                      (match_operand:DI 1 "const_0_to_63_operand" ""))
10897               (not:DI (zero_extract:DI
10898                         (match_dup 0) (const_int 1) (match_dup 1))))
10899               (clobber (reg:CC FLAGS_REG))])]
10900   "TARGET_64BIT && !TARGET_USE_BT"
10901   [(const_int 0)]
10902 {
10903   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10904   rtx op1;
10905
10906   if (HOST_BITS_PER_WIDE_INT >= 64)
10907     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10908   else if (i < HOST_BITS_PER_WIDE_INT)
10909     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10910   else
10911     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10912
10913   op1 = immed_double_const (lo, hi, DImode);
10914   if (i >= 31)
10915     {
10916       emit_move_insn (operands[2], op1);
10917       op1 = operands[2];
10918     }
10919
10920   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10921   DONE;
10922 })
10923
10924 (define_insn "*btdi_rex64"
10925   [(set (reg:CCC FLAGS_REG)
10926         (compare:CCC
10927           (zero_extract:DI
10928             (match_operand:DI 0 "register_operand" "r")
10929             (const_int 1)
10930             (match_operand:DI 1 "nonmemory_operand" "rN"))
10931           (const_int 0)))]
10932   "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
10933   "bt{q}\t{%1, %0|%0, %1}"
10934   [(set_attr "type" "alu1")
10935    (set_attr "prefix_0f" "1")
10936    (set_attr "mode" "DI")])
10937
10938 (define_insn "*btsi"
10939   [(set (reg:CCC FLAGS_REG)
10940         (compare:CCC
10941           (zero_extract:SI
10942             (match_operand:SI 0 "register_operand" "r")
10943             (const_int 1)
10944             (match_operand:SI 1 "nonmemory_operand" "rN"))
10945           (const_int 0)))]
10946   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10947   "bt{l}\t{%1, %0|%0, %1}"
10948   [(set_attr "type" "alu1")
10949    (set_attr "prefix_0f" "1")
10950    (set_attr "mode" "SI")])
10951 \f
10952 ;; Store-flag instructions.
10953
10954 ;; For all sCOND expanders, also expand the compare or test insn that
10955 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
10956
10957 (define_insn_and_split "*setcc_di_1"
10958   [(set (match_operand:DI 0 "register_operand" "=q")
10959         (match_operator:DI 1 "ix86_comparison_operator"
10960           [(reg FLAGS_REG) (const_int 0)]))]
10961   "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10962   "#"
10963   "&& reload_completed"
10964   [(set (match_dup 2) (match_dup 1))
10965    (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10966 {
10967   PUT_MODE (operands[1], QImode);
10968   operands[2] = gen_lowpart (QImode, operands[0]);
10969 })
10970
10971 (define_insn_and_split "*setcc_si_1_and"
10972   [(set (match_operand:SI 0 "register_operand" "=q")
10973         (match_operator:SI 1 "ix86_comparison_operator"
10974           [(reg FLAGS_REG) (const_int 0)]))
10975    (clobber (reg:CC FLAGS_REG))]
10976   "!TARGET_PARTIAL_REG_STALL
10977    && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10978   "#"
10979   "&& reload_completed"
10980   [(set (match_dup 2) (match_dup 1))
10981    (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10982               (clobber (reg:CC FLAGS_REG))])]
10983 {
10984   PUT_MODE (operands[1], QImode);
10985   operands[2] = gen_lowpart (QImode, operands[0]);
10986 })
10987
10988 (define_insn_and_split "*setcc_si_1_movzbl"
10989   [(set (match_operand:SI 0 "register_operand" "=q")
10990         (match_operator:SI 1 "ix86_comparison_operator"
10991           [(reg FLAGS_REG) (const_int 0)]))]
10992   "!TARGET_PARTIAL_REG_STALL
10993    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10994   "#"
10995   "&& reload_completed"
10996   [(set (match_dup 2) (match_dup 1))
10997    (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10998 {
10999   PUT_MODE (operands[1], QImode);
11000   operands[2] = gen_lowpart (QImode, operands[0]);
11001 })
11002
11003 (define_insn "*setcc_qi"
11004   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11005         (match_operator:QI 1 "ix86_comparison_operator"
11006           [(reg FLAGS_REG) (const_int 0)]))]
11007   ""
11008   "set%C1\t%0"
11009   [(set_attr "type" "setcc")
11010    (set_attr "mode" "QI")])
11011
11012 (define_insn "*setcc_qi_slp"
11013   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11014         (match_operator:QI 1 "ix86_comparison_operator"
11015           [(reg FLAGS_REG) (const_int 0)]))]
11016   ""
11017   "set%C1\t%0"
11018   [(set_attr "type" "setcc")
11019    (set_attr "mode" "QI")])
11020
11021 ;; In general it is not safe to assume too much about CCmode registers,
11022 ;; so simplify-rtx stops when it sees a second one.  Under certain
11023 ;; conditions this is safe on x86, so help combine not create
11024 ;;
11025 ;;      seta    %al
11026 ;;      testb   %al, %al
11027 ;;      sete    %al
11028
11029 (define_split
11030   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11031         (ne:QI (match_operator 1 "ix86_comparison_operator"
11032                  [(reg FLAGS_REG) (const_int 0)])
11033             (const_int 0)))]
11034   ""
11035   [(set (match_dup 0) (match_dup 1))]
11036 {
11037   PUT_MODE (operands[1], QImode);
11038 })
11039
11040 (define_split
11041   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
11042         (ne:QI (match_operator 1 "ix86_comparison_operator"
11043                  [(reg FLAGS_REG) (const_int 0)])
11044             (const_int 0)))]
11045   ""
11046   [(set (match_dup 0) (match_dup 1))]
11047 {
11048   PUT_MODE (operands[1], QImode);
11049 })
11050
11051 (define_split
11052   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11053         (eq:QI (match_operator 1 "ix86_comparison_operator"
11054                  [(reg FLAGS_REG) (const_int 0)])
11055             (const_int 0)))]
11056   ""
11057   [(set (match_dup 0) (match_dup 1))]
11058 {
11059   rtx new_op1 = copy_rtx (operands[1]);
11060   operands[1] = new_op1;
11061   PUT_MODE (new_op1, QImode);
11062   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
11063                                              GET_MODE (XEXP (new_op1, 0))));
11064
11065   /* Make sure that (a) the CCmode we have for the flags is strong
11066      enough for the reversed compare or (b) we have a valid FP compare.  */
11067   if (! ix86_comparison_operator (new_op1, VOIDmode))
11068     FAIL;
11069 })
11070
11071 (define_split
11072   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
11073         (eq:QI (match_operator 1 "ix86_comparison_operator"
11074                  [(reg FLAGS_REG) (const_int 0)])
11075             (const_int 0)))]
11076   ""
11077   [(set (match_dup 0) (match_dup 1))]
11078 {
11079   rtx new_op1 = copy_rtx (operands[1]);
11080   operands[1] = new_op1;
11081   PUT_MODE (new_op1, QImode);
11082   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
11083                                              GET_MODE (XEXP (new_op1, 0))));
11084
11085   /* Make sure that (a) the CCmode we have for the flags is strong
11086      enough for the reversed compare or (b) we have a valid FP compare.  */
11087   if (! ix86_comparison_operator (new_op1, VOIDmode))
11088     FAIL;
11089 })
11090
11091 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
11092 ;; subsequent logical operations are used to imitate conditional moves.
11093 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
11094 ;; it directly.
11095
11096 (define_insn "*avx_setcc<mode>"
11097   [(set (match_operand:MODEF 0 "register_operand" "=x")
11098         (match_operator:MODEF 1 "avx_comparison_float_operator"
11099           [(match_operand:MODEF 2 "register_operand" "x")
11100            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
11101   "TARGET_AVX"
11102   "vcmp%D1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
11103   [(set_attr "type" "ssecmp")
11104    (set_attr "prefix" "vex")
11105    (set_attr "length_immediate" "1")
11106    (set_attr "mode" "<MODE>")])
11107
11108 (define_insn "*sse_setcc<mode>"
11109   [(set (match_operand:MODEF 0 "register_operand" "=x")
11110         (match_operator:MODEF 1 "sse_comparison_operator"
11111           [(match_operand:MODEF 2 "register_operand" "0")
11112            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
11113   "SSE_FLOAT_MODE_P (<MODE>mode)"
11114   "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
11115   [(set_attr "type" "ssecmp")
11116    (set_attr "length_immediate" "1")
11117    (set_attr "mode" "<MODE>")])
11118 \f
11119 ;; Basic conditional jump instructions.
11120 ;; We ignore the overflow flag for signed branch instructions.
11121
11122 (define_insn "*jcc_1"
11123   [(set (pc)
11124         (if_then_else (match_operator 1 "ix86_comparison_operator"
11125                                       [(reg FLAGS_REG) (const_int 0)])
11126                       (label_ref (match_operand 0 "" ""))
11127                       (pc)))]
11128   ""
11129   "%+j%C1\t%l0"
11130   [(set_attr "type" "ibr")
11131    (set_attr "modrm" "0")
11132    (set (attr "length")
11133            (if_then_else (and (ge (minus (match_dup 0) (pc))
11134                                   (const_int -126))
11135                               (lt (minus (match_dup 0) (pc))
11136                                   (const_int 128)))
11137              (const_int 2)
11138              (const_int 6)))])
11139
11140 (define_insn "*jcc_2"
11141   [(set (pc)
11142         (if_then_else (match_operator 1 "ix86_comparison_operator"
11143                                       [(reg FLAGS_REG) (const_int 0)])
11144                       (pc)
11145                       (label_ref (match_operand 0 "" ""))))]
11146   ""
11147   "%+j%c1\t%l0"
11148   [(set_attr "type" "ibr")
11149    (set_attr "modrm" "0")
11150    (set (attr "length")
11151            (if_then_else (and (ge (minus (match_dup 0) (pc))
11152                                   (const_int -126))
11153                               (lt (minus (match_dup 0) (pc))
11154                                   (const_int 128)))
11155              (const_int 2)
11156              (const_int 6)))])
11157
11158 ;; In general it is not safe to assume too much about CCmode registers,
11159 ;; so simplify-rtx stops when it sees a second one.  Under certain
11160 ;; conditions this is safe on x86, so help combine not create
11161 ;;
11162 ;;      seta    %al
11163 ;;      testb   %al, %al
11164 ;;      je      Lfoo
11165
11166 (define_split
11167   [(set (pc)
11168         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
11169                                       [(reg FLAGS_REG) (const_int 0)])
11170                           (const_int 0))
11171                       (label_ref (match_operand 1 "" ""))
11172                       (pc)))]
11173   ""
11174   [(set (pc)
11175         (if_then_else (match_dup 0)
11176                       (label_ref (match_dup 1))
11177                       (pc)))]
11178 {
11179   PUT_MODE (operands[0], VOIDmode);
11180 })
11181
11182 (define_split
11183   [(set (pc)
11184         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
11185                                       [(reg FLAGS_REG) (const_int 0)])
11186                           (const_int 0))
11187                       (label_ref (match_operand 1 "" ""))
11188                       (pc)))]
11189   ""
11190   [(set (pc)
11191         (if_then_else (match_dup 0)
11192                       (label_ref (match_dup 1))
11193                       (pc)))]
11194 {
11195   rtx new_op0 = copy_rtx (operands[0]);
11196   operands[0] = new_op0;
11197   PUT_MODE (new_op0, VOIDmode);
11198   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
11199                                              GET_MODE (XEXP (new_op0, 0))));
11200
11201   /* Make sure that (a) the CCmode we have for the flags is strong
11202      enough for the reversed compare or (b) we have a valid FP compare.  */
11203   if (! ix86_comparison_operator (new_op0, VOIDmode))
11204     FAIL;
11205 })
11206
11207 ;; zero_extend in SImode is correct, since this is what combine pass
11208 ;; generates from shift insn with QImode operand.  Actually, the mode of
11209 ;; operand 2 (bit offset operand) doesn't matter since bt insn takes
11210 ;; appropriate modulo of the bit offset value.
11211
11212 (define_insn_and_split "*jcc_btdi_rex64"
11213   [(set (pc)
11214         (if_then_else (match_operator 0 "bt_comparison_operator"
11215                         [(zero_extract:DI
11216                            (match_operand:DI 1 "register_operand" "r")
11217                            (const_int 1)
11218                            (zero_extend:SI
11219                              (match_operand:QI 2 "register_operand" "r")))
11220                          (const_int 0)])
11221                       (label_ref (match_operand 3 "" ""))
11222                       (pc)))
11223    (clobber (reg:CC FLAGS_REG))]
11224   "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
11225   "#"
11226   "&& 1"
11227   [(set (reg:CCC FLAGS_REG)
11228         (compare:CCC
11229           (zero_extract:DI
11230             (match_dup 1)
11231             (const_int 1)
11232             (match_dup 2))
11233           (const_int 0)))
11234    (set (pc)
11235         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11236                       (label_ref (match_dup 3))
11237                       (pc)))]
11238 {
11239   operands[2] = simplify_gen_subreg (DImode, operands[2], QImode, 0);
11240
11241   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11242 })
11243
11244 ;; avoid useless masking of bit offset operand
11245 (define_insn_and_split "*jcc_btdi_mask_rex64"
11246   [(set (pc)
11247         (if_then_else (match_operator 0 "bt_comparison_operator"
11248                         [(zero_extract:DI
11249                            (match_operand:DI 1 "register_operand" "r")
11250                            (const_int 1)
11251                            (and:SI
11252                              (match_operand:SI 2 "register_operand" "r")
11253                              (match_operand:SI 3 "const_int_operand" "n")))])
11254                       (label_ref (match_operand 4 "" ""))
11255                       (pc)))
11256    (clobber (reg:CC FLAGS_REG))]
11257   "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))
11258    && (INTVAL (operands[3]) & 0x3f) == 0x3f"
11259   "#"
11260   "&& 1"
11261   [(set (reg:CCC FLAGS_REG)
11262         (compare:CCC
11263           (zero_extract:DI
11264             (match_dup 1)
11265             (const_int 1)
11266             (match_dup 2))
11267           (const_int 0)))
11268    (set (pc)
11269         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11270                       (label_ref (match_dup 4))
11271                       (pc)))]
11272 {
11273   operands[2] = simplify_gen_subreg (DImode, operands[2], SImode, 0);
11274
11275   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11276 })
11277
11278 (define_insn_and_split "*jcc_btsi"
11279   [(set (pc)
11280         (if_then_else (match_operator 0 "bt_comparison_operator"
11281                         [(zero_extract:SI
11282                            (match_operand:SI 1 "register_operand" "r")
11283                            (const_int 1)
11284                            (zero_extend:SI
11285                              (match_operand:QI 2 "register_operand" "r")))
11286                          (const_int 0)])
11287                       (label_ref (match_operand 3 "" ""))
11288                       (pc)))
11289    (clobber (reg:CC FLAGS_REG))]
11290   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
11291   "#"
11292   "&& 1"
11293   [(set (reg:CCC FLAGS_REG)
11294         (compare:CCC
11295           (zero_extract:SI
11296             (match_dup 1)
11297             (const_int 1)
11298             (match_dup 2))
11299           (const_int 0)))
11300    (set (pc)
11301         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11302                       (label_ref (match_dup 3))
11303                       (pc)))]
11304 {
11305   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
11306
11307   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11308 })
11309
11310 ;; avoid useless masking of bit offset operand
11311 (define_insn_and_split "*jcc_btsi_mask"
11312   [(set (pc)
11313         (if_then_else (match_operator 0 "bt_comparison_operator"
11314                         [(zero_extract:SI
11315                            (match_operand:SI 1 "register_operand" "r")
11316                            (const_int 1)
11317                            (and:SI
11318                              (match_operand:SI 2 "register_operand" "r")
11319                              (match_operand:SI 3 "const_int_operand" "n")))])
11320                       (label_ref (match_operand 4 "" ""))
11321                       (pc)))
11322    (clobber (reg:CC FLAGS_REG))]
11323   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11324    && (INTVAL (operands[3]) & 0x1f) == 0x1f"
11325   "#"
11326   "&& 1"
11327   [(set (reg:CCC FLAGS_REG)
11328         (compare:CCC
11329           (zero_extract:SI
11330             (match_dup 1)
11331             (const_int 1)
11332             (match_dup 2))
11333           (const_int 0)))
11334    (set (pc)
11335         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11336                       (label_ref (match_dup 4))
11337                       (pc)))]
11338   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
11339
11340 (define_insn_and_split "*jcc_btsi_1"
11341   [(set (pc)
11342         (if_then_else (match_operator 0 "bt_comparison_operator"
11343                         [(and:SI
11344                            (lshiftrt:SI
11345                              (match_operand:SI 1 "register_operand" "r")
11346                              (match_operand:QI 2 "register_operand" "r"))
11347                            (const_int 1))
11348                          (const_int 0)])
11349                       (label_ref (match_operand 3 "" ""))
11350                       (pc)))
11351    (clobber (reg:CC FLAGS_REG))]
11352   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
11353   "#"
11354   "&& 1"
11355   [(set (reg:CCC FLAGS_REG)
11356         (compare:CCC
11357           (zero_extract:SI
11358             (match_dup 1)
11359             (const_int 1)
11360             (match_dup 2))
11361           (const_int 0)))
11362    (set (pc)
11363         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11364                       (label_ref (match_dup 3))
11365                       (pc)))]
11366 {
11367   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
11368
11369   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11370 })
11371
11372 ;; avoid useless masking of bit offset operand
11373 (define_insn_and_split "*jcc_btsi_mask_1"
11374   [(set (pc)
11375         (if_then_else
11376           (match_operator 0 "bt_comparison_operator"
11377             [(and:SI
11378                (lshiftrt:SI
11379                  (match_operand:SI 1 "register_operand" "r")
11380                  (subreg:QI
11381                    (and:SI
11382                      (match_operand:SI 2 "register_operand" "r")
11383                      (match_operand:SI 3 "const_int_operand" "n")) 0))
11384                (const_int 1))
11385              (const_int 0)])
11386           (label_ref (match_operand 4 "" ""))
11387           (pc)))
11388    (clobber (reg:CC FLAGS_REG))]
11389   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11390    && (INTVAL (operands[3]) & 0x1f) == 0x1f"
11391   "#"
11392   "&& 1"
11393   [(set (reg:CCC FLAGS_REG)
11394         (compare:CCC
11395           (zero_extract:SI
11396             (match_dup 1)
11397             (const_int 1)
11398             (match_dup 2))
11399           (const_int 0)))
11400    (set (pc)
11401         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11402                       (label_ref (match_dup 4))
11403                       (pc)))]
11404   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
11405
11406 ;; Define combination compare-and-branch fp compare instructions to help
11407 ;; combine.
11408
11409 (define_insn "*fp_jcc_3_387"
11410   [(set (pc)
11411         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11412                         [(match_operand 1 "register_operand" "f")
11413                          (match_operand 2 "nonimmediate_operand" "fm")])
11414           (label_ref (match_operand 3 "" ""))
11415           (pc)))
11416    (clobber (reg:CCFP FPSR_REG))
11417    (clobber (reg:CCFP FLAGS_REG))
11418    (clobber (match_scratch:HI 4 "=a"))]
11419   "TARGET_80387
11420    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
11421    && GET_MODE (operands[1]) == GET_MODE (operands[2])
11422    && SELECT_CC_MODE (GET_CODE (operands[0]),
11423                       operands[1], operands[2]) == CCFPmode
11424    && !TARGET_CMOVE"
11425   "#")
11426
11427 (define_insn "*fp_jcc_4_387"
11428   [(set (pc)
11429         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11430                         [(match_operand 1 "register_operand" "f")
11431                          (match_operand 2 "nonimmediate_operand" "fm")])
11432           (pc)
11433           (label_ref (match_operand 3 "" ""))))
11434    (clobber (reg:CCFP FPSR_REG))
11435    (clobber (reg:CCFP FLAGS_REG))
11436    (clobber (match_scratch:HI 4 "=a"))]
11437   "TARGET_80387
11438    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
11439    && GET_MODE (operands[1]) == GET_MODE (operands[2])
11440    && SELECT_CC_MODE (GET_CODE (operands[0]),
11441                       operands[1], operands[2]) == CCFPmode
11442    && !TARGET_CMOVE"
11443   "#")
11444
11445 (define_insn "*fp_jcc_5_387"
11446   [(set (pc)
11447         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11448                         [(match_operand 1 "register_operand" "f")
11449                          (match_operand 2 "register_operand" "f")])
11450           (label_ref (match_operand 3 "" ""))
11451           (pc)))
11452    (clobber (reg:CCFP FPSR_REG))
11453    (clobber (reg:CCFP FLAGS_REG))
11454    (clobber (match_scratch:HI 4 "=a"))]
11455   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11456    && GET_MODE (operands[1]) == GET_MODE (operands[2])
11457    && !TARGET_CMOVE"
11458   "#")
11459
11460 (define_insn "*fp_jcc_6_387"
11461   [(set (pc)
11462         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11463                         [(match_operand 1 "register_operand" "f")
11464                          (match_operand 2 "register_operand" "f")])
11465           (pc)
11466           (label_ref (match_operand 3 "" ""))))
11467    (clobber (reg:CCFP FPSR_REG))
11468    (clobber (reg:CCFP FLAGS_REG))
11469    (clobber (match_scratch:HI 4 "=a"))]
11470   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11471    && GET_MODE (operands[1]) == GET_MODE (operands[2])
11472    && !TARGET_CMOVE"
11473   "#")
11474
11475 (define_insn "*fp_jcc_7_387"
11476   [(set (pc)
11477         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11478                         [(match_operand 1 "register_operand" "f")
11479                          (match_operand 2 "const0_operand" "")])
11480           (label_ref (match_operand 3 "" ""))
11481           (pc)))
11482    (clobber (reg:CCFP FPSR_REG))
11483    (clobber (reg:CCFP FLAGS_REG))
11484    (clobber (match_scratch:HI 4 "=a"))]
11485   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11486    && GET_MODE (operands[1]) == GET_MODE (operands[2])
11487    && SELECT_CC_MODE (GET_CODE (operands[0]),
11488                       operands[1], operands[2]) == CCFPmode
11489    && !TARGET_CMOVE"
11490   "#")
11491
11492 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
11493 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11494 ;; with a precedence over other operators and is always put in the first
11495 ;; place. Swap condition and operands to match ficom instruction.
11496
11497 (define_insn "*fp_jcc_8<mode>_387"
11498   [(set (pc)
11499         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11500                         [(match_operator 1 "float_operator"
11501                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
11502                            (match_operand 3 "register_operand" "f,f")])
11503           (label_ref (match_operand 4 "" ""))
11504           (pc)))
11505    (clobber (reg:CCFP FPSR_REG))
11506    (clobber (reg:CCFP FLAGS_REG))
11507    (clobber (match_scratch:HI 5 "=a,a"))]
11508   "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
11509    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
11510    && GET_MODE (operands[1]) == GET_MODE (operands[3])
11511    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
11512    && !TARGET_CMOVE"
11513   "#")
11514
11515 (define_split
11516   [(set (pc)
11517         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11518                         [(match_operand 1 "register_operand" "")
11519                          (match_operand 2 "nonimmediate_operand" "")])
11520           (match_operand 3 "" "")
11521           (match_operand 4 "" "")))
11522    (clobber (reg:CCFP FPSR_REG))
11523    (clobber (reg:CCFP FLAGS_REG))]
11524   "reload_completed"
11525   [(const_int 0)]
11526 {
11527   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11528                         operands[3], operands[4], NULL_RTX, NULL_RTX);
11529   DONE;
11530 })
11531
11532 (define_split
11533   [(set (pc)
11534         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11535                         [(match_operand 1 "register_operand" "")
11536                          (match_operand 2 "general_operand" "")])
11537           (match_operand 3 "" "")
11538           (match_operand 4 "" "")))
11539    (clobber (reg:CCFP FPSR_REG))
11540    (clobber (reg:CCFP FLAGS_REG))
11541    (clobber (match_scratch:HI 5 "=a"))]
11542   "reload_completed"
11543   [(const_int 0)]
11544 {
11545   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11546                         operands[3], operands[4], operands[5], NULL_RTX);
11547   DONE;
11548 })
11549
11550 (define_split
11551   [(set (pc)
11552         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11553                         [(match_operator 1 "float_operator"
11554                            [(match_operand:X87MODEI12 2 "memory_operand" "")])
11555                            (match_operand 3 "register_operand" "")])
11556           (match_operand 4 "" "")
11557           (match_operand 5 "" "")))
11558    (clobber (reg:CCFP FPSR_REG))
11559    (clobber (reg:CCFP FLAGS_REG))
11560    (clobber (match_scratch:HI 6 "=a"))]
11561   "reload_completed"
11562   [(const_int 0)]
11563 {
11564   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
11565   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11566                         operands[3], operands[7],
11567                         operands[4], operands[5], operands[6], NULL_RTX);
11568   DONE;
11569 })
11570
11571 ;; %%% Kill this when reload knows how to do it.
11572 (define_split
11573   [(set (pc)
11574         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11575                         [(match_operator 1 "float_operator"
11576                            [(match_operand:X87MODEI12 2 "register_operand" "")])
11577                            (match_operand 3 "register_operand" "")])
11578           (match_operand 4 "" "")
11579           (match_operand 5 "" "")))
11580    (clobber (reg:CCFP FPSR_REG))
11581    (clobber (reg:CCFP FLAGS_REG))
11582    (clobber (match_scratch:HI 6 "=a"))]
11583   "reload_completed"
11584   [(const_int 0)]
11585 {
11586   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11587   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
11588   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11589                         operands[3], operands[7],
11590                         operands[4], operands[5], operands[6], operands[2]);
11591   DONE;
11592 })
11593 \f
11594 ;; Unconditional and other jump instructions
11595
11596 (define_insn "jump"
11597   [(set (pc)
11598         (label_ref (match_operand 0 "" "")))]
11599   ""
11600   "jmp\t%l0"
11601   [(set_attr "type" "ibr")
11602    (set (attr "length")
11603            (if_then_else (and (ge (minus (match_dup 0) (pc))
11604                                   (const_int -126))
11605                               (lt (minus (match_dup 0) (pc))
11606                                   (const_int 128)))
11607              (const_int 2)
11608              (const_int 5)))
11609    (set_attr "modrm" "0")])
11610
11611 (define_expand "indirect_jump"
11612   [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
11613   ""
11614   "")
11615
11616 (define_insn "*indirect_jump"
11617   [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
11618   ""
11619   "jmp\t%A0"
11620   [(set_attr "type" "ibr")
11621    (set_attr "length_immediate" "0")])
11622
11623 (define_expand "tablejump"
11624   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
11625               (use (label_ref (match_operand 1 "" "")))])]
11626   ""
11627 {
11628   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11629      relative.  Convert the relative address to an absolute address.  */
11630   if (flag_pic)
11631     {
11632       rtx op0, op1;
11633       enum rtx_code code;
11634
11635       /* We can't use @GOTOFF for text labels on VxWorks;
11636          see gotoff_operand.  */
11637       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11638         {
11639           code = PLUS;
11640           op0 = operands[0];
11641           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11642         }
11643       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11644         {
11645           code = PLUS;
11646           op0 = operands[0];
11647           op1 = pic_offset_table_rtx;
11648         }
11649       else
11650         {
11651           code = MINUS;
11652           op0 = pic_offset_table_rtx;
11653           op1 = operands[0];
11654         }
11655
11656       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11657                                          OPTAB_DIRECT);
11658     }
11659 })
11660
11661 (define_insn "*tablejump_1"
11662   [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
11663    (use (label_ref (match_operand 1 "" "")))]
11664   ""
11665   "jmp\t%A0"
11666   [(set_attr "type" "ibr")
11667    (set_attr "length_immediate" "0")])
11668 \f
11669 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11670
11671 (define_peephole2
11672   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11673    (set (match_operand:QI 1 "register_operand" "")
11674         (match_operator:QI 2 "ix86_comparison_operator"
11675           [(reg FLAGS_REG) (const_int 0)]))
11676    (set (match_operand 3 "q_regs_operand" "")
11677         (zero_extend (match_dup 1)))]
11678   "(peep2_reg_dead_p (3, operands[1])
11679     || operands_match_p (operands[1], operands[3]))
11680    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11681   [(set (match_dup 4) (match_dup 0))
11682    (set (strict_low_part (match_dup 5))
11683         (match_dup 2))]
11684 {
11685   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11686   operands[5] = gen_lowpart (QImode, operands[3]);
11687   ix86_expand_clear (operands[3]);
11688 })
11689
11690 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
11691
11692 (define_peephole2
11693   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11694    (set (match_operand:QI 1 "register_operand" "")
11695         (match_operator:QI 2 "ix86_comparison_operator"
11696           [(reg FLAGS_REG) (const_int 0)]))
11697    (parallel [(set (match_operand 3 "q_regs_operand" "")
11698                    (zero_extend (match_dup 1)))
11699               (clobber (reg:CC FLAGS_REG))])]
11700   "(peep2_reg_dead_p (3, operands[1])
11701     || operands_match_p (operands[1], operands[3]))
11702    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11703   [(set (match_dup 4) (match_dup 0))
11704    (set (strict_low_part (match_dup 5))
11705         (match_dup 2))]
11706 {
11707   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11708   operands[5] = gen_lowpart (QImode, operands[3]);
11709   ix86_expand_clear (operands[3]);
11710 })
11711 \f
11712 ;; Call instructions.
11713
11714 ;; The predicates normally associated with named expanders are not properly
11715 ;; checked for calls.  This is a bug in the generic code, but it isn't that
11716 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
11717
11718 ;; P6 processors will jump to the address after the decrement when %esp
11719 ;; is used as a call operand, so they will execute return address as a code.
11720 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11721  
11722 ;; Call subroutine returning no value.
11723
11724 (define_expand "call_pop"
11725   [(parallel [(call (match_operand:QI 0 "" "")
11726                     (match_operand:SI 1 "" ""))
11727               (set (reg:SI SP_REG)
11728                    (plus:SI (reg:SI SP_REG)
11729                             (match_operand:SI 3 "" "")))])]
11730   "!TARGET_64BIT"
11731 {
11732   ix86_expand_call (NULL, operands[0], operands[1],
11733                     operands[2], operands[3], 0);
11734   DONE;
11735 })
11736
11737 (define_insn "*call_pop_0"
11738   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
11739          (match_operand:SI 1 "" ""))
11740    (set (reg:SI SP_REG)
11741         (plus:SI (reg:SI SP_REG)
11742                  (match_operand:SI 2 "immediate_operand" "")))]
11743   "!TARGET_64BIT"
11744 {
11745   if (SIBLING_CALL_P (insn))
11746     return "jmp\t%P0";
11747   else
11748     return "call\t%P0";
11749 }
11750   [(set_attr "type" "call")])
11751
11752 (define_insn "*call_pop_1"
11753   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11754          (match_operand:SI 1 "" ""))
11755    (set (reg:SI SP_REG)
11756         (plus:SI (reg:SI SP_REG)
11757                  (match_operand:SI 2 "immediate_operand" "i")))]
11758   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11759 {
11760   if (constant_call_address_operand (operands[0], Pmode))
11761     return "call\t%P0";
11762   return "call\t%A0";
11763 }
11764   [(set_attr "type" "call")])
11765
11766 (define_insn "*sibcall_pop_1"
11767   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11768          (match_operand:SI 1 "" ""))
11769    (set (reg:SI SP_REG)
11770         (plus:SI (reg:SI SP_REG)
11771                  (match_operand:SI 2 "immediate_operand" "i,i")))]
11772   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11773   "@
11774    jmp\t%P0
11775    jmp\t%A0"
11776   [(set_attr "type" "call")])
11777
11778 (define_expand "call"
11779   [(call (match_operand:QI 0 "" "")
11780          (match_operand 1 "" ""))
11781    (use (match_operand 2 "" ""))]
11782   ""
11783 {
11784   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
11785   DONE;
11786 })
11787
11788 (define_expand "sibcall"
11789   [(call (match_operand:QI 0 "" "")
11790          (match_operand 1 "" ""))
11791    (use (match_operand 2 "" ""))]
11792   ""
11793 {
11794   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
11795   DONE;
11796 })
11797
11798 (define_insn "*call_0"
11799   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
11800          (match_operand 1 "" ""))]
11801   ""
11802 {
11803   if (SIBLING_CALL_P (insn))
11804     return "jmp\t%P0";
11805   else
11806     return "call\t%P0";
11807 }
11808   [(set_attr "type" "call")])
11809
11810 (define_insn "*call_1"
11811   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11812          (match_operand 1 "" ""))]
11813   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11814 {
11815   if (constant_call_address_operand (operands[0], Pmode))
11816     return "call\t%P0";
11817   return "call\t%A0";
11818 }
11819   [(set_attr "type" "call")])
11820
11821 (define_insn "*sibcall_1"
11822   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11823          (match_operand 1 "" ""))]
11824   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11825   "@
11826    jmp\t%P0
11827    jmp\t%A0"
11828   [(set_attr "type" "call")])
11829
11830 (define_insn "*call_1_rex64"
11831   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11832          (match_operand 1 "" ""))]
11833   "TARGET_64BIT && !SIBLING_CALL_P (insn)
11834    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
11835 {
11836   if (constant_call_address_operand (operands[0], Pmode))
11837     return "call\t%P0";
11838   return "call\t%A0";
11839 }
11840   [(set_attr "type" "call")])
11841
11842 (define_insn "*call_1_rex64_ms_sysv"
11843   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11844          (match_operand 1 "" ""))
11845    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11846    (clobber (reg:TI XMM6_REG))
11847    (clobber (reg:TI XMM7_REG))
11848    (clobber (reg:TI XMM8_REG))
11849    (clobber (reg:TI XMM9_REG))
11850    (clobber (reg:TI XMM10_REG))
11851    (clobber (reg:TI XMM11_REG))
11852    (clobber (reg:TI XMM12_REG))
11853    (clobber (reg:TI XMM13_REG))
11854    (clobber (reg:TI XMM14_REG))
11855    (clobber (reg:TI XMM15_REG))
11856    (clobber (reg:DI SI_REG))
11857    (clobber (reg:DI DI_REG))]
11858   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11859 {
11860   if (constant_call_address_operand (operands[0], Pmode))
11861     return "call\t%P0";
11862   return "call\t%A0";
11863 }
11864   [(set_attr "type" "call")])
11865
11866 (define_insn "*call_1_rex64_large"
11867   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
11868          (match_operand 1 "" ""))]
11869   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11870   "call\t%A0"
11871   [(set_attr "type" "call")])
11872
11873 (define_insn "*sibcall_1_rex64"
11874   [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
11875          (match_operand 1 "" ""))]
11876   "TARGET_64BIT && SIBLING_CALL_P (insn)"
11877   "@
11878    jmp\t%P0
11879    jmp\t%A0"
11880   [(set_attr "type" "call")])
11881
11882 ;; Call subroutine, returning value in operand 0
11883 (define_expand "call_value_pop"
11884   [(parallel [(set (match_operand 0 "" "")
11885                    (call (match_operand:QI 1 "" "")
11886                          (match_operand:SI 2 "" "")))
11887               (set (reg:SI SP_REG)
11888                    (plus:SI (reg:SI SP_REG)
11889                             (match_operand:SI 4 "" "")))])]
11890   "!TARGET_64BIT"
11891 {
11892   ix86_expand_call (operands[0], operands[1], operands[2],
11893                     operands[3], operands[4], 0);
11894   DONE;
11895 })
11896
11897 (define_expand "call_value"
11898   [(set (match_operand 0 "" "")
11899         (call (match_operand:QI 1 "" "")
11900               (match_operand:SI 2 "" "")))
11901    (use (match_operand:SI 3 "" ""))]
11902   ;; Operand 3 is not used on the i386.
11903   ""
11904 {
11905   ix86_expand_call (operands[0], operands[1], operands[2],
11906                     operands[3], NULL, 0);
11907   DONE;
11908 })
11909
11910 (define_expand "sibcall_value"
11911   [(set (match_operand 0 "" "")
11912         (call (match_operand:QI 1 "" "")
11913               (match_operand:SI 2 "" "")))
11914    (use (match_operand:SI 3 "" ""))]
11915   ;; Operand 3 is not used on the i386.
11916   ""
11917 {
11918   ix86_expand_call (operands[0], operands[1], operands[2],
11919                     operands[3], NULL, 1);
11920   DONE;
11921 })
11922
11923 ;; Call subroutine returning any type.
11924
11925 (define_expand "untyped_call"
11926   [(parallel [(call (match_operand 0 "" "")
11927                     (const_int 0))
11928               (match_operand 1 "" "")
11929               (match_operand 2 "" "")])]
11930   ""
11931 {
11932   int i;
11933
11934   /* In order to give reg-stack an easier job in validating two
11935      coprocessor registers as containing a possible return value,
11936      simply pretend the untyped call returns a complex long double
11937      value. 
11938
11939      We can't use SSE_REGPARM_MAX here since callee is unprototyped
11940      and should have the default ABI.  */
11941
11942   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11943                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11944                     operands[0], const0_rtx,
11945                     GEN_INT ((TARGET_64BIT
11946                               ? (ix86_abi == SYSV_ABI
11947                                  ? X86_64_SSE_REGPARM_MAX
11948                                  : X86_64_MS_SSE_REGPARM_MAX)
11949                               : X86_32_SSE_REGPARM_MAX)
11950                              - 1),
11951                     NULL, 0);
11952
11953   for (i = 0; i < XVECLEN (operands[2], 0); i++)
11954     {
11955       rtx set = XVECEXP (operands[2], 0, i);
11956       emit_move_insn (SET_DEST (set), SET_SRC (set));
11957     }
11958
11959   /* The optimizer does not know that the call sets the function value
11960      registers we stored in the result block.  We avoid problems by
11961      claiming that all hard registers are used and clobbered at this
11962      point.  */
11963   emit_insn (gen_blockage ());
11964
11965   DONE;
11966 })
11967 \f
11968 ;; Prologue and epilogue instructions
11969
11970 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11971 ;; all of memory.  This blocks insns from being moved across this point.
11972
11973 (define_insn "blockage"
11974   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11975   ""
11976   ""
11977   [(set_attr "length" "0")])
11978
11979 ;; Do not schedule instructions accessing memory across this point.
11980
11981 (define_expand "memory_blockage"
11982   [(set (match_dup 0)
11983         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11984   ""
11985 {
11986   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11987   MEM_VOLATILE_P (operands[0]) = 1;
11988 })
11989
11990 (define_insn "*memory_blockage"
11991   [(set (match_operand:BLK 0 "" "")
11992         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11993   ""
11994   ""
11995   [(set_attr "length" "0")])
11996
11997 ;; As USE insns aren't meaningful after reload, this is used instead
11998 ;; to prevent deleting instructions setting registers for PIC code
11999 (define_insn "prologue_use"
12000   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
12001   ""
12002   ""
12003   [(set_attr "length" "0")])
12004
12005 ;; Insn emitted into the body of a function to return from a function.
12006 ;; This is only done if the function's epilogue is known to be simple.
12007 ;; See comments for ix86_can_use_return_insn_p in i386.c.
12008
12009 (define_expand "return"
12010   [(return)]
12011   "ix86_can_use_return_insn_p ()"
12012 {
12013   if (crtl->args.pops_args)
12014     {
12015       rtx popc = GEN_INT (crtl->args.pops_args);
12016       emit_jump_insn (gen_return_pop_internal (popc));
12017       DONE;
12018     }
12019 })
12020
12021 (define_insn "return_internal"
12022   [(return)]
12023   "reload_completed"
12024   "ret"
12025   [(set_attr "length" "1")
12026    (set_attr "atom_unit" "jeu")
12027    (set_attr "length_immediate" "0")
12028    (set_attr "modrm" "0")])
12029
12030 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
12031 ;; instruction Athlon and K8 have.
12032
12033 (define_insn "return_internal_long"
12034   [(return)
12035    (unspec [(const_int 0)] UNSPEC_REP)]
12036   "reload_completed"
12037   "rep\;ret"
12038   [(set_attr "length" "2")
12039    (set_attr "atom_unit" "jeu")
12040    (set_attr "length_immediate" "0")
12041    (set_attr "prefix_rep" "1")
12042    (set_attr "modrm" "0")])
12043
12044 (define_insn "return_pop_internal"
12045   [(return)
12046    (use (match_operand:SI 0 "const_int_operand" ""))]
12047   "reload_completed"
12048   "ret\t%0"
12049   [(set_attr "length" "3")
12050    (set_attr "atom_unit" "jeu")
12051    (set_attr "length_immediate" "2")
12052    (set_attr "modrm" "0")])
12053
12054 (define_insn "return_indirect_internal"
12055   [(return)
12056    (use (match_operand:SI 0 "register_operand" "r"))]
12057   "reload_completed"
12058   "jmp\t%A0"
12059   [(set_attr "type" "ibr")
12060    (set_attr "length_immediate" "0")])
12061
12062 (define_insn "nop"
12063   [(const_int 0)]
12064   ""
12065   "nop"
12066   [(set_attr "length" "1")
12067    (set_attr "length_immediate" "0")
12068    (set_attr "modrm" "0")])
12069
12070 (define_insn "vswapmov"
12071   [(set (match_operand:SI 0 "register_operand" "=r")
12072         (match_operand:SI 1 "register_operand" "r"))
12073    (unspec_volatile [(const_int 0)] UNSPECV_VSWAPMOV)]
12074   ""
12075   "movl.s\t{%1, %0|%0, %1}"
12076   [(set_attr "length" "2")
12077    (set_attr "length_immediate" "0")
12078    (set_attr "modrm" "0")])
12079
12080 ;; Pad to 16-byte boundary, max skip in op0.  Used to avoid
12081 ;; branch prediction penalty for the third jump in a 16-byte
12082 ;; block on K8.
12083
12084 (define_insn "pad"
12085   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
12086   ""
12087 {
12088 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
12089   ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
12090 #else
12091   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
12092      The align insn is used to avoid 3 jump instructions in the row to improve
12093      branch prediction and the benefits hardly outweigh the cost of extra 8
12094      nops on the average inserted by full alignment pseudo operation.  */
12095 #endif
12096   return "";
12097 }
12098   [(set_attr "length" "16")])
12099
12100 (define_expand "prologue"
12101   [(const_int 0)]
12102   ""
12103   "ix86_expand_prologue (); DONE;")
12104
12105 (define_insn "set_got"
12106   [(set (match_operand:SI 0 "register_operand" "=r")
12107         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
12108    (clobber (reg:CC FLAGS_REG))]
12109   "!TARGET_64BIT"
12110   { return output_set_got (operands[0], NULL_RTX); }
12111   [(set_attr "type" "multi")
12112    (set_attr "length" "12")])
12113
12114 (define_insn "set_got_labelled"
12115   [(set (match_operand:SI 0 "register_operand" "=r")
12116         (unspec:SI [(label_ref (match_operand 1 "" ""))]
12117          UNSPEC_SET_GOT))
12118    (clobber (reg:CC FLAGS_REG))]
12119   "!TARGET_64BIT"
12120   { return output_set_got (operands[0], operands[1]); }
12121   [(set_attr "type" "multi")
12122    (set_attr "length" "12")])
12123
12124 (define_insn "set_got_rex64"
12125   [(set (match_operand:DI 0 "register_operand" "=r")
12126         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
12127   "TARGET_64BIT"
12128   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
12129   [(set_attr "type" "lea")
12130    (set_attr "length_address" "4")
12131    (set_attr "mode" "DI")])
12132
12133 (define_insn "set_rip_rex64"
12134   [(set (match_operand:DI 0 "register_operand" "=r")
12135         (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
12136   "TARGET_64BIT"
12137   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
12138   [(set_attr "type" "lea")
12139    (set_attr "length_address" "4")
12140    (set_attr "mode" "DI")])
12141
12142 (define_insn "set_got_offset_rex64"
12143   [(set (match_operand:DI 0 "register_operand" "=r")
12144         (unspec:DI
12145           [(label_ref (match_operand 1 "" ""))]
12146           UNSPEC_SET_GOT_OFFSET))]
12147   "TARGET_64BIT"
12148   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
12149   [(set_attr "type" "imov")
12150    (set_attr "length_immediate" "0")
12151    (set_attr "length_address" "8")
12152    (set_attr "mode" "DI")])
12153
12154 (define_expand "epilogue"
12155   [(const_int 0)]
12156   ""
12157   "ix86_expand_epilogue (1); DONE;")
12158
12159 (define_expand "sibcall_epilogue"
12160   [(const_int 0)]
12161   ""
12162   "ix86_expand_epilogue (0); DONE;")
12163
12164 (define_expand "eh_return"
12165   [(use (match_operand 0 "register_operand" ""))]
12166   ""
12167 {
12168   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
12169
12170   /* Tricky bit: we write the address of the handler to which we will
12171      be returning into someone else's stack frame, one word below the
12172      stack address we wish to restore.  */
12173   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
12174   tmp = plus_constant (tmp, -UNITS_PER_WORD);
12175   tmp = gen_rtx_MEM (Pmode, tmp);
12176   emit_move_insn (tmp, ra);
12177
12178   emit_jump_insn (gen_eh_return_internal ());
12179   emit_barrier ();
12180   DONE;
12181 })
12182
12183 (define_insn_and_split "eh_return_internal"
12184   [(eh_return)]
12185   ""
12186   "#"
12187   "epilogue_completed"
12188   [(const_int 0)]
12189   "ix86_expand_epilogue (2); DONE;")
12190
12191 (define_insn "leave"
12192   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
12193    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
12194    (clobber (mem:BLK (scratch)))]
12195   "!TARGET_64BIT"
12196   "leave"
12197   [(set_attr "type" "leave")])
12198
12199 (define_insn "leave_rex64"
12200   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
12201    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
12202    (clobber (mem:BLK (scratch)))]
12203   "TARGET_64BIT"
12204   "leave"
12205   [(set_attr "type" "leave")])
12206 \f
12207 (define_expand "ffssi2"
12208   [(parallel
12209      [(set (match_operand:SI 0 "register_operand" "")
12210            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
12211       (clobber (match_scratch:SI 2 ""))
12212       (clobber (reg:CC FLAGS_REG))])]
12213   ""
12214 {
12215   if (TARGET_CMOVE)
12216     {
12217       emit_insn (gen_ffs_cmove (operands[0], operands[1]));
12218       DONE;
12219     }
12220 })
12221
12222 (define_expand "ffs_cmove"
12223   [(set (match_dup 2) (const_int -1))
12224    (parallel [(set (reg:CCZ FLAGS_REG)
12225                    (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "")
12226                                 (const_int 0)))
12227               (set (match_operand:SI 0 "register_operand" "")
12228                    (ctz:SI (match_dup 1)))])
12229    (set (match_dup 0) (if_then_else:SI
12230                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
12231                         (match_dup 2)
12232                         (match_dup 0)))
12233    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12234               (clobber (reg:CC FLAGS_REG))])]
12235   "TARGET_CMOVE"
12236   "operands[2] = gen_reg_rtx (SImode);")
12237
12238 (define_insn_and_split "*ffs_no_cmove"
12239   [(set (match_operand:SI 0 "register_operand" "=r")
12240         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12241    (clobber (match_scratch:SI 2 "=&q"))
12242    (clobber (reg:CC FLAGS_REG))]
12243   "!TARGET_CMOVE"
12244   "#"
12245   "&& reload_completed"
12246   [(parallel [(set (reg:CCZ FLAGS_REG)
12247                    (compare:CCZ (match_dup 1) (const_int 0)))
12248               (set (match_dup 0) (ctz:SI (match_dup 1)))])
12249    (set (strict_low_part (match_dup 3))
12250         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
12251    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12252               (clobber (reg:CC FLAGS_REG))])
12253    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12254               (clobber (reg:CC FLAGS_REG))])
12255    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12256               (clobber (reg:CC FLAGS_REG))])]
12257 {
12258   operands[3] = gen_lowpart (QImode, operands[2]);
12259   ix86_expand_clear (operands[2]);
12260 })
12261
12262 (define_insn "*ffssi_1"
12263   [(set (reg:CCZ FLAGS_REG)
12264         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
12265                      (const_int 0)))
12266    (set (match_operand:SI 0 "register_operand" "=r")
12267         (ctz:SI (match_dup 1)))]
12268   ""
12269   "bsf{l}\t{%1, %0|%0, %1}"
12270   [(set_attr "type" "alu1")
12271    (set_attr "prefix_0f" "1")
12272    (set_attr "mode" "SI")])
12273
12274 (define_expand "ffsdi2"
12275   [(set (match_dup 2) (const_int -1))
12276    (parallel [(set (reg:CCZ FLAGS_REG)
12277                    (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "")
12278                                 (const_int 0)))
12279               (set (match_operand:DI 0 "register_operand" "")
12280                    (ctz:DI (match_dup 1)))])
12281    (set (match_dup 0) (if_then_else:DI
12282                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
12283                         (match_dup 2)
12284                         (match_dup 0)))
12285    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
12286               (clobber (reg:CC FLAGS_REG))])]
12287   "TARGET_64BIT"
12288   "operands[2] = gen_reg_rtx (DImode);")
12289
12290 (define_insn "*ffsdi_1"
12291   [(set (reg:CCZ FLAGS_REG)
12292         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
12293                      (const_int 0)))
12294    (set (match_operand:DI 0 "register_operand" "=r")
12295         (ctz:DI (match_dup 1)))]
12296   "TARGET_64BIT"
12297   "bsf{q}\t{%1, %0|%0, %1}"
12298   [(set_attr "type" "alu1")
12299    (set_attr "prefix_0f" "1")
12300    (set_attr "mode" "DI")])
12301
12302 (define_insn "ctzsi2"
12303   [(set (match_operand:SI 0 "register_operand" "=r")
12304         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12305    (clobber (reg:CC FLAGS_REG))]
12306   ""
12307   "bsf{l}\t{%1, %0|%0, %1}"
12308   [(set_attr "type" "alu1")
12309    (set_attr "prefix_0f" "1")
12310    (set_attr "mode" "SI")])
12311
12312 (define_insn "ctzdi2"
12313   [(set (match_operand:DI 0 "register_operand" "=r")
12314         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
12315    (clobber (reg:CC FLAGS_REG))]
12316   "TARGET_64BIT"
12317   "bsf{q}\t{%1, %0|%0, %1}"
12318   [(set_attr "type" "alu1")
12319    (set_attr "prefix_0f" "1")
12320    (set_attr "mode" "DI")])
12321
12322 (define_expand "clzsi2"
12323   [(parallel
12324      [(set (match_operand:SI 0 "register_operand" "")
12325            (minus:SI (const_int 31)
12326                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
12327       (clobber (reg:CC FLAGS_REG))])
12328    (parallel
12329      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
12330       (clobber (reg:CC FLAGS_REG))])]
12331   ""
12332 {
12333   if (TARGET_ABM)
12334     {
12335       emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
12336       DONE;
12337     }
12338 })
12339
12340 (define_insn "clzsi2_abm"
12341   [(set (match_operand:SI 0 "register_operand" "=r")
12342         (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12343    (clobber (reg:CC FLAGS_REG))]
12344   "TARGET_ABM"
12345   "lzcnt{l}\t{%1, %0|%0, %1}"
12346   [(set_attr "prefix_rep" "1")
12347    (set_attr "type" "bitmanip")
12348    (set_attr "mode" "SI")])
12349
12350 (define_insn "bsr"
12351   [(set (match_operand:SI 0 "register_operand" "=r")
12352         (minus:SI (const_int 31)
12353                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12354    (clobber (reg:CC FLAGS_REG))]
12355   ""
12356   "bsr{l}\t{%1, %0|%0, %1}"
12357   [(set_attr "type" "alu1")
12358    (set_attr "prefix_0f" "1")
12359    (set_attr "mode" "SI")])
12360
12361 (define_insn "popcount<mode>2"
12362   [(set (match_operand:SWI248 0 "register_operand" "=r")
12363         (popcount:SWI248
12364           (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12365    (clobber (reg:CC FLAGS_REG))]
12366   "TARGET_POPCNT"
12367 {
12368 #if TARGET_MACHO
12369   return "popcnt\t{%1, %0|%0, %1}";
12370 #else
12371   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12372 #endif
12373 }
12374   [(set_attr "prefix_rep" "1")
12375    (set_attr "type" "bitmanip")
12376    (set_attr "mode" "<MODE>")])
12377
12378 (define_insn "*popcount<mode>2_cmp"
12379   [(set (reg FLAGS_REG)
12380         (compare
12381           (popcount:SWI248
12382             (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12383           (const_int 0)))
12384    (set (match_operand:SWI248 0 "register_operand" "=r")
12385         (popcount:SWI248 (match_dup 1)))]
12386   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12387 {
12388 #if TARGET_MACHO
12389   return "popcnt\t{%1, %0|%0, %1}";
12390 #else
12391   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12392 #endif
12393 }
12394   [(set_attr "prefix_rep" "1")
12395    (set_attr "type" "bitmanip")
12396    (set_attr "mode" "<MODE>")])
12397
12398 (define_insn "*popcountsi2_cmp_zext"
12399   [(set (reg FLAGS_REG)
12400         (compare
12401           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12402           (const_int 0)))
12403    (set (match_operand:DI 0 "register_operand" "=r")
12404         (zero_extend:DI(popcount:SI (match_dup 1))))]
12405   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12406 {
12407 #if TARGET_MACHO
12408   return "popcnt\t{%1, %0|%0, %1}";
12409 #else
12410   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12411 #endif
12412 }
12413   [(set_attr "prefix_rep" "1")
12414    (set_attr "type" "bitmanip")
12415    (set_attr "mode" "SI")])
12416
12417 (define_expand "bswapsi2"
12418   [(set (match_operand:SI 0 "register_operand" "")
12419         (bswap:SI (match_operand:SI 1 "register_operand" "")))]
12420   ""
12421 {
12422   if (!(TARGET_BSWAP || TARGET_MOVBE))
12423     {
12424       rtx x = operands[0];
12425
12426       emit_move_insn (x, operands[1]);
12427       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12428       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12429       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12430       DONE;
12431     }
12432 })
12433
12434 (define_insn "*bswapsi_movbe"
12435   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,m")
12436         (bswap:SI (match_operand:SI 1 "nonimmediate_operand" "0,m,r")))]
12437   "TARGET_MOVBE && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12438   "@
12439     bswap\t%0
12440     movbe\t{%1, %0|%0, %1}
12441     movbe\t{%1, %0|%0, %1}"
12442   [(set_attr "type" "*,imov,imov")
12443    (set_attr "modrm" "*,1,1")
12444    (set_attr "prefix_0f" "1")
12445    (set_attr "prefix_extra" "*,1,1")
12446    (set_attr "length" "2,*,*")
12447    (set_attr "mode" "SI")])
12448
12449 (define_insn "*bswapsi_1"
12450   [(set (match_operand:SI 0 "register_operand" "=r")
12451         (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
12452   "TARGET_BSWAP"
12453   "bswap\t%0"
12454   [(set_attr "prefix_0f" "1")
12455    (set_attr "length" "2")])
12456
12457 (define_insn "*bswaphi_lowpart_1"
12458   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12459         (bswap:HI (match_dup 0)))
12460    (clobber (reg:CC FLAGS_REG))]
12461   "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12462   "@
12463     xchg{b}\t{%h0, %b0|%b0, %h0}
12464     rol{w}\t{$8, %0|%0, 8}"
12465   [(set_attr "length" "2,4")
12466    (set_attr "mode" "QI,HI")])
12467
12468 (define_insn "bswaphi_lowpart"
12469   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12470         (bswap:HI (match_dup 0)))
12471    (clobber (reg:CC FLAGS_REG))]
12472   ""
12473   "rol{w}\t{$8, %0|%0, 8}"
12474   [(set_attr "length" "4")
12475    (set_attr "mode" "HI")])
12476
12477 (define_expand "bswapdi2"
12478   [(set (match_operand:DI 0 "register_operand" "")
12479         (bswap:DI (match_operand:DI 1 "register_operand" "")))]
12480   "TARGET_64BIT"
12481   "")
12482
12483 (define_insn "*bswapdi_movbe"
12484   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m")
12485         (bswap:DI (match_operand:DI 1 "nonimmediate_operand" "0,m,r")))]
12486   "TARGET_64BIT && TARGET_MOVBE
12487    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12488   "@
12489     bswap\t%0
12490     movbe\t{%1, %0|%0, %1}
12491     movbe\t{%1, %0|%0, %1}"
12492   [(set_attr "type" "*,imov,imov")
12493    (set_attr "modrm" "*,1,1")
12494    (set_attr "prefix_0f" "1")
12495    (set_attr "prefix_extra" "*,1,1")
12496    (set_attr "length" "3,*,*")
12497    (set_attr "mode" "DI")])
12498
12499 (define_insn "*bswapdi_1"
12500   [(set (match_operand:DI 0 "register_operand" "=r")
12501         (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
12502   "TARGET_64BIT"
12503   "bswap\t%0"
12504   [(set_attr "prefix_0f" "1")
12505    (set_attr "length" "3")])
12506
12507 (define_expand "clzdi2"
12508   [(parallel
12509      [(set (match_operand:DI 0 "register_operand" "")
12510            (minus:DI (const_int 63)
12511                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
12512       (clobber (reg:CC FLAGS_REG))])
12513    (parallel
12514      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
12515       (clobber (reg:CC FLAGS_REG))])]
12516   "TARGET_64BIT"
12517 {
12518   if (TARGET_ABM)
12519     {
12520       emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
12521       DONE;
12522     }
12523 })
12524
12525 (define_insn "clzdi2_abm"
12526   [(set (match_operand:DI 0 "register_operand" "=r")
12527         (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
12528    (clobber (reg:CC FLAGS_REG))]
12529   "TARGET_64BIT && TARGET_ABM"
12530   "lzcnt{q}\t{%1, %0|%0, %1}"
12531   [(set_attr "prefix_rep" "1")
12532    (set_attr "type" "bitmanip")
12533    (set_attr "mode" "DI")])
12534
12535 (define_insn "bsr_rex64"
12536   [(set (match_operand:DI 0 "register_operand" "=r")
12537         (minus:DI (const_int 63)
12538                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12539    (clobber (reg:CC FLAGS_REG))]
12540   "TARGET_64BIT"
12541   "bsr{q}\t{%1, %0|%0, %1}"
12542   [(set_attr "type" "alu1")
12543    (set_attr "prefix_0f" "1")
12544    (set_attr "mode" "DI")])
12545
12546 (define_expand "clzhi2"
12547   [(parallel
12548      [(set (match_operand:HI 0 "register_operand" "")
12549            (minus:HI (const_int 15)
12550                      (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
12551       (clobber (reg:CC FLAGS_REG))])
12552    (parallel
12553      [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
12554       (clobber (reg:CC FLAGS_REG))])]
12555   ""
12556 {
12557   if (TARGET_ABM)
12558     {
12559       emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
12560       DONE;
12561     }
12562 })
12563
12564 (define_insn "clzhi2_abm"
12565   [(set (match_operand:HI 0 "register_operand" "=r")
12566         (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm")))
12567    (clobber (reg:CC FLAGS_REG))]
12568   "TARGET_ABM"
12569   "lzcnt{w}\t{%1, %0|%0, %1}"
12570   [(set_attr "prefix_rep" "1")
12571    (set_attr "type" "bitmanip")
12572    (set_attr "mode" "HI")])
12573
12574 (define_insn "*bsrhi"
12575   [(set (match_operand:HI 0 "register_operand" "=r")
12576         (minus:HI (const_int 15)
12577                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12578    (clobber (reg:CC FLAGS_REG))]
12579   ""
12580   "bsr{w}\t{%1, %0|%0, %1}"
12581   [(set_attr "type" "alu1")
12582    (set_attr "prefix_0f" "1")
12583    (set_attr "mode" "HI")])
12584
12585 (define_expand "paritydi2"
12586   [(set (match_operand:DI 0 "register_operand" "")
12587         (parity:DI (match_operand:DI 1 "register_operand" "")))]
12588   "! TARGET_POPCNT"
12589 {
12590   rtx scratch = gen_reg_rtx (QImode);
12591   rtx cond;
12592
12593   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12594                                 NULL_RTX, operands[1]));
12595
12596   cond = gen_rtx_fmt_ee (ORDERED, QImode,
12597                          gen_rtx_REG (CCmode, FLAGS_REG),
12598                          const0_rtx);
12599   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12600
12601   if (TARGET_64BIT)
12602     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12603   else
12604     {
12605       rtx tmp = gen_reg_rtx (SImode);
12606
12607       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12608       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12609     }
12610   DONE;
12611 })
12612
12613 (define_insn_and_split "paritydi2_cmp"
12614   [(set (reg:CC FLAGS_REG)
12615         (parity:CC (match_operand:DI 3 "register_operand" "0")))
12616    (clobber (match_scratch:DI 0 "=r"))
12617    (clobber (match_scratch:SI 1 "=&r"))
12618    (clobber (match_scratch:HI 2 "=Q"))]
12619   "! TARGET_POPCNT"
12620   "#"
12621   "&& reload_completed"
12622   [(parallel
12623      [(set (match_dup 1)
12624            (xor:SI (match_dup 1) (match_dup 4)))
12625       (clobber (reg:CC FLAGS_REG))])
12626    (parallel
12627      [(set (reg:CC FLAGS_REG)
12628            (parity:CC (match_dup 1)))
12629       (clobber (match_dup 1))
12630       (clobber (match_dup 2))])]
12631 {
12632   operands[4] = gen_lowpart (SImode, operands[3]);
12633
12634   if (TARGET_64BIT)
12635     {
12636       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12637       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12638     }
12639   else
12640     operands[1] = gen_highpart (SImode, operands[3]);
12641 })
12642
12643 (define_expand "paritysi2"
12644   [(set (match_operand:SI 0 "register_operand" "")
12645         (parity:SI (match_operand:SI 1 "register_operand" "")))]
12646   "! TARGET_POPCNT"
12647 {
12648   rtx scratch = gen_reg_rtx (QImode);
12649   rtx cond;
12650
12651   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12652
12653   cond = gen_rtx_fmt_ee (ORDERED, QImode,
12654                          gen_rtx_REG (CCmode, FLAGS_REG),
12655                          const0_rtx);
12656   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12657
12658   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12659   DONE;
12660 })
12661
12662 (define_insn_and_split "paritysi2_cmp"
12663   [(set (reg:CC FLAGS_REG)
12664         (parity:CC (match_operand:SI 2 "register_operand" "0")))
12665    (clobber (match_scratch:SI 0 "=r"))
12666    (clobber (match_scratch:HI 1 "=&Q"))]
12667   "! TARGET_POPCNT"
12668   "#"
12669   "&& reload_completed"
12670   [(parallel
12671      [(set (match_dup 1)
12672            (xor:HI (match_dup 1) (match_dup 3)))
12673       (clobber (reg:CC FLAGS_REG))])
12674    (parallel
12675      [(set (reg:CC FLAGS_REG)
12676            (parity:CC (match_dup 1)))
12677       (clobber (match_dup 1))])]
12678 {
12679   operands[3] = gen_lowpart (HImode, operands[2]);
12680
12681   emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12682   emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12683 })
12684
12685 (define_insn "*parityhi2_cmp"
12686   [(set (reg:CC FLAGS_REG)
12687         (parity:CC (match_operand:HI 1 "register_operand" "0")))
12688    (clobber (match_scratch:HI 0 "=Q"))]
12689   "! TARGET_POPCNT"
12690   "xor{b}\t{%h0, %b0|%b0, %h0}"
12691   [(set_attr "length" "2")
12692    (set_attr "mode" "HI")])
12693
12694 (define_insn "*parityqi2_cmp"
12695   [(set (reg:CC FLAGS_REG)
12696         (parity:CC (match_operand:QI 0 "register_operand" "q")))]
12697   "! TARGET_POPCNT"
12698   "test{b}\t%0, %0"
12699   [(set_attr "length" "2")
12700    (set_attr "mode" "QI")])
12701 \f
12702 ;; Thread-local storage patterns for ELF.
12703 ;;
12704 ;; Note that these code sequences must appear exactly as shown
12705 ;; in order to allow linker relaxation.
12706
12707 (define_insn "*tls_global_dynamic_32_gnu"
12708   [(set (match_operand:SI 0 "register_operand" "=a")
12709         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12710                     (match_operand:SI 2 "tls_symbolic_operand" "")
12711                     (match_operand:SI 3 "call_insn_operand" "")]
12712                     UNSPEC_TLS_GD))
12713    (clobber (match_scratch:SI 4 "=d"))
12714    (clobber (match_scratch:SI 5 "=c"))
12715    (clobber (reg:CC FLAGS_REG))]
12716   "!TARGET_64BIT && TARGET_GNU_TLS"
12717   "lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}\;call\t%P3"
12718   [(set_attr "type" "multi")
12719    (set_attr "length" "12")])
12720
12721 (define_expand "tls_global_dynamic_32"
12722   [(parallel [(set (match_operand:SI 0 "register_operand" "")
12723                    (unspec:SI
12724                     [(match_dup 2)
12725                      (match_operand:SI 1 "tls_symbolic_operand" "")
12726                      (match_dup 3)]
12727                     UNSPEC_TLS_GD))
12728               (clobber (match_scratch:SI 4 ""))
12729               (clobber (match_scratch:SI 5 ""))
12730               (clobber (reg:CC FLAGS_REG))])]
12731   ""
12732 {
12733   if (flag_pic)
12734     operands[2] = pic_offset_table_rtx;
12735   else
12736     {
12737       operands[2] = gen_reg_rtx (Pmode);
12738       emit_insn (gen_set_got (operands[2]));
12739     }
12740   if (TARGET_GNU2_TLS)
12741     {
12742        emit_insn (gen_tls_dynamic_gnu2_32
12743                   (operands[0], operands[1], operands[2]));
12744        DONE;
12745     }
12746   operands[3] = ix86_tls_get_addr ();
12747 })
12748
12749 (define_insn "*tls_global_dynamic_64"
12750   [(set (match_operand:DI 0 "register_operand" "=a")
12751         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
12752                  (match_operand:DI 3 "" "")))
12753    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12754               UNSPEC_TLS_GD)]
12755   "TARGET_64BIT"
12756   { 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"; }
12757   [(set_attr "type" "multi")
12758    (set_attr "length" "16")])
12759
12760 (define_expand "tls_global_dynamic_64"
12761   [(parallel [(set (match_operand:DI 0 "register_operand" "")
12762                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
12763               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12764                          UNSPEC_TLS_GD)])]
12765   ""
12766 {
12767   if (TARGET_GNU2_TLS)
12768     {
12769        emit_insn (gen_tls_dynamic_gnu2_64
12770                   (operands[0], operands[1]));
12771        DONE;
12772     }
12773   operands[2] = ix86_tls_get_addr ();
12774 })
12775
12776 (define_insn "*tls_local_dynamic_base_32_gnu"
12777   [(set (match_operand:SI 0 "register_operand" "=a")
12778         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12779                     (match_operand:SI 2 "call_insn_operand" "")]
12780                    UNSPEC_TLS_LD_BASE))
12781    (clobber (match_scratch:SI 3 "=d"))
12782    (clobber (match_scratch:SI 4 "=c"))
12783    (clobber (reg:CC FLAGS_REG))]
12784   "!TARGET_64BIT && TARGET_GNU_TLS"
12785   "lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}\;call\t%P2"
12786   [(set_attr "type" "multi")
12787    (set_attr "length" "11")])
12788
12789 (define_expand "tls_local_dynamic_base_32"
12790   [(parallel [(set (match_operand:SI 0 "register_operand" "")
12791                    (unspec:SI [(match_dup 1) (match_dup 2)]
12792                               UNSPEC_TLS_LD_BASE))
12793               (clobber (match_scratch:SI 3 ""))
12794               (clobber (match_scratch:SI 4 ""))
12795               (clobber (reg:CC FLAGS_REG))])]
12796   ""
12797 {
12798   if (flag_pic)
12799     operands[1] = pic_offset_table_rtx;
12800   else
12801     {
12802       operands[1] = gen_reg_rtx (Pmode);
12803       emit_insn (gen_set_got (operands[1]));
12804     }
12805   if (TARGET_GNU2_TLS)
12806     {
12807        emit_insn (gen_tls_dynamic_gnu2_32
12808                   (operands[0], ix86_tls_module_base (), operands[1]));
12809        DONE;
12810     }
12811   operands[2] = ix86_tls_get_addr ();
12812 })
12813
12814 (define_insn "*tls_local_dynamic_base_64"
12815   [(set (match_operand:DI 0 "register_operand" "=a")
12816         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
12817                  (match_operand:DI 2 "" "")))
12818    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12819   "TARGET_64BIT"
12820   "lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}\;call\t%P1"
12821   [(set_attr "type" "multi")
12822    (set_attr "length" "12")])
12823
12824 (define_expand "tls_local_dynamic_base_64"
12825   [(parallel [(set (match_operand:DI 0 "register_operand" "")
12826                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
12827               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
12828   ""
12829 {
12830   if (TARGET_GNU2_TLS)
12831     {
12832        emit_insn (gen_tls_dynamic_gnu2_64
12833                   (operands[0], ix86_tls_module_base ()));
12834        DONE;
12835     }
12836   operands[1] = ix86_tls_get_addr ();
12837 })
12838
12839 ;; Local dynamic of a single variable is a lose.  Show combine how
12840 ;; to convert that back to global dynamic.
12841
12842 (define_insn_and_split "*tls_local_dynamic_32_once"
12843   [(set (match_operand:SI 0 "register_operand" "=a")
12844         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12845                              (match_operand:SI 2 "call_insn_operand" "")]
12846                             UNSPEC_TLS_LD_BASE)
12847                  (const:SI (unspec:SI
12848                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
12849                             UNSPEC_DTPOFF))))
12850    (clobber (match_scratch:SI 4 "=d"))
12851    (clobber (match_scratch:SI 5 "=c"))
12852    (clobber (reg:CC FLAGS_REG))]
12853   ""
12854   "#"
12855   ""
12856   [(parallel [(set (match_dup 0)
12857                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12858                               UNSPEC_TLS_GD))
12859               (clobber (match_dup 4))
12860               (clobber (match_dup 5))
12861               (clobber (reg:CC FLAGS_REG))])]
12862   "")
12863
12864 ;; Load and add the thread base pointer from %gs:0.
12865
12866 (define_insn "*load_tp_si"
12867   [(set (match_operand:SI 0 "register_operand" "=r")
12868         (unspec:SI [(const_int 0)] UNSPEC_TP))]
12869   "!TARGET_64BIT"
12870   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
12871   [(set_attr "type" "imov")
12872    (set_attr "modrm" "0")
12873    (set_attr "length" "7")
12874    (set_attr "memory" "load")
12875    (set_attr "imm_disp" "false")])
12876
12877 (define_insn "*add_tp_si"
12878   [(set (match_operand:SI 0 "register_operand" "=r")
12879         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12880                  (match_operand:SI 1 "register_operand" "0")))
12881    (clobber (reg:CC FLAGS_REG))]
12882   "!TARGET_64BIT"
12883   "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
12884   [(set_attr "type" "alu")
12885    (set_attr "modrm" "0")
12886    (set_attr "length" "7")
12887    (set_attr "memory" "load")
12888    (set_attr "imm_disp" "false")])
12889
12890 (define_insn "*load_tp_di"
12891   [(set (match_operand:DI 0 "register_operand" "=r")
12892         (unspec:DI [(const_int 0)] UNSPEC_TP))]
12893   "TARGET_64BIT"
12894   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
12895   [(set_attr "type" "imov")
12896    (set_attr "modrm" "0")
12897    (set_attr "length" "7")
12898    (set_attr "memory" "load")
12899    (set_attr "imm_disp" "false")])
12900
12901 (define_insn "*add_tp_di"
12902   [(set (match_operand:DI 0 "register_operand" "=r")
12903         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
12904                  (match_operand:DI 1 "register_operand" "0")))
12905    (clobber (reg:CC FLAGS_REG))]
12906   "TARGET_64BIT"
12907   "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
12908   [(set_attr "type" "alu")
12909    (set_attr "modrm" "0")
12910    (set_attr "length" "7")
12911    (set_attr "memory" "load")
12912    (set_attr "imm_disp" "false")])
12913
12914 ;; GNU2 TLS patterns can be split.
12915
12916 (define_expand "tls_dynamic_gnu2_32"
12917   [(set (match_dup 3)
12918         (plus:SI (match_operand:SI 2 "register_operand" "")
12919                  (const:SI
12920                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12921                              UNSPEC_TLSDESC))))
12922    (parallel
12923     [(set (match_operand:SI 0 "register_operand" "")
12924           (unspec:SI [(match_dup 1) (match_dup 3)
12925                       (match_dup 2) (reg:SI SP_REG)]
12926                       UNSPEC_TLSDESC))
12927      (clobber (reg:CC FLAGS_REG))])]
12928   "!TARGET_64BIT && TARGET_GNU2_TLS"
12929 {
12930   operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12931   ix86_tls_descriptor_calls_expanded_in_cfun = true;
12932 })
12933
12934 (define_insn "*tls_dynamic_lea_32"
12935   [(set (match_operand:SI 0 "register_operand" "=r")
12936         (plus:SI (match_operand:SI 1 "register_operand" "b")
12937                  (const:SI
12938                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12939                               UNSPEC_TLSDESC))))]
12940   "!TARGET_64BIT && TARGET_GNU2_TLS"
12941   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
12942   [(set_attr "type" "lea")
12943    (set_attr "mode" "SI")
12944    (set_attr "length" "6")
12945    (set_attr "length_address" "4")])
12946
12947 (define_insn "*tls_dynamic_call_32"
12948   [(set (match_operand:SI 0 "register_operand" "=a")
12949         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12950                     (match_operand:SI 2 "register_operand" "0")
12951                     ;; we have to make sure %ebx still points to the GOT
12952                     (match_operand:SI 3 "register_operand" "b")
12953                     (reg:SI SP_REG)]
12954                    UNSPEC_TLSDESC))
12955    (clobber (reg:CC FLAGS_REG))]
12956   "!TARGET_64BIT && TARGET_GNU2_TLS"
12957   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12958   [(set_attr "type" "call")
12959    (set_attr "length" "2")
12960    (set_attr "length_address" "0")])
12961
12962 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12963   [(set (match_operand:SI 0 "register_operand" "=&a")
12964         (plus:SI
12965          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12966                      (match_operand:SI 4 "" "")
12967                      (match_operand:SI 2 "register_operand" "b")
12968                      (reg:SI SP_REG)]
12969                     UNSPEC_TLSDESC)
12970          (const:SI (unspec:SI
12971                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
12972                     UNSPEC_DTPOFF))))
12973    (clobber (reg:CC FLAGS_REG))]
12974   "!TARGET_64BIT && TARGET_GNU2_TLS"
12975   "#"
12976   ""
12977   [(set (match_dup 0) (match_dup 5))]
12978 {
12979   operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12980   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12981 })
12982
12983 (define_expand "tls_dynamic_gnu2_64"
12984   [(set (match_dup 2)
12985         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12986                    UNSPEC_TLSDESC))
12987    (parallel
12988     [(set (match_operand:DI 0 "register_operand" "")
12989           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12990                      UNSPEC_TLSDESC))
12991      (clobber (reg:CC FLAGS_REG))])]
12992   "TARGET_64BIT && TARGET_GNU2_TLS"
12993 {
12994   operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12995   ix86_tls_descriptor_calls_expanded_in_cfun = true;
12996 })
12997
12998 (define_insn "*tls_dynamic_lea_64"
12999   [(set (match_operand:DI 0 "register_operand" "=r")
13000         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
13001                    UNSPEC_TLSDESC))]
13002   "TARGET_64BIT && TARGET_GNU2_TLS"
13003   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
13004   [(set_attr "type" "lea")
13005    (set_attr "mode" "DI")
13006    (set_attr "length" "7")
13007    (set_attr "length_address" "4")])
13008
13009 (define_insn "*tls_dynamic_call_64"
13010   [(set (match_operand:DI 0 "register_operand" "=a")
13011         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
13012                     (match_operand:DI 2 "register_operand" "0")
13013                     (reg:DI SP_REG)]
13014                    UNSPEC_TLSDESC))
13015    (clobber (reg:CC FLAGS_REG))]
13016   "TARGET_64BIT && TARGET_GNU2_TLS"
13017   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
13018   [(set_attr "type" "call")
13019    (set_attr "length" "2")
13020    (set_attr "length_address" "0")])
13021
13022 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
13023   [(set (match_operand:DI 0 "register_operand" "=&a")
13024         (plus:DI
13025          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
13026                      (match_operand:DI 3 "" "")
13027                      (reg:DI SP_REG)]
13028                     UNSPEC_TLSDESC)
13029          (const:DI (unspec:DI
13030                     [(match_operand:DI 1 "tls_symbolic_operand" "")]
13031                     UNSPEC_DTPOFF))))
13032    (clobber (reg:CC FLAGS_REG))]
13033   "TARGET_64BIT && TARGET_GNU2_TLS"
13034   "#"
13035   ""
13036   [(set (match_dup 0) (match_dup 4))]
13037 {
13038   operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13039   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
13040 })
13041
13042 ;;
13043 \f
13044 ;; These patterns match the binary 387 instructions for addM3, subM3,
13045 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
13046 ;; SFmode.  The first is the normal insn, the second the same insn but
13047 ;; with one operand a conversion, and the third the same insn but with
13048 ;; the other operand a conversion.  The conversion may be SFmode or
13049 ;; SImode if the target mode DFmode, but only SImode if the target mode
13050 ;; is SFmode.
13051
13052 ;; Gcc is slightly more smart about handling normal two address instructions
13053 ;; so use special patterns for add and mull.
13054
13055 (define_insn "*fop_<mode>_comm_mixed_avx"
13056   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
13057         (match_operator:MODEF 3 "binary_fp_operator"
13058           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
13059            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
13060   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13061    && COMMUTATIVE_ARITH_P (operands[3])
13062    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13063   "* return output_387_binary_op (insn, operands);"
13064   [(set (attr "type")
13065         (if_then_else (eq_attr "alternative" "1")
13066            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13067               (const_string "ssemul")
13068               (const_string "sseadd"))
13069            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13070               (const_string "fmul")
13071               (const_string "fop"))))
13072    (set_attr "prefix" "orig,maybe_vex")
13073    (set_attr "mode" "<MODE>")])
13074
13075 (define_insn "*fop_<mode>_comm_mixed"
13076   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
13077         (match_operator:MODEF 3 "binary_fp_operator"
13078           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
13079            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
13080   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13081    && COMMUTATIVE_ARITH_P (operands[3])
13082    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13083   "* return output_387_binary_op (insn, operands);"
13084   [(set (attr "type")
13085         (if_then_else (eq_attr "alternative" "1")
13086            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13087               (const_string "ssemul")
13088               (const_string "sseadd"))
13089            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13090               (const_string "fmul")
13091               (const_string "fop"))))
13092    (set_attr "mode" "<MODE>")])
13093
13094 (define_insn "*fop_<mode>_comm_avx"
13095   [(set (match_operand:MODEF 0 "register_operand" "=x")
13096         (match_operator:MODEF 3 "binary_fp_operator"
13097           [(match_operand:MODEF 1 "nonimmediate_operand" "%x")
13098            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
13099   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13100    && COMMUTATIVE_ARITH_P (operands[3])
13101    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13102   "* return output_387_binary_op (insn, operands);"
13103   [(set (attr "type")
13104         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13105            (const_string "ssemul")
13106            (const_string "sseadd")))
13107    (set_attr "prefix" "vex")
13108    (set_attr "mode" "<MODE>")])
13109
13110 (define_insn "*fop_<mode>_comm_sse"
13111   [(set (match_operand:MODEF 0 "register_operand" "=x")
13112         (match_operator:MODEF 3 "binary_fp_operator"
13113           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13114            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
13115   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13116    && COMMUTATIVE_ARITH_P (operands[3])
13117    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13118   "* return output_387_binary_op (insn, operands);"
13119   [(set (attr "type")
13120         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13121            (const_string "ssemul")
13122            (const_string "sseadd")))
13123    (set_attr "mode" "<MODE>")])
13124
13125 (define_insn "*fop_<mode>_comm_i387"
13126   [(set (match_operand:MODEF 0 "register_operand" "=f")
13127         (match_operator:MODEF 3 "binary_fp_operator"
13128           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13129            (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
13130   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13131    && COMMUTATIVE_ARITH_P (operands[3])
13132    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13133   "* return output_387_binary_op (insn, operands);"
13134   [(set (attr "type")
13135         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13136            (const_string "fmul")
13137            (const_string "fop")))
13138    (set_attr "mode" "<MODE>")])
13139
13140 (define_insn "*fop_<mode>_1_mixed_avx"
13141   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
13142         (match_operator:MODEF 3 "binary_fp_operator"
13143           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,x")
13144            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
13145   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13146    && !COMMUTATIVE_ARITH_P (operands[3])
13147    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13148   "* return output_387_binary_op (insn, operands);"
13149   [(set (attr "type")
13150         (cond [(and (eq_attr "alternative" "2")
13151                     (match_operand:MODEF 3 "mult_operator" ""))
13152                  (const_string "ssemul")
13153                (and (eq_attr "alternative" "2")
13154                     (match_operand:MODEF 3 "div_operator" ""))
13155                  (const_string "ssediv")
13156                (eq_attr "alternative" "2")
13157                  (const_string "sseadd")
13158                (match_operand:MODEF 3 "mult_operator" "")
13159                  (const_string "fmul")
13160                (match_operand:MODEF 3 "div_operator" "")
13161                  (const_string "fdiv")
13162               ]
13163               (const_string "fop")))
13164    (set_attr "prefix" "orig,orig,maybe_vex")
13165    (set_attr "mode" "<MODE>")])
13166
13167 (define_insn "*fop_<mode>_1_mixed"
13168   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
13169         (match_operator:MODEF 3 "binary_fp_operator"
13170           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
13171            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
13172   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13173    && !COMMUTATIVE_ARITH_P (operands[3])
13174    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13175   "* return output_387_binary_op (insn, operands);"
13176   [(set (attr "type")
13177         (cond [(and (eq_attr "alternative" "2")
13178                     (match_operand:MODEF 3 "mult_operator" ""))
13179                  (const_string "ssemul")
13180                (and (eq_attr "alternative" "2")
13181                     (match_operand:MODEF 3 "div_operator" ""))
13182                  (const_string "ssediv")
13183                (eq_attr "alternative" "2")
13184                  (const_string "sseadd")
13185                (match_operand:MODEF 3 "mult_operator" "")
13186                  (const_string "fmul")
13187                (match_operand:MODEF 3 "div_operator" "")
13188                  (const_string "fdiv")
13189               ]
13190               (const_string "fop")))
13191    (set_attr "mode" "<MODE>")])
13192
13193 (define_insn "*rcpsf2_sse"
13194   [(set (match_operand:SF 0 "register_operand" "=x")
13195         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13196                    UNSPEC_RCP))]
13197   "TARGET_SSE_MATH"
13198   "%vrcpss\t{%1, %d0|%d0, %1}"
13199   [(set_attr "type" "sse")
13200    (set_attr "atom_sse_attr" "rcp")
13201    (set_attr "prefix" "maybe_vex")
13202    (set_attr "mode" "SF")])
13203
13204 (define_insn "*fop_<mode>_1_avx"
13205   [(set (match_operand:MODEF 0 "register_operand" "=x")
13206         (match_operator:MODEF 3 "binary_fp_operator"
13207           [(match_operand:MODEF 1 "register_operand" "x")
13208            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
13209   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13210    && !COMMUTATIVE_ARITH_P (operands[3])"
13211   "* return output_387_binary_op (insn, operands);"
13212   [(set (attr "type")
13213         (cond [(match_operand:MODEF 3 "mult_operator" "")
13214                  (const_string "ssemul")
13215                (match_operand:MODEF 3 "div_operator" "")
13216                  (const_string "ssediv")
13217               ]
13218               (const_string "sseadd")))
13219    (set_attr "prefix" "vex")
13220    (set_attr "mode" "<MODE>")])
13221
13222 (define_insn "*fop_<mode>_1_sse"
13223   [(set (match_operand:MODEF 0 "register_operand" "=x")
13224         (match_operator:MODEF 3 "binary_fp_operator"
13225           [(match_operand:MODEF 1 "register_operand" "0")
13226            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
13227   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13228    && !COMMUTATIVE_ARITH_P (operands[3])"
13229   "* return output_387_binary_op (insn, operands);"
13230   [(set (attr "type")
13231         (cond [(match_operand:MODEF 3 "mult_operator" "")
13232                  (const_string "ssemul")
13233                (match_operand:MODEF 3 "div_operator" "")
13234                  (const_string "ssediv")
13235               ]
13236               (const_string "sseadd")))
13237    (set_attr "mode" "<MODE>")])
13238
13239 ;; This pattern is not fully shadowed by the pattern above.
13240 (define_insn "*fop_<mode>_1_i387"
13241   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13242         (match_operator:MODEF 3 "binary_fp_operator"
13243           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13244            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13245   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13246    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13247    && !COMMUTATIVE_ARITH_P (operands[3])
13248    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13249   "* return output_387_binary_op (insn, operands);"
13250   [(set (attr "type")
13251         (cond [(match_operand:MODEF 3 "mult_operator" "")
13252                  (const_string "fmul")
13253                (match_operand:MODEF 3 "div_operator" "")
13254                  (const_string "fdiv")
13255               ]
13256               (const_string "fop")))
13257    (set_attr "mode" "<MODE>")])
13258
13259 ;; ??? Add SSE splitters for these!
13260 (define_insn "*fop_<MODEF:mode>_2_i387"
13261   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13262         (match_operator:MODEF 3 "binary_fp_operator"
13263           [(float:MODEF
13264              (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
13265            (match_operand:MODEF 2 "register_operand" "0,0")]))]
13266   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
13267    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13268    && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13269   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13270   [(set (attr "type")
13271         (cond [(match_operand:MODEF 3 "mult_operator" "")
13272                  (const_string "fmul")
13273                (match_operand:MODEF 3 "div_operator" "")
13274                  (const_string "fdiv")
13275               ]
13276               (const_string "fop")))
13277    (set_attr "fp_int_src" "true")
13278    (set_attr "mode" "<X87MODEI12:MODE>")])
13279
13280 (define_insn "*fop_<MODEF:mode>_3_i387"
13281   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13282         (match_operator:MODEF 3 "binary_fp_operator"
13283           [(match_operand:MODEF 1 "register_operand" "0,0")
13284            (float:MODEF
13285              (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
13286   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
13287    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13288    && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13289   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13290   [(set (attr "type")
13291         (cond [(match_operand:MODEF 3 "mult_operator" "")
13292                  (const_string "fmul")
13293                (match_operand:MODEF 3 "div_operator" "")
13294                  (const_string "fdiv")
13295               ]
13296               (const_string "fop")))
13297    (set_attr "fp_int_src" "true")
13298    (set_attr "mode" "<MODE>")])
13299
13300 (define_insn "*fop_df_4_i387"
13301   [(set (match_operand:DF 0 "register_operand" "=f,f")
13302         (match_operator:DF 3 "binary_fp_operator"
13303            [(float_extend:DF
13304              (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13305             (match_operand:DF 2 "register_operand" "0,f")]))]
13306   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13307    && !(TARGET_SSE2 && TARGET_SSE_MATH)
13308    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13309   "* return output_387_binary_op (insn, operands);"
13310   [(set (attr "type")
13311         (cond [(match_operand:DF 3 "mult_operator" "")
13312                  (const_string "fmul")
13313                (match_operand:DF 3 "div_operator" "")
13314                  (const_string "fdiv")
13315               ]
13316               (const_string "fop")))
13317    (set_attr "mode" "SF")])
13318
13319 (define_insn "*fop_df_5_i387"
13320   [(set (match_operand:DF 0 "register_operand" "=f,f")
13321         (match_operator:DF 3 "binary_fp_operator"
13322           [(match_operand:DF 1 "register_operand" "0,f")
13323            (float_extend:DF
13324             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13325   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13326    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13327   "* return output_387_binary_op (insn, operands);"
13328   [(set (attr "type")
13329         (cond [(match_operand:DF 3 "mult_operator" "")
13330                  (const_string "fmul")
13331                (match_operand:DF 3 "div_operator" "")
13332                  (const_string "fdiv")
13333               ]
13334               (const_string "fop")))
13335    (set_attr "mode" "SF")])
13336
13337 (define_insn "*fop_df_6_i387"
13338   [(set (match_operand:DF 0 "register_operand" "=f,f")
13339         (match_operator:DF 3 "binary_fp_operator"
13340           [(float_extend:DF
13341             (match_operand:SF 1 "register_operand" "0,f"))
13342            (float_extend:DF
13343             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13344   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13345    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13346   "* return output_387_binary_op (insn, operands);"
13347   [(set (attr "type")
13348         (cond [(match_operand:DF 3 "mult_operator" "")
13349                  (const_string "fmul")
13350                (match_operand:DF 3 "div_operator" "")
13351                  (const_string "fdiv")
13352               ]
13353               (const_string "fop")))
13354    (set_attr "mode" "SF")])
13355
13356 (define_insn "*fop_xf_comm_i387"
13357   [(set (match_operand:XF 0 "register_operand" "=f")
13358         (match_operator:XF 3 "binary_fp_operator"
13359                         [(match_operand:XF 1 "register_operand" "%0")
13360                          (match_operand:XF 2 "register_operand" "f")]))]
13361   "TARGET_80387
13362    && COMMUTATIVE_ARITH_P (operands[3])"
13363   "* return output_387_binary_op (insn, operands);"
13364   [(set (attr "type")
13365         (if_then_else (match_operand:XF 3 "mult_operator" "")
13366            (const_string "fmul")
13367            (const_string "fop")))
13368    (set_attr "mode" "XF")])
13369
13370 (define_insn "*fop_xf_1_i387"
13371   [(set (match_operand:XF 0 "register_operand" "=f,f")
13372         (match_operator:XF 3 "binary_fp_operator"
13373                         [(match_operand:XF 1 "register_operand" "0,f")
13374                          (match_operand:XF 2 "register_operand" "f,0")]))]
13375   "TARGET_80387
13376    && !COMMUTATIVE_ARITH_P (operands[3])"
13377   "* return output_387_binary_op (insn, operands);"
13378   [(set (attr "type")
13379         (cond [(match_operand:XF 3 "mult_operator" "")
13380                  (const_string "fmul")
13381                (match_operand:XF 3 "div_operator" "")
13382                  (const_string "fdiv")
13383               ]
13384               (const_string "fop")))
13385    (set_attr "mode" "XF")])
13386
13387 (define_insn "*fop_xf_2_i387"
13388   [(set (match_operand:XF 0 "register_operand" "=f,f")
13389         (match_operator:XF 3 "binary_fp_operator"
13390           [(float:XF
13391              (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
13392            (match_operand:XF 2 "register_operand" "0,0")]))]
13393   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13394   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13395   [(set (attr "type")
13396         (cond [(match_operand:XF 3 "mult_operator" "")
13397                  (const_string "fmul")
13398                (match_operand:XF 3 "div_operator" "")
13399                  (const_string "fdiv")
13400               ]
13401               (const_string "fop")))
13402    (set_attr "fp_int_src" "true")
13403    (set_attr "mode" "<MODE>")])
13404
13405 (define_insn "*fop_xf_3_i387"
13406   [(set (match_operand:XF 0 "register_operand" "=f,f")
13407         (match_operator:XF 3 "binary_fp_operator"
13408           [(match_operand:XF 1 "register_operand" "0,0")
13409            (float:XF
13410              (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
13411   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13412   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13413   [(set (attr "type")
13414         (cond [(match_operand:XF 3 "mult_operator" "")
13415                  (const_string "fmul")
13416                (match_operand:XF 3 "div_operator" "")
13417                  (const_string "fdiv")
13418               ]
13419               (const_string "fop")))
13420    (set_attr "fp_int_src" "true")
13421    (set_attr "mode" "<MODE>")])
13422
13423 (define_insn "*fop_xf_4_i387"
13424   [(set (match_operand:XF 0 "register_operand" "=f,f")
13425         (match_operator:XF 3 "binary_fp_operator"
13426            [(float_extend:XF
13427               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13428             (match_operand:XF 2 "register_operand" "0,f")]))]
13429   "TARGET_80387"
13430   "* return output_387_binary_op (insn, operands);"
13431   [(set (attr "type")
13432         (cond [(match_operand:XF 3 "mult_operator" "")
13433                  (const_string "fmul")
13434                (match_operand:XF 3 "div_operator" "")
13435                  (const_string "fdiv")
13436               ]
13437               (const_string "fop")))
13438    (set_attr "mode" "<MODE>")])
13439
13440 (define_insn "*fop_xf_5_i387"
13441   [(set (match_operand:XF 0 "register_operand" "=f,f")
13442         (match_operator:XF 3 "binary_fp_operator"
13443           [(match_operand:XF 1 "register_operand" "0,f")
13444            (float_extend:XF
13445              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13446   "TARGET_80387"
13447   "* return output_387_binary_op (insn, operands);"
13448   [(set (attr "type")
13449         (cond [(match_operand:XF 3 "mult_operator" "")
13450                  (const_string "fmul")
13451                (match_operand:XF 3 "div_operator" "")
13452                  (const_string "fdiv")
13453               ]
13454               (const_string "fop")))
13455    (set_attr "mode" "<MODE>")])
13456
13457 (define_insn "*fop_xf_6_i387"
13458   [(set (match_operand:XF 0 "register_operand" "=f,f")
13459         (match_operator:XF 3 "binary_fp_operator"
13460           [(float_extend:XF
13461              (match_operand:MODEF 1 "register_operand" "0,f"))
13462            (float_extend:XF
13463              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13464   "TARGET_80387"
13465   "* return output_387_binary_op (insn, operands);"
13466   [(set (attr "type")
13467         (cond [(match_operand:XF 3 "mult_operator" "")
13468                  (const_string "fmul")
13469                (match_operand:XF 3 "div_operator" "")
13470                  (const_string "fdiv")
13471               ]
13472               (const_string "fop")))
13473    (set_attr "mode" "<MODE>")])
13474
13475 (define_split
13476   [(set (match_operand 0 "register_operand" "")
13477         (match_operator 3 "binary_fp_operator"
13478            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
13479             (match_operand 2 "register_operand" "")]))]
13480   "reload_completed
13481    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13482    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13483   [(const_int 0)]
13484 {
13485   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13486   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13487   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13488                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
13489                                           GET_MODE (operands[3]),
13490                                           operands[4],
13491                                           operands[2])));
13492   ix86_free_from_memory (GET_MODE (operands[1]));
13493   DONE;
13494 })
13495
13496 (define_split
13497   [(set (match_operand 0 "register_operand" "")
13498         (match_operator 3 "binary_fp_operator"
13499            [(match_operand 1 "register_operand" "")
13500             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
13501   "reload_completed
13502    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13503    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13504   [(const_int 0)]
13505 {
13506   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13507   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13508   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13509                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
13510                                           GET_MODE (operands[3]),
13511                                           operands[1],
13512                                           operands[4])));
13513   ix86_free_from_memory (GET_MODE (operands[2]));
13514   DONE;
13515 })
13516 \f
13517 ;; FPU special functions.
13518
13519 ;; This pattern implements a no-op XFmode truncation for
13520 ;; all fancy i386 XFmode math functions.
13521
13522 (define_insn "truncxf<mode>2_i387_noop_unspec"
13523   [(set (match_operand:MODEF 0 "register_operand" "=f")
13524         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13525         UNSPEC_TRUNC_NOOP))]
13526   "TARGET_USE_FANCY_MATH_387"
13527   "* return output_387_reg_move (insn, operands);"
13528   [(set_attr "type" "fmov")
13529    (set_attr "mode" "<MODE>")])
13530
13531 (define_insn "sqrtxf2"
13532   [(set (match_operand:XF 0 "register_operand" "=f")
13533         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13534   "TARGET_USE_FANCY_MATH_387"
13535   "fsqrt"
13536   [(set_attr "type" "fpspc")
13537    (set_attr "mode" "XF")
13538    (set_attr "athlon_decode" "direct")
13539    (set_attr "amdfam10_decode" "direct")])
13540
13541 (define_insn "sqrt_extend<mode>xf2_i387"
13542   [(set (match_operand:XF 0 "register_operand" "=f")
13543         (sqrt:XF
13544           (float_extend:XF
13545             (match_operand:MODEF 1 "register_operand" "0"))))]
13546   "TARGET_USE_FANCY_MATH_387"
13547   "fsqrt"
13548   [(set_attr "type" "fpspc")
13549    (set_attr "mode" "XF")
13550    (set_attr "athlon_decode" "direct")
13551    (set_attr "amdfam10_decode" "direct")])
13552
13553 (define_insn "*rsqrtsf2_sse"
13554   [(set (match_operand:SF 0 "register_operand" "=x")
13555         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13556                    UNSPEC_RSQRT))]
13557   "TARGET_SSE_MATH"
13558   "%vrsqrtss\t{%1, %d0|%d0, %1}"
13559   [(set_attr "type" "sse")
13560    (set_attr "atom_sse_attr" "rcp")
13561    (set_attr "prefix" "maybe_vex")
13562    (set_attr "mode" "SF")])
13563
13564 (define_expand "rsqrtsf2"
13565   [(set (match_operand:SF 0 "register_operand" "")
13566         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
13567                    UNSPEC_RSQRT))]
13568   "TARGET_SSE_MATH"
13569 {
13570   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13571   DONE;
13572 })
13573
13574 (define_insn "*sqrt<mode>2_sse"
13575   [(set (match_operand:MODEF 0 "register_operand" "=x")
13576         (sqrt:MODEF
13577           (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13578   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13579   "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}"
13580   [(set_attr "type" "sse")
13581    (set_attr "atom_sse_attr" "sqrt")
13582    (set_attr "prefix" "maybe_vex")
13583    (set_attr "mode" "<MODE>")
13584    (set_attr "athlon_decode" "*")
13585    (set_attr "amdfam10_decode" "*")])
13586
13587 (define_expand "sqrt<mode>2"
13588   [(set (match_operand:MODEF 0 "register_operand" "")
13589         (sqrt:MODEF
13590           (match_operand:MODEF 1 "nonimmediate_operand" "")))]
13591   "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13592    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13593 {
13594   if (<MODE>mode == SFmode
13595       && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
13596       && flag_finite_math_only && !flag_trapping_math
13597       && flag_unsafe_math_optimizations)
13598     {
13599       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13600       DONE;
13601     }
13602
13603   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13604     {
13605       rtx op0 = gen_reg_rtx (XFmode);
13606       rtx op1 = force_reg (<MODE>mode, operands[1]);
13607
13608       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13609       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13610       DONE;
13611    }
13612 })
13613
13614 (define_insn "fpremxf4_i387"
13615   [(set (match_operand:XF 0 "register_operand" "=f")
13616         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13617                     (match_operand:XF 3 "register_operand" "1")]
13618                    UNSPEC_FPREM_F))
13619    (set (match_operand:XF 1 "register_operand" "=u")
13620         (unspec:XF [(match_dup 2) (match_dup 3)]
13621                    UNSPEC_FPREM_U))
13622    (set (reg:CCFP FPSR_REG)
13623         (unspec:CCFP [(match_dup 2) (match_dup 3)]
13624                      UNSPEC_C2_FLAG))]
13625   "TARGET_USE_FANCY_MATH_387"
13626   "fprem"
13627   [(set_attr "type" "fpspc")
13628    (set_attr "mode" "XF")])
13629
13630 (define_expand "fmodxf3"
13631   [(use (match_operand:XF 0 "register_operand" ""))
13632    (use (match_operand:XF 1 "general_operand" ""))
13633    (use (match_operand:XF 2 "general_operand" ""))]
13634   "TARGET_USE_FANCY_MATH_387"
13635 {
13636   rtx label = gen_label_rtx ();
13637
13638   rtx op1 = gen_reg_rtx (XFmode);
13639   rtx op2 = gen_reg_rtx (XFmode);
13640
13641   emit_move_insn (op2, operands[2]);
13642   emit_move_insn (op1, operands[1]);
13643
13644   emit_label (label);
13645   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13646   ix86_emit_fp_unordered_jump (label);
13647   LABEL_NUSES (label) = 1;
13648
13649   emit_move_insn (operands[0], op1);
13650   DONE;
13651 })
13652
13653 (define_expand "fmod<mode>3"
13654   [(use (match_operand:MODEF 0 "register_operand" ""))
13655    (use (match_operand:MODEF 1 "general_operand" ""))
13656    (use (match_operand:MODEF 2 "general_operand" ""))]
13657   "TARGET_USE_FANCY_MATH_387"
13658 {
13659   rtx label = gen_label_rtx ();
13660
13661   rtx op1 = gen_reg_rtx (XFmode);
13662   rtx op2 = gen_reg_rtx (XFmode);
13663
13664   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13665   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13666
13667   emit_label (label);
13668   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13669   ix86_emit_fp_unordered_jump (label);
13670   LABEL_NUSES (label) = 1;
13671
13672   /* Truncate the result properly for strict SSE math.  */
13673   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13674       && !TARGET_MIX_SSE_I387)
13675     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
13676   else
13677     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
13678
13679   DONE;
13680 })
13681
13682 (define_insn "fprem1xf4_i387"
13683   [(set (match_operand:XF 0 "register_operand" "=f")
13684         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13685                     (match_operand:XF 3 "register_operand" "1")]
13686                    UNSPEC_FPREM1_F))
13687    (set (match_operand:XF 1 "register_operand" "=u")
13688         (unspec:XF [(match_dup 2) (match_dup 3)]
13689                    UNSPEC_FPREM1_U))
13690    (set (reg:CCFP FPSR_REG)
13691         (unspec:CCFP [(match_dup 2) (match_dup 3)]
13692                      UNSPEC_C2_FLAG))]
13693   "TARGET_USE_FANCY_MATH_387"
13694   "fprem1"
13695   [(set_attr "type" "fpspc")
13696    (set_attr "mode" "XF")])
13697
13698 (define_expand "remainderxf3"
13699   [(use (match_operand:XF 0 "register_operand" ""))
13700    (use (match_operand:XF 1 "general_operand" ""))
13701    (use (match_operand:XF 2 "general_operand" ""))]
13702   "TARGET_USE_FANCY_MATH_387"
13703 {
13704   rtx label = gen_label_rtx ();
13705
13706   rtx op1 = gen_reg_rtx (XFmode);
13707   rtx op2 = gen_reg_rtx (XFmode);
13708
13709   emit_move_insn (op2, operands[2]);
13710   emit_move_insn (op1, operands[1]);
13711
13712   emit_label (label);
13713   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13714   ix86_emit_fp_unordered_jump (label);
13715   LABEL_NUSES (label) = 1;
13716
13717   emit_move_insn (operands[0], op1);
13718   DONE;
13719 })
13720
13721 (define_expand "remainder<mode>3"
13722   [(use (match_operand:MODEF 0 "register_operand" ""))
13723    (use (match_operand:MODEF 1 "general_operand" ""))
13724    (use (match_operand:MODEF 2 "general_operand" ""))]
13725   "TARGET_USE_FANCY_MATH_387"
13726 {
13727   rtx label = gen_label_rtx ();
13728
13729   rtx op1 = gen_reg_rtx (XFmode);
13730   rtx op2 = gen_reg_rtx (XFmode);
13731
13732   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13733   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13734
13735   emit_label (label);
13736
13737   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13738   ix86_emit_fp_unordered_jump (label);
13739   LABEL_NUSES (label) = 1;
13740
13741   /* Truncate the result properly for strict SSE math.  */
13742   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13743       && !TARGET_MIX_SSE_I387)
13744     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
13745   else
13746     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
13747
13748   DONE;
13749 })
13750
13751 (define_insn "*sinxf2_i387"
13752   [(set (match_operand:XF 0 "register_operand" "=f")
13753         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13754   "TARGET_USE_FANCY_MATH_387
13755    && flag_unsafe_math_optimizations"
13756   "fsin"
13757   [(set_attr "type" "fpspc")
13758    (set_attr "mode" "XF")])
13759
13760 (define_insn "*sin_extend<mode>xf2_i387"
13761   [(set (match_operand:XF 0 "register_operand" "=f")
13762         (unspec:XF [(float_extend:XF
13763                       (match_operand:MODEF 1 "register_operand" "0"))]
13764                    UNSPEC_SIN))]
13765   "TARGET_USE_FANCY_MATH_387
13766    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13767        || TARGET_MIX_SSE_I387)
13768    && flag_unsafe_math_optimizations"
13769   "fsin"
13770   [(set_attr "type" "fpspc")
13771    (set_attr "mode" "XF")])
13772
13773 (define_insn "*cosxf2_i387"
13774   [(set (match_operand:XF 0 "register_operand" "=f")
13775         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13776   "TARGET_USE_FANCY_MATH_387
13777    && flag_unsafe_math_optimizations"
13778   "fcos"
13779   [(set_attr "type" "fpspc")
13780    (set_attr "mode" "XF")])
13781
13782 (define_insn "*cos_extend<mode>xf2_i387"
13783   [(set (match_operand:XF 0 "register_operand" "=f")
13784         (unspec:XF [(float_extend:XF
13785                       (match_operand:MODEF 1 "register_operand" "0"))]
13786                    UNSPEC_COS))]
13787   "TARGET_USE_FANCY_MATH_387
13788    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13789        || TARGET_MIX_SSE_I387)
13790    && flag_unsafe_math_optimizations"
13791   "fcos"
13792   [(set_attr "type" "fpspc")
13793    (set_attr "mode" "XF")])
13794
13795 ;; When sincos pattern is defined, sin and cos builtin functions will be
13796 ;; expanded to sincos pattern with one of its outputs left unused.
13797 ;; CSE pass will figure out if two sincos patterns can be combined,
13798 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13799 ;; depending on the unused output.
13800
13801 (define_insn "sincosxf3"
13802   [(set (match_operand:XF 0 "register_operand" "=f")
13803         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13804                    UNSPEC_SINCOS_COS))
13805    (set (match_operand:XF 1 "register_operand" "=u")
13806         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13807   "TARGET_USE_FANCY_MATH_387
13808    && flag_unsafe_math_optimizations"
13809   "fsincos"
13810   [(set_attr "type" "fpspc")
13811    (set_attr "mode" "XF")])
13812
13813 (define_split
13814   [(set (match_operand:XF 0 "register_operand" "")
13815         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13816                    UNSPEC_SINCOS_COS))
13817    (set (match_operand:XF 1 "register_operand" "")
13818         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13819   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13820    && !(reload_completed || reload_in_progress)"
13821   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
13822   "")
13823
13824 (define_split
13825   [(set (match_operand:XF 0 "register_operand" "")
13826         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13827                    UNSPEC_SINCOS_COS))
13828    (set (match_operand:XF 1 "register_operand" "")
13829         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13830   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13831    && !(reload_completed || reload_in_progress)"
13832   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
13833   "")
13834
13835 (define_insn "sincos_extend<mode>xf3_i387"
13836   [(set (match_operand:XF 0 "register_operand" "=f")
13837         (unspec:XF [(float_extend:XF
13838                       (match_operand:MODEF 2 "register_operand" "0"))]
13839                    UNSPEC_SINCOS_COS))
13840    (set (match_operand:XF 1 "register_operand" "=u")
13841         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13842   "TARGET_USE_FANCY_MATH_387
13843    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13844        || TARGET_MIX_SSE_I387)
13845    && flag_unsafe_math_optimizations"
13846   "fsincos"
13847   [(set_attr "type" "fpspc")
13848    (set_attr "mode" "XF")])
13849
13850 (define_split
13851   [(set (match_operand:XF 0 "register_operand" "")
13852         (unspec:XF [(float_extend:XF
13853                       (match_operand:MODEF 2 "register_operand" ""))]
13854                    UNSPEC_SINCOS_COS))
13855    (set (match_operand:XF 1 "register_operand" "")
13856         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13857   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13858    && !(reload_completed || reload_in_progress)"
13859   [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
13860   "")
13861
13862 (define_split
13863   [(set (match_operand:XF 0 "register_operand" "")
13864         (unspec:XF [(float_extend:XF
13865                       (match_operand:MODEF 2 "register_operand" ""))]
13866                    UNSPEC_SINCOS_COS))
13867    (set (match_operand:XF 1 "register_operand" "")
13868         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13869   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13870    && !(reload_completed || reload_in_progress)"
13871   [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
13872   "")
13873
13874 (define_expand "sincos<mode>3"
13875   [(use (match_operand:MODEF 0 "register_operand" ""))
13876    (use (match_operand:MODEF 1 "register_operand" ""))
13877    (use (match_operand:MODEF 2 "register_operand" ""))]
13878   "TARGET_USE_FANCY_MATH_387
13879    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13880        || TARGET_MIX_SSE_I387)
13881    && flag_unsafe_math_optimizations"
13882 {
13883   rtx op0 = gen_reg_rtx (XFmode);
13884   rtx op1 = gen_reg_rtx (XFmode);
13885
13886   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13887   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13888   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13889   DONE;
13890 })
13891
13892 (define_insn "fptanxf4_i387"
13893   [(set (match_operand:XF 0 "register_operand" "=f")
13894         (match_operand:XF 3 "const_double_operand" "F"))
13895    (set (match_operand:XF 1 "register_operand" "=u")
13896         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13897                    UNSPEC_TAN))]
13898   "TARGET_USE_FANCY_MATH_387
13899    && flag_unsafe_math_optimizations
13900    && standard_80387_constant_p (operands[3]) == 2"
13901   "fptan"
13902   [(set_attr "type" "fpspc")
13903    (set_attr "mode" "XF")])
13904
13905 (define_insn "fptan_extend<mode>xf4_i387"
13906   [(set (match_operand:MODEF 0 "register_operand" "=f")
13907         (match_operand:MODEF 3 "const_double_operand" "F"))
13908    (set (match_operand:XF 1 "register_operand" "=u")
13909         (unspec:XF [(float_extend:XF
13910                       (match_operand:MODEF 2 "register_operand" "0"))]
13911                    UNSPEC_TAN))]
13912   "TARGET_USE_FANCY_MATH_387
13913    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13914        || TARGET_MIX_SSE_I387)
13915    && flag_unsafe_math_optimizations
13916    && standard_80387_constant_p (operands[3]) == 2"
13917   "fptan"
13918   [(set_attr "type" "fpspc")
13919    (set_attr "mode" "XF")])
13920
13921 (define_expand "tanxf2"
13922   [(use (match_operand:XF 0 "register_operand" ""))
13923    (use (match_operand:XF 1 "register_operand" ""))]
13924   "TARGET_USE_FANCY_MATH_387
13925    && flag_unsafe_math_optimizations"
13926 {
13927   rtx one = gen_reg_rtx (XFmode);
13928   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13929
13930   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13931   DONE;
13932 })
13933
13934 (define_expand "tan<mode>2"
13935   [(use (match_operand:MODEF 0 "register_operand" ""))
13936    (use (match_operand:MODEF 1 "register_operand" ""))]
13937   "TARGET_USE_FANCY_MATH_387
13938    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13939        || TARGET_MIX_SSE_I387)
13940    && flag_unsafe_math_optimizations"
13941 {
13942   rtx op0 = gen_reg_rtx (XFmode);
13943
13944   rtx one = gen_reg_rtx (<MODE>mode);
13945   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13946
13947   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13948                                              operands[1], op2));
13949   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13950   DONE;
13951 })
13952
13953 (define_insn "*fpatanxf3_i387"
13954   [(set (match_operand:XF 0 "register_operand" "=f")
13955         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13956                     (match_operand:XF 2 "register_operand" "u")]
13957                    UNSPEC_FPATAN))
13958    (clobber (match_scratch:XF 3 "=2"))]
13959   "TARGET_USE_FANCY_MATH_387
13960    && flag_unsafe_math_optimizations"
13961   "fpatan"
13962   [(set_attr "type" "fpspc")
13963    (set_attr "mode" "XF")])
13964
13965 (define_insn "fpatan_extend<mode>xf3_i387"
13966   [(set (match_operand:XF 0 "register_operand" "=f")
13967         (unspec:XF [(float_extend:XF
13968                       (match_operand:MODEF 1 "register_operand" "0"))
13969                     (float_extend:XF
13970                       (match_operand:MODEF 2 "register_operand" "u"))]
13971                    UNSPEC_FPATAN))
13972    (clobber (match_scratch:XF 3 "=2"))]
13973   "TARGET_USE_FANCY_MATH_387
13974    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13975        || TARGET_MIX_SSE_I387)
13976    && flag_unsafe_math_optimizations"
13977   "fpatan"
13978   [(set_attr "type" "fpspc")
13979    (set_attr "mode" "XF")])
13980
13981 (define_expand "atan2xf3"
13982   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13983                    (unspec:XF [(match_operand:XF 2 "register_operand" "")
13984                                (match_operand:XF 1 "register_operand" "")]
13985                               UNSPEC_FPATAN))
13986               (clobber (match_scratch:XF 3 ""))])]
13987   "TARGET_USE_FANCY_MATH_387
13988    && flag_unsafe_math_optimizations"
13989   "")
13990
13991 (define_expand "atan2<mode>3"
13992   [(use (match_operand:MODEF 0 "register_operand" ""))
13993    (use (match_operand:MODEF 1 "register_operand" ""))
13994    (use (match_operand:MODEF 2 "register_operand" ""))]
13995   "TARGET_USE_FANCY_MATH_387
13996    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13997        || TARGET_MIX_SSE_I387)
13998    && flag_unsafe_math_optimizations"
13999 {
14000   rtx op0 = gen_reg_rtx (XFmode);
14001
14002   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
14003   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14004   DONE;
14005 })
14006
14007 (define_expand "atanxf2"
14008   [(parallel [(set (match_operand:XF 0 "register_operand" "")
14009                    (unspec:XF [(match_dup 2)
14010                                (match_operand:XF 1 "register_operand" "")]
14011                               UNSPEC_FPATAN))
14012               (clobber (match_scratch:XF 3 ""))])]
14013   "TARGET_USE_FANCY_MATH_387
14014    && flag_unsafe_math_optimizations"
14015 {
14016   operands[2] = gen_reg_rtx (XFmode);
14017   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
14018 })
14019
14020 (define_expand "atan<mode>2"
14021   [(use (match_operand:MODEF 0 "register_operand" ""))
14022    (use (match_operand:MODEF 1 "register_operand" ""))]
14023   "TARGET_USE_FANCY_MATH_387
14024    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14025        || TARGET_MIX_SSE_I387)
14026    && flag_unsafe_math_optimizations"
14027 {
14028   rtx op0 = gen_reg_rtx (XFmode);
14029
14030   rtx op2 = gen_reg_rtx (<MODE>mode);
14031   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
14032
14033   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
14034   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14035   DONE;
14036 })
14037
14038 (define_expand "asinxf2"
14039   [(set (match_dup 2)
14040         (mult:XF (match_operand:XF 1 "register_operand" "")
14041                  (match_dup 1)))
14042    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14043    (set (match_dup 5) (sqrt:XF (match_dup 4)))
14044    (parallel [(set (match_operand:XF 0 "register_operand" "")
14045                    (unspec:XF [(match_dup 5) (match_dup 1)]
14046                               UNSPEC_FPATAN))
14047               (clobber (match_scratch:XF 6 ""))])]
14048   "TARGET_USE_FANCY_MATH_387
14049    && flag_unsafe_math_optimizations"
14050 {
14051   int i;
14052
14053   if (optimize_insn_for_size_p ())
14054     FAIL;
14055
14056   for (i = 2; i < 6; i++)
14057     operands[i] = gen_reg_rtx (XFmode);
14058
14059   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
14060 })
14061
14062 (define_expand "asin<mode>2"
14063   [(use (match_operand:MODEF 0 "register_operand" ""))
14064    (use (match_operand:MODEF 1 "general_operand" ""))]
14065  "TARGET_USE_FANCY_MATH_387
14066    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14067        || TARGET_MIX_SSE_I387)
14068    && flag_unsafe_math_optimizations"
14069 {
14070   rtx op0 = gen_reg_rtx (XFmode);
14071   rtx op1 = gen_reg_rtx (XFmode);
14072
14073   if (optimize_insn_for_size_p ())
14074     FAIL;
14075
14076   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14077   emit_insn (gen_asinxf2 (op0, op1));
14078   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14079   DONE;
14080 })
14081
14082 (define_expand "acosxf2"
14083   [(set (match_dup 2)
14084         (mult:XF (match_operand:XF 1 "register_operand" "")
14085                  (match_dup 1)))
14086    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14087    (set (match_dup 5) (sqrt:XF (match_dup 4)))
14088    (parallel [(set (match_operand:XF 0 "register_operand" "")
14089                    (unspec:XF [(match_dup 1) (match_dup 5)]
14090                               UNSPEC_FPATAN))
14091               (clobber (match_scratch:XF 6 ""))])]
14092   "TARGET_USE_FANCY_MATH_387
14093    && flag_unsafe_math_optimizations"
14094 {
14095   int i;
14096
14097   if (optimize_insn_for_size_p ())
14098     FAIL;
14099
14100   for (i = 2; i < 6; i++)
14101     operands[i] = gen_reg_rtx (XFmode);
14102
14103   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
14104 })
14105
14106 (define_expand "acos<mode>2"
14107   [(use (match_operand:MODEF 0 "register_operand" ""))
14108    (use (match_operand:MODEF 1 "general_operand" ""))]
14109  "TARGET_USE_FANCY_MATH_387
14110    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14111        || TARGET_MIX_SSE_I387)
14112    && flag_unsafe_math_optimizations"
14113 {
14114   rtx op0 = gen_reg_rtx (XFmode);
14115   rtx op1 = gen_reg_rtx (XFmode);
14116
14117   if (optimize_insn_for_size_p ())
14118     FAIL;
14119
14120   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14121   emit_insn (gen_acosxf2 (op0, op1));
14122   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14123   DONE;
14124 })
14125
14126 (define_insn "fyl2xxf3_i387"
14127   [(set (match_operand:XF 0 "register_operand" "=f")
14128         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14129                     (match_operand:XF 2 "register_operand" "u")]
14130                    UNSPEC_FYL2X))
14131    (clobber (match_scratch:XF 3 "=2"))]
14132   "TARGET_USE_FANCY_MATH_387
14133    && flag_unsafe_math_optimizations"
14134   "fyl2x"
14135   [(set_attr "type" "fpspc")
14136    (set_attr "mode" "XF")])
14137
14138 (define_insn "fyl2x_extend<mode>xf3_i387"
14139   [(set (match_operand:XF 0 "register_operand" "=f")
14140         (unspec:XF [(float_extend:XF
14141                       (match_operand:MODEF 1 "register_operand" "0"))
14142                     (match_operand:XF 2 "register_operand" "u")]
14143                    UNSPEC_FYL2X))
14144    (clobber (match_scratch:XF 3 "=2"))]
14145   "TARGET_USE_FANCY_MATH_387
14146    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14147        || TARGET_MIX_SSE_I387)
14148    && flag_unsafe_math_optimizations"
14149   "fyl2x"
14150   [(set_attr "type" "fpspc")
14151    (set_attr "mode" "XF")])
14152
14153 (define_expand "logxf2"
14154   [(parallel [(set (match_operand:XF 0 "register_operand" "")
14155                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
14156                                (match_dup 2)] UNSPEC_FYL2X))
14157               (clobber (match_scratch:XF 3 ""))])]
14158   "TARGET_USE_FANCY_MATH_387
14159    && flag_unsafe_math_optimizations"
14160 {
14161   operands[2] = gen_reg_rtx (XFmode);
14162   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
14163 })
14164
14165 (define_expand "log<mode>2"
14166   [(use (match_operand:MODEF 0 "register_operand" ""))
14167    (use (match_operand:MODEF 1 "register_operand" ""))]
14168   "TARGET_USE_FANCY_MATH_387
14169    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14170        || TARGET_MIX_SSE_I387)
14171    && flag_unsafe_math_optimizations"
14172 {
14173   rtx op0 = gen_reg_rtx (XFmode);
14174
14175   rtx op2 = gen_reg_rtx (XFmode);
14176   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
14177
14178   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14179   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14180   DONE;
14181 })
14182
14183 (define_expand "log10xf2"
14184   [(parallel [(set (match_operand:XF 0 "register_operand" "")
14185                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
14186                                (match_dup 2)] UNSPEC_FYL2X))
14187               (clobber (match_scratch:XF 3 ""))])]
14188   "TARGET_USE_FANCY_MATH_387
14189    && flag_unsafe_math_optimizations"
14190 {
14191   operands[2] = gen_reg_rtx (XFmode);
14192   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14193 })
14194
14195 (define_expand "log10<mode>2"
14196   [(use (match_operand:MODEF 0 "register_operand" ""))
14197    (use (match_operand:MODEF 1 "register_operand" ""))]
14198   "TARGET_USE_FANCY_MATH_387
14199    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14200        || TARGET_MIX_SSE_I387)
14201    && flag_unsafe_math_optimizations"
14202 {
14203   rtx op0 = gen_reg_rtx (XFmode);
14204
14205   rtx op2 = gen_reg_rtx (XFmode);
14206   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14207
14208   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14209   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14210   DONE;
14211 })
14212
14213 (define_expand "log2xf2"
14214   [(parallel [(set (match_operand:XF 0 "register_operand" "")
14215                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
14216                                (match_dup 2)] UNSPEC_FYL2X))
14217               (clobber (match_scratch:XF 3 ""))])]
14218   "TARGET_USE_FANCY_MATH_387
14219    && flag_unsafe_math_optimizations"
14220 {
14221   operands[2] = gen_reg_rtx (XFmode);
14222   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14223 })
14224
14225 (define_expand "log2<mode>2"
14226   [(use (match_operand:MODEF 0 "register_operand" ""))
14227    (use (match_operand:MODEF 1 "register_operand" ""))]
14228   "TARGET_USE_FANCY_MATH_387
14229    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14230        || TARGET_MIX_SSE_I387)
14231    && flag_unsafe_math_optimizations"
14232 {
14233   rtx op0 = gen_reg_rtx (XFmode);
14234
14235   rtx op2 = gen_reg_rtx (XFmode);
14236   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14237
14238   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14239   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14240   DONE;
14241 })
14242
14243 (define_insn "fyl2xp1xf3_i387"
14244   [(set (match_operand:XF 0 "register_operand" "=f")
14245         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14246                     (match_operand:XF 2 "register_operand" "u")]
14247                    UNSPEC_FYL2XP1))
14248    (clobber (match_scratch:XF 3 "=2"))]
14249   "TARGET_USE_FANCY_MATH_387
14250    && flag_unsafe_math_optimizations"
14251   "fyl2xp1"
14252   [(set_attr "type" "fpspc")
14253    (set_attr "mode" "XF")])
14254
14255 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14256   [(set (match_operand:XF 0 "register_operand" "=f")
14257         (unspec:XF [(float_extend:XF
14258                       (match_operand:MODEF 1 "register_operand" "0"))
14259                     (match_operand:XF 2 "register_operand" "u")]
14260                    UNSPEC_FYL2XP1))
14261    (clobber (match_scratch:XF 3 "=2"))]
14262   "TARGET_USE_FANCY_MATH_387
14263    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14264        || TARGET_MIX_SSE_I387)
14265    && flag_unsafe_math_optimizations"
14266   "fyl2xp1"
14267   [(set_attr "type" "fpspc")
14268    (set_attr "mode" "XF")])
14269
14270 (define_expand "log1pxf2"
14271   [(use (match_operand:XF 0 "register_operand" ""))
14272    (use (match_operand:XF 1 "register_operand" ""))]
14273   "TARGET_USE_FANCY_MATH_387
14274    && flag_unsafe_math_optimizations"
14275 {
14276   if (optimize_insn_for_size_p ())
14277     FAIL;
14278
14279   ix86_emit_i387_log1p (operands[0], operands[1]);
14280   DONE;
14281 })
14282
14283 (define_expand "log1p<mode>2"
14284   [(use (match_operand:MODEF 0 "register_operand" ""))
14285    (use (match_operand:MODEF 1 "register_operand" ""))]
14286   "TARGET_USE_FANCY_MATH_387
14287    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14288        || TARGET_MIX_SSE_I387)
14289    && flag_unsafe_math_optimizations"
14290 {
14291   rtx op0;
14292
14293   if (optimize_insn_for_size_p ())
14294     FAIL;
14295
14296   op0 = gen_reg_rtx (XFmode);
14297
14298   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14299
14300   ix86_emit_i387_log1p (op0, operands[1]);
14301   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14302   DONE;
14303 })
14304
14305 (define_insn "fxtractxf3_i387"
14306   [(set (match_operand:XF 0 "register_operand" "=f")
14307         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14308                    UNSPEC_XTRACT_FRACT))
14309    (set (match_operand:XF 1 "register_operand" "=u")
14310         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14311   "TARGET_USE_FANCY_MATH_387
14312    && flag_unsafe_math_optimizations"
14313   "fxtract"
14314   [(set_attr "type" "fpspc")
14315    (set_attr "mode" "XF")])
14316
14317 (define_insn "fxtract_extend<mode>xf3_i387"
14318   [(set (match_operand:XF 0 "register_operand" "=f")
14319         (unspec:XF [(float_extend:XF
14320                       (match_operand:MODEF 2 "register_operand" "0"))]
14321                    UNSPEC_XTRACT_FRACT))
14322    (set (match_operand:XF 1 "register_operand" "=u")
14323         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14324   "TARGET_USE_FANCY_MATH_387
14325    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14326        || TARGET_MIX_SSE_I387)
14327    && flag_unsafe_math_optimizations"
14328   "fxtract"
14329   [(set_attr "type" "fpspc")
14330    (set_attr "mode" "XF")])
14331
14332 (define_expand "logbxf2"
14333   [(parallel [(set (match_dup 2)
14334                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14335                               UNSPEC_XTRACT_FRACT))
14336               (set (match_operand:XF 0 "register_operand" "")
14337                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14338   "TARGET_USE_FANCY_MATH_387
14339    && flag_unsafe_math_optimizations"
14340 {
14341   operands[2] = gen_reg_rtx (XFmode);
14342 })
14343
14344 (define_expand "logb<mode>2"
14345   [(use (match_operand:MODEF 0 "register_operand" ""))
14346    (use (match_operand:MODEF 1 "register_operand" ""))]
14347   "TARGET_USE_FANCY_MATH_387
14348    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14349        || TARGET_MIX_SSE_I387)
14350    && flag_unsafe_math_optimizations"
14351 {
14352   rtx op0 = gen_reg_rtx (XFmode);
14353   rtx op1 = gen_reg_rtx (XFmode);
14354
14355   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14356   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14357   DONE;
14358 })
14359
14360 (define_expand "ilogbxf2"
14361   [(use (match_operand:SI 0 "register_operand" ""))
14362    (use (match_operand:XF 1 "register_operand" ""))]
14363   "TARGET_USE_FANCY_MATH_387
14364    && flag_unsafe_math_optimizations"
14365 {
14366   rtx op0, op1;
14367
14368   if (optimize_insn_for_size_p ())
14369     FAIL;
14370
14371   op0 = gen_reg_rtx (XFmode);
14372   op1 = gen_reg_rtx (XFmode);
14373
14374   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14375   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14376   DONE;
14377 })
14378
14379 (define_expand "ilogb<mode>2"
14380   [(use (match_operand:SI 0 "register_operand" ""))
14381    (use (match_operand:MODEF 1 "register_operand" ""))]
14382   "TARGET_USE_FANCY_MATH_387
14383    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14384        || TARGET_MIX_SSE_I387)
14385    && flag_unsafe_math_optimizations"
14386 {
14387   rtx op0, op1;
14388
14389   if (optimize_insn_for_size_p ())
14390     FAIL;
14391
14392   op0 = gen_reg_rtx (XFmode);
14393   op1 = gen_reg_rtx (XFmode);
14394
14395   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14396   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14397   DONE;
14398 })
14399
14400 (define_insn "*f2xm1xf2_i387"
14401   [(set (match_operand:XF 0 "register_operand" "=f")
14402         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14403                    UNSPEC_F2XM1))]
14404   "TARGET_USE_FANCY_MATH_387
14405    && flag_unsafe_math_optimizations"
14406   "f2xm1"
14407   [(set_attr "type" "fpspc")
14408    (set_attr "mode" "XF")])
14409
14410 (define_insn "*fscalexf4_i387"
14411   [(set (match_operand:XF 0 "register_operand" "=f")
14412         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14413                     (match_operand:XF 3 "register_operand" "1")]
14414                    UNSPEC_FSCALE_FRACT))
14415    (set (match_operand:XF 1 "register_operand" "=u")
14416         (unspec:XF [(match_dup 2) (match_dup 3)]
14417                    UNSPEC_FSCALE_EXP))]
14418   "TARGET_USE_FANCY_MATH_387
14419    && flag_unsafe_math_optimizations"
14420   "fscale"
14421   [(set_attr "type" "fpspc")
14422    (set_attr "mode" "XF")])
14423
14424 (define_expand "expNcorexf3"
14425   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14426                                (match_operand:XF 2 "register_operand" "")))
14427    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14428    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14429    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14430    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14431    (parallel [(set (match_operand:XF 0 "register_operand" "")
14432                    (unspec:XF [(match_dup 8) (match_dup 4)]
14433                               UNSPEC_FSCALE_FRACT))
14434               (set (match_dup 9)
14435                    (unspec:XF [(match_dup 8) (match_dup 4)]
14436                               UNSPEC_FSCALE_EXP))])]
14437   "TARGET_USE_FANCY_MATH_387
14438    && flag_unsafe_math_optimizations"
14439 {
14440   int i;
14441
14442   if (optimize_insn_for_size_p ())
14443     FAIL;
14444
14445   for (i = 3; i < 10; i++)
14446     operands[i] = gen_reg_rtx (XFmode);
14447
14448   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
14449 })
14450
14451 (define_expand "expxf2"
14452   [(use (match_operand:XF 0 "register_operand" ""))
14453    (use (match_operand:XF 1 "register_operand" ""))]
14454   "TARGET_USE_FANCY_MATH_387
14455    && flag_unsafe_math_optimizations"
14456 {
14457   rtx op2;
14458
14459   if (optimize_insn_for_size_p ())
14460     FAIL;
14461
14462   op2 = gen_reg_rtx (XFmode);
14463   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14464
14465   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14466   DONE;
14467 })
14468
14469 (define_expand "exp<mode>2"
14470   [(use (match_operand:MODEF 0 "register_operand" ""))
14471    (use (match_operand:MODEF 1 "general_operand" ""))]
14472  "TARGET_USE_FANCY_MATH_387
14473    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14474        || TARGET_MIX_SSE_I387)
14475    && flag_unsafe_math_optimizations"
14476 {
14477   rtx op0, op1;
14478
14479   if (optimize_insn_for_size_p ())
14480     FAIL;
14481
14482   op0 = gen_reg_rtx (XFmode);
14483   op1 = gen_reg_rtx (XFmode);
14484
14485   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14486   emit_insn (gen_expxf2 (op0, op1));
14487   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14488   DONE;
14489 })
14490
14491 (define_expand "exp10xf2"
14492   [(use (match_operand:XF 0 "register_operand" ""))
14493    (use (match_operand:XF 1 "register_operand" ""))]
14494   "TARGET_USE_FANCY_MATH_387
14495    && flag_unsafe_math_optimizations"
14496 {
14497   rtx op2;
14498
14499   if (optimize_insn_for_size_p ())
14500     FAIL;
14501
14502   op2 = gen_reg_rtx (XFmode);
14503   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14504
14505   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14506   DONE;
14507 })
14508
14509 (define_expand "exp10<mode>2"
14510   [(use (match_operand:MODEF 0 "register_operand" ""))
14511    (use (match_operand:MODEF 1 "general_operand" ""))]
14512  "TARGET_USE_FANCY_MATH_387
14513    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14514        || TARGET_MIX_SSE_I387)
14515    && flag_unsafe_math_optimizations"
14516 {
14517   rtx op0, op1;
14518
14519   if (optimize_insn_for_size_p ())
14520     FAIL;
14521
14522   op0 = gen_reg_rtx (XFmode);
14523   op1 = gen_reg_rtx (XFmode);
14524
14525   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14526   emit_insn (gen_exp10xf2 (op0, op1));
14527   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14528   DONE;
14529 })
14530
14531 (define_expand "exp2xf2"
14532   [(use (match_operand:XF 0 "register_operand" ""))
14533    (use (match_operand:XF 1 "register_operand" ""))]
14534   "TARGET_USE_FANCY_MATH_387
14535    && flag_unsafe_math_optimizations"
14536 {
14537   rtx op2;
14538
14539   if (optimize_insn_for_size_p ())
14540     FAIL;
14541
14542   op2 = gen_reg_rtx (XFmode);
14543   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
14544
14545   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14546   DONE;
14547 })
14548
14549 (define_expand "exp2<mode>2"
14550   [(use (match_operand:MODEF 0 "register_operand" ""))
14551    (use (match_operand:MODEF 1 "general_operand" ""))]
14552  "TARGET_USE_FANCY_MATH_387
14553    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14554        || TARGET_MIX_SSE_I387)
14555    && flag_unsafe_math_optimizations"
14556 {
14557   rtx op0, op1;
14558
14559   if (optimize_insn_for_size_p ())
14560     FAIL;
14561
14562   op0 = gen_reg_rtx (XFmode);
14563   op1 = gen_reg_rtx (XFmode);
14564
14565   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14566   emit_insn (gen_exp2xf2 (op0, op1));
14567   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14568   DONE;
14569 })
14570
14571 (define_expand "expm1xf2"
14572   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14573                                (match_dup 2)))
14574    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14575    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14576    (set (match_dup 9) (float_extend:XF (match_dup 13)))
14577    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14578    (parallel [(set (match_dup 7)
14579                    (unspec:XF [(match_dup 6) (match_dup 4)]
14580                               UNSPEC_FSCALE_FRACT))
14581               (set (match_dup 8)
14582                    (unspec:XF [(match_dup 6) (match_dup 4)]
14583                               UNSPEC_FSCALE_EXP))])
14584    (parallel [(set (match_dup 10)
14585                    (unspec:XF [(match_dup 9) (match_dup 8)]
14586                               UNSPEC_FSCALE_FRACT))
14587               (set (match_dup 11)
14588                    (unspec:XF [(match_dup 9) (match_dup 8)]
14589                               UNSPEC_FSCALE_EXP))])
14590    (set (match_dup 12) (minus:XF (match_dup 10)
14591                                  (float_extend:XF (match_dup 13))))
14592    (set (match_operand:XF 0 "register_operand" "")
14593         (plus:XF (match_dup 12) (match_dup 7)))]
14594   "TARGET_USE_FANCY_MATH_387
14595    && flag_unsafe_math_optimizations"
14596 {
14597   int i;
14598
14599   if (optimize_insn_for_size_p ())
14600     FAIL;
14601
14602   for (i = 2; i < 13; i++)
14603     operands[i] = gen_reg_rtx (XFmode);
14604
14605   operands[13]
14606     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14607
14608   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14609 })
14610
14611 (define_expand "expm1<mode>2"
14612   [(use (match_operand:MODEF 0 "register_operand" ""))
14613    (use (match_operand:MODEF 1 "general_operand" ""))]
14614  "TARGET_USE_FANCY_MATH_387
14615    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14616        || TARGET_MIX_SSE_I387)
14617    && flag_unsafe_math_optimizations"
14618 {
14619   rtx op0, op1;
14620
14621   if (optimize_insn_for_size_p ())
14622     FAIL;
14623
14624   op0 = gen_reg_rtx (XFmode);
14625   op1 = gen_reg_rtx (XFmode);
14626
14627   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14628   emit_insn (gen_expm1xf2 (op0, op1));
14629   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14630   DONE;
14631 })
14632
14633 (define_expand "ldexpxf3"
14634   [(set (match_dup 3)
14635         (float:XF (match_operand:SI 2 "register_operand" "")))
14636    (parallel [(set (match_operand:XF 0 " register_operand" "")
14637                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
14638                                (match_dup 3)]
14639                               UNSPEC_FSCALE_FRACT))
14640               (set (match_dup 4)
14641                    (unspec:XF [(match_dup 1) (match_dup 3)]
14642                               UNSPEC_FSCALE_EXP))])]
14643   "TARGET_USE_FANCY_MATH_387
14644    && flag_unsafe_math_optimizations"
14645 {
14646   if (optimize_insn_for_size_p ())
14647     FAIL;
14648
14649   operands[3] = gen_reg_rtx (XFmode);
14650   operands[4] = gen_reg_rtx (XFmode);
14651 })
14652
14653 (define_expand "ldexp<mode>3"
14654   [(use (match_operand:MODEF 0 "register_operand" ""))
14655    (use (match_operand:MODEF 1 "general_operand" ""))
14656    (use (match_operand:SI 2 "register_operand" ""))]
14657  "TARGET_USE_FANCY_MATH_387
14658    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14659        || TARGET_MIX_SSE_I387)
14660    && flag_unsafe_math_optimizations"
14661 {
14662   rtx op0, op1;
14663
14664   if (optimize_insn_for_size_p ())
14665     FAIL;
14666
14667   op0 = gen_reg_rtx (XFmode);
14668   op1 = gen_reg_rtx (XFmode);
14669
14670   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14671   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14672   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14673   DONE;
14674 })
14675
14676 (define_expand "scalbxf3"
14677   [(parallel [(set (match_operand:XF 0 " register_operand" "")
14678                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
14679                                (match_operand:XF 2 "register_operand" "")]
14680                               UNSPEC_FSCALE_FRACT))
14681               (set (match_dup 3)
14682                    (unspec:XF [(match_dup 1) (match_dup 2)]
14683                               UNSPEC_FSCALE_EXP))])]
14684   "TARGET_USE_FANCY_MATH_387
14685    && flag_unsafe_math_optimizations"
14686 {
14687   if (optimize_insn_for_size_p ())
14688     FAIL;
14689
14690   operands[3] = gen_reg_rtx (XFmode);
14691 })
14692
14693 (define_expand "scalb<mode>3"
14694   [(use (match_operand:MODEF 0 "register_operand" ""))
14695    (use (match_operand:MODEF 1 "general_operand" ""))
14696    (use (match_operand:MODEF 2 "general_operand" ""))]
14697  "TARGET_USE_FANCY_MATH_387
14698    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14699        || TARGET_MIX_SSE_I387)
14700    && flag_unsafe_math_optimizations"
14701 {
14702   rtx op0, op1, op2;
14703
14704   if (optimize_insn_for_size_p ())
14705     FAIL;
14706
14707   op0 = gen_reg_rtx (XFmode);
14708   op1 = gen_reg_rtx (XFmode);
14709   op2 = gen_reg_rtx (XFmode);
14710
14711   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14712   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14713   emit_insn (gen_scalbxf3 (op0, op1, op2));
14714   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14715   DONE;
14716 })
14717
14718 (define_expand "significandxf2"
14719   [(parallel [(set (match_operand:XF 0 "register_operand" "")
14720                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14721                               UNSPEC_XTRACT_FRACT))
14722               (set (match_dup 2)
14723                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14724   "TARGET_USE_FANCY_MATH_387
14725    && flag_unsafe_math_optimizations"
14726 {
14727   operands[2] = gen_reg_rtx (XFmode);
14728 })
14729
14730 (define_expand "significand<mode>2"
14731   [(use (match_operand:MODEF 0 "register_operand" ""))
14732    (use (match_operand:MODEF 1 "register_operand" ""))]
14733   "TARGET_USE_FANCY_MATH_387
14734    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14735        || TARGET_MIX_SSE_I387)
14736    && flag_unsafe_math_optimizations"
14737 {
14738   rtx op0 = gen_reg_rtx (XFmode);
14739   rtx op1 = gen_reg_rtx (XFmode);
14740
14741   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14742   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14743   DONE;
14744 })
14745 \f
14746
14747 (define_insn "sse4_1_round<mode>2"
14748   [(set (match_operand:MODEF 0 "register_operand" "=x")
14749         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14750                        (match_operand:SI 2 "const_0_to_15_operand" "n")]
14751                       UNSPEC_ROUND))]
14752   "TARGET_ROUND"
14753   "%vrounds<ssemodefsuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14754   [(set_attr "type" "ssecvt")
14755    (set_attr "prefix_extra" "1")
14756    (set_attr "prefix" "maybe_vex")
14757    (set_attr "mode" "<MODE>")])
14758
14759 (define_insn "rintxf2"
14760   [(set (match_operand:XF 0 "register_operand" "=f")
14761         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14762                    UNSPEC_FRNDINT))]
14763   "TARGET_USE_FANCY_MATH_387
14764    && flag_unsafe_math_optimizations"
14765   "frndint"
14766   [(set_attr "type" "fpspc")
14767    (set_attr "mode" "XF")])
14768
14769 (define_expand "rint<mode>2"
14770   [(use (match_operand:MODEF 0 "register_operand" ""))
14771    (use (match_operand:MODEF 1 "register_operand" ""))]
14772   "(TARGET_USE_FANCY_MATH_387
14773     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14774         || TARGET_MIX_SSE_I387)
14775     && flag_unsafe_math_optimizations)
14776    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14777        && !flag_trapping_math)"
14778 {
14779   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14780       && !flag_trapping_math)
14781     {
14782       if (!TARGET_ROUND && optimize_insn_for_size_p ())
14783         FAIL;
14784       if (TARGET_ROUND)
14785         emit_insn (gen_sse4_1_round<mode>2
14786                    (operands[0], operands[1], GEN_INT (0x04)));
14787       else
14788         ix86_expand_rint (operand0, operand1);
14789     }
14790   else
14791     {
14792       rtx op0 = gen_reg_rtx (XFmode);
14793       rtx op1 = gen_reg_rtx (XFmode);
14794
14795       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14796       emit_insn (gen_rintxf2 (op0, op1));
14797
14798       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14799     }
14800   DONE;
14801 })
14802
14803 (define_expand "round<mode>2"
14804   [(match_operand:MODEF 0 "register_operand" "")
14805    (match_operand:MODEF 1 "nonimmediate_operand" "")]
14806   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14807    && !flag_trapping_math && !flag_rounding_math"
14808 {
14809   if (optimize_insn_for_size_p ())
14810     FAIL;
14811   if (TARGET_64BIT || (<MODE>mode != DFmode))
14812     ix86_expand_round (operand0, operand1);
14813   else
14814     ix86_expand_rounddf_32 (operand0, operand1);
14815   DONE;
14816 })
14817
14818 (define_insn_and_split "*fistdi2_1"
14819   [(set (match_operand:DI 0 "nonimmediate_operand" "")
14820         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14821                    UNSPEC_FIST))]
14822   "TARGET_USE_FANCY_MATH_387
14823    && can_create_pseudo_p ()"
14824   "#"
14825   "&& 1"
14826   [(const_int 0)]
14827 {
14828   if (memory_operand (operands[0], VOIDmode))
14829     emit_insn (gen_fistdi2 (operands[0], operands[1]));
14830   else
14831     {
14832       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14833       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14834                                          operands[2]));
14835     }
14836   DONE;
14837 }
14838   [(set_attr "type" "fpspc")
14839    (set_attr "mode" "DI")])
14840
14841 (define_insn "fistdi2"
14842   [(set (match_operand:DI 0 "memory_operand" "=m")
14843         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14844                    UNSPEC_FIST))
14845    (clobber (match_scratch:XF 2 "=&1f"))]
14846   "TARGET_USE_FANCY_MATH_387"
14847   "* return output_fix_trunc (insn, operands, 0);"
14848   [(set_attr "type" "fpspc")
14849    (set_attr "mode" "DI")])
14850
14851 (define_insn "fistdi2_with_temp"
14852   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14853         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14854                    UNSPEC_FIST))
14855    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14856    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14857   "TARGET_USE_FANCY_MATH_387"
14858   "#"
14859   [(set_attr "type" "fpspc")
14860    (set_attr "mode" "DI")])
14861
14862 (define_split
14863   [(set (match_operand:DI 0 "register_operand" "")
14864         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14865                    UNSPEC_FIST))
14866    (clobber (match_operand:DI 2 "memory_operand" ""))
14867    (clobber (match_scratch 3 ""))]
14868   "reload_completed"
14869   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14870               (clobber (match_dup 3))])
14871    (set (match_dup 0) (match_dup 2))]
14872   "")
14873
14874 (define_split
14875   [(set (match_operand:DI 0 "memory_operand" "")
14876         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14877                    UNSPEC_FIST))
14878    (clobber (match_operand:DI 2 "memory_operand" ""))
14879    (clobber (match_scratch 3 ""))]
14880   "reload_completed"
14881   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14882               (clobber (match_dup 3))])]
14883   "")
14884
14885 (define_insn_and_split "*fist<mode>2_1"
14886   [(set (match_operand:X87MODEI12 0 "register_operand" "")
14887         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14888                            UNSPEC_FIST))]
14889   "TARGET_USE_FANCY_MATH_387
14890    && can_create_pseudo_p ()"
14891   "#"
14892   "&& 1"
14893   [(const_int 0)]
14894 {
14895   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14896   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14897                                         operands[2]));
14898   DONE;
14899 }
14900   [(set_attr "type" "fpspc")
14901    (set_attr "mode" "<MODE>")])
14902
14903 (define_insn "fist<mode>2"
14904   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14905         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14906                            UNSPEC_FIST))]
14907   "TARGET_USE_FANCY_MATH_387"
14908   "* return output_fix_trunc (insn, operands, 0);"
14909   [(set_attr "type" "fpspc")
14910    (set_attr "mode" "<MODE>")])
14911
14912 (define_insn "fist<mode>2_with_temp"
14913   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
14914         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14915                            UNSPEC_FIST))
14916    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
14917   "TARGET_USE_FANCY_MATH_387"
14918   "#"
14919   [(set_attr "type" "fpspc")
14920    (set_attr "mode" "<MODE>")])
14921
14922 (define_split
14923   [(set (match_operand:X87MODEI12 0 "register_operand" "")
14924         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14925                            UNSPEC_FIST))
14926    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14927   "reload_completed"
14928   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
14929    (set (match_dup 0) (match_dup 2))]
14930   "")
14931
14932 (define_split
14933   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14934         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14935                            UNSPEC_FIST))
14936    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14937   "reload_completed"
14938   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
14939   "")
14940
14941 (define_expand "lrintxf<mode>2"
14942   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14943      (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14944                       UNSPEC_FIST))]
14945   "TARGET_USE_FANCY_MATH_387"
14946   "")
14947
14948 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
14949   [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14950      (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
14951                         UNSPEC_FIX_NOTRUNC))]
14952   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14953    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
14954   "")
14955
14956 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
14957   [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14958    (match_operand:MODEF 1 "register_operand" "")]
14959   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14960    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
14961    && !flag_trapping_math && !flag_rounding_math"
14962 {
14963   if (optimize_insn_for_size_p ())
14964     FAIL;
14965   ix86_expand_lround (operand0, operand1);
14966   DONE;
14967 })
14968
14969 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14970 (define_insn_and_split "frndintxf2_floor"
14971   [(set (match_operand:XF 0 "register_operand" "")
14972         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14973          UNSPEC_FRNDINT_FLOOR))
14974    (clobber (reg:CC FLAGS_REG))]
14975   "TARGET_USE_FANCY_MATH_387
14976    && flag_unsafe_math_optimizations
14977    && can_create_pseudo_p ()"
14978   "#"
14979   "&& 1"
14980   [(const_int 0)]
14981 {
14982   ix86_optimize_mode_switching[I387_FLOOR] = 1;
14983
14984   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14985   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14986
14987   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14988                                         operands[2], operands[3]));
14989   DONE;
14990 }
14991   [(set_attr "type" "frndint")
14992    (set_attr "i387_cw" "floor")
14993    (set_attr "mode" "XF")])
14994
14995 (define_insn "frndintxf2_floor_i387"
14996   [(set (match_operand:XF 0 "register_operand" "=f")
14997         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14998          UNSPEC_FRNDINT_FLOOR))
14999    (use (match_operand:HI 2 "memory_operand" "m"))
15000    (use (match_operand:HI 3 "memory_operand" "m"))]
15001   "TARGET_USE_FANCY_MATH_387
15002    && flag_unsafe_math_optimizations"
15003   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15004   [(set_attr "type" "frndint")
15005    (set_attr "i387_cw" "floor")
15006    (set_attr "mode" "XF")])
15007
15008 (define_expand "floorxf2"
15009   [(use (match_operand:XF 0 "register_operand" ""))
15010    (use (match_operand:XF 1 "register_operand" ""))]
15011   "TARGET_USE_FANCY_MATH_387
15012    && flag_unsafe_math_optimizations"
15013 {
15014   if (optimize_insn_for_size_p ())
15015     FAIL;
15016   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
15017   DONE;
15018 })
15019
15020 (define_expand "floor<mode>2"
15021   [(use (match_operand:MODEF 0 "register_operand" ""))
15022    (use (match_operand:MODEF 1 "register_operand" ""))]
15023   "(TARGET_USE_FANCY_MATH_387
15024     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15025         || TARGET_MIX_SSE_I387)
15026     && flag_unsafe_math_optimizations)
15027    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15028        && !flag_trapping_math)"
15029 {
15030   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15031       && !flag_trapping_math
15032       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
15033     {
15034       if (!TARGET_ROUND && optimize_insn_for_size_p ())
15035         FAIL;
15036       if (TARGET_ROUND)
15037         emit_insn (gen_sse4_1_round<mode>2
15038                    (operands[0], operands[1], GEN_INT (0x01)));
15039       else if (TARGET_64BIT || (<MODE>mode != DFmode))
15040         ix86_expand_floorceil (operand0, operand1, true);
15041       else
15042         ix86_expand_floorceildf_32 (operand0, operand1, true);
15043     }
15044   else
15045     {
15046       rtx op0, op1;
15047
15048       if (optimize_insn_for_size_p ())
15049         FAIL;
15050
15051       op0 = gen_reg_rtx (XFmode);
15052       op1 = gen_reg_rtx (XFmode);
15053       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15054       emit_insn (gen_frndintxf2_floor (op0, op1));
15055
15056       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15057     }
15058   DONE;
15059 })
15060
15061 (define_insn_and_split "*fist<mode>2_floor_1"
15062   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
15063         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
15064          UNSPEC_FIST_FLOOR))
15065    (clobber (reg:CC FLAGS_REG))]
15066   "TARGET_USE_FANCY_MATH_387
15067    && flag_unsafe_math_optimizations
15068    && can_create_pseudo_p ()"
15069   "#"
15070   "&& 1"
15071   [(const_int 0)]
15072 {
15073   ix86_optimize_mode_switching[I387_FLOOR] = 1;
15074
15075   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15076   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
15077   if (memory_operand (operands[0], VOIDmode))
15078     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
15079                                       operands[2], operands[3]));
15080   else
15081     {
15082       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15083       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
15084                                                   operands[2], operands[3],
15085                                                   operands[4]));
15086     }
15087   DONE;
15088 }
15089   [(set_attr "type" "fistp")
15090    (set_attr "i387_cw" "floor")
15091    (set_attr "mode" "<MODE>")])
15092
15093 (define_insn "fistdi2_floor"
15094   [(set (match_operand:DI 0 "memory_operand" "=m")
15095         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15096          UNSPEC_FIST_FLOOR))
15097    (use (match_operand:HI 2 "memory_operand" "m"))
15098    (use (match_operand:HI 3 "memory_operand" "m"))
15099    (clobber (match_scratch:XF 4 "=&1f"))]
15100   "TARGET_USE_FANCY_MATH_387
15101    && flag_unsafe_math_optimizations"
15102   "* return output_fix_trunc (insn, operands, 0);"
15103   [(set_attr "type" "fistp")
15104    (set_attr "i387_cw" "floor")
15105    (set_attr "mode" "DI")])
15106
15107 (define_insn "fistdi2_floor_with_temp"
15108   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15109         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15110          UNSPEC_FIST_FLOOR))
15111    (use (match_operand:HI 2 "memory_operand" "m,m"))
15112    (use (match_operand:HI 3 "memory_operand" "m,m"))
15113    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15114    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15115   "TARGET_USE_FANCY_MATH_387
15116    && flag_unsafe_math_optimizations"
15117   "#"
15118   [(set_attr "type" "fistp")
15119    (set_attr "i387_cw" "floor")
15120    (set_attr "mode" "DI")])
15121
15122 (define_split
15123   [(set (match_operand:DI 0 "register_operand" "")
15124         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15125          UNSPEC_FIST_FLOOR))
15126    (use (match_operand:HI 2 "memory_operand" ""))
15127    (use (match_operand:HI 3 "memory_operand" ""))
15128    (clobber (match_operand:DI 4 "memory_operand" ""))
15129    (clobber (match_scratch 5 ""))]
15130   "reload_completed"
15131   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
15132               (use (match_dup 2))
15133               (use (match_dup 3))
15134               (clobber (match_dup 5))])
15135    (set (match_dup 0) (match_dup 4))]
15136   "")
15137
15138 (define_split
15139   [(set (match_operand:DI 0 "memory_operand" "")
15140         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15141          UNSPEC_FIST_FLOOR))
15142    (use (match_operand:HI 2 "memory_operand" ""))
15143    (use (match_operand:HI 3 "memory_operand" ""))
15144    (clobber (match_operand:DI 4 "memory_operand" ""))
15145    (clobber (match_scratch 5 ""))]
15146   "reload_completed"
15147   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
15148               (use (match_dup 2))
15149               (use (match_dup 3))
15150               (clobber (match_dup 5))])]
15151   "")
15152
15153 (define_insn "fist<mode>2_floor"
15154   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
15155         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
15156          UNSPEC_FIST_FLOOR))
15157    (use (match_operand:HI 2 "memory_operand" "m"))
15158    (use (match_operand:HI 3 "memory_operand" "m"))]
15159   "TARGET_USE_FANCY_MATH_387
15160    && flag_unsafe_math_optimizations"
15161   "* return output_fix_trunc (insn, operands, 0);"
15162   [(set_attr "type" "fistp")
15163    (set_attr "i387_cw" "floor")
15164    (set_attr "mode" "<MODE>")])
15165
15166 (define_insn "fist<mode>2_floor_with_temp"
15167   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
15168         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
15169          UNSPEC_FIST_FLOOR))
15170    (use (match_operand:HI 2 "memory_operand" "m,m"))
15171    (use (match_operand:HI 3 "memory_operand" "m,m"))
15172    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
15173   "TARGET_USE_FANCY_MATH_387
15174    && flag_unsafe_math_optimizations"
15175   "#"
15176   [(set_attr "type" "fistp")
15177    (set_attr "i387_cw" "floor")
15178    (set_attr "mode" "<MODE>")])
15179
15180 (define_split
15181   [(set (match_operand:X87MODEI12 0 "register_operand" "")
15182         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
15183          UNSPEC_FIST_FLOOR))
15184    (use (match_operand:HI 2 "memory_operand" ""))
15185    (use (match_operand:HI 3 "memory_operand" ""))
15186    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
15187   "reload_completed"
15188   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
15189                                   UNSPEC_FIST_FLOOR))
15190               (use (match_dup 2))
15191               (use (match_dup 3))])
15192    (set (match_dup 0) (match_dup 4))]
15193   "")
15194
15195 (define_split
15196   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
15197         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
15198          UNSPEC_FIST_FLOOR))
15199    (use (match_operand:HI 2 "memory_operand" ""))
15200    (use (match_operand:HI 3 "memory_operand" ""))
15201    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
15202   "reload_completed"
15203   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
15204                                   UNSPEC_FIST_FLOOR))
15205               (use (match_dup 2))
15206               (use (match_dup 3))])]
15207   "")
15208
15209 (define_expand "lfloorxf<mode>2"
15210   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
15211                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
15212                     UNSPEC_FIST_FLOOR))
15213               (clobber (reg:CC FLAGS_REG))])]
15214   "TARGET_USE_FANCY_MATH_387
15215    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15216    && flag_unsafe_math_optimizations"
15217   "")
15218
15219 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
15220   [(match_operand:SWI48 0 "nonimmediate_operand" "")
15221    (match_operand:MODEF 1 "register_operand" "")]
15222   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15223    && !flag_trapping_math"
15224 {
15225   if (TARGET_64BIT && optimize_insn_for_size_p ())
15226     FAIL;
15227   ix86_expand_lfloorceil (operand0, operand1, true);
15228   DONE;
15229 })
15230
15231 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15232 (define_insn_and_split "frndintxf2_ceil"
15233   [(set (match_operand:XF 0 "register_operand" "")
15234         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15235          UNSPEC_FRNDINT_CEIL))
15236    (clobber (reg:CC FLAGS_REG))]
15237   "TARGET_USE_FANCY_MATH_387
15238    && flag_unsafe_math_optimizations
15239    && can_create_pseudo_p ()"
15240   "#"
15241   "&& 1"
15242   [(const_int 0)]
15243 {
15244   ix86_optimize_mode_switching[I387_CEIL] = 1;
15245
15246   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15247   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15248
15249   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
15250                                        operands[2], operands[3]));
15251   DONE;
15252 }
15253   [(set_attr "type" "frndint")
15254    (set_attr "i387_cw" "ceil")
15255    (set_attr "mode" "XF")])
15256
15257 (define_insn "frndintxf2_ceil_i387"
15258   [(set (match_operand:XF 0 "register_operand" "=f")
15259         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15260          UNSPEC_FRNDINT_CEIL))
15261    (use (match_operand:HI 2 "memory_operand" "m"))
15262    (use (match_operand:HI 3 "memory_operand" "m"))]
15263   "TARGET_USE_FANCY_MATH_387
15264    && flag_unsafe_math_optimizations"
15265   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15266   [(set_attr "type" "frndint")
15267    (set_attr "i387_cw" "ceil")
15268    (set_attr "mode" "XF")])
15269
15270 (define_expand "ceilxf2"
15271   [(use (match_operand:XF 0 "register_operand" ""))
15272    (use (match_operand:XF 1 "register_operand" ""))]
15273   "TARGET_USE_FANCY_MATH_387
15274    && flag_unsafe_math_optimizations"
15275 {
15276   if (optimize_insn_for_size_p ())
15277     FAIL;
15278   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
15279   DONE;
15280 })
15281
15282 (define_expand "ceil<mode>2"
15283   [(use (match_operand:MODEF 0 "register_operand" ""))
15284    (use (match_operand:MODEF 1 "register_operand" ""))]
15285   "(TARGET_USE_FANCY_MATH_387
15286     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15287         || TARGET_MIX_SSE_I387)
15288     && flag_unsafe_math_optimizations)
15289    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15290        && !flag_trapping_math)"
15291 {
15292   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15293       && !flag_trapping_math
15294       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
15295     {
15296       if (TARGET_ROUND)
15297         emit_insn (gen_sse4_1_round<mode>2
15298                    (operands[0], operands[1], GEN_INT (0x02)));
15299       else if (optimize_insn_for_size_p ())
15300         FAIL;
15301       else if (TARGET_64BIT || (<MODE>mode != DFmode))
15302         ix86_expand_floorceil (operand0, operand1, false);
15303       else
15304         ix86_expand_floorceildf_32 (operand0, operand1, false);
15305     }
15306   else
15307     {
15308       rtx op0, op1;
15309
15310       if (optimize_insn_for_size_p ())
15311         FAIL;
15312
15313       op0 = gen_reg_rtx (XFmode);
15314       op1 = gen_reg_rtx (XFmode);
15315       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15316       emit_insn (gen_frndintxf2_ceil (op0, op1));
15317
15318       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15319     }
15320   DONE;
15321 })
15322
15323 (define_insn_and_split "*fist<mode>2_ceil_1"
15324   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
15325         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
15326          UNSPEC_FIST_CEIL))
15327    (clobber (reg:CC FLAGS_REG))]
15328   "TARGET_USE_FANCY_MATH_387
15329    && flag_unsafe_math_optimizations
15330    && can_create_pseudo_p ()"
15331   "#"
15332   "&& 1"
15333   [(const_int 0)]
15334 {
15335   ix86_optimize_mode_switching[I387_CEIL] = 1;
15336
15337   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15338   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15339   if (memory_operand (operands[0], VOIDmode))
15340     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
15341                                      operands[2], operands[3]));
15342   else
15343     {
15344       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15345       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
15346                                                  operands[2], operands[3],
15347                                                  operands[4]));
15348     }
15349   DONE;
15350 }
15351   [(set_attr "type" "fistp")
15352    (set_attr "i387_cw" "ceil")
15353    (set_attr "mode" "<MODE>")])
15354
15355 (define_insn "fistdi2_ceil"
15356   [(set (match_operand:DI 0 "memory_operand" "=m")
15357         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15358          UNSPEC_FIST_CEIL))
15359    (use (match_operand:HI 2 "memory_operand" "m"))
15360    (use (match_operand:HI 3 "memory_operand" "m"))
15361    (clobber (match_scratch:XF 4 "=&1f"))]
15362   "TARGET_USE_FANCY_MATH_387
15363    && flag_unsafe_math_optimizations"
15364   "* return output_fix_trunc (insn, operands, 0);"
15365   [(set_attr "type" "fistp")
15366    (set_attr "i387_cw" "ceil")
15367    (set_attr "mode" "DI")])
15368
15369 (define_insn "fistdi2_ceil_with_temp"
15370   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15371         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15372          UNSPEC_FIST_CEIL))
15373    (use (match_operand:HI 2 "memory_operand" "m,m"))
15374    (use (match_operand:HI 3 "memory_operand" "m,m"))
15375    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15376    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15377   "TARGET_USE_FANCY_MATH_387
15378    && flag_unsafe_math_optimizations"
15379   "#"
15380   [(set_attr "type" "fistp")
15381    (set_attr "i387_cw" "ceil")
15382    (set_attr "mode" "DI")])
15383
15384 (define_split
15385   [(set (match_operand:DI 0 "register_operand" "")
15386         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15387          UNSPEC_FIST_CEIL))
15388    (use (match_operand:HI 2 "memory_operand" ""))
15389    (use (match_operand:HI 3 "memory_operand" ""))
15390    (clobber (match_operand:DI 4 "memory_operand" ""))
15391    (clobber (match_scratch 5 ""))]
15392   "reload_completed"
15393   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15394               (use (match_dup 2))
15395               (use (match_dup 3))
15396               (clobber (match_dup 5))])
15397    (set (match_dup 0) (match_dup 4))]
15398   "")
15399
15400 (define_split
15401   [(set (match_operand:DI 0 "memory_operand" "")
15402         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15403          UNSPEC_FIST_CEIL))
15404    (use (match_operand:HI 2 "memory_operand" ""))
15405    (use (match_operand:HI 3 "memory_operand" ""))
15406    (clobber (match_operand:DI 4 "memory_operand" ""))
15407    (clobber (match_scratch 5 ""))]
15408   "reload_completed"
15409   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15410               (use (match_dup 2))
15411               (use (match_dup 3))
15412               (clobber (match_dup 5))])]
15413   "")
15414
15415 (define_insn "fist<mode>2_ceil"
15416   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
15417         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
15418          UNSPEC_FIST_CEIL))
15419    (use (match_operand:HI 2 "memory_operand" "m"))
15420    (use (match_operand:HI 3 "memory_operand" "m"))]
15421   "TARGET_USE_FANCY_MATH_387
15422    && flag_unsafe_math_optimizations"
15423   "* return output_fix_trunc (insn, operands, 0);"
15424   [(set_attr "type" "fistp")
15425    (set_attr "i387_cw" "ceil")
15426    (set_attr "mode" "<MODE>")])
15427
15428 (define_insn "fist<mode>2_ceil_with_temp"
15429   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
15430         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
15431          UNSPEC_FIST_CEIL))
15432    (use (match_operand:HI 2 "memory_operand" "m,m"))
15433    (use (match_operand:HI 3 "memory_operand" "m,m"))
15434    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
15435   "TARGET_USE_FANCY_MATH_387
15436    && flag_unsafe_math_optimizations"
15437   "#"
15438   [(set_attr "type" "fistp")
15439    (set_attr "i387_cw" "ceil")
15440    (set_attr "mode" "<MODE>")])
15441
15442 (define_split
15443   [(set (match_operand:X87MODEI12 0 "register_operand" "")
15444         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
15445          UNSPEC_FIST_CEIL))
15446    (use (match_operand:HI 2 "memory_operand" ""))
15447    (use (match_operand:HI 3 "memory_operand" ""))
15448    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
15449   "reload_completed"
15450   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
15451                                   UNSPEC_FIST_CEIL))
15452               (use (match_dup 2))
15453               (use (match_dup 3))])
15454    (set (match_dup 0) (match_dup 4))]
15455   "")
15456
15457 (define_split
15458   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
15459         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
15460          UNSPEC_FIST_CEIL))
15461    (use (match_operand:HI 2 "memory_operand" ""))
15462    (use (match_operand:HI 3 "memory_operand" ""))
15463    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
15464   "reload_completed"
15465   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
15466                                   UNSPEC_FIST_CEIL))
15467               (use (match_dup 2))
15468               (use (match_dup 3))])]
15469   "")
15470
15471 (define_expand "lceilxf<mode>2"
15472   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
15473                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
15474                     UNSPEC_FIST_CEIL))
15475               (clobber (reg:CC FLAGS_REG))])]
15476   "TARGET_USE_FANCY_MATH_387
15477    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15478    && flag_unsafe_math_optimizations"
15479   "")
15480
15481 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
15482   [(match_operand:SWI48 0 "nonimmediate_operand" "")
15483    (match_operand:MODEF 1 "register_operand" "")]
15484   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15485    && !flag_trapping_math"
15486 {
15487   ix86_expand_lfloorceil (operand0, operand1, false);
15488   DONE;
15489 })
15490
15491 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15492 (define_insn_and_split "frndintxf2_trunc"
15493   [(set (match_operand:XF 0 "register_operand" "")
15494         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15495          UNSPEC_FRNDINT_TRUNC))
15496    (clobber (reg:CC FLAGS_REG))]
15497   "TARGET_USE_FANCY_MATH_387
15498    && flag_unsafe_math_optimizations
15499    && can_create_pseudo_p ()"
15500   "#"
15501   "&& 1"
15502   [(const_int 0)]
15503 {
15504   ix86_optimize_mode_switching[I387_TRUNC] = 1;
15505
15506   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15507   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
15508
15509   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
15510                                         operands[2], operands[3]));
15511   DONE;
15512 }
15513   [(set_attr "type" "frndint")
15514    (set_attr "i387_cw" "trunc")
15515    (set_attr "mode" "XF")])
15516
15517 (define_insn "frndintxf2_trunc_i387"
15518   [(set (match_operand:XF 0 "register_operand" "=f")
15519         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15520          UNSPEC_FRNDINT_TRUNC))
15521    (use (match_operand:HI 2 "memory_operand" "m"))
15522    (use (match_operand:HI 3 "memory_operand" "m"))]
15523   "TARGET_USE_FANCY_MATH_387
15524    && flag_unsafe_math_optimizations"
15525   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15526   [(set_attr "type" "frndint")
15527    (set_attr "i387_cw" "trunc")
15528    (set_attr "mode" "XF")])
15529
15530 (define_expand "btruncxf2"
15531   [(use (match_operand:XF 0 "register_operand" ""))
15532    (use (match_operand:XF 1 "register_operand" ""))]
15533   "TARGET_USE_FANCY_MATH_387
15534    && flag_unsafe_math_optimizations"
15535 {
15536   if (optimize_insn_for_size_p ())
15537     FAIL;
15538   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
15539   DONE;
15540 })
15541
15542 (define_expand "btrunc<mode>2"
15543   [(use (match_operand:MODEF 0 "register_operand" ""))
15544    (use (match_operand:MODEF 1 "register_operand" ""))]
15545   "(TARGET_USE_FANCY_MATH_387
15546     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15547         || TARGET_MIX_SSE_I387)
15548     && flag_unsafe_math_optimizations)
15549    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15550        && !flag_trapping_math)"
15551 {
15552   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15553       && !flag_trapping_math
15554       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
15555     {
15556       if (TARGET_ROUND)
15557         emit_insn (gen_sse4_1_round<mode>2
15558                    (operands[0], operands[1], GEN_INT (0x03)));
15559       else if (optimize_insn_for_size_p ())
15560         FAIL;
15561       else if (TARGET_64BIT || (<MODE>mode != DFmode))
15562         ix86_expand_trunc (operand0, operand1);
15563       else
15564         ix86_expand_truncdf_32 (operand0, operand1);
15565     }
15566   else
15567     {
15568       rtx op0, op1;
15569
15570       if (optimize_insn_for_size_p ())
15571         FAIL;
15572
15573       op0 = gen_reg_rtx (XFmode);
15574       op1 = gen_reg_rtx (XFmode);
15575       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15576       emit_insn (gen_frndintxf2_trunc (op0, op1));
15577
15578       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15579     }
15580   DONE;
15581 })
15582
15583 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15584 (define_insn_and_split "frndintxf2_mask_pm"
15585   [(set (match_operand:XF 0 "register_operand" "")
15586         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15587          UNSPEC_FRNDINT_MASK_PM))
15588    (clobber (reg:CC FLAGS_REG))]
15589   "TARGET_USE_FANCY_MATH_387
15590    && flag_unsafe_math_optimizations
15591    && can_create_pseudo_p ()"
15592   "#"
15593   "&& 1"
15594   [(const_int 0)]
15595 {
15596   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15597
15598   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15599   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15600
15601   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15602                                           operands[2], operands[3]));
15603   DONE;
15604 }
15605   [(set_attr "type" "frndint")
15606    (set_attr "i387_cw" "mask_pm")
15607    (set_attr "mode" "XF")])
15608
15609 (define_insn "frndintxf2_mask_pm_i387"
15610   [(set (match_operand:XF 0 "register_operand" "=f")
15611         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15612          UNSPEC_FRNDINT_MASK_PM))
15613    (use (match_operand:HI 2 "memory_operand" "m"))
15614    (use (match_operand:HI 3 "memory_operand" "m"))]
15615   "TARGET_USE_FANCY_MATH_387
15616    && flag_unsafe_math_optimizations"
15617   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15618   [(set_attr "type" "frndint")
15619    (set_attr "i387_cw" "mask_pm")
15620    (set_attr "mode" "XF")])
15621
15622 (define_expand "nearbyintxf2"
15623   [(use (match_operand:XF 0 "register_operand" ""))
15624    (use (match_operand:XF 1 "register_operand" ""))]
15625   "TARGET_USE_FANCY_MATH_387
15626    && flag_unsafe_math_optimizations"
15627 {
15628   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15629
15630   DONE;
15631 })
15632
15633 (define_expand "nearbyint<mode>2"
15634   [(use (match_operand:MODEF 0 "register_operand" ""))
15635    (use (match_operand:MODEF 1 "register_operand" ""))]
15636   "TARGET_USE_FANCY_MATH_387
15637    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15638        || TARGET_MIX_SSE_I387)
15639    && flag_unsafe_math_optimizations"
15640 {
15641   rtx op0 = gen_reg_rtx (XFmode);
15642   rtx op1 = gen_reg_rtx (XFmode);
15643
15644   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15645   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15646
15647   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15648   DONE;
15649 })
15650
15651 (define_insn "fxam<mode>2_i387"
15652   [(set (match_operand:HI 0 "register_operand" "=a")
15653         (unspec:HI
15654           [(match_operand:X87MODEF 1 "register_operand" "f")]
15655           UNSPEC_FXAM))]
15656   "TARGET_USE_FANCY_MATH_387"
15657   "fxam\n\tfnstsw\t%0"
15658   [(set_attr "type" "multi")
15659    (set_attr "length" "4")
15660    (set_attr "unit" "i387")
15661    (set_attr "mode" "<MODE>")])
15662
15663 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15664   [(set (match_operand:HI 0 "register_operand" "")
15665         (unspec:HI
15666           [(match_operand:MODEF 1 "memory_operand" "")]
15667           UNSPEC_FXAM_MEM))]
15668   "TARGET_USE_FANCY_MATH_387
15669    && can_create_pseudo_p ()"
15670   "#"
15671   "&& 1"
15672   [(set (match_dup 2)(match_dup 1))
15673    (set (match_dup 0)
15674         (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15675 {
15676   operands[2] = gen_reg_rtx (<MODE>mode);
15677
15678   MEM_VOLATILE_P (operands[1]) = 1;
15679 }
15680   [(set_attr "type" "multi")
15681    (set_attr "unit" "i387")
15682    (set_attr "mode" "<MODE>")])
15683
15684 (define_expand "isinfxf2"
15685   [(use (match_operand:SI 0 "register_operand" ""))
15686    (use (match_operand:XF 1 "register_operand" ""))]
15687   "TARGET_USE_FANCY_MATH_387
15688    && TARGET_C99_FUNCTIONS"
15689 {
15690   rtx mask = GEN_INT (0x45);
15691   rtx val = GEN_INT (0x05);
15692
15693   rtx cond;
15694
15695   rtx scratch = gen_reg_rtx (HImode);
15696   rtx res = gen_reg_rtx (QImode);
15697
15698   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15699
15700   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15701   emit_insn (gen_cmpqi_ext_3 (scratch, val));
15702   cond = gen_rtx_fmt_ee (EQ, QImode,
15703                          gen_rtx_REG (CCmode, FLAGS_REG),
15704                          const0_rtx);
15705   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15706   emit_insn (gen_zero_extendqisi2 (operands[0], res));
15707   DONE;
15708 })
15709
15710 (define_expand "isinf<mode>2"
15711   [(use (match_operand:SI 0 "register_operand" ""))
15712    (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15713   "TARGET_USE_FANCY_MATH_387
15714    && TARGET_C99_FUNCTIONS
15715    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15716 {
15717   rtx mask = GEN_INT (0x45);
15718   rtx val = GEN_INT (0x05);
15719
15720   rtx cond;
15721
15722   rtx scratch = gen_reg_rtx (HImode);
15723   rtx res = gen_reg_rtx (QImode);
15724
15725   /* Remove excess precision by forcing value through memory. */
15726   if (memory_operand (operands[1], VOIDmode))
15727     emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15728   else
15729     {
15730       enum ix86_stack_slot slot = (virtuals_instantiated
15731                                    ? SLOT_TEMP
15732                                    : SLOT_VIRTUAL);
15733       rtx temp = assign_386_stack_local (<MODE>mode, slot);
15734
15735       emit_move_insn (temp, operands[1]);
15736       emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15737     }
15738
15739   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15740   emit_insn (gen_cmpqi_ext_3 (scratch, val));
15741   cond = gen_rtx_fmt_ee (EQ, QImode,
15742                          gen_rtx_REG (CCmode, FLAGS_REG),
15743                          const0_rtx);
15744   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15745   emit_insn (gen_zero_extendqisi2 (operands[0], res));
15746   DONE;
15747 })
15748
15749 (define_expand "signbit<mode>2"
15750   [(use (match_operand:SI 0 "register_operand" ""))
15751    (use (match_operand:X87MODEF 1 "register_operand" ""))]
15752   "TARGET_USE_FANCY_MATH_387
15753    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15754 {
15755   rtx mask = GEN_INT (0x0200);
15756
15757   rtx scratch = gen_reg_rtx (HImode);
15758
15759   emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
15760   emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
15761   DONE;
15762 })
15763 \f
15764 ;; Block operation instructions
15765
15766 (define_insn "cld"
15767   [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15768   ""
15769   "cld"
15770   [(set_attr "length" "1")
15771    (set_attr "length_immediate" "0")
15772    (set_attr "modrm" "0")])
15773
15774 (define_expand "movmemsi"
15775   [(use (match_operand:BLK 0 "memory_operand" ""))
15776    (use (match_operand:BLK 1 "memory_operand" ""))
15777    (use (match_operand:SI 2 "nonmemory_operand" ""))
15778    (use (match_operand:SI 3 "const_int_operand" ""))
15779    (use (match_operand:SI 4 "const_int_operand" ""))
15780    (use (match_operand:SI 5 "const_int_operand" ""))]
15781   ""
15782 {
15783  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15784                          operands[4], operands[5]))
15785    DONE;
15786  else
15787    FAIL;
15788 })
15789
15790 (define_expand "movmemdi"
15791   [(use (match_operand:BLK 0 "memory_operand" ""))
15792    (use (match_operand:BLK 1 "memory_operand" ""))
15793    (use (match_operand:DI 2 "nonmemory_operand" ""))
15794    (use (match_operand:DI 3 "const_int_operand" ""))
15795    (use (match_operand:SI 4 "const_int_operand" ""))
15796    (use (match_operand:SI 5 "const_int_operand" ""))]
15797   "TARGET_64BIT"
15798 {
15799  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15800                          operands[4], operands[5]))
15801    DONE;
15802  else
15803    FAIL;
15804 })
15805
15806 ;; Most CPUs don't like single string operations
15807 ;; Handle this case here to simplify previous expander.
15808
15809 (define_expand "strmov"
15810   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15811    (set (match_operand 1 "memory_operand" "") (match_dup 4))
15812    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15813               (clobber (reg:CC FLAGS_REG))])
15814    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15815               (clobber (reg:CC FLAGS_REG))])]
15816   ""
15817 {
15818   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15819
15820   /* If .md ever supports :P for Pmode, these can be directly
15821      in the pattern above.  */
15822   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15823   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15824
15825   /* Can't use this if the user has appropriated esi or edi.  */
15826   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15827       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15828     {
15829       emit_insn (gen_strmov_singleop (operands[0], operands[1],
15830                                       operands[2], operands[3],
15831                                       operands[5], operands[6]));
15832       DONE;
15833     }
15834
15835   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15836 })
15837
15838 (define_expand "strmov_singleop"
15839   [(parallel [(set (match_operand 1 "memory_operand" "")
15840                    (match_operand 3 "memory_operand" ""))
15841               (set (match_operand 0 "register_operand" "")
15842                    (match_operand 4 "" ""))
15843               (set (match_operand 2 "register_operand" "")
15844                    (match_operand 5 "" ""))])]
15845   ""
15846   "ix86_current_function_needs_cld = 1;")
15847
15848 (define_insn "*strmovdi_rex_1"
15849   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15850         (mem:DI (match_operand:DI 3 "register_operand" "1")))
15851    (set (match_operand:DI 0 "register_operand" "=D")
15852         (plus:DI (match_dup 2)
15853                  (const_int 8)))
15854    (set (match_operand:DI 1 "register_operand" "=S")
15855         (plus:DI (match_dup 3)
15856                  (const_int 8)))]
15857   "TARGET_64BIT"
15858   "movsq"
15859   [(set_attr "type" "str")
15860    (set_attr "mode" "DI")
15861    (set_attr "memory" "both")])
15862
15863 (define_insn "*strmovsi_1"
15864   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
15865         (mem:SI (match_operand:SI 3 "register_operand" "1")))
15866    (set (match_operand:SI 0 "register_operand" "=D")
15867         (plus:SI (match_dup 2)
15868                  (const_int 4)))
15869    (set (match_operand:SI 1 "register_operand" "=S")
15870         (plus:SI (match_dup 3)
15871                  (const_int 4)))]
15872   "!TARGET_64BIT"
15873   "movs{l|d}"
15874   [(set_attr "type" "str")
15875    (set_attr "mode" "SI")
15876    (set_attr "memory" "both")])
15877
15878 (define_insn "*strmovsi_rex_1"
15879   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
15880         (mem:SI (match_operand:DI 3 "register_operand" "1")))
15881    (set (match_operand:DI 0 "register_operand" "=D")
15882         (plus:DI (match_dup 2)
15883                  (const_int 4)))
15884    (set (match_operand:DI 1 "register_operand" "=S")
15885         (plus:DI (match_dup 3)
15886                  (const_int 4)))]
15887   "TARGET_64BIT"
15888   "movs{l|d}"
15889   [(set_attr "type" "str")
15890    (set_attr "mode" "SI")
15891    (set_attr "memory" "both")])
15892
15893 (define_insn "*strmovhi_1"
15894   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
15895         (mem:HI (match_operand:SI 3 "register_operand" "1")))
15896    (set (match_operand:SI 0 "register_operand" "=D")
15897         (plus:SI (match_dup 2)
15898                  (const_int 2)))
15899    (set (match_operand:SI 1 "register_operand" "=S")
15900         (plus:SI (match_dup 3)
15901                  (const_int 2)))]
15902   "!TARGET_64BIT"
15903   "movsw"
15904   [(set_attr "type" "str")
15905    (set_attr "memory" "both")
15906    (set_attr "mode" "HI")])
15907
15908 (define_insn "*strmovhi_rex_1"
15909   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
15910         (mem:HI (match_operand:DI 3 "register_operand" "1")))
15911    (set (match_operand:DI 0 "register_operand" "=D")
15912         (plus:DI (match_dup 2)
15913                  (const_int 2)))
15914    (set (match_operand:DI 1 "register_operand" "=S")
15915         (plus:DI (match_dup 3)
15916                  (const_int 2)))]
15917   "TARGET_64BIT"
15918   "movsw"
15919   [(set_attr "type" "str")
15920    (set_attr "memory" "both")
15921    (set_attr "mode" "HI")])
15922
15923 (define_insn "*strmovqi_1"
15924   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
15925         (mem:QI (match_operand:SI 3 "register_operand" "1")))
15926    (set (match_operand:SI 0 "register_operand" "=D")
15927         (plus:SI (match_dup 2)
15928                  (const_int 1)))
15929    (set (match_operand:SI 1 "register_operand" "=S")
15930         (plus:SI (match_dup 3)
15931                  (const_int 1)))]
15932   "!TARGET_64BIT"
15933   "movsb"
15934   [(set_attr "type" "str")
15935    (set_attr "memory" "both")
15936    (set_attr "mode" "QI")])
15937
15938 (define_insn "*strmovqi_rex_1"
15939   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
15940         (mem:QI (match_operand:DI 3 "register_operand" "1")))
15941    (set (match_operand:DI 0 "register_operand" "=D")
15942         (plus:DI (match_dup 2)
15943                  (const_int 1)))
15944    (set (match_operand:DI 1 "register_operand" "=S")
15945         (plus:DI (match_dup 3)
15946                  (const_int 1)))]
15947   "TARGET_64BIT"
15948   "movsb"
15949   [(set_attr "type" "str")
15950    (set_attr "memory" "both")
15951    (set_attr "prefix_rex" "0")
15952    (set_attr "mode" "QI")])
15953
15954 (define_expand "rep_mov"
15955   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15956               (set (match_operand 0 "register_operand" "")
15957                    (match_operand 5 "" ""))
15958               (set (match_operand 2 "register_operand" "")
15959                    (match_operand 6 "" ""))
15960               (set (match_operand 1 "memory_operand" "")
15961                    (match_operand 3 "memory_operand" ""))
15962               (use (match_dup 4))])]
15963   ""
15964   "ix86_current_function_needs_cld = 1;")
15965
15966 (define_insn "*rep_movdi_rex64"
15967   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15968    (set (match_operand:DI 0 "register_operand" "=D")
15969         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15970                             (const_int 3))
15971                  (match_operand:DI 3 "register_operand" "0")))
15972    (set (match_operand:DI 1 "register_operand" "=S")
15973         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15974                  (match_operand:DI 4 "register_operand" "1")))
15975    (set (mem:BLK (match_dup 3))
15976         (mem:BLK (match_dup 4)))
15977    (use (match_dup 5))]
15978   "TARGET_64BIT"
15979   "rep movsq"
15980   [(set_attr "type" "str")
15981    (set_attr "prefix_rep" "1")
15982    (set_attr "memory" "both")
15983    (set_attr "mode" "DI")])
15984
15985 (define_insn "*rep_movsi"
15986   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
15987    (set (match_operand:SI 0 "register_operand" "=D")
15988         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
15989                             (const_int 2))
15990                  (match_operand:SI 3 "register_operand" "0")))
15991    (set (match_operand:SI 1 "register_operand" "=S")
15992         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
15993                  (match_operand:SI 4 "register_operand" "1")))
15994    (set (mem:BLK (match_dup 3))
15995         (mem:BLK (match_dup 4)))
15996    (use (match_dup 5))]
15997   "!TARGET_64BIT"
15998   "rep movs{l|d}"
15999   [(set_attr "type" "str")
16000    (set_attr "prefix_rep" "1")
16001    (set_attr "memory" "both")
16002    (set_attr "mode" "SI")])
16003
16004 (define_insn "*rep_movsi_rex64"
16005   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16006    (set (match_operand:DI 0 "register_operand" "=D")
16007         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
16008                             (const_int 2))
16009                  (match_operand:DI 3 "register_operand" "0")))
16010    (set (match_operand:DI 1 "register_operand" "=S")
16011         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
16012                  (match_operand:DI 4 "register_operand" "1")))
16013    (set (mem:BLK (match_dup 3))
16014         (mem:BLK (match_dup 4)))
16015    (use (match_dup 5))]
16016   "TARGET_64BIT"
16017   "rep movs{l|d}"
16018   [(set_attr "type" "str")
16019    (set_attr "prefix_rep" "1")
16020    (set_attr "memory" "both")
16021    (set_attr "mode" "SI")])
16022
16023 (define_insn "*rep_movqi"
16024   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
16025    (set (match_operand:SI 0 "register_operand" "=D")
16026         (plus:SI (match_operand:SI 3 "register_operand" "0")
16027                  (match_operand:SI 5 "register_operand" "2")))
16028    (set (match_operand:SI 1 "register_operand" "=S")
16029         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
16030    (set (mem:BLK (match_dup 3))
16031         (mem:BLK (match_dup 4)))
16032    (use (match_dup 5))]
16033   "!TARGET_64BIT"
16034   "rep movsb"
16035   [(set_attr "type" "str")
16036    (set_attr "prefix_rep" "1")
16037    (set_attr "memory" "both")
16038    (set_attr "mode" "SI")])
16039
16040 (define_insn "*rep_movqi_rex64"
16041   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16042    (set (match_operand:DI 0 "register_operand" "=D")
16043         (plus:DI (match_operand:DI 3 "register_operand" "0")
16044                  (match_operand:DI 5 "register_operand" "2")))
16045    (set (match_operand:DI 1 "register_operand" "=S")
16046         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
16047    (set (mem:BLK (match_dup 3))
16048         (mem:BLK (match_dup 4)))
16049    (use (match_dup 5))]
16050   "TARGET_64BIT"
16051   "rep movsb"
16052   [(set_attr "type" "str")
16053    (set_attr "prefix_rep" "1")
16054    (set_attr "memory" "both")
16055    (set_attr "mode" "SI")])
16056
16057 (define_expand "setmemsi"
16058    [(use (match_operand:BLK 0 "memory_operand" ""))
16059     (use (match_operand:SI 1 "nonmemory_operand" ""))
16060     (use (match_operand 2 "const_int_operand" ""))
16061     (use (match_operand 3 "const_int_operand" ""))
16062     (use (match_operand:SI 4 "const_int_operand" ""))
16063     (use (match_operand:SI 5 "const_int_operand" ""))]
16064   ""
16065 {
16066  if (ix86_expand_setmem (operands[0], operands[1],
16067                          operands[2], operands[3],
16068                          operands[4], operands[5]))
16069    DONE;
16070  else
16071    FAIL;
16072 })
16073
16074 (define_expand "setmemdi"
16075    [(use (match_operand:BLK 0 "memory_operand" ""))
16076     (use (match_operand:DI 1 "nonmemory_operand" ""))
16077     (use (match_operand 2 "const_int_operand" ""))
16078     (use (match_operand 3 "const_int_operand" ""))
16079     (use (match_operand 4 "const_int_operand" ""))
16080     (use (match_operand 5 "const_int_operand" ""))]
16081   "TARGET_64BIT"
16082 {
16083  if (ix86_expand_setmem (operands[0], operands[1],
16084                          operands[2], operands[3],
16085                          operands[4], operands[5]))
16086    DONE;
16087  else
16088    FAIL;
16089 })
16090
16091 ;; Most CPUs don't like single string operations
16092 ;; Handle this case here to simplify previous expander.
16093
16094 (define_expand "strset"
16095   [(set (match_operand 1 "memory_operand" "")
16096         (match_operand 2 "register_operand" ""))
16097    (parallel [(set (match_operand 0 "register_operand" "")
16098                    (match_dup 3))
16099               (clobber (reg:CC FLAGS_REG))])]
16100   ""
16101 {
16102   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
16103     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
16104
16105   /* If .md ever supports :P for Pmode, this can be directly
16106      in the pattern above.  */
16107   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
16108                               GEN_INT (GET_MODE_SIZE (GET_MODE
16109                                                       (operands[2]))));
16110   if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
16111     {
16112       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
16113                                       operands[3]));
16114       DONE;
16115     }
16116 })
16117
16118 (define_expand "strset_singleop"
16119   [(parallel [(set (match_operand 1 "memory_operand" "")
16120                    (match_operand 2 "register_operand" ""))
16121               (set (match_operand 0 "register_operand" "")
16122                    (match_operand 3 "" ""))])]
16123   ""
16124   "ix86_current_function_needs_cld = 1;")
16125
16126 (define_insn "*strsetdi_rex_1"
16127   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
16128         (match_operand:DI 2 "register_operand" "a"))
16129    (set (match_operand:DI 0 "register_operand" "=D")
16130         (plus:DI (match_dup 1)
16131                  (const_int 8)))]
16132   "TARGET_64BIT"
16133   "stosq"
16134   [(set_attr "type" "str")
16135    (set_attr "memory" "store")
16136    (set_attr "mode" "DI")])
16137
16138 (define_insn "*strsetsi_1"
16139   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
16140         (match_operand:SI 2 "register_operand" "a"))
16141    (set (match_operand:SI 0 "register_operand" "=D")
16142         (plus:SI (match_dup 1)
16143                  (const_int 4)))]
16144   "!TARGET_64BIT"
16145   "stos{l|d}"
16146   [(set_attr "type" "str")
16147    (set_attr "memory" "store")
16148    (set_attr "mode" "SI")])
16149
16150 (define_insn "*strsetsi_rex_1"
16151   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
16152         (match_operand:SI 2 "register_operand" "a"))
16153    (set (match_operand:DI 0 "register_operand" "=D")
16154         (plus:DI (match_dup 1)
16155                  (const_int 4)))]
16156   "TARGET_64BIT"
16157   "stos{l|d}"
16158   [(set_attr "type" "str")
16159    (set_attr "memory" "store")
16160    (set_attr "mode" "SI")])
16161
16162 (define_insn "*strsethi_1"
16163   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
16164         (match_operand:HI 2 "register_operand" "a"))
16165    (set (match_operand:SI 0 "register_operand" "=D")
16166         (plus:SI (match_dup 1)
16167                  (const_int 2)))]
16168   "!TARGET_64BIT"
16169   "stosw"
16170   [(set_attr "type" "str")
16171    (set_attr "memory" "store")
16172    (set_attr "mode" "HI")])
16173
16174 (define_insn "*strsethi_rex_1"
16175   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
16176         (match_operand:HI 2 "register_operand" "a"))
16177    (set (match_operand:DI 0 "register_operand" "=D")
16178         (plus:DI (match_dup 1)
16179                  (const_int 2)))]
16180   "TARGET_64BIT"
16181   "stosw"
16182   [(set_attr "type" "str")
16183    (set_attr "memory" "store")
16184    (set_attr "mode" "HI")])
16185
16186 (define_insn "*strsetqi_1"
16187   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
16188         (match_operand:QI 2 "register_operand" "a"))
16189    (set (match_operand:SI 0 "register_operand" "=D")
16190         (plus:SI (match_dup 1)
16191                  (const_int 1)))]
16192   "!TARGET_64BIT"
16193   "stosb"
16194   [(set_attr "type" "str")
16195    (set_attr "memory" "store")
16196    (set_attr "mode" "QI")])
16197
16198 (define_insn "*strsetqi_rex_1"
16199   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
16200         (match_operand:QI 2 "register_operand" "a"))
16201    (set (match_operand:DI 0 "register_operand" "=D")
16202         (plus:DI (match_dup 1)
16203                  (const_int 1)))]
16204   "TARGET_64BIT"
16205   "stosb"
16206   [(set_attr "type" "str")
16207    (set_attr "memory" "store")
16208    (set_attr "prefix_rex" "0")
16209    (set_attr "mode" "QI")])
16210
16211 (define_expand "rep_stos"
16212   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
16213               (set (match_operand 0 "register_operand" "")
16214                    (match_operand 4 "" ""))
16215               (set (match_operand 2 "memory_operand" "") (const_int 0))
16216               (use (match_operand 3 "register_operand" ""))
16217               (use (match_dup 1))])]
16218   ""
16219   "ix86_current_function_needs_cld = 1;")
16220
16221 (define_insn "*rep_stosdi_rex64"
16222   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16223    (set (match_operand:DI 0 "register_operand" "=D")
16224         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
16225                             (const_int 3))
16226                  (match_operand:DI 3 "register_operand" "0")))
16227    (set (mem:BLK (match_dup 3))
16228         (const_int 0))
16229    (use (match_operand:DI 2 "register_operand" "a"))
16230    (use (match_dup 4))]
16231   "TARGET_64BIT"
16232   "rep stosq"
16233   [(set_attr "type" "str")
16234    (set_attr "prefix_rep" "1")
16235    (set_attr "memory" "store")
16236    (set_attr "mode" "DI")])
16237
16238 (define_insn "*rep_stossi"
16239   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
16240    (set (match_operand:SI 0 "register_operand" "=D")
16241         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
16242                             (const_int 2))
16243                  (match_operand:SI 3 "register_operand" "0")))
16244    (set (mem:BLK (match_dup 3))
16245         (const_int 0))
16246    (use (match_operand:SI 2 "register_operand" "a"))
16247    (use (match_dup 4))]
16248   "!TARGET_64BIT"
16249   "rep stos{l|d}"
16250   [(set_attr "type" "str")
16251    (set_attr "prefix_rep" "1")
16252    (set_attr "memory" "store")
16253    (set_attr "mode" "SI")])
16254
16255 (define_insn "*rep_stossi_rex64"
16256   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16257    (set (match_operand:DI 0 "register_operand" "=D")
16258         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
16259                             (const_int 2))
16260                  (match_operand:DI 3 "register_operand" "0")))
16261    (set (mem:BLK (match_dup 3))
16262         (const_int 0))
16263    (use (match_operand:SI 2 "register_operand" "a"))
16264    (use (match_dup 4))]
16265   "TARGET_64BIT"
16266   "rep stos{l|d}"
16267   [(set_attr "type" "str")
16268    (set_attr "prefix_rep" "1")
16269    (set_attr "memory" "store")
16270    (set_attr "mode" "SI")])
16271
16272 (define_insn "*rep_stosqi"
16273   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
16274    (set (match_operand:SI 0 "register_operand" "=D")
16275         (plus:SI (match_operand:SI 3 "register_operand" "0")
16276                  (match_operand:SI 4 "register_operand" "1")))
16277    (set (mem:BLK (match_dup 3))
16278         (const_int 0))
16279    (use (match_operand:QI 2 "register_operand" "a"))
16280    (use (match_dup 4))]
16281   "!TARGET_64BIT"
16282   "rep stosb"
16283   [(set_attr "type" "str")
16284    (set_attr "prefix_rep" "1")
16285    (set_attr "memory" "store")
16286    (set_attr "mode" "QI")])
16287
16288 (define_insn "*rep_stosqi_rex64"
16289   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16290    (set (match_operand:DI 0 "register_operand" "=D")
16291         (plus:DI (match_operand:DI 3 "register_operand" "0")
16292                  (match_operand:DI 4 "register_operand" "1")))
16293    (set (mem:BLK (match_dup 3))
16294         (const_int 0))
16295    (use (match_operand:QI 2 "register_operand" "a"))
16296    (use (match_dup 4))]
16297   "TARGET_64BIT"
16298   "rep stosb"
16299   [(set_attr "type" "str")
16300    (set_attr "prefix_rep" "1")
16301    (set_attr "memory" "store")
16302    (set_attr "prefix_rex" "0")
16303    (set_attr "mode" "QI")])
16304
16305 (define_expand "cmpstrnsi"
16306   [(set (match_operand:SI 0 "register_operand" "")
16307         (compare:SI (match_operand:BLK 1 "general_operand" "")
16308                     (match_operand:BLK 2 "general_operand" "")))
16309    (use (match_operand 3 "general_operand" ""))
16310    (use (match_operand 4 "immediate_operand" ""))]
16311   ""
16312 {
16313   rtx addr1, addr2, out, outlow, count, countreg, align;
16314
16315   if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16316     FAIL;
16317
16318   /* Can't use this if the user has appropriated esi or edi.  */
16319   if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
16320     FAIL;
16321
16322   out = operands[0];
16323   if (!REG_P (out))
16324     out = gen_reg_rtx (SImode);
16325
16326   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
16327   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
16328   if (addr1 != XEXP (operands[1], 0))
16329     operands[1] = replace_equiv_address_nv (operands[1], addr1);
16330   if (addr2 != XEXP (operands[2], 0))
16331     operands[2] = replace_equiv_address_nv (operands[2], addr2);
16332
16333   count = operands[3];
16334   countreg = ix86_zero_extend_to_Pmode (count);
16335
16336   /* %%% Iff we are testing strict equality, we can use known alignment
16337      to good advantage.  This may be possible with combine, particularly
16338      once cc0 is dead.  */
16339   align = operands[4];
16340
16341   if (CONST_INT_P (count))
16342     {
16343       if (INTVAL (count) == 0)
16344         {
16345           emit_move_insn (operands[0], const0_rtx);
16346           DONE;
16347         }
16348       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16349                                      operands[1], operands[2]));
16350     }
16351   else
16352     {
16353       rtx (*cmp_insn)(rtx, rtx);
16354
16355       if (TARGET_64BIT)
16356         cmp_insn = gen_cmpdi_1;
16357       else
16358         cmp_insn = gen_cmpsi_1;
16359       emit_insn (cmp_insn (countreg, countreg));
16360       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16361                                   operands[1], operands[2]));
16362     }
16363
16364   outlow = gen_lowpart (QImode, out);
16365   emit_insn (gen_cmpintqi (outlow));
16366   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16367
16368   if (operands[0] != out)
16369     emit_move_insn (operands[0], out);
16370
16371   DONE;
16372 })
16373
16374 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16375
16376 (define_expand "cmpintqi"
16377   [(set (match_dup 1)
16378         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16379    (set (match_dup 2)
16380         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16381    (parallel [(set (match_operand:QI 0 "register_operand" "")
16382                    (minus:QI (match_dup 1)
16383                              (match_dup 2)))
16384               (clobber (reg:CC FLAGS_REG))])]
16385   ""
16386   "operands[1] = gen_reg_rtx (QImode);
16387    operands[2] = gen_reg_rtx (QImode);")
16388
16389 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
16390 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
16391
16392 (define_expand "cmpstrnqi_nz_1"
16393   [(parallel [(set (reg:CC FLAGS_REG)
16394                    (compare:CC (match_operand 4 "memory_operand" "")
16395                                (match_operand 5 "memory_operand" "")))
16396               (use (match_operand 2 "register_operand" ""))
16397               (use (match_operand:SI 3 "immediate_operand" ""))
16398               (clobber (match_operand 0 "register_operand" ""))
16399               (clobber (match_operand 1 "register_operand" ""))
16400               (clobber (match_dup 2))])]
16401   ""
16402   "ix86_current_function_needs_cld = 1;")
16403
16404 (define_insn "*cmpstrnqi_nz_1"
16405   [(set (reg:CC FLAGS_REG)
16406         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
16407                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
16408    (use (match_operand:SI 6 "register_operand" "2"))
16409    (use (match_operand:SI 3 "immediate_operand" "i"))
16410    (clobber (match_operand:SI 0 "register_operand" "=S"))
16411    (clobber (match_operand:SI 1 "register_operand" "=D"))
16412    (clobber (match_operand:SI 2 "register_operand" "=c"))]
16413   "!TARGET_64BIT"
16414   "repz cmpsb"
16415   [(set_attr "type" "str")
16416    (set_attr "mode" "QI")
16417    (set_attr "prefix_rep" "1")])
16418
16419 (define_insn "*cmpstrnqi_nz_rex_1"
16420   [(set (reg:CC FLAGS_REG)
16421         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
16422                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
16423    (use (match_operand:DI 6 "register_operand" "2"))
16424    (use (match_operand:SI 3 "immediate_operand" "i"))
16425    (clobber (match_operand:DI 0 "register_operand" "=S"))
16426    (clobber (match_operand:DI 1 "register_operand" "=D"))
16427    (clobber (match_operand:DI 2 "register_operand" "=c"))]
16428   "TARGET_64BIT"
16429   "repz cmpsb"
16430   [(set_attr "type" "str")
16431    (set_attr "mode" "QI")
16432    (set_attr "prefix_rex" "0")
16433    (set_attr "prefix_rep" "1")])
16434
16435 ;; The same, but the count is not known to not be zero.
16436
16437 (define_expand "cmpstrnqi_1"
16438   [(parallel [(set (reg:CC FLAGS_REG)
16439                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
16440                                      (const_int 0))
16441                   (compare:CC (match_operand 4 "memory_operand" "")
16442                               (match_operand 5 "memory_operand" ""))
16443                   (const_int 0)))
16444               (use (match_operand:SI 3 "immediate_operand" ""))
16445               (use (reg:CC FLAGS_REG))
16446               (clobber (match_operand 0 "register_operand" ""))
16447               (clobber (match_operand 1 "register_operand" ""))
16448               (clobber (match_dup 2))])]
16449   ""
16450   "ix86_current_function_needs_cld = 1;")
16451
16452 (define_insn "*cmpstrnqi_1"
16453   [(set (reg:CC FLAGS_REG)
16454         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
16455                              (const_int 0))
16456           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
16457                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
16458           (const_int 0)))
16459    (use (match_operand:SI 3 "immediate_operand" "i"))
16460    (use (reg:CC FLAGS_REG))
16461    (clobber (match_operand:SI 0 "register_operand" "=S"))
16462    (clobber (match_operand:SI 1 "register_operand" "=D"))
16463    (clobber (match_operand:SI 2 "register_operand" "=c"))]
16464   "!TARGET_64BIT"
16465   "repz cmpsb"
16466   [(set_attr "type" "str")
16467    (set_attr "mode" "QI")
16468    (set_attr "prefix_rep" "1")])
16469
16470 (define_insn "*cmpstrnqi_rex_1"
16471   [(set (reg:CC FLAGS_REG)
16472         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
16473                              (const_int 0))
16474           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
16475                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
16476           (const_int 0)))
16477    (use (match_operand:SI 3 "immediate_operand" "i"))
16478    (use (reg:CC FLAGS_REG))
16479    (clobber (match_operand:DI 0 "register_operand" "=S"))
16480    (clobber (match_operand:DI 1 "register_operand" "=D"))
16481    (clobber (match_operand:DI 2 "register_operand" "=c"))]
16482   "TARGET_64BIT"
16483   "repz cmpsb"
16484   [(set_attr "type" "str")
16485    (set_attr "mode" "QI")
16486    (set_attr "prefix_rex" "0")
16487    (set_attr "prefix_rep" "1")])
16488
16489 (define_expand "strlensi"
16490   [(set (match_operand:SI 0 "register_operand" "")
16491         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
16492                     (match_operand:QI 2 "immediate_operand" "")
16493                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
16494   ""
16495 {
16496  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16497    DONE;
16498  else
16499    FAIL;
16500 })
16501
16502 (define_expand "strlendi"
16503   [(set (match_operand:DI 0 "register_operand" "")
16504         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
16505                     (match_operand:QI 2 "immediate_operand" "")
16506                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
16507   ""
16508 {
16509  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16510    DONE;
16511  else
16512    FAIL;
16513 })
16514
16515 (define_expand "strlenqi_1"
16516   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
16517               (clobber (match_operand 1 "register_operand" ""))
16518               (clobber (reg:CC FLAGS_REG))])]
16519   ""
16520   "ix86_current_function_needs_cld = 1;")
16521
16522 (define_insn "*strlenqi_1"
16523   [(set (match_operand:SI 0 "register_operand" "=&c")
16524         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
16525                     (match_operand:QI 2 "register_operand" "a")
16526                     (match_operand:SI 3 "immediate_operand" "i")
16527                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
16528    (clobber (match_operand:SI 1 "register_operand" "=D"))
16529    (clobber (reg:CC FLAGS_REG))]
16530   "!TARGET_64BIT"
16531   "repnz scasb"
16532   [(set_attr "type" "str")
16533    (set_attr "mode" "QI")
16534    (set_attr "prefix_rep" "1")])
16535
16536 (define_insn "*strlenqi_rex_1"
16537   [(set (match_operand:DI 0 "register_operand" "=&c")
16538         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
16539                     (match_operand:QI 2 "register_operand" "a")
16540                     (match_operand:DI 3 "immediate_operand" "i")
16541                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
16542    (clobber (match_operand:DI 1 "register_operand" "=D"))
16543    (clobber (reg:CC FLAGS_REG))]
16544   "TARGET_64BIT"
16545   "repnz scasb"
16546   [(set_attr "type" "str")
16547    (set_attr "mode" "QI")
16548    (set_attr "prefix_rex" "0")
16549    (set_attr "prefix_rep" "1")])
16550
16551 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
16552 ;; handled in combine, but it is not currently up to the task.
16553 ;; When used for their truth value, the cmpstrn* expanders generate
16554 ;; code like this:
16555 ;;
16556 ;;   repz cmpsb
16557 ;;   seta       %al
16558 ;;   setb       %dl
16559 ;;   cmpb       %al, %dl
16560 ;;   jcc        label
16561 ;;
16562 ;; The intermediate three instructions are unnecessary.
16563
16564 ;; This one handles cmpstrn*_nz_1...
16565 (define_peephole2
16566   [(parallel[
16567      (set (reg:CC FLAGS_REG)
16568           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16569                       (mem:BLK (match_operand 5 "register_operand" ""))))
16570      (use (match_operand 6 "register_operand" ""))
16571      (use (match_operand:SI 3 "immediate_operand" ""))
16572      (clobber (match_operand 0 "register_operand" ""))
16573      (clobber (match_operand 1 "register_operand" ""))
16574      (clobber (match_operand 2 "register_operand" ""))])
16575    (set (match_operand:QI 7 "register_operand" "")
16576         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16577    (set (match_operand:QI 8 "register_operand" "")
16578         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16579    (set (reg FLAGS_REG)
16580         (compare (match_dup 7) (match_dup 8)))
16581   ]
16582   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16583   [(parallel[
16584      (set (reg:CC FLAGS_REG)
16585           (compare:CC (mem:BLK (match_dup 4))
16586                       (mem:BLK (match_dup 5))))
16587      (use (match_dup 6))
16588      (use (match_dup 3))
16589      (clobber (match_dup 0))
16590      (clobber (match_dup 1))
16591      (clobber (match_dup 2))])]
16592   "")
16593
16594 ;; ...and this one handles cmpstrn*_1.
16595 (define_peephole2
16596   [(parallel[
16597      (set (reg:CC FLAGS_REG)
16598           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
16599                                (const_int 0))
16600             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16601                         (mem:BLK (match_operand 5 "register_operand" "")))
16602             (const_int 0)))
16603      (use (match_operand:SI 3 "immediate_operand" ""))
16604      (use (reg:CC FLAGS_REG))
16605      (clobber (match_operand 0 "register_operand" ""))
16606      (clobber (match_operand 1 "register_operand" ""))
16607      (clobber (match_operand 2 "register_operand" ""))])
16608    (set (match_operand:QI 7 "register_operand" "")
16609         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16610    (set (match_operand:QI 8 "register_operand" "")
16611         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16612    (set (reg FLAGS_REG)
16613         (compare (match_dup 7) (match_dup 8)))
16614   ]
16615   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16616   [(parallel[
16617      (set (reg:CC FLAGS_REG)
16618           (if_then_else:CC (ne (match_dup 6)
16619                                (const_int 0))
16620             (compare:CC (mem:BLK (match_dup 4))
16621                         (mem:BLK (match_dup 5)))
16622             (const_int 0)))
16623      (use (match_dup 3))
16624      (use (reg:CC FLAGS_REG))
16625      (clobber (match_dup 0))
16626      (clobber (match_dup 1))
16627      (clobber (match_dup 2))])]
16628   "")
16629
16630
16631 \f
16632 ;; Conditional move instructions.
16633
16634 (define_expand "mov<mode>cc"
16635   [(set (match_operand:SWIM 0 "register_operand" "")
16636         (if_then_else:SWIM (match_operand 1 "comparison_operator" "")
16637                            (match_operand:SWIM 2 "general_operand" "")
16638                            (match_operand:SWIM 3 "general_operand" "")))]
16639   ""
16640   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16641
16642 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16643 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16644 ;; So just document what we're doing explicitly.
16645
16646 (define_expand "x86_mov<mode>cc_0_m1"
16647   [(parallel
16648     [(set (match_operand:SWI48 0 "register_operand" "")
16649           (if_then_else:SWI48
16650             (match_operator:SWI48 2 "ix86_carry_flag_operator"
16651              [(match_operand 1 "flags_reg_operand" "")
16652               (const_int 0)])
16653             (const_int -1)
16654             (const_int 0)))
16655      (clobber (reg:CC FLAGS_REG))])]
16656   ""
16657   "")
16658
16659 (define_insn "*x86_mov<mode>cc_0_m1"
16660   [(set (match_operand:SWI48 0 "register_operand" "=r")
16661         (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16662                              [(reg FLAGS_REG) (const_int 0)])
16663           (const_int -1)
16664           (const_int 0)))
16665    (clobber (reg:CC FLAGS_REG))]
16666   ""
16667   "sbb{<imodesuffix>}\t%0, %0"
16668   ; Since we don't have the proper number of operands for an alu insn,
16669   ; fill in all the blanks.
16670   [(set_attr "type" "alu")
16671    (set_attr "use_carry" "1")
16672    (set_attr "pent_pair" "pu")
16673    (set_attr "memory" "none")
16674    (set_attr "imm_disp" "false")
16675    (set_attr "mode" "<MODE>")
16676    (set_attr "length_immediate" "0")])
16677
16678 (define_insn "*x86_mov<mode>cc_0_m1_se"
16679   [(set (match_operand:SWI48 0 "register_operand" "=r")
16680         (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16681                              [(reg FLAGS_REG) (const_int 0)])
16682                             (const_int 1)
16683                             (const_int 0)))
16684    (clobber (reg:CC FLAGS_REG))]
16685   ""
16686   "sbb{<imodesuffix>}\t%0, %0"
16687   [(set_attr "type" "alu")
16688    (set_attr "use_carry" "1")
16689    (set_attr "pent_pair" "pu")
16690    (set_attr "memory" "none")
16691    (set_attr "imm_disp" "false")
16692    (set_attr "mode" "<MODE>")
16693    (set_attr "length_immediate" "0")])
16694
16695 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16696   [(set (match_operand:SWI48 0 "register_operand" "=r")
16697         (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16698                     [(reg FLAGS_REG) (const_int 0)])))]
16699   ""
16700   "sbb{<imodesuffix>}\t%0, %0"
16701   [(set_attr "type" "alu")
16702    (set_attr "use_carry" "1")
16703    (set_attr "pent_pair" "pu")
16704    (set_attr "memory" "none")
16705    (set_attr "imm_disp" "false")
16706    (set_attr "mode" "<MODE>")
16707    (set_attr "length_immediate" "0")])
16708
16709 (define_insn "*mov<mode>cc_noc"
16710   [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16711         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16712                                [(reg FLAGS_REG) (const_int 0)])
16713           (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16714           (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16715   "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16716   "@
16717    cmov%O2%C1\t{%2, %0|%0, %2}
16718    cmov%O2%c1\t{%3, %0|%0, %3}"
16719   [(set_attr "type" "icmov")
16720    (set_attr "mode" "<MODE>")])
16721
16722 (define_insn_and_split "*movqicc_noc"
16723   [(set (match_operand:QI 0 "register_operand" "=r,r")
16724         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16725                            [(match_operand 4 "flags_reg_operand" "")
16726                             (const_int 0)])
16727                       (match_operand:QI 2 "register_operand" "r,0")
16728                       (match_operand:QI 3 "register_operand" "0,r")))]
16729   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16730   "#"
16731   "&& reload_completed"
16732   [(set (match_dup 0)
16733         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16734                       (match_dup 2)
16735                       (match_dup 3)))]
16736   "operands[0] = gen_lowpart (SImode, operands[0]);
16737    operands[2] = gen_lowpart (SImode, operands[2]);
16738    operands[3] = gen_lowpart (SImode, operands[3]);"
16739   [(set_attr "type" "icmov")
16740    (set_attr "mode" "SI")])
16741
16742 (define_expand "mov<mode>cc"
16743   [(set (match_operand:X87MODEF 0 "register_operand" "")
16744         (if_then_else:X87MODEF
16745           (match_operand 1 "ix86_fp_comparison_operator" "")
16746           (match_operand:X87MODEF 2 "register_operand" "")
16747           (match_operand:X87MODEF 3 "register_operand" "")))]
16748   "(TARGET_80387 && TARGET_CMOVE)
16749    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16750   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16751
16752 (define_insn "*movsfcc_1_387"
16753   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16754         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16755                                 [(reg FLAGS_REG) (const_int 0)])
16756                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16757                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16758   "TARGET_80387 && TARGET_CMOVE
16759    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16760   "@
16761    fcmov%F1\t{%2, %0|%0, %2}
16762    fcmov%f1\t{%3, %0|%0, %3}
16763    cmov%O2%C1\t{%2, %0|%0, %2}
16764    cmov%O2%c1\t{%3, %0|%0, %3}"
16765   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16766    (set_attr "mode" "SF,SF,SI,SI")])
16767
16768 (define_insn "*movdfcc_1"
16769   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16770         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16771                                 [(reg FLAGS_REG) (const_int 0)])
16772                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16773                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16774   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16775    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16776   "@
16777    fcmov%F1\t{%2, %0|%0, %2}
16778    fcmov%f1\t{%3, %0|%0, %3}
16779    #
16780    #"
16781   [(set_attr "type" "fcmov,fcmov,multi,multi")
16782    (set_attr "mode" "DF")])
16783
16784 (define_insn "*movdfcc_1_rex64"
16785   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16786         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16787                                 [(reg FLAGS_REG) (const_int 0)])
16788                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16789                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16790   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16791    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16792   "@
16793    fcmov%F1\t{%2, %0|%0, %2}
16794    fcmov%f1\t{%3, %0|%0, %3}
16795    cmov%O2%C1\t{%2, %0|%0, %2}
16796    cmov%O2%c1\t{%3, %0|%0, %3}"
16797   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16798    (set_attr "mode" "DF")])
16799
16800 (define_split
16801   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16802         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16803                                 [(match_operand 4 "flags_reg_operand" "")
16804                                  (const_int 0)])
16805                       (match_operand:DF 2 "nonimmediate_operand" "")
16806                       (match_operand:DF 3 "nonimmediate_operand" "")))]
16807   "!TARGET_64BIT && reload_completed"
16808   [(set (match_dup 2)
16809         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16810                       (match_dup 5)
16811                       (match_dup 6)))
16812    (set (match_dup 3)
16813         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16814                       (match_dup 7)
16815                       (match_dup 8)))]
16816   "split_di (&operands[2], 2, &operands[5], &operands[7]);
16817    split_di (&operands[0], 1, &operands[2], &operands[3]);")
16818
16819 (define_insn "*movxfcc_1"
16820   [(set (match_operand:XF 0 "register_operand" "=f,f")
16821         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16822                                 [(reg FLAGS_REG) (const_int 0)])
16823                       (match_operand:XF 2 "register_operand" "f,0")
16824                       (match_operand:XF 3 "register_operand" "0,f")))]
16825   "TARGET_80387 && TARGET_CMOVE"
16826   "@
16827    fcmov%F1\t{%2, %0|%0, %2}
16828    fcmov%f1\t{%3, %0|%0, %3}"
16829   [(set_attr "type" "fcmov")
16830    (set_attr "mode" "XF")])
16831
16832 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16833 ;; the scalar versions to have only XMM registers as operands.
16834
16835 ;; XOP conditional move
16836 (define_insn "*xop_pcmov_<mode>"
16837   [(set (match_operand:MODEF 0 "register_operand" "=x")
16838         (if_then_else:MODEF
16839           (match_operand:MODEF 1 "register_operand" "x")
16840           (match_operand:MODEF 2 "register_operand" "x")
16841           (match_operand:MODEF 3 "register_operand" "x")))]
16842   "TARGET_XOP"
16843   "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16844   [(set_attr "type" "sse4arg")])
16845
16846 ;; These versions of the min/max patterns are intentionally ignorant of
16847 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16848 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16849 ;; are undefined in this condition, we're certain this is correct.
16850
16851 (define_insn "*avx_<code><mode>3"
16852   [(set (match_operand:MODEF 0 "register_operand" "=x")
16853         (smaxmin:MODEF
16854           (match_operand:MODEF 1 "nonimmediate_operand" "%x")
16855           (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
16856   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16857   "v<maxminfprefix>s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16858   [(set_attr "type" "sseadd")
16859    (set_attr "prefix" "vex")
16860    (set_attr "mode" "<MODE>")])
16861
16862 (define_insn "<code><mode>3"
16863   [(set (match_operand:MODEF 0 "register_operand" "=x")
16864         (smaxmin:MODEF
16865           (match_operand:MODEF 1 "nonimmediate_operand" "%0")
16866           (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
16867   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16868   "<maxminfprefix>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
16869   [(set_attr "type" "sseadd")
16870    (set_attr "mode" "<MODE>")])
16871
16872 ;; These versions of the min/max patterns implement exactly the operations
16873 ;;   min = (op1 < op2 ? op1 : op2)
16874 ;;   max = (!(op1 < op2) ? op1 : op2)
16875 ;; Their operands are not commutative, and thus they may be used in the
16876 ;; presence of -0.0 and NaN.
16877
16878 (define_insn "*avx_ieee_smin<mode>3"
16879   [(set (match_operand:MODEF 0 "register_operand" "=x")
16880         (unspec:MODEF
16881           [(match_operand:MODEF 1 "register_operand" "x")
16882            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16883          UNSPEC_IEEE_MIN))]
16884   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16885   "vmins<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16886   [(set_attr "type" "sseadd")
16887    (set_attr "prefix" "vex")
16888    (set_attr "mode" "<MODE>")])
16889
16890 (define_insn "*ieee_smin<mode>3"
16891   [(set (match_operand:MODEF 0 "register_operand" "=x")
16892         (unspec:MODEF
16893           [(match_operand:MODEF 1 "register_operand" "0")
16894            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16895          UNSPEC_IEEE_MIN))]
16896   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16897   "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
16898   [(set_attr "type" "sseadd")
16899    (set_attr "mode" "<MODE>")])
16900
16901 (define_insn "*avx_ieee_smax<mode>3"
16902   [(set (match_operand:MODEF 0 "register_operand" "=x")
16903         (unspec:MODEF
16904           [(match_operand:MODEF 1 "register_operand" "0")
16905            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16906          UNSPEC_IEEE_MAX))]
16907   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16908   "vmaxs<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16909   [(set_attr "type" "sseadd")
16910    (set_attr "prefix" "vex")
16911    (set_attr "mode" "<MODE>")])
16912
16913 (define_insn "*ieee_smax<mode>3"
16914   [(set (match_operand:MODEF 0 "register_operand" "=x")
16915         (unspec:MODEF
16916           [(match_operand:MODEF 1 "register_operand" "0")
16917            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16918          UNSPEC_IEEE_MAX))]
16919   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16920   "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
16921   [(set_attr "type" "sseadd")
16922    (set_attr "mode" "<MODE>")])
16923
16924 ;; Make two stack loads independent:
16925 ;;   fld aa              fld aa
16926 ;;   fld %st(0)     ->   fld bb
16927 ;;   fmul bb             fmul %st(1), %st
16928 ;;
16929 ;; Actually we only match the last two instructions for simplicity.
16930 (define_peephole2
16931   [(set (match_operand 0 "fp_register_operand" "")
16932         (match_operand 1 "fp_register_operand" ""))
16933    (set (match_dup 0)
16934         (match_operator 2 "binary_fp_operator"
16935            [(match_dup 0)
16936             (match_operand 3 "memory_operand" "")]))]
16937   "REGNO (operands[0]) != REGNO (operands[1])"
16938   [(set (match_dup 0) (match_dup 3))
16939    (set (match_dup 0) (match_dup 4))]
16940
16941   ;; The % modifier is not operational anymore in peephole2's, so we have to
16942   ;; swap the operands manually in the case of addition and multiplication.
16943   "if (COMMUTATIVE_ARITH_P (operands[2]))
16944      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
16945                                  operands[0], operands[1]);
16946    else
16947      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
16948                                  operands[1], operands[0]);")
16949
16950 ;; Conditional addition patterns
16951 (define_expand "add<mode>cc"
16952   [(match_operand:SWI 0 "register_operand" "")
16953    (match_operand 1 "comparison_operator" "")
16954    (match_operand:SWI 2 "register_operand" "")
16955    (match_operand:SWI 3 "const_int_operand" "")]
16956   ""
16957   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16958
16959 \f
16960 ;; Misc patterns (?)
16961
16962 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16963 ;; Otherwise there will be nothing to keep
16964 ;;
16965 ;; [(set (reg ebp) (reg esp))]
16966 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16967 ;;  (clobber (eflags)]
16968 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16969 ;;
16970 ;; in proper program order.
16971 (define_insn "pro_epilogue_adjust_stack_1"
16972   [(set (match_operand:SI 0 "register_operand" "=r,r")
16973         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
16974                  (match_operand:SI 2 "immediate_operand" "i,i")))
16975    (clobber (reg:CC FLAGS_REG))
16976    (clobber (mem:BLK (scratch)))]
16977   "!TARGET_64BIT"
16978 {
16979   switch (get_attr_type (insn))
16980     {
16981     case TYPE_IMOV:
16982       return "mov{l}\t{%1, %0|%0, %1}";
16983
16984     case TYPE_ALU:
16985       if (CONST_INT_P (operands[2])
16986           && (INTVAL (operands[2]) == 128
16987               || (INTVAL (operands[2]) < 0
16988                   && INTVAL (operands[2]) != -128)))
16989         {
16990           operands[2] = GEN_INT (-INTVAL (operands[2]));
16991           return "sub{l}\t{%2, %0|%0, %2}";
16992         }
16993       return "add{l}\t{%2, %0|%0, %2}";
16994
16995     case TYPE_LEA:
16996       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16997       return "lea{l}\t{%a2, %0|%0, %a2}";
16998
16999     default:
17000       gcc_unreachable ();
17001     }
17002 }
17003   [(set (attr "type")
17004         (cond [(and (eq_attr "alternative" "0") 
17005                     (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
17006                  (const_string "alu")
17007                (match_operand:SI 2 "const0_operand" "")
17008                  (const_string "imov")
17009               ]
17010               (const_string "lea")))
17011    (set (attr "length_immediate")
17012         (cond [(eq_attr "type" "imov")
17013                  (const_string "0")
17014                (and (eq_attr "type" "alu")
17015                     (match_operand 2 "const128_operand" ""))
17016                  (const_string "1")
17017               ]
17018               (const_string "*")))
17019    (set_attr "mode" "SI")])
17020
17021 (define_insn "pro_epilogue_adjust_stack_rex64"
17022   [(set (match_operand:DI 0 "register_operand" "=r,r")
17023         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
17024                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
17025    (clobber (reg:CC FLAGS_REG))
17026    (clobber (mem:BLK (scratch)))]
17027   "TARGET_64BIT"
17028 {
17029   switch (get_attr_type (insn))
17030     {
17031     case TYPE_IMOV:
17032       return "mov{q}\t{%1, %0|%0, %1}";
17033
17034     case TYPE_ALU:
17035       if (CONST_INT_P (operands[2])
17036           /* Avoid overflows.  */
17037           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
17038           && (INTVAL (operands[2]) == 128
17039               || (INTVAL (operands[2]) < 0
17040                   && INTVAL (operands[2]) != -128)))
17041         {
17042           operands[2] = GEN_INT (-INTVAL (operands[2]));
17043           return "sub{q}\t{%2, %0|%0, %2}";
17044         }
17045       return "add{q}\t{%2, %0|%0, %2}";
17046
17047     case TYPE_LEA:
17048       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
17049       return "lea{q}\t{%a2, %0|%0, %a2}";
17050
17051     default:
17052       gcc_unreachable ();
17053     }
17054 }
17055   [(set (attr "type")
17056         (cond [(and (eq_attr "alternative" "0")
17057                     (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
17058                  (const_string "alu")
17059                (match_operand:DI 2 "const0_operand" "")
17060                  (const_string "imov")
17061               ]
17062               (const_string "lea")))
17063    (set (attr "length_immediate")
17064         (cond [(eq_attr "type" "imov")
17065                  (const_string "0")
17066                (and (eq_attr "type" "alu")
17067                     (match_operand 2 "const128_operand" ""))
17068                  (const_string "1")
17069               ]
17070               (const_string "*")))
17071    (set_attr "mode" "DI")])
17072
17073 (define_insn "pro_epilogue_adjust_stack_rex64_2"
17074   [(set (match_operand:DI 0 "register_operand" "=r,r")
17075         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
17076                  (match_operand:DI 3 "immediate_operand" "i,i")))
17077    (use (match_operand:DI 2 "register_operand" "r,r"))
17078    (clobber (reg:CC FLAGS_REG))
17079    (clobber (mem:BLK (scratch)))]
17080   "TARGET_64BIT"
17081 {
17082   switch (get_attr_type (insn))
17083     {
17084     case TYPE_ALU:
17085       return "add{q}\t{%2, %0|%0, %2}";
17086
17087     case TYPE_LEA:
17088       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
17089       return "lea{q}\t{%a2, %0|%0, %a2}";
17090
17091     default:
17092       gcc_unreachable ();
17093     }
17094 }
17095   [(set_attr "type" "alu,lea")
17096    (set_attr "mode" "DI")])
17097
17098 (define_insn "allocate_stack_worker_32"
17099   [(set (match_operand:SI 0 "register_operand" "=a")
17100         (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")]
17101                             UNSPECV_STACK_PROBE))
17102    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 1)))
17103    (clobber (reg:CC FLAGS_REG))]
17104   "!TARGET_64BIT && TARGET_STACK_PROBE"
17105   "call\t___chkstk"
17106   [(set_attr "type" "multi")
17107    (set_attr "length" "5")])
17108
17109 (define_insn "allocate_stack_worker_64"
17110   [(set (match_operand:DI 0 "register_operand" "=a")
17111         (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "0")]
17112                             UNSPECV_STACK_PROBE))
17113    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 1)))
17114    (clobber (reg:DI R10_REG))
17115    (clobber (reg:DI R11_REG))
17116    (clobber (reg:CC FLAGS_REG))]
17117   "TARGET_64BIT && TARGET_STACK_PROBE"
17118   "call\t___chkstk"
17119   [(set_attr "type" "multi")
17120    (set_attr "length" "5")])
17121
17122 (define_expand "allocate_stack"
17123   [(match_operand 0 "register_operand" "")
17124    (match_operand 1 "general_operand" "")]
17125   "TARGET_STACK_PROBE"
17126 {
17127   rtx x;
17128
17129 #ifndef CHECK_STACK_LIMIT
17130 #define CHECK_STACK_LIMIT 0
17131 #endif
17132
17133   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
17134       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
17135     {
17136       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
17137                                stack_pointer_rtx, 0, OPTAB_DIRECT);
17138       if (x != stack_pointer_rtx)
17139         emit_move_insn (stack_pointer_rtx, x);
17140     }
17141   else
17142     {
17143       x = copy_to_mode_reg (Pmode, operands[1]);
17144       if (TARGET_64BIT)
17145         x = gen_allocate_stack_worker_64 (x, x);
17146       else
17147         x = gen_allocate_stack_worker_32 (x, x);
17148       emit_insn (x);
17149     }
17150
17151   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
17152   DONE;
17153 })
17154
17155 ;; Use IOR for stack probes, this is shorter.
17156 (define_expand "probe_stack"
17157   [(match_operand 0 "memory_operand" "")]
17158   ""
17159 {
17160   if (GET_MODE (operands[0]) == DImode)
17161     emit_insn (gen_iordi3 (operands[0], operands[0], const0_rtx));
17162   else
17163     emit_insn (gen_iorsi3 (operands[0], operands[0], const0_rtx));
17164   DONE;
17165 })
17166
17167 (define_expand "builtin_setjmp_receiver"
17168   [(label_ref (match_operand 0 "" ""))]
17169   "!TARGET_64BIT && flag_pic"
17170 {
17171 #if TARGET_MACHO
17172   if (TARGET_MACHO)
17173     {
17174       rtx xops[3];
17175       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
17176       rtx label_rtx = gen_label_rtx ();
17177       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
17178       xops[0] = xops[1] = picreg;
17179       xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
17180       ix86_expand_binary_operator (MINUS, SImode, xops);
17181     }
17182   else
17183 #endif
17184     emit_insn (gen_set_got (pic_offset_table_rtx));
17185   DONE;
17186 })
17187 \f
17188 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
17189
17190 (define_split
17191   [(set (match_operand 0 "register_operand" "")
17192         (match_operator 3 "promotable_binary_operator"
17193            [(match_operand 1 "register_operand" "")
17194             (match_operand 2 "aligned_operand" "")]))
17195    (clobber (reg:CC FLAGS_REG))]
17196   "! TARGET_PARTIAL_REG_STALL && reload_completed
17197    && ((GET_MODE (operands[0]) == HImode
17198         && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
17199             /* ??? next two lines just !satisfies_constraint_K (...) */
17200             || !CONST_INT_P (operands[2])
17201             || satisfies_constraint_K (operands[2])))
17202        || (GET_MODE (operands[0]) == QImode
17203            && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
17204   [(parallel [(set (match_dup 0)
17205                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17206               (clobber (reg:CC FLAGS_REG))])]
17207   "operands[0] = gen_lowpart (SImode, operands[0]);
17208    operands[1] = gen_lowpart (SImode, operands[1]);
17209    if (GET_CODE (operands[3]) != ASHIFT)
17210      operands[2] = gen_lowpart (SImode, operands[2]);
17211    PUT_MODE (operands[3], SImode);")
17212
17213 ; Promote the QImode tests, as i386 has encoding of the AND
17214 ; instruction with 32-bit sign-extended immediate and thus the
17215 ; instruction size is unchanged, except in the %eax case for
17216 ; which it is increased by one byte, hence the ! optimize_size.
17217 (define_split
17218   [(set (match_operand 0 "flags_reg_operand" "")
17219         (match_operator 2 "compare_operator"
17220           [(and (match_operand 3 "aligned_operand" "")
17221                 (match_operand 4 "const_int_operand" ""))
17222            (const_int 0)]))
17223    (set (match_operand 1 "register_operand" "")
17224         (and (match_dup 3) (match_dup 4)))]
17225   "! TARGET_PARTIAL_REG_STALL && reload_completed
17226    && optimize_insn_for_speed_p ()
17227    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
17228        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
17229    /* Ensure that the operand will remain sign-extended immediate.  */
17230    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
17231   [(parallel [(set (match_dup 0)
17232                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
17233                                     (const_int 0)]))
17234               (set (match_dup 1)
17235                    (and:SI (match_dup 3) (match_dup 4)))])]
17236 {
17237   operands[4]
17238     = gen_int_mode (INTVAL (operands[4])
17239                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
17240   operands[1] = gen_lowpart (SImode, operands[1]);
17241   operands[3] = gen_lowpart (SImode, operands[3]);
17242 })
17243
17244 ; Don't promote the QImode tests, as i386 doesn't have encoding of
17245 ; the TEST instruction with 32-bit sign-extended immediate and thus
17246 ; the instruction size would at least double, which is not what we
17247 ; want even with ! optimize_size.
17248 (define_split
17249   [(set (match_operand 0 "flags_reg_operand" "")
17250         (match_operator 1 "compare_operator"
17251           [(and (match_operand:HI 2 "aligned_operand" "")
17252                 (match_operand:HI 3 "const_int_operand" ""))
17253            (const_int 0)]))]
17254   "! TARGET_PARTIAL_REG_STALL && reload_completed
17255    && ! TARGET_FAST_PREFIX
17256    && optimize_insn_for_speed_p ()
17257    /* Ensure that the operand will remain sign-extended immediate.  */
17258    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
17259   [(set (match_dup 0)
17260         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17261                          (const_int 0)]))]
17262 {
17263   operands[3]
17264     = gen_int_mode (INTVAL (operands[3])
17265                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
17266   operands[2] = gen_lowpart (SImode, operands[2]);
17267 })
17268
17269 (define_split
17270   [(set (match_operand 0 "register_operand" "")
17271         (neg (match_operand 1 "register_operand" "")))
17272    (clobber (reg:CC FLAGS_REG))]
17273   "! TARGET_PARTIAL_REG_STALL && reload_completed
17274    && (GET_MODE (operands[0]) == HImode
17275        || (GET_MODE (operands[0]) == QImode
17276            && (TARGET_PROMOTE_QImode
17277                || optimize_insn_for_size_p ())))"
17278   [(parallel [(set (match_dup 0)
17279                    (neg:SI (match_dup 1)))
17280               (clobber (reg:CC FLAGS_REG))])]
17281   "operands[0] = gen_lowpart (SImode, operands[0]);
17282    operands[1] = gen_lowpart (SImode, operands[1]);")
17283
17284 (define_split
17285   [(set (match_operand 0 "register_operand" "")
17286         (not (match_operand 1 "register_operand" "")))]
17287   "! TARGET_PARTIAL_REG_STALL && reload_completed
17288    && (GET_MODE (operands[0]) == HImode
17289        || (GET_MODE (operands[0]) == QImode
17290            && (TARGET_PROMOTE_QImode
17291                || optimize_insn_for_size_p ())))"
17292   [(set (match_dup 0)
17293         (not:SI (match_dup 1)))]
17294   "operands[0] = gen_lowpart (SImode, operands[0]);
17295    operands[1] = gen_lowpart (SImode, operands[1]);")
17296
17297 (define_split
17298   [(set (match_operand 0 "register_operand" "")
17299         (if_then_else (match_operator 1 "comparison_operator"
17300                                 [(reg FLAGS_REG) (const_int 0)])
17301                       (match_operand 2 "register_operand" "")
17302                       (match_operand 3 "register_operand" "")))]
17303   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
17304    && (GET_MODE (operands[0]) == HImode
17305        || (GET_MODE (operands[0]) == QImode
17306            && (TARGET_PROMOTE_QImode
17307                || optimize_insn_for_size_p ())))"
17308   [(set (match_dup 0)
17309         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
17310   "operands[0] = gen_lowpart (SImode, operands[0]);
17311    operands[2] = gen_lowpart (SImode, operands[2]);
17312    operands[3] = gen_lowpart (SImode, operands[3]);")
17313
17314 \f
17315 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
17316 ;; transform a complex memory operation into two memory to register operations.
17317
17318 ;; Don't push memory operands
17319 (define_peephole2
17320   [(set (match_operand:SI 0 "push_operand" "")
17321         (match_operand:SI 1 "memory_operand" ""))
17322    (match_scratch:SI 2 "r")]
17323   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
17324    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17325   [(set (match_dup 2) (match_dup 1))
17326    (set (match_dup 0) (match_dup 2))]
17327   "")
17328
17329 (define_peephole2
17330   [(set (match_operand:DI 0 "push_operand" "")
17331         (match_operand:DI 1 "memory_operand" ""))
17332    (match_scratch:DI 2 "r")]
17333   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
17334    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17335   [(set (match_dup 2) (match_dup 1))
17336    (set (match_dup 0) (match_dup 2))]
17337   "")
17338
17339 ;; We need to handle SFmode only, because DFmode and XFmode is split to
17340 ;; SImode pushes.
17341 (define_peephole2
17342   [(set (match_operand:SF 0 "push_operand" "")
17343         (match_operand:SF 1 "memory_operand" ""))
17344    (match_scratch:SF 2 "r")]
17345   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
17346    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17347   [(set (match_dup 2) (match_dup 1))
17348    (set (match_dup 0) (match_dup 2))]
17349   "")
17350
17351 (define_peephole2
17352   [(set (match_operand:HI 0 "push_operand" "")
17353         (match_operand:HI 1 "memory_operand" ""))
17354    (match_scratch:HI 2 "r")]
17355   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
17356    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17357   [(set (match_dup 2) (match_dup 1))
17358    (set (match_dup 0) (match_dup 2))]
17359   "")
17360
17361 (define_peephole2
17362   [(set (match_operand:QI 0 "push_operand" "")
17363         (match_operand:QI 1 "memory_operand" ""))
17364    (match_scratch:QI 2 "q")]
17365   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
17366    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17367   [(set (match_dup 2) (match_dup 1))
17368    (set (match_dup 0) (match_dup 2))]
17369   "")
17370
17371 ;; Don't move an immediate directly to memory when the instruction
17372 ;; gets too big.
17373 (define_peephole2
17374   [(match_scratch:SI 1 "r")
17375    (set (match_operand:SI 0 "memory_operand" "")
17376         (const_int 0))]
17377   "optimize_insn_for_speed_p ()
17378    && ! TARGET_USE_MOV0
17379    && TARGET_SPLIT_LONG_MOVES
17380    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
17381    && peep2_regno_dead_p (0, FLAGS_REG)"
17382   [(parallel [(set (match_dup 1) (const_int 0))
17383               (clobber (reg:CC FLAGS_REG))])
17384    (set (match_dup 0) (match_dup 1))]
17385   "")
17386
17387 (define_peephole2
17388   [(match_scratch:HI 1 "r")
17389    (set (match_operand:HI 0 "memory_operand" "")
17390         (const_int 0))]
17391   "optimize_insn_for_speed_p ()
17392    && ! TARGET_USE_MOV0
17393    && TARGET_SPLIT_LONG_MOVES
17394    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
17395    && peep2_regno_dead_p (0, FLAGS_REG)"
17396   [(parallel [(set (match_dup 2) (const_int 0))
17397               (clobber (reg:CC FLAGS_REG))])
17398    (set (match_dup 0) (match_dup 1))]
17399   "operands[2] = gen_lowpart (SImode, operands[1]);")
17400
17401 (define_peephole2
17402   [(match_scratch:QI 1 "q")
17403    (set (match_operand:QI 0 "memory_operand" "")
17404         (const_int 0))]
17405   "optimize_insn_for_speed_p ()
17406    && ! TARGET_USE_MOV0
17407    && TARGET_SPLIT_LONG_MOVES
17408    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
17409    && peep2_regno_dead_p (0, FLAGS_REG)"
17410   [(parallel [(set (match_dup 2) (const_int 0))
17411               (clobber (reg:CC FLAGS_REG))])
17412    (set (match_dup 0) (match_dup 1))]
17413   "operands[2] = gen_lowpart (SImode, operands[1]);")
17414
17415 (define_peephole2
17416   [(match_scratch:SI 2 "r")
17417    (set (match_operand:SI 0 "memory_operand" "")
17418         (match_operand:SI 1 "immediate_operand" ""))]
17419   "optimize_insn_for_speed_p ()
17420    && TARGET_SPLIT_LONG_MOVES
17421    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
17422   [(set (match_dup 2) (match_dup 1))
17423    (set (match_dup 0) (match_dup 2))]
17424   "")
17425
17426 (define_peephole2
17427   [(match_scratch:HI 2 "r")
17428    (set (match_operand:HI 0 "memory_operand" "")
17429         (match_operand:HI 1 "immediate_operand" ""))]
17430   "optimize_insn_for_speed_p ()
17431    && TARGET_SPLIT_LONG_MOVES
17432    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
17433   [(set (match_dup 2) (match_dup 1))
17434    (set (match_dup 0) (match_dup 2))]
17435   "")
17436
17437 (define_peephole2
17438   [(match_scratch:QI 2 "q")
17439    (set (match_operand:QI 0 "memory_operand" "")
17440         (match_operand:QI 1 "immediate_operand" ""))]
17441   "optimize_insn_for_speed_p ()
17442    && TARGET_SPLIT_LONG_MOVES
17443    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
17444   [(set (match_dup 2) (match_dup 1))
17445    (set (match_dup 0) (match_dup 2))]
17446   "")
17447
17448 ;; Don't compare memory with zero, load and use a test instead.
17449 (define_peephole2
17450   [(set (match_operand 0 "flags_reg_operand" "")
17451         (match_operator 1 "compare_operator"
17452           [(match_operand:SI 2 "memory_operand" "")
17453            (const_int 0)]))
17454    (match_scratch:SI 3 "r")]
17455   "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
17456   [(set (match_dup 3) (match_dup 2))
17457    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
17458   "")
17459
17460 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
17461 ;; Don't split NOTs with a displacement operand, because resulting XOR
17462 ;; will not be pairable anyway.
17463 ;;
17464 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
17465 ;; represented using a modRM byte.  The XOR replacement is long decoded,
17466 ;; so this split helps here as well.
17467 ;;
17468 ;; Note: Can't do this as a regular split because we can't get proper
17469 ;; lifetime information then.
17470
17471 (define_peephole2
17472   [(set (match_operand:SI 0 "nonimmediate_operand" "")
17473         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
17474   "optimize_insn_for_speed_p ()
17475    && ((TARGET_NOT_UNPAIRABLE
17476         && (!MEM_P (operands[0])
17477             || !memory_displacement_operand (operands[0], SImode)))
17478        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
17479    && peep2_regno_dead_p (0, FLAGS_REG)"
17480   [(parallel [(set (match_dup 0)
17481                    (xor:SI (match_dup 1) (const_int -1)))
17482               (clobber (reg:CC FLAGS_REG))])]
17483   "")
17484
17485 (define_peephole2
17486   [(set (match_operand:HI 0 "nonimmediate_operand" "")
17487         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
17488   "optimize_insn_for_speed_p ()
17489    && ((TARGET_NOT_UNPAIRABLE
17490         && (!MEM_P (operands[0])
17491             || !memory_displacement_operand (operands[0], HImode)))
17492        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
17493    && peep2_regno_dead_p (0, FLAGS_REG)"
17494   [(parallel [(set (match_dup 0)
17495                    (xor:HI (match_dup 1) (const_int -1)))
17496               (clobber (reg:CC FLAGS_REG))])]
17497   "")
17498
17499 (define_peephole2
17500   [(set (match_operand:QI 0 "nonimmediate_operand" "")
17501         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
17502   "optimize_insn_for_speed_p ()
17503    && ((TARGET_NOT_UNPAIRABLE
17504         && (!MEM_P (operands[0])
17505             || !memory_displacement_operand (operands[0], QImode)))
17506        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
17507    && peep2_regno_dead_p (0, FLAGS_REG)"
17508   [(parallel [(set (match_dup 0)
17509                    (xor:QI (match_dup 1) (const_int -1)))
17510               (clobber (reg:CC FLAGS_REG))])]
17511   "")
17512
17513 ;; Non pairable "test imm, reg" instructions can be translated to
17514 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
17515 ;; byte opcode instead of two, have a short form for byte operands),
17516 ;; so do it for other CPUs as well.  Given that the value was dead,
17517 ;; this should not create any new dependencies.  Pass on the sub-word
17518 ;; versions if we're concerned about partial register stalls.
17519
17520 (define_peephole2
17521   [(set (match_operand 0 "flags_reg_operand" "")
17522         (match_operator 1 "compare_operator"
17523           [(and:SI (match_operand:SI 2 "register_operand" "")
17524                    (match_operand:SI 3 "immediate_operand" ""))
17525            (const_int 0)]))]
17526   "ix86_match_ccmode (insn, CCNOmode)
17527    && (true_regnum (operands[2]) != AX_REG
17528        || satisfies_constraint_K (operands[3]))
17529    && peep2_reg_dead_p (1, operands[2])"
17530   [(parallel
17531      [(set (match_dup 0)
17532            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17533                             (const_int 0)]))
17534       (set (match_dup 2)
17535            (and:SI (match_dup 2) (match_dup 3)))])]
17536   "")
17537
17538 ;; We don't need to handle HImode case, because it will be promoted to SImode
17539 ;; on ! TARGET_PARTIAL_REG_STALL
17540
17541 (define_peephole2
17542   [(set (match_operand 0 "flags_reg_operand" "")
17543         (match_operator 1 "compare_operator"
17544           [(and:QI (match_operand:QI 2 "register_operand" "")
17545                    (match_operand:QI 3 "immediate_operand" ""))
17546            (const_int 0)]))]
17547   "! TARGET_PARTIAL_REG_STALL
17548    && ix86_match_ccmode (insn, CCNOmode)
17549    && true_regnum (operands[2]) != AX_REG
17550    && peep2_reg_dead_p (1, operands[2])"
17551   [(parallel
17552      [(set (match_dup 0)
17553            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17554                             (const_int 0)]))
17555       (set (match_dup 2)
17556            (and:QI (match_dup 2) (match_dup 3)))])]
17557   "")
17558
17559 (define_peephole2
17560   [(set (match_operand 0 "flags_reg_operand" "")
17561         (match_operator 1 "compare_operator"
17562           [(and:SI
17563              (zero_extract:SI
17564                (match_operand 2 "ext_register_operand" "")
17565                (const_int 8)
17566                (const_int 8))
17567              (match_operand 3 "const_int_operand" ""))
17568            (const_int 0)]))]
17569   "! TARGET_PARTIAL_REG_STALL
17570    && ix86_match_ccmode (insn, CCNOmode)
17571    && true_regnum (operands[2]) != AX_REG
17572    && peep2_reg_dead_p (1, operands[2])"
17573   [(parallel [(set (match_dup 0)
17574                    (match_op_dup 1
17575                      [(and:SI
17576                         (zero_extract:SI
17577                           (match_dup 2)
17578                           (const_int 8)
17579                           (const_int 8))
17580                         (match_dup 3))
17581                       (const_int 0)]))
17582               (set (zero_extract:SI (match_dup 2)
17583                                     (const_int 8)
17584                                     (const_int 8))
17585                    (and:SI
17586                      (zero_extract:SI
17587                        (match_dup 2)
17588                        (const_int 8)
17589                        (const_int 8))
17590                      (match_dup 3)))])]
17591   "")
17592
17593 ;; Don't do logical operations with memory inputs.
17594 (define_peephole2
17595   [(match_scratch:SI 2 "r")
17596    (parallel [(set (match_operand:SI 0 "register_operand" "")
17597                    (match_operator:SI 3 "arith_or_logical_operator"
17598                      [(match_dup 0)
17599                       (match_operand:SI 1 "memory_operand" "")]))
17600               (clobber (reg:CC FLAGS_REG))])]
17601   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
17602   [(set (match_dup 2) (match_dup 1))
17603    (parallel [(set (match_dup 0)
17604                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17605               (clobber (reg:CC FLAGS_REG))])]
17606   "")
17607
17608 (define_peephole2
17609   [(match_scratch:SI 2 "r")
17610    (parallel [(set (match_operand:SI 0 "register_operand" "")
17611                    (match_operator:SI 3 "arith_or_logical_operator"
17612                      [(match_operand:SI 1 "memory_operand" "")
17613                       (match_dup 0)]))
17614               (clobber (reg:CC FLAGS_REG))])]
17615   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
17616   [(set (match_dup 2) (match_dup 1))
17617    (parallel [(set (match_dup 0)
17618                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17619               (clobber (reg:CC FLAGS_REG))])]
17620   "")
17621
17622 ;; Prefer Load+RegOp to Mov+MemOp.  Watch out for cases when the memory address
17623 ;; refers to the destination of the load!
17624
17625 (define_peephole2
17626   [(set (match_operand:SI 0 "register_operand" "")
17627         (match_operand:SI 1 "register_operand" ""))
17628    (parallel [(set (match_dup 0)
17629                    (match_operator:SI 3 "commutative_operator"
17630                      [(match_dup 0)
17631                       (match_operand:SI 2 "memory_operand" "")]))
17632               (clobber (reg:CC FLAGS_REG))])]
17633   "REGNO (operands[0]) != REGNO (operands[1])
17634    && GENERAL_REGNO_P (REGNO (operands[0]))
17635    && GENERAL_REGNO_P (REGNO (operands[1]))"
17636   [(set (match_dup 0) (match_dup 4))
17637    (parallel [(set (match_dup 0)
17638                    (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17639               (clobber (reg:CC FLAGS_REG))])]
17640   "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17641
17642 (define_peephole2
17643   [(set (match_operand 0 "register_operand" "")
17644         (match_operand 1 "register_operand" ""))
17645    (set (match_dup 0)
17646                    (match_operator 3 "commutative_operator"
17647                      [(match_dup 0)
17648                       (match_operand 2 "memory_operand" "")]))]
17649   "REGNO (operands[0]) != REGNO (operands[1])
17650    && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1])) 
17651        || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17652   [(set (match_dup 0) (match_dup 2))
17653    (set (match_dup 0)
17654         (match_op_dup 3 [(match_dup 0) (match_dup 1)]))]
17655   "")
17656
17657 ; Don't do logical operations with memory outputs
17658 ;
17659 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17660 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
17661 ; the same decoder scheduling characteristics as the original.
17662
17663 (define_peephole2
17664   [(match_scratch:SI 2 "r")
17665    (parallel [(set (match_operand:SI 0 "memory_operand" "")
17666                    (match_operator:SI 3 "arith_or_logical_operator"
17667                      [(match_dup 0)
17668                       (match_operand:SI 1 "nonmemory_operand" "")]))
17669               (clobber (reg:CC FLAGS_REG))])]
17670   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
17671    /* Do not split stack checking probes.  */
17672    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17673   [(set (match_dup 2) (match_dup 0))
17674    (parallel [(set (match_dup 2)
17675                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17676               (clobber (reg:CC FLAGS_REG))])
17677    (set (match_dup 0) (match_dup 2))]
17678   "")
17679
17680 (define_peephole2
17681   [(match_scratch:SI 2 "r")
17682    (parallel [(set (match_operand:SI 0 "memory_operand" "")
17683                    (match_operator:SI 3 "arith_or_logical_operator"
17684                      [(match_operand:SI 1 "nonmemory_operand" "")
17685                       (match_dup 0)]))
17686               (clobber (reg:CC FLAGS_REG))])]
17687   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
17688    /* Do not split stack checking probes.  */
17689    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17690   [(set (match_dup 2) (match_dup 0))
17691    (parallel [(set (match_dup 2)
17692                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17693               (clobber (reg:CC FLAGS_REG))])
17694    (set (match_dup 0) (match_dup 2))]
17695   "")
17696
17697 ;; Attempt to always use XOR for zeroing registers.
17698 (define_peephole2
17699   [(set (match_operand 0 "register_operand" "")
17700         (match_operand 1 "const0_operand" ""))]
17701   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17702    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17703    && GENERAL_REG_P (operands[0])
17704    && peep2_regno_dead_p (0, FLAGS_REG)"
17705   [(parallel [(set (match_dup 0) (const_int 0))
17706               (clobber (reg:CC FLAGS_REG))])]
17707 {
17708   operands[0] = gen_lowpart (word_mode, operands[0]);
17709 })
17710
17711 (define_peephole2
17712   [(set (strict_low_part (match_operand 0 "register_operand" ""))
17713         (const_int 0))]
17714   "(GET_MODE (operands[0]) == QImode
17715     || GET_MODE (operands[0]) == HImode)
17716    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17717    && peep2_regno_dead_p (0, FLAGS_REG)"
17718   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17719               (clobber (reg:CC FLAGS_REG))])])
17720
17721 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
17722 (define_peephole2
17723   [(set (match_operand 0 "register_operand" "")
17724         (const_int -1))]
17725   "(GET_MODE (operands[0]) == HImode
17726     || GET_MODE (operands[0]) == SImode
17727     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
17728    && (optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17729    && peep2_regno_dead_p (0, FLAGS_REG)"
17730   [(parallel [(set (match_dup 0) (const_int -1))
17731               (clobber (reg:CC FLAGS_REG))])]
17732   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
17733                               operands[0]);")
17734
17735 ;; Attempt to convert simple leas to adds. These can be created by
17736 ;; move expanders.
17737 (define_peephole2
17738   [(set (match_operand:SI 0 "register_operand" "")
17739         (plus:SI (match_dup 0)
17740                  (match_operand:SI 1 "nonmemory_operand" "")))]
17741   "peep2_regno_dead_p (0, FLAGS_REG)"
17742   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
17743               (clobber (reg:CC FLAGS_REG))])]
17744   "")
17745
17746 (define_peephole2
17747   [(set (match_operand:SI 0 "register_operand" "")
17748         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
17749                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
17750   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
17751   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17752               (clobber (reg:CC FLAGS_REG))])]
17753   "operands[2] = gen_lowpart (SImode, operands[2]);")
17754
17755 (define_peephole2
17756   [(set (match_operand:DI 0 "register_operand" "")
17757         (plus:DI (match_dup 0)
17758                  (match_operand:DI 1 "x86_64_general_operand" "")))]
17759   "peep2_regno_dead_p (0, FLAGS_REG)"
17760   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
17761               (clobber (reg:CC FLAGS_REG))])]
17762   "")
17763
17764 (define_peephole2
17765   [(set (match_operand:SI 0 "register_operand" "")
17766         (mult:SI (match_dup 0)
17767                  (match_operand:SI 1 "const_int_operand" "")))]
17768   "exact_log2 (INTVAL (operands[1])) >= 0
17769    && peep2_regno_dead_p (0, FLAGS_REG)"
17770   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17771               (clobber (reg:CC FLAGS_REG))])]
17772   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17773
17774 (define_peephole2
17775   [(set (match_operand:DI 0 "register_operand" "")
17776         (mult:DI (match_dup 0)
17777                  (match_operand:DI 1 "const_int_operand" "")))]
17778   "exact_log2 (INTVAL (operands[1])) >= 0
17779    && peep2_regno_dead_p (0, FLAGS_REG)"
17780   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
17781               (clobber (reg:CC FLAGS_REG))])]
17782   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17783
17784 (define_peephole2
17785   [(set (match_operand:SI 0 "register_operand" "")
17786         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
17787                    (match_operand:DI 2 "const_int_operand" "")) 0))]
17788   "exact_log2 (INTVAL (operands[2])) >= 0
17789    && REGNO (operands[0]) == REGNO (operands[1])
17790    && peep2_regno_dead_p (0, FLAGS_REG)"
17791   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17792               (clobber (reg:CC FLAGS_REG))])]
17793   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17794
17795 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
17796 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
17797 ;; many CPUs it is also faster, since special hardware to avoid esp
17798 ;; dependencies is present.
17799
17800 ;; While some of these conversions may be done using splitters, we use peepholes
17801 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
17802
17803 ;; Convert prologue esp subtractions to push.
17804 ;; We need register to push.  In order to keep verify_flow_info happy we have
17805 ;; two choices
17806 ;; - use scratch and clobber it in order to avoid dependencies
17807 ;; - use already live register
17808 ;; We can't use the second way right now, since there is no reliable way how to
17809 ;; verify that given register is live.  First choice will also most likely in
17810 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
17811 ;; call clobbered registers are dead.  We may want to use base pointer as an
17812 ;; alternative when no register is available later.
17813
17814 (define_peephole2
17815   [(match_scratch:SI 0 "r")
17816    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
17817               (clobber (reg:CC FLAGS_REG))
17818               (clobber (mem:BLK (scratch)))])]
17819   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
17820   [(clobber (match_dup 0))
17821    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
17822               (clobber (mem:BLK (scratch)))])])
17823
17824 (define_peephole2
17825   [(match_scratch:SI 0 "r")
17826    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
17827               (clobber (reg:CC FLAGS_REG))
17828               (clobber (mem:BLK (scratch)))])]
17829   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
17830   [(clobber (match_dup 0))
17831    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
17832    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
17833               (clobber (mem:BLK (scratch)))])])
17834
17835 ;; Convert esp subtractions to push.
17836 (define_peephole2
17837   [(match_scratch:SI 0 "r")
17838    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
17839               (clobber (reg:CC FLAGS_REG))])]
17840   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
17841   [(clobber (match_dup 0))
17842    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
17843
17844 (define_peephole2
17845   [(match_scratch:SI 0 "r")
17846    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
17847               (clobber (reg:CC FLAGS_REG))])]
17848   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
17849   [(clobber (match_dup 0))
17850    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
17851    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
17852
17853 ;; Convert epilogue deallocator to pop.
17854 (define_peephole2
17855   [(match_scratch:SI 0 "r")
17856    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
17857               (clobber (reg:CC FLAGS_REG))
17858               (clobber (mem:BLK (scratch)))])]
17859   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
17860   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17861               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
17862               (clobber (mem:BLK (scratch)))])]
17863   "")
17864
17865 ;; Two pops case is tricky, since pop causes dependency on destination register.
17866 ;; We use two registers if available.
17867 (define_peephole2
17868   [(match_scratch:SI 0 "r")
17869    (match_scratch:SI 1 "r")
17870    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
17871               (clobber (reg:CC FLAGS_REG))
17872               (clobber (mem:BLK (scratch)))])]
17873   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
17874   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17875               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
17876               (clobber (mem:BLK (scratch)))])
17877    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
17878               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
17879   "")
17880
17881 (define_peephole2
17882   [(match_scratch:SI 0 "r")
17883    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
17884               (clobber (reg:CC FLAGS_REG))
17885               (clobber (mem:BLK (scratch)))])]
17886   "optimize_insn_for_size_p ()"
17887   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17888               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
17889               (clobber (mem:BLK (scratch)))])
17890    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17891               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
17892   "")
17893
17894 ;; Convert esp additions to pop.
17895 (define_peephole2
17896   [(match_scratch:SI 0 "r")
17897    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
17898               (clobber (reg:CC FLAGS_REG))])]
17899   ""
17900   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17901               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
17902   "")
17903
17904 ;; Two pops case is tricky, since pop causes dependency on destination register.
17905 ;; We use two registers if available.
17906 (define_peephole2
17907   [(match_scratch:SI 0 "r")
17908    (match_scratch:SI 1 "r")
17909    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
17910               (clobber (reg:CC FLAGS_REG))])]
17911   ""
17912   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17913               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
17914    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
17915               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
17916   "")
17917
17918 (define_peephole2
17919   [(match_scratch:SI 0 "r")
17920    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
17921               (clobber (reg:CC FLAGS_REG))])]
17922   "optimize_insn_for_size_p ()"
17923   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17924               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
17925    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17926               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
17927   "")
17928 \f
17929 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17930 ;; required and register dies.  Similarly for 128 to -128.
17931 (define_peephole2
17932   [(set (match_operand 0 "flags_reg_operand" "")
17933         (match_operator 1 "compare_operator"
17934           [(match_operand 2 "register_operand" "")
17935            (match_operand 3 "const_int_operand" "")]))]
17936   "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17937      && incdec_operand (operands[3], GET_MODE (operands[3])))
17938     || (!TARGET_FUSE_CMP_AND_BRANCH
17939         && INTVAL (operands[3]) == 128))
17940    && ix86_match_ccmode (insn, CCGCmode)
17941    && peep2_reg_dead_p (1, operands[2])"
17942   [(parallel [(set (match_dup 0)
17943                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17944               (clobber (match_dup 2))])]
17945   "")
17946 \f
17947 (define_peephole2
17948   [(match_scratch:DI 0 "r")
17949    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
17950               (clobber (reg:CC FLAGS_REG))
17951               (clobber (mem:BLK (scratch)))])]
17952   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
17953   [(clobber (match_dup 0))
17954    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
17955               (clobber (mem:BLK (scratch)))])])
17956
17957 (define_peephole2
17958   [(match_scratch:DI 0 "r")
17959    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
17960               (clobber (reg:CC FLAGS_REG))
17961               (clobber (mem:BLK (scratch)))])]
17962   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
17963   [(clobber (match_dup 0))
17964    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
17965    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
17966               (clobber (mem:BLK (scratch)))])])
17967
17968 ;; Convert esp subtractions to push.
17969 (define_peephole2
17970   [(match_scratch:DI 0 "r")
17971    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
17972               (clobber (reg:CC FLAGS_REG))])]
17973   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
17974   [(clobber (match_dup 0))
17975    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
17976
17977 (define_peephole2
17978   [(match_scratch:DI 0 "r")
17979    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
17980               (clobber (reg:CC FLAGS_REG))])]
17981   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
17982   [(clobber (match_dup 0))
17983    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
17984    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
17985
17986 ;; Convert epilogue deallocator to pop.
17987 (define_peephole2
17988   [(match_scratch:DI 0 "r")
17989    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
17990               (clobber (reg:CC FLAGS_REG))
17991               (clobber (mem:BLK (scratch)))])]
17992   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
17993   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17994               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
17995               (clobber (mem:BLK (scratch)))])]
17996   "")
17997
17998 ;; Two pops case is tricky, since pop causes dependency on destination register.
17999 ;; We use two registers if available.
18000 (define_peephole2
18001   [(match_scratch:DI 0 "r")
18002    (match_scratch:DI 1 "r")
18003    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
18004               (clobber (reg:CC FLAGS_REG))
18005               (clobber (mem:BLK (scratch)))])]
18006   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
18007   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18008               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
18009               (clobber (mem:BLK (scratch)))])
18010    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
18011               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
18012   "")
18013
18014 (define_peephole2
18015   [(match_scratch:DI 0 "r")
18016    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
18017               (clobber (reg:CC FLAGS_REG))
18018               (clobber (mem:BLK (scratch)))])]
18019   "optimize_insn_for_size_p ()"
18020   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18021               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
18022               (clobber (mem:BLK (scratch)))])
18023    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18024               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
18025   "")
18026
18027 ;; Convert esp additions to pop.
18028 (define_peephole2
18029   [(match_scratch:DI 0 "r")
18030    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
18031               (clobber (reg:CC FLAGS_REG))])]
18032   ""
18033   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18034               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
18035   "")
18036
18037 ;; Two pops case is tricky, since pop causes dependency on destination register.
18038 ;; We use two registers if available.
18039 (define_peephole2
18040   [(match_scratch:DI 0 "r")
18041    (match_scratch:DI 1 "r")
18042    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
18043               (clobber (reg:CC FLAGS_REG))])]
18044   ""
18045   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18046               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
18047    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
18048               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
18049   "")
18050
18051 (define_peephole2
18052   [(match_scratch:DI 0 "r")
18053    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
18054               (clobber (reg:CC FLAGS_REG))])]
18055   "optimize_insn_for_size_p ()"
18056   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18057               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
18058    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18059               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
18060   "")
18061 \f
18062 ;; Convert imul by three, five and nine into lea
18063 (define_peephole2
18064   [(parallel
18065     [(set (match_operand:SI 0 "register_operand" "")
18066           (mult:SI (match_operand:SI 1 "register_operand" "")
18067                    (match_operand:SI 2 "const_int_operand" "")))
18068      (clobber (reg:CC FLAGS_REG))])]
18069   "INTVAL (operands[2]) == 3
18070    || INTVAL (operands[2]) == 5
18071    || INTVAL (operands[2]) == 9"
18072   [(set (match_dup 0)
18073         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
18074                  (match_dup 1)))]
18075   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
18076
18077 (define_peephole2
18078   [(parallel
18079     [(set (match_operand:SI 0 "register_operand" "")
18080           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
18081                    (match_operand:SI 2 "const_int_operand" "")))
18082      (clobber (reg:CC FLAGS_REG))])]
18083   "optimize_insn_for_speed_p ()
18084    && (INTVAL (operands[2]) == 3
18085        || INTVAL (operands[2]) == 5
18086        || INTVAL (operands[2]) == 9)"
18087   [(set (match_dup 0) (match_dup 1))
18088    (set (match_dup 0)
18089         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
18090                  (match_dup 0)))]
18091   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
18092
18093 (define_peephole2
18094   [(parallel
18095     [(set (match_operand:DI 0 "register_operand" "")
18096           (mult:DI (match_operand:DI 1 "register_operand" "")
18097                    (match_operand:DI 2 "const_int_operand" "")))
18098      (clobber (reg:CC FLAGS_REG))])]
18099   "TARGET_64BIT
18100    && (INTVAL (operands[2]) == 3
18101        || INTVAL (operands[2]) == 5
18102        || INTVAL (operands[2]) == 9)"
18103   [(set (match_dup 0)
18104         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
18105                  (match_dup 1)))]
18106   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
18107
18108 (define_peephole2
18109   [(parallel
18110     [(set (match_operand:DI 0 "register_operand" "")
18111           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
18112                    (match_operand:DI 2 "const_int_operand" "")))
18113      (clobber (reg:CC FLAGS_REG))])]
18114   "TARGET_64BIT
18115    && optimize_insn_for_speed_p ()
18116    && (INTVAL (operands[2]) == 3
18117        || INTVAL (operands[2]) == 5
18118        || INTVAL (operands[2]) == 9)"
18119   [(set (match_dup 0) (match_dup 1))
18120    (set (match_dup 0)
18121         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
18122                  (match_dup 0)))]
18123   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
18124
18125 ;; Imul $32bit_imm, mem, reg is vector decoded, while
18126 ;; imul $32bit_imm, reg, reg is direct decoded.
18127 (define_peephole2
18128   [(match_scratch:DI 3 "r")
18129    (parallel [(set (match_operand:DI 0 "register_operand" "")
18130                    (mult:DI (match_operand:DI 1 "memory_operand" "")
18131                             (match_operand:DI 2 "immediate_operand" "")))
18132               (clobber (reg:CC FLAGS_REG))])]
18133   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
18134    && !satisfies_constraint_K (operands[2])"
18135   [(set (match_dup 3) (match_dup 1))
18136    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
18137               (clobber (reg:CC FLAGS_REG))])]
18138 "")
18139
18140 (define_peephole2
18141   [(match_scratch:SI 3 "r")
18142    (parallel [(set (match_operand:SI 0 "register_operand" "")
18143                    (mult:SI (match_operand:SI 1 "memory_operand" "")
18144                             (match_operand:SI 2 "immediate_operand" "")))
18145               (clobber (reg:CC FLAGS_REG))])]
18146   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
18147    && !satisfies_constraint_K (operands[2])"
18148   [(set (match_dup 3) (match_dup 1))
18149    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
18150               (clobber (reg:CC FLAGS_REG))])]
18151 "")
18152
18153 (define_peephole2
18154   [(match_scratch:SI 3 "r")
18155    (parallel [(set (match_operand:DI 0 "register_operand" "")
18156                    (zero_extend:DI
18157                      (mult:SI (match_operand:SI 1 "memory_operand" "")
18158                               (match_operand:SI 2 "immediate_operand" ""))))
18159               (clobber (reg:CC FLAGS_REG))])]
18160   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
18161    && !satisfies_constraint_K (operands[2])"
18162   [(set (match_dup 3) (match_dup 1))
18163    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
18164               (clobber (reg:CC FLAGS_REG))])]
18165 "")
18166
18167 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
18168 ;; Convert it into imul reg, reg
18169 ;; It would be better to force assembler to encode instruction using long
18170 ;; immediate, but there is apparently no way to do so.
18171 (define_peephole2
18172   [(parallel [(set (match_operand:DI 0 "register_operand" "")
18173                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
18174                             (match_operand:DI 2 "const_int_operand" "")))
18175               (clobber (reg:CC FLAGS_REG))])
18176    (match_scratch:DI 3 "r")]
18177   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
18178    && satisfies_constraint_K (operands[2])"
18179   [(set (match_dup 3) (match_dup 2))
18180    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
18181               (clobber (reg:CC FLAGS_REG))])]
18182 {
18183   if (!rtx_equal_p (operands[0], operands[1]))
18184     emit_move_insn (operands[0], operands[1]);
18185 })
18186
18187 (define_peephole2
18188   [(parallel [(set (match_operand:SI 0 "register_operand" "")
18189                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
18190                             (match_operand:SI 2 "const_int_operand" "")))
18191               (clobber (reg:CC FLAGS_REG))])
18192    (match_scratch:SI 3 "r")]
18193   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
18194    && satisfies_constraint_K (operands[2])"
18195   [(set (match_dup 3) (match_dup 2))
18196    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
18197               (clobber (reg:CC FLAGS_REG))])]
18198 {
18199   if (!rtx_equal_p (operands[0], operands[1]))
18200     emit_move_insn (operands[0], operands[1]);
18201 })
18202
18203 (define_peephole2
18204   [(parallel [(set (match_operand:HI 0 "register_operand" "")
18205                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
18206                             (match_operand:HI 2 "immediate_operand" "")))
18207               (clobber (reg:CC FLAGS_REG))])
18208    (match_scratch:HI 3 "r")]
18209   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()"
18210   [(set (match_dup 3) (match_dup 2))
18211    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
18212               (clobber (reg:CC FLAGS_REG))])]
18213 {
18214   if (!rtx_equal_p (operands[0], operands[1]))
18215     emit_move_insn (operands[0], operands[1]);
18216 })
18217
18218 ;; After splitting up read-modify operations, array accesses with memory
18219 ;; operands might end up in form:
18220 ;;  sall    $2, %eax
18221 ;;  movl    4(%esp), %edx
18222 ;;  addl    %edx, %eax
18223 ;; instead of pre-splitting:
18224 ;;  sall    $2, %eax
18225 ;;  addl    4(%esp), %eax
18226 ;; Turn it into:
18227 ;;  movl    4(%esp), %edx
18228 ;;  leal    (%edx,%eax,4), %eax
18229
18230 (define_peephole2
18231   [(parallel [(set (match_operand 0 "register_operand" "")
18232                    (ashift (match_operand 1 "register_operand" "")
18233                            (match_operand 2 "const_int_operand" "")))
18234                (clobber (reg:CC FLAGS_REG))])
18235    (set (match_operand 3 "register_operand")
18236         (match_operand 4 "x86_64_general_operand" ""))
18237    (parallel [(set (match_operand 5 "register_operand" "")
18238                    (plus (match_operand 6 "register_operand" "")
18239                          (match_operand 7 "register_operand" "")))
18240                    (clobber (reg:CC FLAGS_REG))])]
18241   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
18242    /* Validate MODE for lea.  */
18243    && ((!TARGET_PARTIAL_REG_STALL
18244         && (GET_MODE (operands[0]) == QImode
18245             || GET_MODE (operands[0]) == HImode))
18246        || GET_MODE (operands[0]) == SImode
18247        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
18248    /* We reorder load and the shift.  */
18249    && !rtx_equal_p (operands[1], operands[3])
18250    && !reg_overlap_mentioned_p (operands[0], operands[4])
18251    /* Last PLUS must consist of operand 0 and 3.  */
18252    && !rtx_equal_p (operands[0], operands[3])
18253    && (rtx_equal_p (operands[3], operands[6])
18254        || rtx_equal_p (operands[3], operands[7]))
18255    && (rtx_equal_p (operands[0], operands[6])
18256        || rtx_equal_p (operands[0], operands[7]))
18257    /* The intermediate operand 0 must die or be same as output.  */
18258    && (rtx_equal_p (operands[0], operands[5])
18259        || peep2_reg_dead_p (3, operands[0]))"
18260   [(set (match_dup 3) (match_dup 4))
18261    (set (match_dup 0) (match_dup 1))]
18262 {
18263   enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
18264   int scale = 1 << INTVAL (operands[2]);
18265   rtx index = gen_lowpart (Pmode, operands[1]);
18266   rtx base = gen_lowpart (Pmode, operands[3]);
18267   rtx dest = gen_lowpart (mode, operands[5]);
18268
18269   operands[1] = gen_rtx_PLUS (Pmode, base,
18270                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
18271   if (mode != Pmode)
18272     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
18273   operands[0] = dest;
18274 })
18275 \f
18276 ;; Call-value patterns last so that the wildcard operand does not
18277 ;; disrupt insn-recog's switch tables.
18278
18279 (define_insn "*call_value_pop_0"
18280   [(set (match_operand 0 "" "")
18281         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
18282               (match_operand:SI 2 "" "")))
18283    (set (reg:SI SP_REG)
18284         (plus:SI (reg:SI SP_REG)
18285                  (match_operand:SI 3 "immediate_operand" "")))]
18286   "!TARGET_64BIT"
18287 {
18288   if (SIBLING_CALL_P (insn))
18289     return "jmp\t%P1";
18290   else
18291     return "call\t%P1";
18292 }
18293   [(set_attr "type" "callv")])
18294
18295 (define_insn "*call_value_pop_1"
18296   [(set (match_operand 0 "" "")
18297         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
18298               (match_operand:SI 2 "" "")))
18299    (set (reg:SI SP_REG)
18300         (plus:SI (reg:SI SP_REG)
18301                  (match_operand:SI 3 "immediate_operand" "i")))]
18302   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
18303 {
18304   if (constant_call_address_operand (operands[1], Pmode))
18305     return "call\t%P1";
18306   return "call\t%A1";
18307 }
18308   [(set_attr "type" "callv")])
18309
18310 (define_insn "*sibcall_value_pop_1"
18311   [(set (match_operand 0 "" "")
18312         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
18313               (match_operand:SI 2 "" "")))
18314    (set (reg:SI SP_REG)
18315         (plus:SI (reg:SI SP_REG)
18316                  (match_operand:SI 3 "immediate_operand" "i,i")))]
18317   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
18318   "@
18319    jmp\t%P1
18320    jmp\t%A1"
18321   [(set_attr "type" "callv")])
18322
18323 (define_insn "*call_value_0"
18324   [(set (match_operand 0 "" "")
18325         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
18326               (match_operand:SI 2 "" "")))]
18327   "!TARGET_64BIT"
18328 {
18329   if (SIBLING_CALL_P (insn))
18330     return "jmp\t%P1";
18331   else
18332     return "call\t%P1";
18333 }
18334   [(set_attr "type" "callv")])
18335
18336 (define_insn "*call_value_0_rex64"
18337   [(set (match_operand 0 "" "")
18338         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
18339               (match_operand:DI 2 "const_int_operand" "")))]
18340   "TARGET_64BIT"
18341 {
18342   if (SIBLING_CALL_P (insn))
18343     return "jmp\t%P1";
18344   else
18345     return "call\t%P1";
18346 }
18347   [(set_attr "type" "callv")])
18348
18349 (define_insn "*call_value_0_rex64_ms_sysv"
18350   [(set (match_operand 0 "" "")
18351         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
18352               (match_operand:DI 2 "const_int_operand" "")))
18353    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
18354    (clobber (reg:TI XMM6_REG))
18355    (clobber (reg:TI XMM7_REG))
18356    (clobber (reg:TI XMM8_REG))
18357    (clobber (reg:TI XMM9_REG))
18358    (clobber (reg:TI XMM10_REG))
18359    (clobber (reg:TI XMM11_REG))
18360    (clobber (reg:TI XMM12_REG))
18361    (clobber (reg:TI XMM13_REG))
18362    (clobber (reg:TI XMM14_REG))
18363    (clobber (reg:TI XMM15_REG))
18364    (clobber (reg:DI SI_REG))
18365    (clobber (reg:DI DI_REG))]
18366   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
18367 {
18368   if (SIBLING_CALL_P (insn))
18369     return "jmp\t%P1";
18370   else
18371     return "call\t%P1";
18372 }
18373   [(set_attr "type" "callv")])
18374
18375 (define_insn "*call_value_1"
18376   [(set (match_operand 0 "" "")
18377         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
18378               (match_operand:SI 2 "" "")))]
18379   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
18380 {
18381   if (constant_call_address_operand (operands[1], Pmode))
18382     return "call\t%P1";
18383   return "call\t%A1";
18384 }
18385   [(set_attr "type" "callv")])
18386
18387 (define_insn "*sibcall_value_1"
18388   [(set (match_operand 0 "" "")
18389         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
18390               (match_operand:SI 2 "" "")))]
18391   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
18392   "@
18393    jmp\t%P1
18394    jmp\t%A1"
18395   [(set_attr "type" "callv")])
18396
18397 (define_insn "*call_value_1_rex64"
18398   [(set (match_operand 0 "" "")
18399         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
18400               (match_operand:DI 2 "" "")))]
18401   "TARGET_64BIT && !SIBLING_CALL_P (insn)
18402    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
18403 {
18404   if (constant_call_address_operand (operands[1], Pmode))
18405     return "call\t%P1";
18406   return "call\t%A1";
18407 }
18408   [(set_attr "type" "callv")])
18409
18410 (define_insn "*call_value_1_rex64_ms_sysv"
18411   [(set (match_operand 0 "" "")
18412         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
18413               (match_operand:DI 2 "" "")))
18414    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
18415    (clobber (reg:TI XMM6_REG))
18416    (clobber (reg:TI XMM7_REG))
18417    (clobber (reg:TI XMM8_REG))
18418    (clobber (reg:TI XMM9_REG))
18419    (clobber (reg:TI XMM10_REG))
18420    (clobber (reg:TI XMM11_REG))
18421    (clobber (reg:TI XMM12_REG))
18422    (clobber (reg:TI XMM13_REG))
18423    (clobber (reg:TI XMM14_REG))
18424    (clobber (reg:TI XMM15_REG))
18425    (clobber (reg:DI SI_REG))
18426    (clobber (reg:DI DI_REG))]
18427   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
18428 {
18429   if (constant_call_address_operand (operands[1], Pmode))
18430     return "call\t%P1";
18431   return "call\t%A1";
18432 }
18433   [(set_attr "type" "callv")])
18434
18435 (define_insn "*call_value_1_rex64_large"
18436   [(set (match_operand 0 "" "")
18437         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
18438               (match_operand:DI 2 "" "")))]
18439   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
18440   "call\t%A1"
18441   [(set_attr "type" "callv")])
18442
18443 (define_insn "*sibcall_value_1_rex64"
18444   [(set (match_operand 0 "" "")
18445         (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
18446               (match_operand:DI 2 "" "")))]
18447   "TARGET_64BIT && SIBLING_CALL_P (insn)"
18448   "@
18449    jmp\t%P1
18450    jmp\t%A1"
18451   [(set_attr "type" "callv")])
18452 \f
18453 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
18454 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
18455 ;; caught for use by garbage collectors and the like.  Using an insn that
18456 ;; maps to SIGILL makes it more likely the program will rightfully die.
18457 ;; Keeping with tradition, "6" is in honor of #UD.
18458 (define_insn "trap"
18459   [(trap_if (const_int 1) (const_int 6))]
18460   ""
18461   { return ASM_SHORT "0x0b0f"; }
18462   [(set_attr "length" "2")])
18463
18464 (define_expand "sse_prologue_save"
18465   [(parallel [(set (match_operand:BLK 0 "" "")
18466                    (unspec:BLK [(reg:DI XMM0_REG)
18467                                 (reg:DI XMM1_REG)
18468                                 (reg:DI XMM2_REG)
18469                                 (reg:DI XMM3_REG)
18470                                 (reg:DI XMM4_REG)
18471                                 (reg:DI XMM5_REG)
18472                                 (reg:DI XMM6_REG)
18473                                 (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE))
18474               (use (match_operand:DI 1 "register_operand" ""))
18475               (use (match_operand:DI 2 "immediate_operand" ""))
18476               (use (label_ref:DI (match_operand 3 "" "")))])]
18477   "TARGET_64BIT"
18478   "")
18479
18480 (define_insn "*sse_prologue_save_insn"
18481   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
18482                           (match_operand:DI 4 "const_int_operand" "n")))
18483         (unspec:BLK [(reg:DI XMM0_REG)
18484                      (reg:DI XMM1_REG)
18485                      (reg:DI XMM2_REG)
18486                      (reg:DI XMM3_REG)
18487                      (reg:DI XMM4_REG)
18488                      (reg:DI XMM5_REG)
18489                      (reg:DI XMM6_REG)
18490                      (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE))
18491    (use (match_operand:DI 1 "register_operand" "r"))
18492    (use (match_operand:DI 2 "const_int_operand" "i"))
18493    (use (label_ref:DI (match_operand 3 "" "X")))]
18494   "TARGET_64BIT
18495    && INTVAL (operands[4]) + X86_64_SSE_REGPARM_MAX * 16 - 16 < 128
18496    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
18497 {
18498   int i;
18499   operands[0] = gen_rtx_MEM (Pmode,
18500                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
18501   /* VEX instruction with a REX prefix will #UD.  */
18502   if (TARGET_AVX && GET_CODE (XEXP (operands[0], 0)) != PLUS)
18503     gcc_unreachable ();
18504
18505   output_asm_insn ("jmp\t%A1", operands);
18506   for (i = X86_64_SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
18507     {
18508       operands[4] = adjust_address (operands[0], DImode, i*16);
18509       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
18510       PUT_MODE (operands[4], TImode);
18511       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
18512         output_asm_insn ("rex", operands);
18513       output_asm_insn ("%vmovaps\t{%5, %4|%4, %5}", operands);
18514     }
18515   (*targetm.asm_out.internal_label) (asm_out_file, "L",
18516                                      CODE_LABEL_NUMBER (operands[3]));
18517   return "";
18518 }
18519   [(set_attr "type" "other")
18520    (set_attr "length_immediate" "0")
18521    (set_attr "length_address" "0")
18522    (set (attr "length")
18523      (if_then_else
18524        (eq (symbol_ref "TARGET_AVX") (const_int 0))
18525        (const_string "34")
18526        (const_string "42")))
18527    (set_attr "memory" "store")
18528    (set_attr "modrm" "0")
18529    (set_attr "prefix" "maybe_vex")
18530    (set_attr "mode" "DI")])
18531
18532 (define_expand "prefetch"
18533   [(prefetch (match_operand 0 "address_operand" "")
18534              (match_operand:SI 1 "const_int_operand" "")
18535              (match_operand:SI 2 "const_int_operand" ""))]
18536   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
18537 {
18538   int rw = INTVAL (operands[1]);
18539   int locality = INTVAL (operands[2]);
18540
18541   gcc_assert (rw == 0 || rw == 1);
18542   gcc_assert (locality >= 0 && locality <= 3);
18543   gcc_assert (GET_MODE (operands[0]) == Pmode
18544               || GET_MODE (operands[0]) == VOIDmode);
18545
18546   /* Use 3dNOW prefetch in case we are asking for write prefetch not
18547      supported by SSE counterpart or the SSE prefetch is not available
18548      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
18549      of locality.  */
18550   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
18551     operands[2] = GEN_INT (3);
18552   else
18553     operands[1] = const0_rtx;
18554 })
18555
18556 (define_insn "*prefetch_sse"
18557   [(prefetch (match_operand:SI 0 "address_operand" "p")
18558              (const_int 0)
18559              (match_operand:SI 1 "const_int_operand" ""))]
18560   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
18561 {
18562   static const char * const patterns[4] = {
18563    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
18564   };
18565
18566   int locality = INTVAL (operands[1]);
18567   gcc_assert (locality >= 0 && locality <= 3);
18568
18569   return patterns[locality];
18570 }
18571   [(set_attr "type" "sse")
18572    (set_attr "atom_sse_attr" "prefetch")
18573    (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
18574    (set_attr "memory" "none")])
18575
18576 (define_insn "*prefetch_sse_rex"
18577   [(prefetch (match_operand:DI 0 "address_operand" "p")
18578              (const_int 0)
18579              (match_operand:SI 1 "const_int_operand" ""))]
18580   "TARGET_PREFETCH_SSE && TARGET_64BIT"
18581 {
18582   static const char * const patterns[4] = {
18583    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
18584   };
18585
18586   int locality = INTVAL (operands[1]);
18587   gcc_assert (locality >= 0 && locality <= 3);
18588
18589   return patterns[locality];
18590 }
18591   [(set_attr "type" "sse")
18592    (set_attr "atom_sse_attr" "prefetch")
18593    (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
18594    (set_attr "memory" "none")])
18595
18596 (define_insn "*prefetch_3dnow"
18597   [(prefetch (match_operand:SI 0 "address_operand" "p")
18598              (match_operand:SI 1 "const_int_operand" "n")
18599              (const_int 3))]
18600   "TARGET_3DNOW && !TARGET_64BIT"
18601 {
18602   if (INTVAL (operands[1]) == 0)
18603     return "prefetch\t%a0";
18604   else
18605     return "prefetchw\t%a0";
18606 }
18607   [(set_attr "type" "mmx")
18608    (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
18609    (set_attr "memory" "none")])
18610
18611 (define_insn "*prefetch_3dnow_rex"
18612   [(prefetch (match_operand:DI 0 "address_operand" "p")
18613              (match_operand:SI 1 "const_int_operand" "n")
18614              (const_int 3))]
18615   "TARGET_3DNOW && TARGET_64BIT"
18616 {
18617   if (INTVAL (operands[1]) == 0)
18618     return "prefetch\t%a0";
18619   else
18620     return "prefetchw\t%a0";
18621 }
18622   [(set_attr "type" "mmx")
18623    (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
18624    (set_attr "memory" "none")])
18625
18626 (define_expand "stack_protect_set"
18627   [(match_operand 0 "memory_operand" "")
18628    (match_operand 1 "memory_operand" "")]
18629   ""
18630 {
18631 #ifdef TARGET_THREAD_SSP_OFFSET
18632   if (TARGET_64BIT)
18633     emit_insn (gen_stack_tls_protect_set_di (operands[0],
18634                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
18635   else
18636     emit_insn (gen_stack_tls_protect_set_si (operands[0],
18637                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
18638 #else
18639   if (TARGET_64BIT)
18640     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
18641   else
18642     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
18643 #endif
18644   DONE;
18645 })
18646
18647 (define_insn "stack_protect_set_si"
18648   [(set (match_operand:SI 0 "memory_operand" "=m")
18649         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
18650    (set (match_scratch:SI 2 "=&r") (const_int 0))
18651    (clobber (reg:CC FLAGS_REG))]
18652   ""
18653   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
18654   [(set_attr "type" "multi")])
18655
18656 (define_insn "stack_protect_set_di"
18657   [(set (match_operand:DI 0 "memory_operand" "=m")
18658         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
18659    (set (match_scratch:DI 2 "=&r") (const_int 0))
18660    (clobber (reg:CC FLAGS_REG))]
18661   "TARGET_64BIT"
18662   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
18663   [(set_attr "type" "multi")])
18664
18665 (define_insn "stack_tls_protect_set_si"
18666   [(set (match_operand:SI 0 "memory_operand" "=m")
18667         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
18668    (set (match_scratch:SI 2 "=&r") (const_int 0))
18669    (clobber (reg:CC FLAGS_REG))]
18670   ""
18671   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
18672   [(set_attr "type" "multi")])
18673
18674 (define_insn "stack_tls_protect_set_di"
18675   [(set (match_operand:DI 0 "memory_operand" "=m")
18676         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
18677    (set (match_scratch:DI 2 "=&r") (const_int 0))
18678    (clobber (reg:CC FLAGS_REG))]
18679   "TARGET_64BIT"
18680   {
18681      /* The kernel uses a different segment register for performance reasons; a
18682         system call would not have to trash the userspace segment register,
18683         which would be expensive */
18684      if (ix86_cmodel != CM_KERNEL)
18685         return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
18686      else
18687         return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
18688   }
18689   [(set_attr "type" "multi")])
18690
18691 (define_expand "stack_protect_test"
18692   [(match_operand 0 "memory_operand" "")
18693    (match_operand 1 "memory_operand" "")
18694    (match_operand 2 "" "")]
18695   ""
18696 {
18697   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
18698
18699 #ifdef TARGET_THREAD_SSP_OFFSET
18700   if (TARGET_64BIT)
18701     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
18702                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
18703   else
18704     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
18705                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
18706 #else
18707   if (TARGET_64BIT)
18708     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
18709   else
18710     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
18711 #endif
18712
18713   emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
18714                                   flags, const0_rtx, operands[2]));
18715   DONE;
18716 })
18717
18718 (define_insn "stack_protect_test_si"
18719   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
18720         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
18721                      (match_operand:SI 2 "memory_operand" "m")]
18722                     UNSPEC_SP_TEST))
18723    (clobber (match_scratch:SI 3 "=&r"))]
18724   ""
18725   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
18726   [(set_attr "type" "multi")])
18727
18728 (define_insn "stack_protect_test_di"
18729   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
18730         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
18731                      (match_operand:DI 2 "memory_operand" "m")]
18732                     UNSPEC_SP_TEST))
18733    (clobber (match_scratch:DI 3 "=&r"))]
18734   "TARGET_64BIT"
18735   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
18736   [(set_attr "type" "multi")])
18737
18738 (define_insn "stack_tls_protect_test_si"
18739   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
18740         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
18741                      (match_operand:SI 2 "const_int_operand" "i")]
18742                     UNSPEC_SP_TLS_TEST))
18743    (clobber (match_scratch:SI 3 "=r"))]
18744   ""
18745   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
18746   [(set_attr "type" "multi")])
18747
18748 (define_insn "stack_tls_protect_test_di"
18749   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
18750         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
18751                      (match_operand:DI 2 "const_int_operand" "i")]
18752                     UNSPEC_SP_TLS_TEST))
18753    (clobber (match_scratch:DI 3 "=r"))]
18754   "TARGET_64BIT"
18755   {
18756      /* The kernel uses a different segment register for performance reasons; a
18757         system call would not have to trash the userspace segment register,
18758         which would be expensive */
18759      if (ix86_cmodel != CM_KERNEL)
18760         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
18761      else
18762         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
18763   }
18764   [(set_attr "type" "multi")])
18765
18766 (define_insn "sse4_2_crc32<mode>"
18767   [(set (match_operand:SI 0 "register_operand" "=r")
18768         (unspec:SI
18769           [(match_operand:SI 1 "register_operand" "0")
18770            (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
18771           UNSPEC_CRC32))]
18772   "TARGET_SSE4_2 || TARGET_CRC32"
18773   "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
18774   [(set_attr "type" "sselog1")
18775    (set_attr "prefix_rep" "1")
18776    (set_attr "prefix_extra" "1")
18777    (set (attr "prefix_data16")
18778      (if_then_else (match_operand:HI 2 "" "")
18779        (const_string "1")
18780        (const_string "*")))
18781    (set (attr "prefix_rex")
18782      (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
18783        (const_string "1")
18784        (const_string "*")))
18785    (set_attr "mode" "SI")])
18786
18787 (define_insn "sse4_2_crc32di"
18788   [(set (match_operand:DI 0 "register_operand" "=r")
18789         (unspec:DI
18790           [(match_operand:DI 1 "register_operand" "0")
18791            (match_operand:DI 2 "nonimmediate_operand" "rm")]
18792           UNSPEC_CRC32))]
18793   "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
18794   "crc32{q}\t{%2, %0|%0, %2}"
18795   [(set_attr "type" "sselog1")
18796    (set_attr "prefix_rep" "1")
18797    (set_attr "prefix_extra" "1")
18798    (set_attr "mode" "DI")])
18799
18800 (define_expand "rdpmc"
18801   [(match_operand:DI 0 "register_operand" "")
18802    (match_operand:SI 1 "register_operand" "")]
18803   ""
18804 {
18805   rtx reg = gen_reg_rtx (DImode);
18806   rtx si;
18807
18808   /* Force operand 1 into ECX.  */
18809   rtx ecx = gen_rtx_REG (SImode, CX_REG);
18810   emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
18811   si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
18812                                 UNSPECV_RDPMC);
18813
18814   if (TARGET_64BIT)
18815     {
18816       rtvec vec = rtvec_alloc (2);
18817       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18818       rtx upper = gen_reg_rtx (DImode);
18819       rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
18820                                         gen_rtvec (1, const0_rtx),
18821                                         UNSPECV_RDPMC);
18822       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
18823       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
18824       emit_insn (load);
18825       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18826                                    NULL, 1, OPTAB_DIRECT);
18827       reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
18828                                  OPTAB_DIRECT);
18829     }
18830   else
18831     emit_insn (gen_rtx_SET (VOIDmode, reg, si));
18832   emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
18833   DONE;
18834 })
18835
18836 (define_insn "*rdpmc"
18837   [(set (match_operand:DI 0 "register_operand" "=A")
18838         (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
18839                             UNSPECV_RDPMC))]
18840   "!TARGET_64BIT"
18841   "rdpmc"
18842   [(set_attr "type" "other")
18843    (set_attr "length" "2")])
18844
18845 (define_insn "*rdpmc_rex64"
18846   [(set (match_operand:DI 0 "register_operand" "=a")
18847         (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
18848                             UNSPECV_RDPMC))
18849   (set (match_operand:DI 1 "register_operand" "=d")
18850        (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
18851   "TARGET_64BIT"
18852   "rdpmc"
18853   [(set_attr "type" "other")
18854    (set_attr "length" "2")])
18855
18856 (define_expand "rdtsc"
18857   [(set (match_operand:DI 0 "register_operand" "")
18858         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18859   ""
18860 {
18861   if (TARGET_64BIT)
18862     {
18863       rtvec vec = rtvec_alloc (2);
18864       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18865       rtx upper = gen_reg_rtx (DImode);
18866       rtx lower = gen_reg_rtx (DImode);
18867       rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
18868                                          gen_rtvec (1, const0_rtx),
18869                                          UNSPECV_RDTSC);
18870       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
18871       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
18872       emit_insn (load);
18873       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18874                                    NULL, 1, OPTAB_DIRECT);
18875       lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
18876                                    OPTAB_DIRECT);
18877       emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
18878       DONE;
18879     }
18880 })
18881
18882 (define_insn "*rdtsc"
18883   [(set (match_operand:DI 0 "register_operand" "=A")
18884         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18885   "!TARGET_64BIT"
18886   "rdtsc"
18887   [(set_attr "type" "other")
18888    (set_attr "length" "2")])
18889
18890 (define_insn "*rdtsc_rex64"
18891   [(set (match_operand:DI 0 "register_operand" "=a")
18892         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
18893    (set (match_operand:DI 1 "register_operand" "=d")
18894         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18895   "TARGET_64BIT"
18896   "rdtsc"
18897   [(set_attr "type" "other")
18898    (set_attr "length" "2")])
18899
18900 (define_expand "rdtscp"
18901   [(match_operand:DI 0 "register_operand" "")
18902    (match_operand:SI 1 "memory_operand" "")]
18903   ""
18904 {
18905   rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
18906                                     gen_rtvec (1, const0_rtx),
18907                                     UNSPECV_RDTSCP);
18908   rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
18909                                     gen_rtvec (1, const0_rtx),
18910                                     UNSPECV_RDTSCP);
18911   rtx reg = gen_reg_rtx (DImode);
18912   rtx tmp = gen_reg_rtx (SImode);
18913
18914   if (TARGET_64BIT)
18915     {
18916       rtvec vec = rtvec_alloc (3);
18917       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18918       rtx upper = gen_reg_rtx (DImode);
18919       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
18920       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
18921       RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
18922       emit_insn (load);
18923       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18924                                    NULL, 1, OPTAB_DIRECT);
18925       reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
18926                                  OPTAB_DIRECT);
18927     }
18928   else
18929     {
18930       rtvec vec = rtvec_alloc (2);
18931       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18932       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
18933       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
18934       emit_insn (load);
18935     }
18936   emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
18937   emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
18938   DONE;
18939 })
18940
18941 (define_insn "*rdtscp"
18942   [(set (match_operand:DI 0 "register_operand" "=A")
18943         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18944    (set (match_operand:SI 1 "register_operand" "=c")
18945         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18946   "!TARGET_64BIT"
18947   "rdtscp"
18948   [(set_attr "type" "other")
18949    (set_attr "length" "3")])
18950
18951 (define_insn "*rdtscp_rex64"
18952   [(set (match_operand:DI 0 "register_operand" "=a")
18953         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18954    (set (match_operand:DI 1 "register_operand" "=d")
18955         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18956    (set (match_operand:SI 2 "register_operand" "=c")
18957         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18958   "TARGET_64BIT"
18959   "rdtscp"
18960   [(set_attr "type" "other")
18961    (set_attr "length" "3")])
18962
18963 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18964 ;;
18965 ;; LWP instructions
18966 ;;
18967 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18968
18969 (define_expand "lwp_llwpcb"
18970   [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18971                     UNSPECV_LLWP_INTRINSIC)]
18972   "TARGET_LWP"
18973   "")
18974
18975 (define_insn "*lwp_llwpcb<mode>1"
18976   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18977                     UNSPECV_LLWP_INTRINSIC)]
18978   "TARGET_LWP"
18979   "llwpcb\t%0"
18980   [(set_attr "type" "lwp")
18981    (set_attr "mode" "<MODE>")
18982    (set_attr "length" "5")])
18983
18984 (define_expand "lwp_slwpcb"
18985   [(set (match_operand 0 "register_operand" "=r")
18986         (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18987   "TARGET_LWP"
18988   {
18989     if (TARGET_64BIT)
18990       emit_insn (gen_lwp_slwpcbdi (operands[0]));
18991     else
18992       emit_insn (gen_lwp_slwpcbsi (operands[0]));
18993     DONE;
18994   })
18995
18996 (define_insn "lwp_slwpcb<mode>"
18997   [(set (match_operand:P 0 "register_operand" "=r")
18998         (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18999   "TARGET_LWP"
19000   "slwpcb\t%0"
19001   [(set_attr "type" "lwp")
19002    (set_attr "mode" "<MODE>")
19003    (set_attr "length" "5")])
19004
19005 (define_expand "lwp_lwpval<mode>3"
19006   [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
19007                      (match_operand:SI 2 "nonimmediate_operand" "rm")
19008                      (match_operand:SI 3 "const_int_operand" "i")]
19009                     UNSPECV_LWPVAL_INTRINSIC)]
19010   "TARGET_LWP"
19011   "/* Avoid unused variable warning.  */
19012    (void) operand0;")
19013
19014 (define_insn "*lwp_lwpval<mode>3_1"
19015   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
19016                      (match_operand:SI 1 "nonimmediate_operand" "rm")
19017                      (match_operand:SI 2 "const_int_operand" "i")]
19018                     UNSPECV_LWPVAL_INTRINSIC)]
19019   "TARGET_LWP"
19020   "lwpval\t{%2, %1, %0|%0, %1, %2}"
19021   [(set_attr "type" "lwp")
19022    (set_attr "mode" "<MODE>")
19023    (set (attr "length")
19024         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
19025
19026 (define_expand "lwp_lwpins<mode>3"
19027   [(set (reg:CCC FLAGS_REG)
19028         (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
19029                               (match_operand:SI 2 "nonimmediate_operand" "rm")
19030                               (match_operand:SI 3 "const_int_operand" "i")]
19031                              UNSPECV_LWPINS_INTRINSIC))
19032    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
19033         (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
19034   "TARGET_LWP"
19035   "")
19036
19037 (define_insn "*lwp_lwpins<mode>3_1"
19038   [(set (reg:CCC FLAGS_REG)
19039         (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
19040                               (match_operand:SI 1 "nonimmediate_operand" "rm")
19041                               (match_operand:SI 2 "const_int_operand" "i")]
19042                              UNSPECV_LWPINS_INTRINSIC))]
19043   "TARGET_LWP"
19044   "lwpins\t{%2, %1, %0|%0, %1, %2}"
19045   [(set_attr "type" "lwp")
19046    (set_attr "mode" "<MODE>")
19047    (set (attr "length")
19048         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
19049
19050 (include "mmx.md")
19051 (include "sse.md")
19052 (include "sync.md")