OSDN Git Service

d142c7fbc39f2a1c5180f97aeccee702ccdce95e
[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 maxmin_int [(smax "maxs") (smin "mins")
717                               (umax "maxu") (umin "minu")])
718 (define_code_attr maxmin_float [(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 logic [(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 absneg_mnemonic [(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   "<logic>{<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    <logic>{b}\t{%2, %0|%0, %2}
8801    <logic>{b}\t{%2, %0|%0, %2}
8802    <logic>{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   "<logic>{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   "<logic>{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   "<logic>{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   "<logic>{<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   "<logic>{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   "<logic>{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   "<logic>{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   "<logic>{<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   "<logic>{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   "<logic>{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   "<logic>{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   "<logic>{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<absneg_mnemonic>"
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<absneg_mnemonic>"
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<absneg_mnemonic>"
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<absneg_mnemonic>"
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 (define_insn "*ashlqi3_1_slp"
9990   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9991         (ashift:QI (match_dup 0)
9992                    (match_operand:QI 1 "nonmemory_operand" "cI")))
9993    (clobber (reg:CC FLAGS_REG))]
9994   "(optimize_function_for_size_p (cfun)
9995     || !TARGET_PARTIAL_FLAG_REG_STALL
9996     || (operands[1] == const1_rtx
9997         && (TARGET_SHIFT1
9998             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9999 {
10000   switch (get_attr_type (insn))
10001     {
10002     case TYPE_ALU:
10003       gcc_assert (operands[1] == const1_rtx);
10004       return "add{b}\t%0, %0";
10005
10006     default:
10007       if (operands[1] == const1_rtx
10008           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10009         return "sal{b}\t%0";
10010       else
10011         return "sal{b}\t{%1, %0|%0, %1}";
10012     }
10013 }
10014   [(set (attr "type")
10015      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10016                           (const_int 0))
10017                       (match_operand 0 "register_operand" ""))
10018                  (match_operand 1 "const1_operand" ""))
10019               (const_string "alu")
10020            ]
10021            (const_string "ishift1")))
10022    (set (attr "length_immediate")
10023      (if_then_else
10024        (ior (eq_attr "type" "alu")
10025             (and (eq_attr "type" "ishift1")
10026                  (and (match_operand 1 "const1_operand" "")
10027                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10028                           (const_int 0)))))
10029        (const_string "0")
10030        (const_string "*")))
10031    (set_attr "mode" "QI")])
10032
10033 ;; Convert lea to the lea pattern to avoid flags dependency.
10034 (define_split
10035   [(set (match_operand:DI 0 "register_operand" "")
10036         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10037                    (match_operand:QI 2 "const_int_operand" "")))
10038    (clobber (reg:CC FLAGS_REG))]
10039   "TARGET_64BIT && reload_completed
10040    && true_regnum (operands[0]) != true_regnum (operands[1])"
10041   [(set (match_dup 0)
10042         (mult:DI (match_dup 1)
10043                  (match_dup 2)))]
10044   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10045
10046 ;; Convert lea to the lea pattern to avoid flags dependency.
10047 (define_split
10048   [(set (match_operand 0 "register_operand" "")
10049         (ashift (match_operand 1 "index_register_operand" "")
10050                 (match_operand:QI 2 "const_int_operand" "")))
10051    (clobber (reg:CC FLAGS_REG))]
10052   "reload_completed
10053    && true_regnum (operands[0]) != true_regnum (operands[1])
10054    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10055   [(const_int 0)]
10056 {
10057   rtx pat;
10058   enum machine_mode mode = GET_MODE (operands[0]);
10059
10060   if (GET_MODE_SIZE (mode) < 4)
10061     operands[0] = gen_lowpart (SImode, operands[0]);
10062   if (mode != Pmode)
10063     operands[1] = gen_lowpart (Pmode, operands[1]);
10064   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10065
10066   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10067   if (Pmode != SImode)
10068     pat = gen_rtx_SUBREG (SImode, pat, 0);
10069   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10070   DONE;
10071 })
10072
10073 ;; Rare case of shifting RSP is handled by generating move and shift
10074 (define_split
10075   [(set (match_operand 0 "register_operand" "")
10076         (ashift (match_operand 1 "register_operand" "")
10077                 (match_operand:QI 2 "const_int_operand" "")))
10078    (clobber (reg:CC FLAGS_REG))]
10079   "reload_completed
10080    && true_regnum (operands[0]) != true_regnum (operands[1])"
10081   [(const_int 0)]
10082 {
10083   rtx pat, clob;
10084   emit_move_insn (operands[0], operands[1]);
10085   pat = gen_rtx_SET (VOIDmode, operands[0],
10086                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
10087                                      operands[0], operands[2]));
10088   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10089   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10090   DONE;
10091 })
10092
10093 ;; Convert lea to the lea pattern to avoid flags dependency.
10094 (define_split
10095   [(set (match_operand:DI 0 "register_operand" "")
10096         (zero_extend:DI
10097           (ashift:SI (match_operand:SI 1 "register_operand" "")
10098                      (match_operand:QI 2 "const_int_operand" ""))))
10099    (clobber (reg:CC FLAGS_REG))]
10100   "TARGET_64BIT && reload_completed
10101    && true_regnum (operands[0]) != true_regnum (operands[1])"
10102   [(set (match_dup 0)
10103         (zero_extend:DI (subreg:SI (mult:SI (match_dup 1) (match_dup 2)) 0)))]
10104 {
10105   operands[1] = gen_lowpart (Pmode, operands[1]);
10106   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10107 })
10108
10109 ;; This pattern can't accept a variable shift count, since shifts by
10110 ;; zero don't affect the flags.  We assume that shifts by constant
10111 ;; zero are optimized away.
10112 (define_insn "*ashl<mode>3_cmp"
10113   [(set (reg FLAGS_REG)
10114         (compare
10115           (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10116                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10117           (const_int 0)))
10118    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10119         (ashift:SWI (match_dup 1) (match_dup 2)))]
10120   "(optimize_function_for_size_p (cfun)
10121     || !TARGET_PARTIAL_FLAG_REG_STALL
10122     || (operands[2] == const1_rtx
10123         && (TARGET_SHIFT1
10124             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
10125    && ix86_match_ccmode (insn, CCGOCmode)
10126    && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
10127 {
10128   switch (get_attr_type (insn))
10129     {
10130     case TYPE_ALU:
10131       gcc_assert (operands[2] == const1_rtx);
10132       return "add{<imodesuffix>}\t%0, %0";
10133
10134     default:
10135       if (operands[2] == const1_rtx
10136           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10137         return "sal{<imodesuffix>}\t%0";
10138       else
10139         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10140     }
10141 }
10142   [(set (attr "type")
10143      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10144                           (const_int 0))
10145                       (match_operand 0 "register_operand" ""))
10146                  (match_operand 2 "const1_operand" ""))
10147               (const_string "alu")
10148            ]
10149            (const_string "ishift")))
10150    (set (attr "length_immediate")
10151      (if_then_else
10152        (ior (eq_attr "type" "alu")
10153             (and (eq_attr "type" "ishift")
10154                  (and (match_operand 2 "const1_operand" "")
10155                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10156                           (const_int 0)))))
10157        (const_string "0")
10158        (const_string "*")))
10159    (set_attr "mode" "<MODE>")])
10160
10161 (define_insn "*ashlsi3_cmp_zext"
10162   [(set (reg FLAGS_REG)
10163         (compare
10164           (ashift:SI (match_operand:SI 1 "register_operand" "0")
10165                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10166           (const_int 0)))
10167    (set (match_operand:DI 0 "register_operand" "=r")
10168         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10169   "TARGET_64BIT
10170    && (optimize_function_for_size_p (cfun)
10171        || !TARGET_PARTIAL_FLAG_REG_STALL
10172        || (operands[2] == const1_rtx
10173            && (TARGET_SHIFT1
10174                || TARGET_DOUBLE_WITH_ADD)))
10175    && ix86_match_ccmode (insn, CCGOCmode)
10176    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10177 {
10178   switch (get_attr_type (insn))
10179     {
10180     case TYPE_ALU:
10181       gcc_assert (operands[2] == const1_rtx);
10182       return "add{l}\t%k0, %k0";
10183
10184     default:
10185       if (operands[2] == const1_rtx
10186           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10187         return "sal{l}\t%k0";
10188       else
10189         return "sal{l}\t{%2, %k0|%k0, %2}";
10190     }
10191 }
10192   [(set (attr "type")
10193      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10194                      (const_int 0))
10195                  (match_operand 2 "const1_operand" ""))
10196               (const_string "alu")
10197            ]
10198            (const_string "ishift")))
10199    (set (attr "length_immediate")
10200      (if_then_else
10201        (ior (eq_attr "type" "alu")
10202             (and (eq_attr "type" "ishift")
10203                  (and (match_operand 2 "const1_operand" "")
10204                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10205                           (const_int 0)))))
10206        (const_string "0")
10207        (const_string "*")))
10208    (set_attr "mode" "SI")])
10209
10210 (define_insn "*ashl<mode>3_cconly"
10211   [(set (reg FLAGS_REG)
10212         (compare
10213           (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10214                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10215           (const_int 0)))
10216    (clobber (match_scratch:SWI 0 "=<r>"))]
10217   "(optimize_function_for_size_p (cfun)
10218     || !TARGET_PARTIAL_FLAG_REG_STALL
10219     || (operands[2] == const1_rtx
10220         && (TARGET_SHIFT1
10221             || TARGET_DOUBLE_WITH_ADD)))
10222    && ix86_match_ccmode (insn, CCGOCmode)
10223    && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
10224 {
10225   switch (get_attr_type (insn))
10226     {
10227     case TYPE_ALU:
10228       gcc_assert (operands[2] == const1_rtx);
10229       return "add{<imodesuffix>}\t%0, %0";
10230
10231     default:
10232       if (operands[2] == const1_rtx
10233           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10234         return "sal{<imodesuffix>}\t%0";
10235       else
10236         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10237     }
10238 }
10239   [(set (attr "type")
10240      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10241                           (const_int 0))
10242                       (match_operand 0 "register_operand" ""))
10243                  (match_operand 2 "const1_operand" ""))
10244               (const_string "alu")
10245            ]
10246            (const_string "ishift")))
10247    (set (attr "length_immediate")
10248      (if_then_else
10249        (ior (eq_attr "type" "alu")
10250             (and (eq_attr "type" "ishift")
10251                  (and (match_operand 2 "const1_operand" "")
10252                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10253                           (const_int 0)))))
10254        (const_string "0")
10255        (const_string "*")))
10256    (set_attr "mode" "<MODE>")])
10257
10258 ;; See comment above `ashl<mode>3' about how this works.
10259
10260 (define_expand "<shiftrt_insn><mode>3"
10261   [(set (match_operand:SDWIM 0 "<shift_operand>" "")
10262         (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
10263                            (match_operand:QI 2 "nonmemory_operand" "")))]
10264   ""
10265   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10266
10267 (define_insn_and_split "*<shiftrt_insn><mode>3_doubleword"
10268   [(set (match_operand:DWI 0 "register_operand" "=r")
10269         (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
10270                          (match_operand:QI 2 "nonmemory_operand" "<S>c")))
10271    (clobber (reg:CC FLAGS_REG))]
10272   ""
10273   "#"
10274   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
10275   [(const_int 0)]
10276   "ix86_split_<shiftrt_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
10277   [(set_attr "type" "multi")])
10278
10279 ;; By default we don't ask for a scratch register, because when DWImode
10280 ;; values are manipulated, registers are already at a premium.  But if
10281 ;; we have one handy, we won't turn it away.
10282
10283 (define_peephole2
10284   [(match_scratch:DWIH 3 "r")
10285    (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
10286                    (any_shiftrt:<DWI>
10287                      (match_operand:<DWI> 1 "register_operand" "")
10288                      (match_operand:QI 2 "nonmemory_operand" "")))
10289               (clobber (reg:CC FLAGS_REG))])
10290    (match_dup 3)]
10291   "TARGET_CMOVE"
10292   [(const_int 0)]
10293   "ix86_split_<shiftrt_insn> (operands, operands[3], <DWI>mode); DONE;")
10294
10295 (define_insn "x86_64_shrd"
10296   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
10297         (ior:DI (ashiftrt:DI (match_dup 0)
10298                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
10299                 (ashift:DI (match_operand:DI 1 "register_operand" "r")
10300                   (minus:QI (const_int 64) (match_dup 2)))))
10301    (clobber (reg:CC FLAGS_REG))]
10302   "TARGET_64BIT"
10303   "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
10304   [(set_attr "type" "ishift")
10305    (set_attr "prefix_0f" "1")
10306    (set_attr "mode" "DI")
10307    (set_attr "athlon_decode" "vector")
10308    (set_attr "amdfam10_decode" "vector")])
10309
10310 (define_insn "x86_shrd"
10311   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
10312         (ior:SI (ashiftrt:SI (match_dup 0)
10313                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
10314                 (ashift:SI (match_operand:SI 1 "register_operand" "r")
10315                   (minus:QI (const_int 32) (match_dup 2)))))
10316    (clobber (reg:CC FLAGS_REG))]
10317   ""
10318   "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
10319   [(set_attr "type" "ishift")
10320    (set_attr "prefix_0f" "1")
10321    (set_attr "pent_pair" "np")
10322    (set_attr "mode" "SI")])
10323
10324 (define_insn "ashrdi3_cvt"
10325   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
10326         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
10327                      (match_operand:QI 2 "const_int_operand" "")))
10328    (clobber (reg:CC FLAGS_REG))]
10329   "TARGET_64BIT && INTVAL (operands[2]) == 63
10330    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10331    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10332   "@
10333    {cqto|cqo}
10334    sar{q}\t{%2, %0|%0, %2}"
10335   [(set_attr "type" "imovx,ishift")
10336    (set_attr "prefix_0f" "0,*")
10337    (set_attr "length_immediate" "0,*")
10338    (set_attr "modrm" "0,1")
10339    (set_attr "mode" "DI")])
10340
10341 (define_insn "ashrsi3_cvt"
10342   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
10343         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
10344                      (match_operand:QI 2 "const_int_operand" "")))
10345    (clobber (reg:CC FLAGS_REG))]
10346   "INTVAL (operands[2]) == 31
10347    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10348    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10349   "@
10350    {cltd|cdq}
10351    sar{l}\t{%2, %0|%0, %2}"
10352   [(set_attr "type" "imovx,ishift")
10353    (set_attr "prefix_0f" "0,*")
10354    (set_attr "length_immediate" "0,*")
10355    (set_attr "modrm" "0,1")
10356    (set_attr "mode" "SI")])
10357
10358 (define_insn "*ashrsi3_cvt_zext"
10359   [(set (match_operand:DI 0 "register_operand" "=*d,r")
10360         (zero_extend:DI
10361           (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
10362                        (match_operand:QI 2 "const_int_operand" ""))))
10363    (clobber (reg:CC FLAGS_REG))]
10364   "TARGET_64BIT && INTVAL (operands[2]) == 31
10365    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10366    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10367   "@
10368    {cltd|cdq}
10369    sar{l}\t{%2, %k0|%k0, %2}"
10370   [(set_attr "type" "imovx,ishift")
10371    (set_attr "prefix_0f" "0,*")
10372    (set_attr "length_immediate" "0,*")
10373    (set_attr "modrm" "0,1")
10374    (set_attr "mode" "SI")])
10375
10376 (define_expand "x86_shift<mode>_adj_3"
10377   [(use (match_operand:SWI48 0 "register_operand" ""))
10378    (use (match_operand:SWI48 1 "register_operand" ""))
10379    (use (match_operand:QI 2 "register_operand" ""))]
10380   ""
10381 {
10382   rtx label = gen_label_rtx ();
10383   rtx tmp;
10384
10385   emit_insn (gen_testqi_ccz_1 (operands[2],
10386                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
10387
10388   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10389   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10390   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10391                               gen_rtx_LABEL_REF (VOIDmode, label),
10392                               pc_rtx);
10393   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10394   JUMP_LABEL (tmp) = label;
10395
10396   emit_move_insn (operands[0], operands[1]);
10397   emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
10398                                   GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
10399   emit_label (label);
10400   LABEL_NUSES (label) = 1;
10401
10402   DONE;
10403 })
10404
10405 (define_insn "*<shiftrt_insn><mode>3_1"
10406   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10407         (any_shiftrt:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10408                          (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10409    (clobber (reg:CC FLAGS_REG))]
10410   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10411 {
10412   if (operands[2] == const1_rtx
10413       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10414     return "<shiftrt>{<imodesuffix>}\t%0";
10415   else
10416     return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
10417 }
10418   [(set_attr "type" "ishift")
10419    (set (attr "length_immediate")
10420      (if_then_else
10421        (and (match_operand 2 "const1_operand" "")
10422             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10423                 (const_int 0)))
10424        (const_string "0")
10425        (const_string "*")))
10426    (set_attr "mode" "<MODE>")])
10427
10428 (define_insn "*<shiftrt_insn>si3_1_zext"
10429   [(set (match_operand:DI 0 "register_operand" "=r")
10430         (zero_extend:DI
10431           (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10432                           (match_operand:QI 2 "nonmemory_operand" "cI"))))
10433    (clobber (reg:CC FLAGS_REG))]
10434   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10435 {
10436   if (operands[2] == const1_rtx
10437       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10438     return "<shiftrt>{l}\t%k0";
10439   else
10440     return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
10441 }
10442   [(set_attr "type" "ishift")
10443    (set (attr "length_immediate")
10444      (if_then_else
10445        (and (match_operand 2 "const1_operand" "")
10446             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10447                 (const_int 0)))
10448        (const_string "0")
10449        (const_string "*")))
10450    (set_attr "mode" "SI")])
10451
10452 (define_insn "*<shiftrt_insn>qi3_1_slp"
10453   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10454         (any_shiftrt:QI (match_dup 0)
10455                         (match_operand:QI 1 "nonmemory_operand" "cI")))
10456    (clobber (reg:CC FLAGS_REG))]
10457   "(optimize_function_for_size_p (cfun)
10458     || !TARGET_PARTIAL_REG_STALL
10459     || (operands[1] == const1_rtx
10460         && TARGET_SHIFT1))"
10461 {
10462   if (operands[1] == const1_rtx
10463       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10464     return "<shiftrt>{b}\t%0";
10465   else
10466     return "<shiftrt>{b}\t{%1, %0|%0, %1}";
10467 }
10468   [(set_attr "type" "ishift1")
10469    (set (attr "length_immediate")
10470      (if_then_else
10471        (and (match_operand 1 "const1_operand" "")
10472             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10473                 (const_int 0)))
10474        (const_string "0")
10475        (const_string "*")))
10476    (set_attr "mode" "QI")])
10477
10478 ;; This pattern can't accept a variable shift count, since shifts by
10479 ;; zero don't affect the flags.  We assume that shifts by constant
10480 ;; zero are optimized away.
10481 (define_insn "*<shiftrt_insn><mode>3_cmp"
10482   [(set (reg FLAGS_REG)
10483         (compare
10484           (any_shiftrt:SWI
10485             (match_operand:SWI 1 "nonimmediate_operand" "0")
10486             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10487           (const_int 0)))
10488    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10489         (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
10490   "(optimize_function_for_size_p (cfun)
10491     || !TARGET_PARTIAL_FLAG_REG_STALL
10492     || (operands[2] == const1_rtx
10493         && TARGET_SHIFT1))
10494    && ix86_match_ccmode (insn, CCGOCmode)
10495    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10496 {
10497   if (operands[2] == const1_rtx
10498       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10499     return "<shiftrt>{<imodesuffix>}\t%0";
10500   else
10501     return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
10502 }
10503   [(set_attr "type" "ishift")
10504    (set (attr "length_immediate")
10505      (if_then_else
10506        (and (match_operand 2 "const1_operand" "")
10507             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10508                 (const_int 0)))
10509        (const_string "0")
10510        (const_string "*")))
10511    (set_attr "mode" "<MODE>")])
10512
10513 (define_insn "*<shiftrt_insn>si3_cmp_zext"
10514   [(set (reg FLAGS_REG)
10515         (compare
10516           (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10517                           (match_operand:QI 2 "const_1_to_31_operand" "I"))
10518           (const_int 0)))
10519    (set (match_operand:DI 0 "register_operand" "=r")
10520         (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10521   "TARGET_64BIT
10522    && (optimize_function_for_size_p (cfun)
10523        || !TARGET_PARTIAL_FLAG_REG_STALL
10524        || (operands[2] == const1_rtx
10525            && TARGET_SHIFT1))
10526    && ix86_match_ccmode (insn, CCGOCmode)
10527    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10528 {
10529   if (operands[2] == const1_rtx
10530       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10531     return "<shiftrt>{l}\t%k0";
10532   else
10533     return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
10534 }
10535   [(set_attr "type" "ishift")
10536    (set (attr "length_immediate")
10537      (if_then_else
10538        (and (match_operand 2 "const1_operand" "")
10539             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10540                 (const_int 0)))
10541        (const_string "0")
10542        (const_string "*")))
10543    (set_attr "mode" "SI")])
10544
10545 (define_insn "*<shiftrt_insn><mode>3_cconly"
10546   [(set (reg FLAGS_REG)
10547         (compare
10548           (any_shiftrt:SWI
10549             (match_operand:SWI 1 "nonimmediate_operand" "0")
10550             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10551           (const_int 0)))
10552    (clobber (match_scratch:SWI 0 "=<r>"))]
10553   "(optimize_function_for_size_p (cfun)
10554     || !TARGET_PARTIAL_FLAG_REG_STALL
10555     || (operands[2] == const1_rtx
10556         && TARGET_SHIFT1))
10557    && ix86_match_ccmode (insn, CCGOCmode)
10558    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10559 {
10560   if (operands[2] == const1_rtx
10561       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10562     return "<shiftrt>{<imodesuffix>}\t%0";
10563   else
10564     return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
10565 }
10566   [(set_attr "type" "ishift")
10567    (set (attr "length_immediate")
10568      (if_then_else
10569        (and (match_operand 2 "const1_operand" "")
10570             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10571                 (const_int 0)))
10572        (const_string "0")
10573        (const_string "*")))
10574    (set_attr "mode" "<MODE>")])
10575 \f
10576 ;; Rotate instructions
10577
10578 (define_expand "<rotate_insn>ti3"
10579   [(set (match_operand:TI 0 "register_operand" "")
10580         (any_rotate:TI (match_operand:TI 1 "register_operand" "")
10581                        (match_operand:QI 2 "nonmemory_operand" "")))]
10582   "TARGET_64BIT"
10583 {
10584   if (const_1_to_63_operand (operands[2], VOIDmode))
10585     emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10586                 (operands[0], operands[1], operands[2]));
10587   else
10588     FAIL;
10589
10590   DONE;
10591 })
10592
10593 (define_expand "<rotate_insn>di3"
10594   [(set (match_operand:DI 0 "shiftdi_operand" "")
10595         (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
10596                        (match_operand:QI 2 "nonmemory_operand" "")))]
10597  ""
10598 {
10599   if (TARGET_64BIT)
10600     ix86_expand_binary_operator (<CODE>, DImode, operands);
10601   else if (const_1_to_31_operand (operands[2], VOIDmode))
10602     emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10603                 (operands[0], operands[1], operands[2]));
10604   else
10605     FAIL;
10606
10607   DONE;
10608 })
10609
10610 (define_expand "<rotate_insn><mode>3"
10611   [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
10612         (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
10613                             (match_operand:QI 2 "nonmemory_operand" "")))]
10614   ""
10615   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10616
10617 ;; Implement rotation using two double-precision
10618 ;; shift instructions and a scratch register.
10619
10620 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10621  [(set (match_operand:<DWI> 0 "register_operand" "=r")
10622        (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10623                      (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10624   (clobber (reg:CC FLAGS_REG))
10625   (clobber (match_scratch:DWIH 3 "=&r"))]
10626  ""
10627  "#"
10628  "reload_completed"
10629  [(set (match_dup 3) (match_dup 4))
10630   (parallel
10631    [(set (match_dup 4)
10632          (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10633                    (lshiftrt:DWIH (match_dup 5)
10634                                   (minus:QI (match_dup 6) (match_dup 2)))))
10635     (clobber (reg:CC FLAGS_REG))])
10636   (parallel
10637    [(set (match_dup 5)
10638          (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10639                    (lshiftrt:DWIH (match_dup 3)
10640                                   (minus:QI (match_dup 6) (match_dup 2)))))
10641     (clobber (reg:CC FLAGS_REG))])]
10642 {
10643   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10644
10645   split_<dwi> (&operands[0], 1, &operands[4], &operands[5]);
10646 })
10647
10648 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10649  [(set (match_operand:<DWI> 0 "register_operand" "=r")
10650        (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10651                        (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10652   (clobber (reg:CC FLAGS_REG))
10653   (clobber (match_scratch:DWIH 3 "=&r"))]
10654  ""
10655  "#"
10656  "reload_completed"
10657  [(set (match_dup 3) (match_dup 4))
10658   (parallel
10659    [(set (match_dup 4)
10660          (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10661                    (ashift:DWIH (match_dup 5)
10662                                 (minus:QI (match_dup 6) (match_dup 2)))))
10663     (clobber (reg:CC FLAGS_REG))])
10664   (parallel
10665    [(set (match_dup 5)
10666          (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10667                    (ashift:DWIH (match_dup 3)
10668                                 (minus:QI (match_dup 6) (match_dup 2)))))
10669     (clobber (reg:CC FLAGS_REG))])]
10670 {
10671   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10672
10673   split_<dwi> (&operands[0], 1, &operands[4], &operands[5]);
10674 })
10675
10676 (define_insn "*<rotate_insn><mode>3_1"
10677   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10678         (any_rotate:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10679                         (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10680    (clobber (reg:CC FLAGS_REG))]
10681   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10682 {
10683   if (operands[2] == const1_rtx
10684       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10685     return "<rotate>{<imodesuffix>}\t%0";
10686   else
10687     return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10688 }
10689   [(set_attr "type" "rotate")
10690    (set (attr "length_immediate")
10691      (if_then_else
10692        (and (match_operand 2 "const1_operand" "")
10693             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10694                 (const_int 0)))
10695        (const_string "0")
10696        (const_string "*")))
10697    (set_attr "mode" "<MODE>")])
10698
10699 (define_insn "*<rotate_insn>si3_1_zext"
10700   [(set (match_operand:DI 0 "register_operand" "=r")
10701         (zero_extend:DI
10702           (any_rotate:SI (match_operand:SI 1 "register_operand" "0")
10703                          (match_operand:QI 2 "nonmemory_operand" "cI"))))
10704    (clobber (reg:CC FLAGS_REG))]
10705   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10706 {
10707     if (operands[2] == const1_rtx
10708         && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10709     return "<rotate>{l}\t%k0";
10710   else
10711     return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10712 }
10713   [(set_attr "type" "rotate")
10714    (set (attr "length_immediate")
10715      (if_then_else
10716        (and (match_operand 2 "const1_operand" "")
10717             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10718                 (const_int 0)))
10719        (const_string "0")
10720        (const_string "*")))
10721    (set_attr "mode" "SI")])
10722
10723 (define_insn "*<rotate_insn>qi3_1_slp"
10724   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10725         (any_rotate:QI (match_dup 0)
10726                        (match_operand:QI 1 "nonmemory_operand" "cI")))
10727    (clobber (reg:CC FLAGS_REG))]
10728   "(optimize_function_for_size_p (cfun)
10729     || !TARGET_PARTIAL_REG_STALL
10730     || (operands[1] == const1_rtx
10731         && TARGET_SHIFT1))"
10732 {
10733   if (operands[1] == const1_rtx
10734       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10735     return "<rotate>{b}\t%0";
10736   else
10737     return "<rotate>{b}\t{%1, %0|%0, %1}";
10738 }
10739   [(set_attr "type" "rotate1")
10740    (set (attr "length_immediate")
10741      (if_then_else
10742        (and (match_operand 1 "const1_operand" "")
10743             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10744                 (const_int 0)))
10745        (const_string "0")
10746        (const_string "*")))
10747    (set_attr "mode" "QI")])
10748
10749 (define_split
10750  [(set (match_operand:HI 0 "register_operand" "")
10751        (any_rotate:HI (match_dup 0) (const_int 8)))
10752   (clobber (reg:CC FLAGS_REG))]
10753  "reload_completed
10754   && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10755  [(parallel [(set (strict_low_part (match_dup 0))
10756                   (bswap:HI (match_dup 0)))
10757              (clobber (reg:CC FLAGS_REG))])]
10758  "")
10759 \f
10760 ;; Bit set / bit test instructions
10761
10762 (define_expand "extv"
10763   [(set (match_operand:SI 0 "register_operand" "")
10764         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10765                          (match_operand:SI 2 "const8_operand" "")
10766                          (match_operand:SI 3 "const8_operand" "")))]
10767   ""
10768 {
10769   /* Handle extractions from %ah et al.  */
10770   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10771     FAIL;
10772
10773   /* From mips.md: extract_bit_field doesn't verify that our source
10774      matches the predicate, so check it again here.  */
10775   if (! ext_register_operand (operands[1], VOIDmode))
10776     FAIL;
10777 })
10778
10779 (define_expand "extzv"
10780   [(set (match_operand:SI 0 "register_operand" "")
10781         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10782                          (match_operand:SI 2 "const8_operand" "")
10783                          (match_operand:SI 3 "const8_operand" "")))]
10784   ""
10785 {
10786   /* Handle extractions from %ah et al.  */
10787   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10788     FAIL;
10789
10790   /* From mips.md: extract_bit_field doesn't verify that our source
10791      matches the predicate, so check it again here.  */
10792   if (! ext_register_operand (operands[1], VOIDmode))
10793     FAIL;
10794 })
10795
10796 (define_expand "insv"
10797   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
10798                       (match_operand 1 "const8_operand" "")
10799                       (match_operand 2 "const8_operand" ""))
10800         (match_operand 3 "register_operand" ""))]
10801   ""
10802 {
10803   /* Handle insertions to %ah et al.  */
10804   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10805     FAIL;
10806
10807   /* From mips.md: insert_bit_field doesn't verify that our source
10808      matches the predicate, so check it again here.  */
10809   if (! ext_register_operand (operands[0], VOIDmode))
10810     FAIL;
10811
10812   if (TARGET_64BIT)
10813     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
10814   else
10815     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
10816
10817   DONE;
10818 })
10819
10820 ;; %%% bts, btr, btc, bt.
10821 ;; In general these instructions are *slow* when applied to memory,
10822 ;; since they enforce atomic operation.  When applied to registers,
10823 ;; it depends on the cpu implementation.  They're never faster than
10824 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10825 ;; no point.  But in 64-bit, we can't hold the relevant immediates
10826 ;; within the instruction itself, so operating on bits in the high
10827 ;; 32-bits of a register becomes easier.
10828 ;;
10829 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
10830 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10831 ;; negdf respectively, so they can never be disabled entirely.
10832
10833 (define_insn "*btsq"
10834   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10835                          (const_int 1)
10836                          (match_operand:DI 1 "const_0_to_63_operand" ""))
10837         (const_int 1))
10838    (clobber (reg:CC FLAGS_REG))]
10839   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10840   "bts{q}\t{%1, %0|%0, %1}"
10841   [(set_attr "type" "alu1")
10842    (set_attr "prefix_0f" "1")
10843    (set_attr "mode" "DI")])
10844
10845 (define_insn "*btrq"
10846   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10847                          (const_int 1)
10848                          (match_operand:DI 1 "const_0_to_63_operand" ""))
10849         (const_int 0))
10850    (clobber (reg:CC FLAGS_REG))]
10851   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10852   "btr{q}\t{%1, %0|%0, %1}"
10853   [(set_attr "type" "alu1")
10854    (set_attr "prefix_0f" "1")
10855    (set_attr "mode" "DI")])
10856
10857 (define_insn "*btcq"
10858   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10859                          (const_int 1)
10860                          (match_operand:DI 1 "const_0_to_63_operand" ""))
10861         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10862    (clobber (reg:CC FLAGS_REG))]
10863   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10864   "btc{q}\t{%1, %0|%0, %1}"
10865   [(set_attr "type" "alu1")
10866    (set_attr "prefix_0f" "1")
10867    (set_attr "mode" "DI")])
10868
10869 ;; Allow Nocona to avoid these instructions if a register is available.
10870
10871 (define_peephole2
10872   [(match_scratch:DI 2 "r")
10873    (parallel [(set (zero_extract:DI
10874                      (match_operand:DI 0 "register_operand" "")
10875                      (const_int 1)
10876                      (match_operand:DI 1 "const_0_to_63_operand" ""))
10877                    (const_int 1))
10878               (clobber (reg:CC FLAGS_REG))])]
10879   "TARGET_64BIT && !TARGET_USE_BT"
10880   [(const_int 0)]
10881 {
10882   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10883   rtx op1;
10884
10885   if (HOST_BITS_PER_WIDE_INT >= 64)
10886     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10887   else if (i < HOST_BITS_PER_WIDE_INT)
10888     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10889   else
10890     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10891
10892   op1 = immed_double_const (lo, hi, DImode);
10893   if (i >= 31)
10894     {
10895       emit_move_insn (operands[2], op1);
10896       op1 = operands[2];
10897     }
10898
10899   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10900   DONE;
10901 })
10902
10903 (define_peephole2
10904   [(match_scratch:DI 2 "r")
10905    (parallel [(set (zero_extract:DI
10906                      (match_operand:DI 0 "register_operand" "")
10907                      (const_int 1)
10908                      (match_operand:DI 1 "const_0_to_63_operand" ""))
10909                    (const_int 0))
10910               (clobber (reg:CC FLAGS_REG))])]
10911   "TARGET_64BIT && !TARGET_USE_BT"
10912   [(const_int 0)]
10913 {
10914   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10915   rtx op1;
10916
10917   if (HOST_BITS_PER_WIDE_INT >= 64)
10918     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10919   else if (i < HOST_BITS_PER_WIDE_INT)
10920     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10921   else
10922     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10923
10924   op1 = immed_double_const (~lo, ~hi, DImode);
10925   if (i >= 32)
10926     {
10927       emit_move_insn (operands[2], op1);
10928       op1 = operands[2];
10929     }
10930
10931   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10932   DONE;
10933 })
10934
10935 (define_peephole2
10936   [(match_scratch:DI 2 "r")
10937    (parallel [(set (zero_extract:DI
10938                      (match_operand:DI 0 "register_operand" "")
10939                      (const_int 1)
10940                      (match_operand:DI 1 "const_0_to_63_operand" ""))
10941               (not:DI (zero_extract:DI
10942                         (match_dup 0) (const_int 1) (match_dup 1))))
10943               (clobber (reg:CC FLAGS_REG))])]
10944   "TARGET_64BIT && !TARGET_USE_BT"
10945   [(const_int 0)]
10946 {
10947   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10948   rtx op1;
10949
10950   if (HOST_BITS_PER_WIDE_INT >= 64)
10951     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10952   else if (i < HOST_BITS_PER_WIDE_INT)
10953     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10954   else
10955     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10956
10957   op1 = immed_double_const (lo, hi, DImode);
10958   if (i >= 31)
10959     {
10960       emit_move_insn (operands[2], op1);
10961       op1 = operands[2];
10962     }
10963
10964   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10965   DONE;
10966 })
10967
10968 (define_insn "*bt<mode>"
10969   [(set (reg:CCC FLAGS_REG)
10970         (compare:CCC
10971           (zero_extract:SWI48
10972             (match_operand:SWI48 0 "register_operand" "r")
10973             (const_int 1)
10974             (match_operand:SWI48 1 "nonmemory_operand" "rN"))
10975           (const_int 0)))]
10976   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10977   "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10978   [(set_attr "type" "alu1")
10979    (set_attr "prefix_0f" "1")
10980    (set_attr "mode" "<MODE>")])
10981 \f
10982 ;; Store-flag instructions.
10983
10984 ;; For all sCOND expanders, also expand the compare or test insn that
10985 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
10986
10987 (define_insn_and_split "*setcc_di_1"
10988   [(set (match_operand:DI 0 "register_operand" "=q")
10989         (match_operator:DI 1 "ix86_comparison_operator"
10990           [(reg FLAGS_REG) (const_int 0)]))]
10991   "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10992   "#"
10993   "&& reload_completed"
10994   [(set (match_dup 2) (match_dup 1))
10995    (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10996 {
10997   PUT_MODE (operands[1], QImode);
10998   operands[2] = gen_lowpart (QImode, operands[0]);
10999 })
11000
11001 (define_insn_and_split "*setcc_si_1_and"
11002   [(set (match_operand:SI 0 "register_operand" "=q")
11003         (match_operator:SI 1 "ix86_comparison_operator"
11004           [(reg FLAGS_REG) (const_int 0)]))
11005    (clobber (reg:CC FLAGS_REG))]
11006   "!TARGET_PARTIAL_REG_STALL
11007    && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
11008   "#"
11009   "&& reload_completed"
11010   [(set (match_dup 2) (match_dup 1))
11011    (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
11012               (clobber (reg:CC FLAGS_REG))])]
11013 {
11014   PUT_MODE (operands[1], QImode);
11015   operands[2] = gen_lowpart (QImode, operands[0]);
11016 })
11017
11018 (define_insn_and_split "*setcc_si_1_movzbl"
11019   [(set (match_operand:SI 0 "register_operand" "=q")
11020         (match_operator:SI 1 "ix86_comparison_operator"
11021           [(reg FLAGS_REG) (const_int 0)]))]
11022   "!TARGET_PARTIAL_REG_STALL
11023    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
11024   "#"
11025   "&& reload_completed"
11026   [(set (match_dup 2) (match_dup 1))
11027    (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
11028 {
11029   PUT_MODE (operands[1], QImode);
11030   operands[2] = gen_lowpart (QImode, operands[0]);
11031 })
11032
11033 (define_insn "*setcc_qi"
11034   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11035         (match_operator:QI 1 "ix86_comparison_operator"
11036           [(reg FLAGS_REG) (const_int 0)]))]
11037   ""
11038   "set%C1\t%0"
11039   [(set_attr "type" "setcc")
11040    (set_attr "mode" "QI")])
11041
11042 (define_insn "*setcc_qi_slp"
11043   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11044         (match_operator:QI 1 "ix86_comparison_operator"
11045           [(reg FLAGS_REG) (const_int 0)]))]
11046   ""
11047   "set%C1\t%0"
11048   [(set_attr "type" "setcc")
11049    (set_attr "mode" "QI")])
11050
11051 ;; In general it is not safe to assume too much about CCmode registers,
11052 ;; so simplify-rtx stops when it sees a second one.  Under certain
11053 ;; conditions this is safe on x86, so help combine not create
11054 ;;
11055 ;;      seta    %al
11056 ;;      testb   %al, %al
11057 ;;      sete    %al
11058
11059 (define_split
11060   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11061         (ne:QI (match_operator 1 "ix86_comparison_operator"
11062                  [(reg FLAGS_REG) (const_int 0)])
11063             (const_int 0)))]
11064   ""
11065   [(set (match_dup 0) (match_dup 1))]
11066 {
11067   PUT_MODE (operands[1], QImode);
11068 })
11069
11070 (define_split
11071   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
11072         (ne:QI (match_operator 1 "ix86_comparison_operator"
11073                  [(reg FLAGS_REG) (const_int 0)])
11074             (const_int 0)))]
11075   ""
11076   [(set (match_dup 0) (match_dup 1))]
11077 {
11078   PUT_MODE (operands[1], QImode);
11079 })
11080
11081 (define_split
11082   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11083         (eq:QI (match_operator 1 "ix86_comparison_operator"
11084                  [(reg FLAGS_REG) (const_int 0)])
11085             (const_int 0)))]
11086   ""
11087   [(set (match_dup 0) (match_dup 1))]
11088 {
11089   rtx new_op1 = copy_rtx (operands[1]);
11090   operands[1] = new_op1;
11091   PUT_MODE (new_op1, QImode);
11092   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
11093                                              GET_MODE (XEXP (new_op1, 0))));
11094
11095   /* Make sure that (a) the CCmode we have for the flags is strong
11096      enough for the reversed compare or (b) we have a valid FP compare.  */
11097   if (! ix86_comparison_operator (new_op1, VOIDmode))
11098     FAIL;
11099 })
11100
11101 (define_split
11102   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
11103         (eq:QI (match_operator 1 "ix86_comparison_operator"
11104                  [(reg FLAGS_REG) (const_int 0)])
11105             (const_int 0)))]
11106   ""
11107   [(set (match_dup 0) (match_dup 1))]
11108 {
11109   rtx new_op1 = copy_rtx (operands[1]);
11110   operands[1] = new_op1;
11111   PUT_MODE (new_op1, QImode);
11112   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
11113                                              GET_MODE (XEXP (new_op1, 0))));
11114
11115   /* Make sure that (a) the CCmode we have for the flags is strong
11116      enough for the reversed compare or (b) we have a valid FP compare.  */
11117   if (! ix86_comparison_operator (new_op1, VOIDmode))
11118     FAIL;
11119 })
11120
11121 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
11122 ;; subsequent logical operations are used to imitate conditional moves.
11123 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
11124 ;; it directly.
11125
11126 (define_insn "*avx_setcc<mode>"
11127   [(set (match_operand:MODEF 0 "register_operand" "=x")
11128         (match_operator:MODEF 1 "avx_comparison_float_operator"
11129           [(match_operand:MODEF 2 "register_operand" "x")
11130            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
11131   "TARGET_AVX"
11132   "vcmp%D1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
11133   [(set_attr "type" "ssecmp")
11134    (set_attr "prefix" "vex")
11135    (set_attr "length_immediate" "1")
11136    (set_attr "mode" "<MODE>")])
11137
11138 (define_insn "*sse_setcc<mode>"
11139   [(set (match_operand:MODEF 0 "register_operand" "=x")
11140         (match_operator:MODEF 1 "sse_comparison_operator"
11141           [(match_operand:MODEF 2 "register_operand" "0")
11142            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
11143   "SSE_FLOAT_MODE_P (<MODE>mode)"
11144   "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
11145   [(set_attr "type" "ssecmp")
11146    (set_attr "length_immediate" "1")
11147    (set_attr "mode" "<MODE>")])
11148 \f
11149 ;; Basic conditional jump instructions.
11150 ;; We ignore the overflow flag for signed branch instructions.
11151
11152 (define_insn "*jcc_1"
11153   [(set (pc)
11154         (if_then_else (match_operator 1 "ix86_comparison_operator"
11155                                       [(reg FLAGS_REG) (const_int 0)])
11156                       (label_ref (match_operand 0 "" ""))
11157                       (pc)))]
11158   ""
11159   "%+j%C1\t%l0"
11160   [(set_attr "type" "ibr")
11161    (set_attr "modrm" "0")
11162    (set (attr "length")
11163            (if_then_else (and (ge (minus (match_dup 0) (pc))
11164                                   (const_int -126))
11165                               (lt (minus (match_dup 0) (pc))
11166                                   (const_int 128)))
11167              (const_int 2)
11168              (const_int 6)))])
11169
11170 (define_insn "*jcc_2"
11171   [(set (pc)
11172         (if_then_else (match_operator 1 "ix86_comparison_operator"
11173                                       [(reg FLAGS_REG) (const_int 0)])
11174                       (pc)
11175                       (label_ref (match_operand 0 "" ""))))]
11176   ""
11177   "%+j%c1\t%l0"
11178   [(set_attr "type" "ibr")
11179    (set_attr "modrm" "0")
11180    (set (attr "length")
11181            (if_then_else (and (ge (minus (match_dup 0) (pc))
11182                                   (const_int -126))
11183                               (lt (minus (match_dup 0) (pc))
11184                                   (const_int 128)))
11185              (const_int 2)
11186              (const_int 6)))])
11187
11188 ;; In general it is not safe to assume too much about CCmode registers,
11189 ;; so simplify-rtx stops when it sees a second one.  Under certain
11190 ;; conditions this is safe on x86, so help combine not create
11191 ;;
11192 ;;      seta    %al
11193 ;;      testb   %al, %al
11194 ;;      je      Lfoo
11195
11196 (define_split
11197   [(set (pc)
11198         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
11199                                       [(reg FLAGS_REG) (const_int 0)])
11200                           (const_int 0))
11201                       (label_ref (match_operand 1 "" ""))
11202                       (pc)))]
11203   ""
11204   [(set (pc)
11205         (if_then_else (match_dup 0)
11206                       (label_ref (match_dup 1))
11207                       (pc)))]
11208 {
11209   PUT_MODE (operands[0], VOIDmode);
11210 })
11211
11212 (define_split
11213   [(set (pc)
11214         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
11215                                       [(reg FLAGS_REG) (const_int 0)])
11216                           (const_int 0))
11217                       (label_ref (match_operand 1 "" ""))
11218                       (pc)))]
11219   ""
11220   [(set (pc)
11221         (if_then_else (match_dup 0)
11222                       (label_ref (match_dup 1))
11223                       (pc)))]
11224 {
11225   rtx new_op0 = copy_rtx (operands[0]);
11226   operands[0] = new_op0;
11227   PUT_MODE (new_op0, VOIDmode);
11228   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
11229                                              GET_MODE (XEXP (new_op0, 0))));
11230
11231   /* Make sure that (a) the CCmode we have for the flags is strong
11232      enough for the reversed compare or (b) we have a valid FP compare.  */
11233   if (! ix86_comparison_operator (new_op0, VOIDmode))
11234     FAIL;
11235 })
11236
11237 ;; zero_extend in SImode is correct also for DImode, since this is what combine
11238 ;; pass generates from shift insn with QImode operand.  Actually, the mode
11239 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
11240 ;; appropriate modulo of the bit offset value.
11241
11242 (define_insn_and_split "*jcc_bt<mode>"
11243   [(set (pc)
11244         (if_then_else (match_operator 0 "bt_comparison_operator"
11245                         [(zero_extract:SWI48
11246                            (match_operand:SWI48 1 "register_operand" "r")
11247                            (const_int 1)
11248                            (zero_extend:SI
11249                              (match_operand:QI 2 "register_operand" "r")))
11250                          (const_int 0)])
11251                       (label_ref (match_operand 3 "" ""))
11252                       (pc)))
11253    (clobber (reg:CC FLAGS_REG))]
11254   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
11255   "#"
11256   "&& 1"
11257   [(set (reg:CCC FLAGS_REG)
11258         (compare:CCC
11259           (zero_extract:SWI48
11260             (match_dup 1)
11261             (const_int 1)
11262             (match_dup 2))
11263           (const_int 0)))
11264    (set (pc)
11265         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11266                       (label_ref (match_dup 3))
11267                       (pc)))]
11268 {
11269   operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
11270
11271   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11272 })
11273
11274 ;; Avoid useless masking of bit offset operand.  "and" in SImode is correct
11275 ;; also for DImode, this is what combine produces.
11276 define_insn_and_split "*jcc_bt<mode>_mask"
11277   [(set (pc)
11278         (if_then_else (match_operator 0 "bt_comparison_operator"
11279                         [(zero_extract:SWI48
11280                            (match_operand:SWI48 1 "register_operand" "r")
11281                            (const_int 1)
11282                            (and:SI
11283                              (match_operand:SI 2 "register_operand" "r")
11284                              (match_operand:SI 3 "const_int_operand" "n")))])
11285                       (label_ref (match_operand 4 "" ""))
11286                       (pc)))
11287    (clobber (reg:CC FLAGS_REG))]
11288   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11289    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11290       == GET_MODE_BITSIZE (<MODE>mode)-1"
11291   "#"
11292   "&& 1"
11293   [(set (reg:CCC FLAGS_REG)
11294         (compare:CCC
11295           (zero_extract:SWI48
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 4))
11303                       (pc)))]
11304 {
11305   operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
11306
11307   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11308 })
11309
11310 (define_insn_and_split "*jcc_btsi_1"
11311   [(set (pc)
11312         (if_then_else (match_operator 0 "bt_comparison_operator"
11313                         [(and:SI
11314                            (lshiftrt:SI
11315                              (match_operand:SI 1 "register_operand" "r")
11316                              (match_operand:QI 2 "register_operand" "r"))
11317                            (const_int 1))
11318                          (const_int 0)])
11319                       (label_ref (match_operand 3 "" ""))
11320                       (pc)))
11321    (clobber (reg:CC FLAGS_REG))]
11322   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
11323   "#"
11324   "&& 1"
11325   [(set (reg:CCC FLAGS_REG)
11326         (compare:CCC
11327           (zero_extract:SI
11328             (match_dup 1)
11329             (const_int 1)
11330             (match_dup 2))
11331           (const_int 0)))
11332    (set (pc)
11333         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11334                       (label_ref (match_dup 3))
11335                       (pc)))]
11336 {
11337   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
11338
11339   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11340 })
11341
11342 ;; avoid useless masking of bit offset operand
11343 (define_insn_and_split "*jcc_btsi_mask_1"
11344   [(set (pc)
11345         (if_then_else
11346           (match_operator 0 "bt_comparison_operator"
11347             [(and:SI
11348                (lshiftrt:SI
11349                  (match_operand:SI 1 "register_operand" "r")
11350                  (subreg:QI
11351                    (and:SI
11352                      (match_operand:SI 2 "register_operand" "r")
11353                      (match_operand:SI 3 "const_int_operand" "n")) 0))
11354                (const_int 1))
11355              (const_int 0)])
11356           (label_ref (match_operand 4 "" ""))
11357           (pc)))
11358    (clobber (reg:CC FLAGS_REG))]
11359   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11360    && (INTVAL (operands[3]) & 0x1f) == 0x1f"
11361   "#"
11362   "&& 1"
11363   [(set (reg:CCC FLAGS_REG)
11364         (compare:CCC
11365           (zero_extract:SI
11366             (match_dup 1)
11367             (const_int 1)
11368             (match_dup 2))
11369           (const_int 0)))
11370    (set (pc)
11371         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11372                       (label_ref (match_dup 4))
11373                       (pc)))]
11374   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
11375
11376 ;; Define combination compare-and-branch fp compare instructions to help
11377 ;; combine.
11378
11379 (define_insn "*fp_jcc_3_387"
11380   [(set (pc)
11381         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11382                         [(match_operand 1 "register_operand" "f")
11383                          (match_operand 2 "nonimmediate_operand" "fm")])
11384           (label_ref (match_operand 3 "" ""))
11385           (pc)))
11386    (clobber (reg:CCFP FPSR_REG))
11387    (clobber (reg:CCFP FLAGS_REG))
11388    (clobber (match_scratch:HI 4 "=a"))]
11389   "TARGET_80387
11390    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
11391    && GET_MODE (operands[1]) == GET_MODE (operands[2])
11392    && SELECT_CC_MODE (GET_CODE (operands[0]),
11393                       operands[1], operands[2]) == CCFPmode
11394    && !TARGET_CMOVE"
11395   "#")
11396
11397 (define_insn "*fp_jcc_4_387"
11398   [(set (pc)
11399         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11400                         [(match_operand 1 "register_operand" "f")
11401                          (match_operand 2 "nonimmediate_operand" "fm")])
11402           (pc)
11403           (label_ref (match_operand 3 "" ""))))
11404    (clobber (reg:CCFP FPSR_REG))
11405    (clobber (reg:CCFP FLAGS_REG))
11406    (clobber (match_scratch:HI 4 "=a"))]
11407   "TARGET_80387
11408    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
11409    && GET_MODE (operands[1]) == GET_MODE (operands[2])
11410    && SELECT_CC_MODE (GET_CODE (operands[0]),
11411                       operands[1], operands[2]) == CCFPmode
11412    && !TARGET_CMOVE"
11413   "#")
11414
11415 (define_insn "*fp_jcc_5_387"
11416   [(set (pc)
11417         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11418                         [(match_operand 1 "register_operand" "f")
11419                          (match_operand 2 "register_operand" "f")])
11420           (label_ref (match_operand 3 "" ""))
11421           (pc)))
11422    (clobber (reg:CCFP FPSR_REG))
11423    (clobber (reg:CCFP FLAGS_REG))
11424    (clobber (match_scratch:HI 4 "=a"))]
11425   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11426    && GET_MODE (operands[1]) == GET_MODE (operands[2])
11427    && !TARGET_CMOVE"
11428   "#")
11429
11430 (define_insn "*fp_jcc_6_387"
11431   [(set (pc)
11432         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11433                         [(match_operand 1 "register_operand" "f")
11434                          (match_operand 2 "register_operand" "f")])
11435           (pc)
11436           (label_ref (match_operand 3 "" ""))))
11437    (clobber (reg:CCFP FPSR_REG))
11438    (clobber (reg:CCFP FLAGS_REG))
11439    (clobber (match_scratch:HI 4 "=a"))]
11440   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11441    && GET_MODE (operands[1]) == GET_MODE (operands[2])
11442    && !TARGET_CMOVE"
11443   "#")
11444
11445 (define_insn "*fp_jcc_7_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 "const0_operand" "")])
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    && SELECT_CC_MODE (GET_CODE (operands[0]),
11458                       operands[1], operands[2]) == CCFPmode
11459    && !TARGET_CMOVE"
11460   "#")
11461
11462 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
11463 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11464 ;; with a precedence over other operators and is always put in the first
11465 ;; place. Swap condition and operands to match ficom instruction.
11466
11467 (define_insn "*fp_jcc_8<mode>_387"
11468   [(set (pc)
11469         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11470                         [(match_operator 1 "float_operator"
11471                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
11472                            (match_operand 3 "register_operand" "f,f")])
11473           (label_ref (match_operand 4 "" ""))
11474           (pc)))
11475    (clobber (reg:CCFP FPSR_REG))
11476    (clobber (reg:CCFP FLAGS_REG))
11477    (clobber (match_scratch:HI 5 "=a,a"))]
11478   "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
11479    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
11480    && GET_MODE (operands[1]) == GET_MODE (operands[3])
11481    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
11482    && !TARGET_CMOVE"
11483   "#")
11484
11485 (define_split
11486   [(set (pc)
11487         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11488                         [(match_operand 1 "register_operand" "")
11489                          (match_operand 2 "nonimmediate_operand" "")])
11490           (match_operand 3 "" "")
11491           (match_operand 4 "" "")))
11492    (clobber (reg:CCFP FPSR_REG))
11493    (clobber (reg:CCFP FLAGS_REG))]
11494   "reload_completed"
11495   [(const_int 0)]
11496 {
11497   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11498                         operands[3], operands[4], NULL_RTX, NULL_RTX);
11499   DONE;
11500 })
11501
11502 (define_split
11503   [(set (pc)
11504         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11505                         [(match_operand 1 "register_operand" "")
11506                          (match_operand 2 "general_operand" "")])
11507           (match_operand 3 "" "")
11508           (match_operand 4 "" "")))
11509    (clobber (reg:CCFP FPSR_REG))
11510    (clobber (reg:CCFP FLAGS_REG))
11511    (clobber (match_scratch:HI 5 "=a"))]
11512   "reload_completed"
11513   [(const_int 0)]
11514 {
11515   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11516                         operands[3], operands[4], operands[5], NULL_RTX);
11517   DONE;
11518 })
11519
11520 (define_split
11521   [(set (pc)
11522         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11523                         [(match_operator 1 "float_operator"
11524                            [(match_operand:X87MODEI12 2 "memory_operand" "")])
11525                            (match_operand 3 "register_operand" "")])
11526           (match_operand 4 "" "")
11527           (match_operand 5 "" "")))
11528    (clobber (reg:CCFP FPSR_REG))
11529    (clobber (reg:CCFP FLAGS_REG))
11530    (clobber (match_scratch:HI 6 "=a"))]
11531   "reload_completed"
11532   [(const_int 0)]
11533 {
11534   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
11535   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11536                         operands[3], operands[7],
11537                         operands[4], operands[5], operands[6], NULL_RTX);
11538   DONE;
11539 })
11540
11541 ;; %%% Kill this when reload knows how to do it.
11542 (define_split
11543   [(set (pc)
11544         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11545                         [(match_operator 1 "float_operator"
11546                            [(match_operand:X87MODEI12 2 "register_operand" "")])
11547                            (match_operand 3 "register_operand" "")])
11548           (match_operand 4 "" "")
11549           (match_operand 5 "" "")))
11550    (clobber (reg:CCFP FPSR_REG))
11551    (clobber (reg:CCFP FLAGS_REG))
11552    (clobber (match_scratch:HI 6 "=a"))]
11553   "reload_completed"
11554   [(const_int 0)]
11555 {
11556   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11557   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
11558   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11559                         operands[3], operands[7],
11560                         operands[4], operands[5], operands[6], operands[2]);
11561   DONE;
11562 })
11563 \f
11564 ;; Unconditional and other jump instructions
11565
11566 (define_insn "jump"
11567   [(set (pc)
11568         (label_ref (match_operand 0 "" "")))]
11569   ""
11570   "jmp\t%l0"
11571   [(set_attr "type" "ibr")
11572    (set (attr "length")
11573            (if_then_else (and (ge (minus (match_dup 0) (pc))
11574                                   (const_int -126))
11575                               (lt (minus (match_dup 0) (pc))
11576                                   (const_int 128)))
11577              (const_int 2)
11578              (const_int 5)))
11579    (set_attr "modrm" "0")])
11580
11581 (define_expand "indirect_jump"
11582   [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
11583   ""
11584   "")
11585
11586 (define_insn "*indirect_jump"
11587   [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
11588   ""
11589   "jmp\t%A0"
11590   [(set_attr "type" "ibr")
11591    (set_attr "length_immediate" "0")])
11592
11593 (define_expand "tablejump"
11594   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
11595               (use (label_ref (match_operand 1 "" "")))])]
11596   ""
11597 {
11598   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11599      relative.  Convert the relative address to an absolute address.  */
11600   if (flag_pic)
11601     {
11602       rtx op0, op1;
11603       enum rtx_code code;
11604
11605       /* We can't use @GOTOFF for text labels on VxWorks;
11606          see gotoff_operand.  */
11607       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11608         {
11609           code = PLUS;
11610           op0 = operands[0];
11611           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11612         }
11613       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11614         {
11615           code = PLUS;
11616           op0 = operands[0];
11617           op1 = pic_offset_table_rtx;
11618         }
11619       else
11620         {
11621           code = MINUS;
11622           op0 = pic_offset_table_rtx;
11623           op1 = operands[0];
11624         }
11625
11626       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11627                                          OPTAB_DIRECT);
11628     }
11629 })
11630
11631 (define_insn "*tablejump_1"
11632   [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
11633    (use (label_ref (match_operand 1 "" "")))]
11634   ""
11635   "jmp\t%A0"
11636   [(set_attr "type" "ibr")
11637    (set_attr "length_immediate" "0")])
11638 \f
11639 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11640
11641 (define_peephole2
11642   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11643    (set (match_operand:QI 1 "register_operand" "")
11644         (match_operator:QI 2 "ix86_comparison_operator"
11645           [(reg FLAGS_REG) (const_int 0)]))
11646    (set (match_operand 3 "q_regs_operand" "")
11647         (zero_extend (match_dup 1)))]
11648   "(peep2_reg_dead_p (3, operands[1])
11649     || operands_match_p (operands[1], operands[3]))
11650    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11651   [(set (match_dup 4) (match_dup 0))
11652    (set (strict_low_part (match_dup 5))
11653         (match_dup 2))]
11654 {
11655   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11656   operands[5] = gen_lowpart (QImode, operands[3]);
11657   ix86_expand_clear (operands[3]);
11658 })
11659
11660 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
11661
11662 (define_peephole2
11663   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11664    (set (match_operand:QI 1 "register_operand" "")
11665         (match_operator:QI 2 "ix86_comparison_operator"
11666           [(reg FLAGS_REG) (const_int 0)]))
11667    (parallel [(set (match_operand 3 "q_regs_operand" "")
11668                    (zero_extend (match_dup 1)))
11669               (clobber (reg:CC FLAGS_REG))])]
11670   "(peep2_reg_dead_p (3, operands[1])
11671     || operands_match_p (operands[1], operands[3]))
11672    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11673   [(set (match_dup 4) (match_dup 0))
11674    (set (strict_low_part (match_dup 5))
11675         (match_dup 2))]
11676 {
11677   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11678   operands[5] = gen_lowpart (QImode, operands[3]);
11679   ix86_expand_clear (operands[3]);
11680 })
11681 \f
11682 ;; Call instructions.
11683
11684 ;; The predicates normally associated with named expanders are not properly
11685 ;; checked for calls.  This is a bug in the generic code, but it isn't that
11686 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
11687
11688 ;; P6 processors will jump to the address after the decrement when %esp
11689 ;; is used as a call operand, so they will execute return address as a code.
11690 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11691  
11692 ;; Call subroutine returning no value.
11693
11694 (define_expand "call_pop"
11695   [(parallel [(call (match_operand:QI 0 "" "")
11696                     (match_operand:SI 1 "" ""))
11697               (set (reg:SI SP_REG)
11698                    (plus:SI (reg:SI SP_REG)
11699                             (match_operand:SI 3 "" "")))])]
11700   "!TARGET_64BIT"
11701 {
11702   ix86_expand_call (NULL, operands[0], operands[1],
11703                     operands[2], operands[3], 0);
11704   DONE;
11705 })
11706
11707 (define_insn "*call_pop_0"
11708   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
11709          (match_operand:SI 1 "" ""))
11710    (set (reg:SI SP_REG)
11711         (plus:SI (reg:SI SP_REG)
11712                  (match_operand:SI 2 "immediate_operand" "")))]
11713   "!TARGET_64BIT"
11714 {
11715   if (SIBLING_CALL_P (insn))
11716     return "jmp\t%P0";
11717   else
11718     return "call\t%P0";
11719 }
11720   [(set_attr "type" "call")])
11721
11722 (define_insn "*call_pop_1"
11723   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11724          (match_operand:SI 1 "" ""))
11725    (set (reg:SI SP_REG)
11726         (plus:SI (reg:SI SP_REG)
11727                  (match_operand:SI 2 "immediate_operand" "i")))]
11728   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11729 {
11730   if (constant_call_address_operand (operands[0], Pmode))
11731     return "call\t%P0";
11732   return "call\t%A0";
11733 }
11734   [(set_attr "type" "call")])
11735
11736 (define_insn "*sibcall_pop_1"
11737   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11738          (match_operand:SI 1 "" ""))
11739    (set (reg:SI SP_REG)
11740         (plus:SI (reg:SI SP_REG)
11741                  (match_operand:SI 2 "immediate_operand" "i,i")))]
11742   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11743   "@
11744    jmp\t%P0
11745    jmp\t%A0"
11746   [(set_attr "type" "call")])
11747
11748 (define_expand "call"
11749   [(call (match_operand:QI 0 "" "")
11750          (match_operand 1 "" ""))
11751    (use (match_operand 2 "" ""))]
11752   ""
11753 {
11754   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
11755   DONE;
11756 })
11757
11758 (define_expand "sibcall"
11759   [(call (match_operand:QI 0 "" "")
11760          (match_operand 1 "" ""))
11761    (use (match_operand 2 "" ""))]
11762   ""
11763 {
11764   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
11765   DONE;
11766 })
11767
11768 (define_insn "*call_0"
11769   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
11770          (match_operand 1 "" ""))]
11771   ""
11772 {
11773   if (SIBLING_CALL_P (insn))
11774     return "jmp\t%P0";
11775   else
11776     return "call\t%P0";
11777 }
11778   [(set_attr "type" "call")])
11779
11780 (define_insn "*call_1"
11781   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11782          (match_operand 1 "" ""))]
11783   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11784 {
11785   if (constant_call_address_operand (operands[0], Pmode))
11786     return "call\t%P0";
11787   return "call\t%A0";
11788 }
11789   [(set_attr "type" "call")])
11790
11791 (define_insn "*sibcall_1"
11792   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11793          (match_operand 1 "" ""))]
11794   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11795   "@
11796    jmp\t%P0
11797    jmp\t%A0"
11798   [(set_attr "type" "call")])
11799
11800 (define_insn "*call_1_rex64"
11801   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11802          (match_operand 1 "" ""))]
11803   "TARGET_64BIT && !SIBLING_CALL_P (insn)
11804    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
11805 {
11806   if (constant_call_address_operand (operands[0], Pmode))
11807     return "call\t%P0";
11808   return "call\t%A0";
11809 }
11810   [(set_attr "type" "call")])
11811
11812 (define_insn "*call_1_rex64_ms_sysv"
11813   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11814          (match_operand 1 "" ""))
11815    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11816    (clobber (reg:TI XMM6_REG))
11817    (clobber (reg:TI XMM7_REG))
11818    (clobber (reg:TI XMM8_REG))
11819    (clobber (reg:TI XMM9_REG))
11820    (clobber (reg:TI XMM10_REG))
11821    (clobber (reg:TI XMM11_REG))
11822    (clobber (reg:TI XMM12_REG))
11823    (clobber (reg:TI XMM13_REG))
11824    (clobber (reg:TI XMM14_REG))
11825    (clobber (reg:TI XMM15_REG))
11826    (clobber (reg:DI SI_REG))
11827    (clobber (reg:DI DI_REG))]
11828   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11829 {
11830   if (constant_call_address_operand (operands[0], Pmode))
11831     return "call\t%P0";
11832   return "call\t%A0";
11833 }
11834   [(set_attr "type" "call")])
11835
11836 (define_insn "*call_1_rex64_large"
11837   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
11838          (match_operand 1 "" ""))]
11839   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11840   "call\t%A0"
11841   [(set_attr "type" "call")])
11842
11843 (define_insn "*sibcall_1_rex64"
11844   [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
11845          (match_operand 1 "" ""))]
11846   "TARGET_64BIT && SIBLING_CALL_P (insn)"
11847   "@
11848    jmp\t%P0
11849    jmp\t%A0"
11850   [(set_attr "type" "call")])
11851
11852 ;; Call subroutine, returning value in operand 0
11853 (define_expand "call_value_pop"
11854   [(parallel [(set (match_operand 0 "" "")
11855                    (call (match_operand:QI 1 "" "")
11856                          (match_operand:SI 2 "" "")))
11857               (set (reg:SI SP_REG)
11858                    (plus:SI (reg:SI SP_REG)
11859                             (match_operand:SI 4 "" "")))])]
11860   "!TARGET_64BIT"
11861 {
11862   ix86_expand_call (operands[0], operands[1], operands[2],
11863                     operands[3], operands[4], 0);
11864   DONE;
11865 })
11866
11867 (define_expand "call_value"
11868   [(set (match_operand 0 "" "")
11869         (call (match_operand:QI 1 "" "")
11870               (match_operand:SI 2 "" "")))
11871    (use (match_operand:SI 3 "" ""))]
11872   ;; Operand 3 is not used on the i386.
11873   ""
11874 {
11875   ix86_expand_call (operands[0], operands[1], operands[2],
11876                     operands[3], NULL, 0);
11877   DONE;
11878 })
11879
11880 (define_expand "sibcall_value"
11881   [(set (match_operand 0 "" "")
11882         (call (match_operand:QI 1 "" "")
11883               (match_operand:SI 2 "" "")))
11884    (use (match_operand:SI 3 "" ""))]
11885   ;; Operand 3 is not used on the i386.
11886   ""
11887 {
11888   ix86_expand_call (operands[0], operands[1], operands[2],
11889                     operands[3], NULL, 1);
11890   DONE;
11891 })
11892
11893 ;; Call subroutine returning any type.
11894
11895 (define_expand "untyped_call"
11896   [(parallel [(call (match_operand 0 "" "")
11897                     (const_int 0))
11898               (match_operand 1 "" "")
11899               (match_operand 2 "" "")])]
11900   ""
11901 {
11902   int i;
11903
11904   /* In order to give reg-stack an easier job in validating two
11905      coprocessor registers as containing a possible return value,
11906      simply pretend the untyped call returns a complex long double
11907      value. 
11908
11909      We can't use SSE_REGPARM_MAX here since callee is unprototyped
11910      and should have the default ABI.  */
11911
11912   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11913                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11914                     operands[0], const0_rtx,
11915                     GEN_INT ((TARGET_64BIT
11916                               ? (ix86_abi == SYSV_ABI
11917                                  ? X86_64_SSE_REGPARM_MAX
11918                                  : X86_64_MS_SSE_REGPARM_MAX)
11919                               : X86_32_SSE_REGPARM_MAX)
11920                              - 1),
11921                     NULL, 0);
11922
11923   for (i = 0; i < XVECLEN (operands[2], 0); i++)
11924     {
11925       rtx set = XVECEXP (operands[2], 0, i);
11926       emit_move_insn (SET_DEST (set), SET_SRC (set));
11927     }
11928
11929   /* The optimizer does not know that the call sets the function value
11930      registers we stored in the result block.  We avoid problems by
11931      claiming that all hard registers are used and clobbered at this
11932      point.  */
11933   emit_insn (gen_blockage ());
11934
11935   DONE;
11936 })
11937 \f
11938 ;; Prologue and epilogue instructions
11939
11940 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11941 ;; all of memory.  This blocks insns from being moved across this point.
11942
11943 (define_insn "blockage"
11944   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11945   ""
11946   ""
11947   [(set_attr "length" "0")])
11948
11949 ;; Do not schedule instructions accessing memory across this point.
11950
11951 (define_expand "memory_blockage"
11952   [(set (match_dup 0)
11953         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11954   ""
11955 {
11956   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11957   MEM_VOLATILE_P (operands[0]) = 1;
11958 })
11959
11960 (define_insn "*memory_blockage"
11961   [(set (match_operand:BLK 0 "" "")
11962         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11963   ""
11964   ""
11965   [(set_attr "length" "0")])
11966
11967 ;; As USE insns aren't meaningful after reload, this is used instead
11968 ;; to prevent deleting instructions setting registers for PIC code
11969 (define_insn "prologue_use"
11970   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11971   ""
11972   ""
11973   [(set_attr "length" "0")])
11974
11975 ;; Insn emitted into the body of a function to return from a function.
11976 ;; This is only done if the function's epilogue is known to be simple.
11977 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11978
11979 (define_expand "return"
11980   [(return)]
11981   "ix86_can_use_return_insn_p ()"
11982 {
11983   if (crtl->args.pops_args)
11984     {
11985       rtx popc = GEN_INT (crtl->args.pops_args);
11986       emit_jump_insn (gen_return_pop_internal (popc));
11987       DONE;
11988     }
11989 })
11990
11991 (define_insn "return_internal"
11992   [(return)]
11993   "reload_completed"
11994   "ret"
11995   [(set_attr "length" "1")
11996    (set_attr "atom_unit" "jeu")
11997    (set_attr "length_immediate" "0")
11998    (set_attr "modrm" "0")])
11999
12000 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
12001 ;; instruction Athlon and K8 have.
12002
12003 (define_insn "return_internal_long"
12004   [(return)
12005    (unspec [(const_int 0)] UNSPEC_REP)]
12006   "reload_completed"
12007   "rep\;ret"
12008   [(set_attr "length" "2")
12009    (set_attr "atom_unit" "jeu")
12010    (set_attr "length_immediate" "0")
12011    (set_attr "prefix_rep" "1")
12012    (set_attr "modrm" "0")])
12013
12014 (define_insn "return_pop_internal"
12015   [(return)
12016    (use (match_operand:SI 0 "const_int_operand" ""))]
12017   "reload_completed"
12018   "ret\t%0"
12019   [(set_attr "length" "3")
12020    (set_attr "atom_unit" "jeu")
12021    (set_attr "length_immediate" "2")
12022    (set_attr "modrm" "0")])
12023
12024 (define_insn "return_indirect_internal"
12025   [(return)
12026    (use (match_operand:SI 0 "register_operand" "r"))]
12027   "reload_completed"
12028   "jmp\t%A0"
12029   [(set_attr "type" "ibr")
12030    (set_attr "length_immediate" "0")])
12031
12032 (define_insn "nop"
12033   [(const_int 0)]
12034   ""
12035   "nop"
12036   [(set_attr "length" "1")
12037    (set_attr "length_immediate" "0")
12038    (set_attr "modrm" "0")])
12039
12040 (define_insn "vswapmov"
12041   [(set (match_operand:SI 0 "register_operand" "=r")
12042         (match_operand:SI 1 "register_operand" "r"))
12043    (unspec_volatile [(const_int 0)] UNSPECV_VSWAPMOV)]
12044   ""
12045   "movl.s\t{%1, %0|%0, %1}"
12046   [(set_attr "length" "2")
12047    (set_attr "length_immediate" "0")
12048    (set_attr "modrm" "0")])
12049
12050 ;; Pad to 16-byte boundary, max skip in op0.  Used to avoid
12051 ;; branch prediction penalty for the third jump in a 16-byte
12052 ;; block on K8.
12053
12054 (define_insn "pad"
12055   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
12056   ""
12057 {
12058 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
12059   ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
12060 #else
12061   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
12062      The align insn is used to avoid 3 jump instructions in the row to improve
12063      branch prediction and the benefits hardly outweigh the cost of extra 8
12064      nops on the average inserted by full alignment pseudo operation.  */
12065 #endif
12066   return "";
12067 }
12068   [(set_attr "length" "16")])
12069
12070 (define_expand "prologue"
12071   [(const_int 0)]
12072   ""
12073   "ix86_expand_prologue (); DONE;")
12074
12075 (define_insn "set_got"
12076   [(set (match_operand:SI 0 "register_operand" "=r")
12077         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
12078    (clobber (reg:CC FLAGS_REG))]
12079   "!TARGET_64BIT"
12080   { return output_set_got (operands[0], NULL_RTX); }
12081   [(set_attr "type" "multi")
12082    (set_attr "length" "12")])
12083
12084 (define_insn "set_got_labelled"
12085   [(set (match_operand:SI 0 "register_operand" "=r")
12086         (unspec:SI [(label_ref (match_operand 1 "" ""))]
12087          UNSPEC_SET_GOT))
12088    (clobber (reg:CC FLAGS_REG))]
12089   "!TARGET_64BIT"
12090   { return output_set_got (operands[0], operands[1]); }
12091   [(set_attr "type" "multi")
12092    (set_attr "length" "12")])
12093
12094 (define_insn "set_got_rex64"
12095   [(set (match_operand:DI 0 "register_operand" "=r")
12096         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
12097   "TARGET_64BIT"
12098   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
12099   [(set_attr "type" "lea")
12100    (set_attr "length_address" "4")
12101    (set_attr "mode" "DI")])
12102
12103 (define_insn "set_rip_rex64"
12104   [(set (match_operand:DI 0 "register_operand" "=r")
12105         (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
12106   "TARGET_64BIT"
12107   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
12108   [(set_attr "type" "lea")
12109    (set_attr "length_address" "4")
12110    (set_attr "mode" "DI")])
12111
12112 (define_insn "set_got_offset_rex64"
12113   [(set (match_operand:DI 0 "register_operand" "=r")
12114         (unspec:DI
12115           [(label_ref (match_operand 1 "" ""))]
12116           UNSPEC_SET_GOT_OFFSET))]
12117   "TARGET_64BIT"
12118   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
12119   [(set_attr "type" "imov")
12120    (set_attr "length_immediate" "0")
12121    (set_attr "length_address" "8")
12122    (set_attr "mode" "DI")])
12123
12124 (define_expand "epilogue"
12125   [(const_int 0)]
12126   ""
12127   "ix86_expand_epilogue (1); DONE;")
12128
12129 (define_expand "sibcall_epilogue"
12130   [(const_int 0)]
12131   ""
12132   "ix86_expand_epilogue (0); DONE;")
12133
12134 (define_expand "eh_return"
12135   [(use (match_operand 0 "register_operand" ""))]
12136   ""
12137 {
12138   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
12139
12140   /* Tricky bit: we write the address of the handler to which we will
12141      be returning into someone else's stack frame, one word below the
12142      stack address we wish to restore.  */
12143   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
12144   tmp = plus_constant (tmp, -UNITS_PER_WORD);
12145   tmp = gen_rtx_MEM (Pmode, tmp);
12146   emit_move_insn (tmp, ra);
12147
12148   emit_jump_insn (gen_eh_return_internal ());
12149   emit_barrier ();
12150   DONE;
12151 })
12152
12153 (define_insn_and_split "eh_return_internal"
12154   [(eh_return)]
12155   ""
12156   "#"
12157   "epilogue_completed"
12158   [(const_int 0)]
12159   "ix86_expand_epilogue (2); DONE;")
12160
12161 (define_insn "leave"
12162   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
12163    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
12164    (clobber (mem:BLK (scratch)))]
12165   "!TARGET_64BIT"
12166   "leave"
12167   [(set_attr "type" "leave")])
12168
12169 (define_insn "leave_rex64"
12170   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
12171    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
12172    (clobber (mem:BLK (scratch)))]
12173   "TARGET_64BIT"
12174   "leave"
12175   [(set_attr "type" "leave")])
12176 \f
12177 (define_expand "ffssi2"
12178   [(parallel
12179      [(set (match_operand:SI 0 "register_operand" "")
12180            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
12181       (clobber (match_scratch:SI 2 ""))
12182       (clobber (reg:CC FLAGS_REG))])]
12183   ""
12184 {
12185   if (TARGET_CMOVE)
12186     {
12187       emit_insn (gen_ffs_cmove (operands[0], operands[1]));
12188       DONE;
12189     }
12190 })
12191
12192 (define_expand "ffs_cmove"
12193   [(set (match_dup 2) (const_int -1))
12194    (parallel [(set (reg:CCZ FLAGS_REG)
12195                    (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "")
12196                                 (const_int 0)))
12197               (set (match_operand:SI 0 "register_operand" "")
12198                    (ctz:SI (match_dup 1)))])
12199    (set (match_dup 0) (if_then_else:SI
12200                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
12201                         (match_dup 2)
12202                         (match_dup 0)))
12203    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12204               (clobber (reg:CC FLAGS_REG))])]
12205   "TARGET_CMOVE"
12206   "operands[2] = gen_reg_rtx (SImode);")
12207
12208 (define_insn_and_split "*ffs_no_cmove"
12209   [(set (match_operand:SI 0 "register_operand" "=r")
12210         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12211    (clobber (match_scratch:SI 2 "=&q"))
12212    (clobber (reg:CC FLAGS_REG))]
12213   "!TARGET_CMOVE"
12214   "#"
12215   "&& reload_completed"
12216   [(parallel [(set (reg:CCZ FLAGS_REG)
12217                    (compare:CCZ (match_dup 1) (const_int 0)))
12218               (set (match_dup 0) (ctz:SI (match_dup 1)))])
12219    (set (strict_low_part (match_dup 3))
12220         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
12221    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12222               (clobber (reg:CC FLAGS_REG))])
12223    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12224               (clobber (reg:CC FLAGS_REG))])
12225    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12226               (clobber (reg:CC FLAGS_REG))])]
12227 {
12228   operands[3] = gen_lowpart (QImode, operands[2]);
12229   ix86_expand_clear (operands[2]);
12230 })
12231
12232 (define_insn "*ffssi_1"
12233   [(set (reg:CCZ FLAGS_REG)
12234         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
12235                      (const_int 0)))
12236    (set (match_operand:SI 0 "register_operand" "=r")
12237         (ctz:SI (match_dup 1)))]
12238   ""
12239   "bsf{l}\t{%1, %0|%0, %1}"
12240   [(set_attr "type" "alu1")
12241    (set_attr "prefix_0f" "1")
12242    (set_attr "mode" "SI")])
12243
12244 (define_expand "ffsdi2"
12245   [(set (match_dup 2) (const_int -1))
12246    (parallel [(set (reg:CCZ FLAGS_REG)
12247                    (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "")
12248                                 (const_int 0)))
12249               (set (match_operand:DI 0 "register_operand" "")
12250                    (ctz:DI (match_dup 1)))])
12251    (set (match_dup 0) (if_then_else:DI
12252                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
12253                         (match_dup 2)
12254                         (match_dup 0)))
12255    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
12256               (clobber (reg:CC FLAGS_REG))])]
12257   "TARGET_64BIT"
12258   "operands[2] = gen_reg_rtx (DImode);")
12259
12260 (define_insn "*ffsdi_1"
12261   [(set (reg:CCZ FLAGS_REG)
12262         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
12263                      (const_int 0)))
12264    (set (match_operand:DI 0 "register_operand" "=r")
12265         (ctz:DI (match_dup 1)))]
12266   "TARGET_64BIT"
12267   "bsf{q}\t{%1, %0|%0, %1}"
12268   [(set_attr "type" "alu1")
12269    (set_attr "prefix_0f" "1")
12270    (set_attr "mode" "DI")])
12271
12272 (define_insn "ctzsi2"
12273   [(set (match_operand:SI 0 "register_operand" "=r")
12274         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12275    (clobber (reg:CC FLAGS_REG))]
12276   ""
12277   "bsf{l}\t{%1, %0|%0, %1}"
12278   [(set_attr "type" "alu1")
12279    (set_attr "prefix_0f" "1")
12280    (set_attr "mode" "SI")])
12281
12282 (define_insn "ctzdi2"
12283   [(set (match_operand:DI 0 "register_operand" "=r")
12284         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
12285    (clobber (reg:CC FLAGS_REG))]
12286   "TARGET_64BIT"
12287   "bsf{q}\t{%1, %0|%0, %1}"
12288   [(set_attr "type" "alu1")
12289    (set_attr "prefix_0f" "1")
12290    (set_attr "mode" "DI")])
12291
12292 (define_expand "clzsi2"
12293   [(parallel
12294      [(set (match_operand:SI 0 "register_operand" "")
12295            (minus:SI (const_int 31)
12296                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
12297       (clobber (reg:CC FLAGS_REG))])
12298    (parallel
12299      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
12300       (clobber (reg:CC FLAGS_REG))])]
12301   ""
12302 {
12303   if (TARGET_ABM)
12304     {
12305       emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
12306       DONE;
12307     }
12308 })
12309
12310 (define_insn "clzsi2_abm"
12311   [(set (match_operand:SI 0 "register_operand" "=r")
12312         (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12313    (clobber (reg:CC FLAGS_REG))]
12314   "TARGET_ABM"
12315   "lzcnt{l}\t{%1, %0|%0, %1}"
12316   [(set_attr "prefix_rep" "1")
12317    (set_attr "type" "bitmanip")
12318    (set_attr "mode" "SI")])
12319
12320 (define_insn "bsr"
12321   [(set (match_operand:SI 0 "register_operand" "=r")
12322         (minus:SI (const_int 31)
12323                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12324    (clobber (reg:CC FLAGS_REG))]
12325   ""
12326   "bsr{l}\t{%1, %0|%0, %1}"
12327   [(set_attr "type" "alu1")
12328    (set_attr "prefix_0f" "1")
12329    (set_attr "mode" "SI")])
12330
12331 (define_insn "popcount<mode>2"
12332   [(set (match_operand:SWI248 0 "register_operand" "=r")
12333         (popcount:SWI248
12334           (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12335    (clobber (reg:CC FLAGS_REG))]
12336   "TARGET_POPCNT"
12337 {
12338 #if TARGET_MACHO
12339   return "popcnt\t{%1, %0|%0, %1}";
12340 #else
12341   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12342 #endif
12343 }
12344   [(set_attr "prefix_rep" "1")
12345    (set_attr "type" "bitmanip")
12346    (set_attr "mode" "<MODE>")])
12347
12348 (define_insn "*popcount<mode>2_cmp"
12349   [(set (reg FLAGS_REG)
12350         (compare
12351           (popcount:SWI248
12352             (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12353           (const_int 0)))
12354    (set (match_operand:SWI248 0 "register_operand" "=r")
12355         (popcount:SWI248 (match_dup 1)))]
12356   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12357 {
12358 #if TARGET_MACHO
12359   return "popcnt\t{%1, %0|%0, %1}";
12360 #else
12361   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12362 #endif
12363 }
12364   [(set_attr "prefix_rep" "1")
12365    (set_attr "type" "bitmanip")
12366    (set_attr "mode" "<MODE>")])
12367
12368 (define_insn "*popcountsi2_cmp_zext"
12369   [(set (reg FLAGS_REG)
12370         (compare
12371           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12372           (const_int 0)))
12373    (set (match_operand:DI 0 "register_operand" "=r")
12374         (zero_extend:DI(popcount:SI (match_dup 1))))]
12375   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12376 {
12377 #if TARGET_MACHO
12378   return "popcnt\t{%1, %0|%0, %1}";
12379 #else
12380   return "popcnt{l}\t{%1, %0|%0, %1}";
12381 #endif
12382 }
12383   [(set_attr "prefix_rep" "1")
12384    (set_attr "type" "bitmanip")
12385    (set_attr "mode" "SI")])
12386
12387 (define_expand "bswapsi2"
12388   [(set (match_operand:SI 0 "register_operand" "")
12389         (bswap:SI (match_operand:SI 1 "register_operand" "")))]
12390   ""
12391 {
12392   if (!(TARGET_BSWAP || TARGET_MOVBE))
12393     {
12394       rtx x = operands[0];
12395
12396       emit_move_insn (x, operands[1]);
12397       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12398       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12399       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12400       DONE;
12401     }
12402 })
12403
12404 (define_insn "*bswapsi_movbe"
12405   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,m")
12406         (bswap:SI (match_operand:SI 1 "nonimmediate_operand" "0,m,r")))]
12407   "TARGET_MOVBE && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12408   "@
12409     bswap\t%0
12410     movbe\t{%1, %0|%0, %1}
12411     movbe\t{%1, %0|%0, %1}"
12412   [(set_attr "type" "*,imov,imov")
12413    (set_attr "modrm" "*,1,1")
12414    (set_attr "prefix_0f" "1")
12415    (set_attr "prefix_extra" "*,1,1")
12416    (set_attr "length" "2,*,*")
12417    (set_attr "mode" "SI")])
12418
12419 (define_insn "*bswapsi_1"
12420   [(set (match_operand:SI 0 "register_operand" "=r")
12421         (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
12422   "TARGET_BSWAP"
12423   "bswap\t%0"
12424   [(set_attr "prefix_0f" "1")
12425    (set_attr "length" "2")])
12426
12427 (define_insn "*bswaphi_lowpart_1"
12428   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12429         (bswap:HI (match_dup 0)))
12430    (clobber (reg:CC FLAGS_REG))]
12431   "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12432   "@
12433     xchg{b}\t{%h0, %b0|%b0, %h0}
12434     rol{w}\t{$8, %0|%0, 8}"
12435   [(set_attr "length" "2,4")
12436    (set_attr "mode" "QI,HI")])
12437
12438 (define_insn "bswaphi_lowpart"
12439   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12440         (bswap:HI (match_dup 0)))
12441    (clobber (reg:CC FLAGS_REG))]
12442   ""
12443   "rol{w}\t{$8, %0|%0, 8}"
12444   [(set_attr "length" "4")
12445    (set_attr "mode" "HI")])
12446
12447 (define_expand "bswapdi2"
12448   [(set (match_operand:DI 0 "register_operand" "")
12449         (bswap:DI (match_operand:DI 1 "register_operand" "")))]
12450   "TARGET_64BIT"
12451   "")
12452
12453 (define_insn "*bswapdi_movbe"
12454   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m")
12455         (bswap:DI (match_operand:DI 1 "nonimmediate_operand" "0,m,r")))]
12456   "TARGET_64BIT && TARGET_MOVBE
12457    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12458   "@
12459     bswap\t%0
12460     movbe\t{%1, %0|%0, %1}
12461     movbe\t{%1, %0|%0, %1}"
12462   [(set_attr "type" "*,imov,imov")
12463    (set_attr "modrm" "*,1,1")
12464    (set_attr "prefix_0f" "1")
12465    (set_attr "prefix_extra" "*,1,1")
12466    (set_attr "length" "3,*,*")
12467    (set_attr "mode" "DI")])
12468
12469 (define_insn "*bswapdi_1"
12470   [(set (match_operand:DI 0 "register_operand" "=r")
12471         (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
12472   "TARGET_64BIT"
12473   "bswap\t%0"
12474   [(set_attr "prefix_0f" "1")
12475    (set_attr "length" "3")])
12476
12477 (define_expand "clzdi2"
12478   [(parallel
12479      [(set (match_operand:DI 0 "register_operand" "")
12480            (minus:DI (const_int 63)
12481                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
12482       (clobber (reg:CC FLAGS_REG))])
12483    (parallel
12484      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
12485       (clobber (reg:CC FLAGS_REG))])]
12486   "TARGET_64BIT"
12487 {
12488   if (TARGET_ABM)
12489     {
12490       emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
12491       DONE;
12492     }
12493 })
12494
12495 (define_insn "clzdi2_abm"
12496   [(set (match_operand:DI 0 "register_operand" "=r")
12497         (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
12498    (clobber (reg:CC FLAGS_REG))]
12499   "TARGET_64BIT && TARGET_ABM"
12500   "lzcnt{q}\t{%1, %0|%0, %1}"
12501   [(set_attr "prefix_rep" "1")
12502    (set_attr "type" "bitmanip")
12503    (set_attr "mode" "DI")])
12504
12505 (define_insn "bsr_rex64"
12506   [(set (match_operand:DI 0 "register_operand" "=r")
12507         (minus:DI (const_int 63)
12508                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12509    (clobber (reg:CC FLAGS_REG))]
12510   "TARGET_64BIT"
12511   "bsr{q}\t{%1, %0|%0, %1}"
12512   [(set_attr "type" "alu1")
12513    (set_attr "prefix_0f" "1")
12514    (set_attr "mode" "DI")])
12515
12516 (define_expand "clzhi2"
12517   [(parallel
12518      [(set (match_operand:HI 0 "register_operand" "")
12519            (minus:HI (const_int 15)
12520                      (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
12521       (clobber (reg:CC FLAGS_REG))])
12522    (parallel
12523      [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
12524       (clobber (reg:CC FLAGS_REG))])]
12525   ""
12526 {
12527   if (TARGET_ABM)
12528     {
12529       emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
12530       DONE;
12531     }
12532 })
12533
12534 (define_insn "clzhi2_abm"
12535   [(set (match_operand:HI 0 "register_operand" "=r")
12536         (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm")))
12537    (clobber (reg:CC FLAGS_REG))]
12538   "TARGET_ABM"
12539   "lzcnt{w}\t{%1, %0|%0, %1}"
12540   [(set_attr "prefix_rep" "1")
12541    (set_attr "type" "bitmanip")
12542    (set_attr "mode" "HI")])
12543
12544 (define_insn "*bsrhi"
12545   [(set (match_operand:HI 0 "register_operand" "=r")
12546         (minus:HI (const_int 15)
12547                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12548    (clobber (reg:CC FLAGS_REG))]
12549   ""
12550   "bsr{w}\t{%1, %0|%0, %1}"
12551   [(set_attr "type" "alu1")
12552    (set_attr "prefix_0f" "1")
12553    (set_attr "mode" "HI")])
12554
12555 (define_expand "paritydi2"
12556   [(set (match_operand:DI 0 "register_operand" "")
12557         (parity:DI (match_operand:DI 1 "register_operand" "")))]
12558   "! TARGET_POPCNT"
12559 {
12560   rtx scratch = gen_reg_rtx (QImode);
12561   rtx cond;
12562
12563   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12564                                 NULL_RTX, operands[1]));
12565
12566   cond = gen_rtx_fmt_ee (ORDERED, QImode,
12567                          gen_rtx_REG (CCmode, FLAGS_REG),
12568                          const0_rtx);
12569   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12570
12571   if (TARGET_64BIT)
12572     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12573   else
12574     {
12575       rtx tmp = gen_reg_rtx (SImode);
12576
12577       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12578       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12579     }
12580   DONE;
12581 })
12582
12583 (define_insn_and_split "paritydi2_cmp"
12584   [(set (reg:CC FLAGS_REG)
12585         (parity:CC (match_operand:DI 3 "register_operand" "0")))
12586    (clobber (match_scratch:DI 0 "=r"))
12587    (clobber (match_scratch:SI 1 "=&r"))
12588    (clobber (match_scratch:HI 2 "=Q"))]
12589   "! TARGET_POPCNT"
12590   "#"
12591   "&& reload_completed"
12592   [(parallel
12593      [(set (match_dup 1)
12594            (xor:SI (match_dup 1) (match_dup 4)))
12595       (clobber (reg:CC FLAGS_REG))])
12596    (parallel
12597      [(set (reg:CC FLAGS_REG)
12598            (parity:CC (match_dup 1)))
12599       (clobber (match_dup 1))
12600       (clobber (match_dup 2))])]
12601 {
12602   operands[4] = gen_lowpart (SImode, operands[3]);
12603
12604   if (TARGET_64BIT)
12605     {
12606       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12607       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12608     }
12609   else
12610     operands[1] = gen_highpart (SImode, operands[3]);
12611 })
12612
12613 (define_expand "paritysi2"
12614   [(set (match_operand:SI 0 "register_operand" "")
12615         (parity:SI (match_operand:SI 1 "register_operand" "")))]
12616   "! TARGET_POPCNT"
12617 {
12618   rtx scratch = gen_reg_rtx (QImode);
12619   rtx cond;
12620
12621   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12622
12623   cond = gen_rtx_fmt_ee (ORDERED, QImode,
12624                          gen_rtx_REG (CCmode, FLAGS_REG),
12625                          const0_rtx);
12626   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12627
12628   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12629   DONE;
12630 })
12631
12632 (define_insn_and_split "paritysi2_cmp"
12633   [(set (reg:CC FLAGS_REG)
12634         (parity:CC (match_operand:SI 2 "register_operand" "0")))
12635    (clobber (match_scratch:SI 0 "=r"))
12636    (clobber (match_scratch:HI 1 "=&Q"))]
12637   "! TARGET_POPCNT"
12638   "#"
12639   "&& reload_completed"
12640   [(parallel
12641      [(set (match_dup 1)
12642            (xor:HI (match_dup 1) (match_dup 3)))
12643       (clobber (reg:CC FLAGS_REG))])
12644    (parallel
12645      [(set (reg:CC FLAGS_REG)
12646            (parity:CC (match_dup 1)))
12647       (clobber (match_dup 1))])]
12648 {
12649   operands[3] = gen_lowpart (HImode, operands[2]);
12650
12651   emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12652   emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12653 })
12654
12655 (define_insn "*parityhi2_cmp"
12656   [(set (reg:CC FLAGS_REG)
12657         (parity:CC (match_operand:HI 1 "register_operand" "0")))
12658    (clobber (match_scratch:HI 0 "=Q"))]
12659   "! TARGET_POPCNT"
12660   "xor{b}\t{%h0, %b0|%b0, %h0}"
12661   [(set_attr "length" "2")
12662    (set_attr "mode" "HI")])
12663
12664 (define_insn "*parityqi2_cmp"
12665   [(set (reg:CC FLAGS_REG)
12666         (parity:CC (match_operand:QI 0 "register_operand" "q")))]
12667   "! TARGET_POPCNT"
12668   "test{b}\t%0, %0"
12669   [(set_attr "length" "2")
12670    (set_attr "mode" "QI")])
12671 \f
12672 ;; Thread-local storage patterns for ELF.
12673 ;;
12674 ;; Note that these code sequences must appear exactly as shown
12675 ;; in order to allow linker relaxation.
12676
12677 (define_insn "*tls_global_dynamic_32_gnu"
12678   [(set (match_operand:SI 0 "register_operand" "=a")
12679         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12680                     (match_operand:SI 2 "tls_symbolic_operand" "")
12681                     (match_operand:SI 3 "call_insn_operand" "")]
12682                     UNSPEC_TLS_GD))
12683    (clobber (match_scratch:SI 4 "=d"))
12684    (clobber (match_scratch:SI 5 "=c"))
12685    (clobber (reg:CC FLAGS_REG))]
12686   "!TARGET_64BIT && TARGET_GNU_TLS"
12687   "lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}\;call\t%P3"
12688   [(set_attr "type" "multi")
12689    (set_attr "length" "12")])
12690
12691 (define_expand "tls_global_dynamic_32"
12692   [(parallel [(set (match_operand:SI 0 "register_operand" "")
12693                    (unspec:SI
12694                     [(match_dup 2)
12695                      (match_operand:SI 1 "tls_symbolic_operand" "")
12696                      (match_dup 3)]
12697                     UNSPEC_TLS_GD))
12698               (clobber (match_scratch:SI 4 ""))
12699               (clobber (match_scratch:SI 5 ""))
12700               (clobber (reg:CC FLAGS_REG))])]
12701   ""
12702 {
12703   if (flag_pic)
12704     operands[2] = pic_offset_table_rtx;
12705   else
12706     {
12707       operands[2] = gen_reg_rtx (Pmode);
12708       emit_insn (gen_set_got (operands[2]));
12709     }
12710   if (TARGET_GNU2_TLS)
12711     {
12712        emit_insn (gen_tls_dynamic_gnu2_32
12713                   (operands[0], operands[1], operands[2]));
12714        DONE;
12715     }
12716   operands[3] = ix86_tls_get_addr ();
12717 })
12718
12719 (define_insn "*tls_global_dynamic_64"
12720   [(set (match_operand:DI 0 "register_operand" "=a")
12721         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
12722                  (match_operand:DI 3 "" "")))
12723    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12724               UNSPEC_TLS_GD)]
12725   "TARGET_64BIT"
12726   { 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"; }
12727   [(set_attr "type" "multi")
12728    (set_attr "length" "16")])
12729
12730 (define_expand "tls_global_dynamic_64"
12731   [(parallel [(set (match_operand:DI 0 "register_operand" "")
12732                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
12733               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12734                          UNSPEC_TLS_GD)])]
12735   ""
12736 {
12737   if (TARGET_GNU2_TLS)
12738     {
12739        emit_insn (gen_tls_dynamic_gnu2_64
12740                   (operands[0], operands[1]));
12741        DONE;
12742     }
12743   operands[2] = ix86_tls_get_addr ();
12744 })
12745
12746 (define_insn "*tls_local_dynamic_base_32_gnu"
12747   [(set (match_operand:SI 0 "register_operand" "=a")
12748         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12749                     (match_operand:SI 2 "call_insn_operand" "")]
12750                    UNSPEC_TLS_LD_BASE))
12751    (clobber (match_scratch:SI 3 "=d"))
12752    (clobber (match_scratch:SI 4 "=c"))
12753    (clobber (reg:CC FLAGS_REG))]
12754   "!TARGET_64BIT && TARGET_GNU_TLS"
12755   "lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}\;call\t%P2"
12756   [(set_attr "type" "multi")
12757    (set_attr "length" "11")])
12758
12759 (define_expand "tls_local_dynamic_base_32"
12760   [(parallel [(set (match_operand:SI 0 "register_operand" "")
12761                    (unspec:SI [(match_dup 1) (match_dup 2)]
12762                               UNSPEC_TLS_LD_BASE))
12763               (clobber (match_scratch:SI 3 ""))
12764               (clobber (match_scratch:SI 4 ""))
12765               (clobber (reg:CC FLAGS_REG))])]
12766   ""
12767 {
12768   if (flag_pic)
12769     operands[1] = pic_offset_table_rtx;
12770   else
12771     {
12772       operands[1] = gen_reg_rtx (Pmode);
12773       emit_insn (gen_set_got (operands[1]));
12774     }
12775   if (TARGET_GNU2_TLS)
12776     {
12777        emit_insn (gen_tls_dynamic_gnu2_32
12778                   (operands[0], ix86_tls_module_base (), operands[1]));
12779        DONE;
12780     }
12781   operands[2] = ix86_tls_get_addr ();
12782 })
12783
12784 (define_insn "*tls_local_dynamic_base_64"
12785   [(set (match_operand:DI 0 "register_operand" "=a")
12786         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
12787                  (match_operand:DI 2 "" "")))
12788    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12789   "TARGET_64BIT"
12790   "lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}\;call\t%P1"
12791   [(set_attr "type" "multi")
12792    (set_attr "length" "12")])
12793
12794 (define_expand "tls_local_dynamic_base_64"
12795   [(parallel [(set (match_operand:DI 0 "register_operand" "")
12796                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
12797               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
12798   ""
12799 {
12800   if (TARGET_GNU2_TLS)
12801     {
12802        emit_insn (gen_tls_dynamic_gnu2_64
12803                   (operands[0], ix86_tls_module_base ()));
12804        DONE;
12805     }
12806   operands[1] = ix86_tls_get_addr ();
12807 })
12808
12809 ;; Local dynamic of a single variable is a lose.  Show combine how
12810 ;; to convert that back to global dynamic.
12811
12812 (define_insn_and_split "*tls_local_dynamic_32_once"
12813   [(set (match_operand:SI 0 "register_operand" "=a")
12814         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12815                              (match_operand:SI 2 "call_insn_operand" "")]
12816                             UNSPEC_TLS_LD_BASE)
12817                  (const:SI (unspec:SI
12818                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
12819                             UNSPEC_DTPOFF))))
12820    (clobber (match_scratch:SI 4 "=d"))
12821    (clobber (match_scratch:SI 5 "=c"))
12822    (clobber (reg:CC FLAGS_REG))]
12823   ""
12824   "#"
12825   ""
12826   [(parallel [(set (match_dup 0)
12827                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12828                               UNSPEC_TLS_GD))
12829               (clobber (match_dup 4))
12830               (clobber (match_dup 5))
12831               (clobber (reg:CC FLAGS_REG))])]
12832   "")
12833
12834 ;; Load and add the thread base pointer from %gs:0.
12835
12836 (define_insn "*load_tp_si"
12837   [(set (match_operand:SI 0 "register_operand" "=r")
12838         (unspec:SI [(const_int 0)] UNSPEC_TP))]
12839   "!TARGET_64BIT"
12840   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
12841   [(set_attr "type" "imov")
12842    (set_attr "modrm" "0")
12843    (set_attr "length" "7")
12844    (set_attr "memory" "load")
12845    (set_attr "imm_disp" "false")])
12846
12847 (define_insn "*add_tp_si"
12848   [(set (match_operand:SI 0 "register_operand" "=r")
12849         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12850                  (match_operand:SI 1 "register_operand" "0")))
12851    (clobber (reg:CC FLAGS_REG))]
12852   "!TARGET_64BIT"
12853   "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
12854   [(set_attr "type" "alu")
12855    (set_attr "modrm" "0")
12856    (set_attr "length" "7")
12857    (set_attr "memory" "load")
12858    (set_attr "imm_disp" "false")])
12859
12860 (define_insn "*load_tp_di"
12861   [(set (match_operand:DI 0 "register_operand" "=r")
12862         (unspec:DI [(const_int 0)] UNSPEC_TP))]
12863   "TARGET_64BIT"
12864   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
12865   [(set_attr "type" "imov")
12866    (set_attr "modrm" "0")
12867    (set_attr "length" "7")
12868    (set_attr "memory" "load")
12869    (set_attr "imm_disp" "false")])
12870
12871 (define_insn "*add_tp_di"
12872   [(set (match_operand:DI 0 "register_operand" "=r")
12873         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
12874                  (match_operand:DI 1 "register_operand" "0")))
12875    (clobber (reg:CC FLAGS_REG))]
12876   "TARGET_64BIT"
12877   "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
12878   [(set_attr "type" "alu")
12879    (set_attr "modrm" "0")
12880    (set_attr "length" "7")
12881    (set_attr "memory" "load")
12882    (set_attr "imm_disp" "false")])
12883
12884 ;; GNU2 TLS patterns can be split.
12885
12886 (define_expand "tls_dynamic_gnu2_32"
12887   [(set (match_dup 3)
12888         (plus:SI (match_operand:SI 2 "register_operand" "")
12889                  (const:SI
12890                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12891                              UNSPEC_TLSDESC))))
12892    (parallel
12893     [(set (match_operand:SI 0 "register_operand" "")
12894           (unspec:SI [(match_dup 1) (match_dup 3)
12895                       (match_dup 2) (reg:SI SP_REG)]
12896                       UNSPEC_TLSDESC))
12897      (clobber (reg:CC FLAGS_REG))])]
12898   "!TARGET_64BIT && TARGET_GNU2_TLS"
12899 {
12900   operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12901   ix86_tls_descriptor_calls_expanded_in_cfun = true;
12902 })
12903
12904 (define_insn "*tls_dynamic_lea_32"
12905   [(set (match_operand:SI 0 "register_operand" "=r")
12906         (plus:SI (match_operand:SI 1 "register_operand" "b")
12907                  (const:SI
12908                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12909                               UNSPEC_TLSDESC))))]
12910   "!TARGET_64BIT && TARGET_GNU2_TLS"
12911   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
12912   [(set_attr "type" "lea")
12913    (set_attr "mode" "SI")
12914    (set_attr "length" "6")
12915    (set_attr "length_address" "4")])
12916
12917 (define_insn "*tls_dynamic_call_32"
12918   [(set (match_operand:SI 0 "register_operand" "=a")
12919         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12920                     (match_operand:SI 2 "register_operand" "0")
12921                     ;; we have to make sure %ebx still points to the GOT
12922                     (match_operand:SI 3 "register_operand" "b")
12923                     (reg:SI SP_REG)]
12924                    UNSPEC_TLSDESC))
12925    (clobber (reg:CC FLAGS_REG))]
12926   "!TARGET_64BIT && TARGET_GNU2_TLS"
12927   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12928   [(set_attr "type" "call")
12929    (set_attr "length" "2")
12930    (set_attr "length_address" "0")])
12931
12932 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12933   [(set (match_operand:SI 0 "register_operand" "=&a")
12934         (plus:SI
12935          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12936                      (match_operand:SI 4 "" "")
12937                      (match_operand:SI 2 "register_operand" "b")
12938                      (reg:SI SP_REG)]
12939                     UNSPEC_TLSDESC)
12940          (const:SI (unspec:SI
12941                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
12942                     UNSPEC_DTPOFF))))
12943    (clobber (reg:CC FLAGS_REG))]
12944   "!TARGET_64BIT && TARGET_GNU2_TLS"
12945   "#"
12946   ""
12947   [(set (match_dup 0) (match_dup 5))]
12948 {
12949   operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12950   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12951 })
12952
12953 (define_expand "tls_dynamic_gnu2_64"
12954   [(set (match_dup 2)
12955         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12956                    UNSPEC_TLSDESC))
12957    (parallel
12958     [(set (match_operand:DI 0 "register_operand" "")
12959           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12960                      UNSPEC_TLSDESC))
12961      (clobber (reg:CC FLAGS_REG))])]
12962   "TARGET_64BIT && TARGET_GNU2_TLS"
12963 {
12964   operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12965   ix86_tls_descriptor_calls_expanded_in_cfun = true;
12966 })
12967
12968 (define_insn "*tls_dynamic_lea_64"
12969   [(set (match_operand:DI 0 "register_operand" "=r")
12970         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12971                    UNSPEC_TLSDESC))]
12972   "TARGET_64BIT && TARGET_GNU2_TLS"
12973   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
12974   [(set_attr "type" "lea")
12975    (set_attr "mode" "DI")
12976    (set_attr "length" "7")
12977    (set_attr "length_address" "4")])
12978
12979 (define_insn "*tls_dynamic_call_64"
12980   [(set (match_operand:DI 0 "register_operand" "=a")
12981         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
12982                     (match_operand:DI 2 "register_operand" "0")
12983                     (reg:DI SP_REG)]
12984                    UNSPEC_TLSDESC))
12985    (clobber (reg:CC FLAGS_REG))]
12986   "TARGET_64BIT && TARGET_GNU2_TLS"
12987   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12988   [(set_attr "type" "call")
12989    (set_attr "length" "2")
12990    (set_attr "length_address" "0")])
12991
12992 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12993   [(set (match_operand:DI 0 "register_operand" "=&a")
12994         (plus:DI
12995          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12996                      (match_operand:DI 3 "" "")
12997                      (reg:DI SP_REG)]
12998                     UNSPEC_TLSDESC)
12999          (const:DI (unspec:DI
13000                     [(match_operand:DI 1 "tls_symbolic_operand" "")]
13001                     UNSPEC_DTPOFF))))
13002    (clobber (reg:CC FLAGS_REG))]
13003   "TARGET_64BIT && TARGET_GNU2_TLS"
13004   "#"
13005   ""
13006   [(set (match_dup 0) (match_dup 4))]
13007 {
13008   operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13009   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
13010 })
13011
13012 ;;
13013 \f
13014 ;; These patterns match the binary 387 instructions for addM3, subM3,
13015 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
13016 ;; SFmode.  The first is the normal insn, the second the same insn but
13017 ;; with one operand a conversion, and the third the same insn but with
13018 ;; the other operand a conversion.  The conversion may be SFmode or
13019 ;; SImode if the target mode DFmode, but only SImode if the target mode
13020 ;; is SFmode.
13021
13022 ;; Gcc is slightly more smart about handling normal two address instructions
13023 ;; so use special patterns for add and mull.
13024
13025 (define_insn "*fop_<mode>_comm_mixed_avx"
13026   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
13027         (match_operator:MODEF 3 "binary_fp_operator"
13028           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
13029            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
13030   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13031    && COMMUTATIVE_ARITH_P (operands[3])
13032    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13033   "* return output_387_binary_op (insn, operands);"
13034   [(set (attr "type")
13035         (if_then_else (eq_attr "alternative" "1")
13036            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13037               (const_string "ssemul")
13038               (const_string "sseadd"))
13039            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13040               (const_string "fmul")
13041               (const_string "fop"))))
13042    (set_attr "prefix" "orig,maybe_vex")
13043    (set_attr "mode" "<MODE>")])
13044
13045 (define_insn "*fop_<mode>_comm_mixed"
13046   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
13047         (match_operator:MODEF 3 "binary_fp_operator"
13048           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
13049            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
13050   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13051    && COMMUTATIVE_ARITH_P (operands[3])
13052    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13053   "* return output_387_binary_op (insn, operands);"
13054   [(set (attr "type")
13055         (if_then_else (eq_attr "alternative" "1")
13056            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13057               (const_string "ssemul")
13058               (const_string "sseadd"))
13059            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13060               (const_string "fmul")
13061               (const_string "fop"))))
13062    (set_attr "mode" "<MODE>")])
13063
13064 (define_insn "*fop_<mode>_comm_avx"
13065   [(set (match_operand:MODEF 0 "register_operand" "=x")
13066         (match_operator:MODEF 3 "binary_fp_operator"
13067           [(match_operand:MODEF 1 "nonimmediate_operand" "%x")
13068            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
13069   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13070    && COMMUTATIVE_ARITH_P (operands[3])
13071    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13072   "* return output_387_binary_op (insn, operands);"
13073   [(set (attr "type")
13074         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13075            (const_string "ssemul")
13076            (const_string "sseadd")))
13077    (set_attr "prefix" "vex")
13078    (set_attr "mode" "<MODE>")])
13079
13080 (define_insn "*fop_<mode>_comm_sse"
13081   [(set (match_operand:MODEF 0 "register_operand" "=x")
13082         (match_operator:MODEF 3 "binary_fp_operator"
13083           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13084            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
13085   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13086    && COMMUTATIVE_ARITH_P (operands[3])
13087    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13088   "* return output_387_binary_op (insn, operands);"
13089   [(set (attr "type")
13090         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13091            (const_string "ssemul")
13092            (const_string "sseadd")))
13093    (set_attr "mode" "<MODE>")])
13094
13095 (define_insn "*fop_<mode>_comm_i387"
13096   [(set (match_operand:MODEF 0 "register_operand" "=f")
13097         (match_operator:MODEF 3 "binary_fp_operator"
13098           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13099            (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
13100   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13101    && COMMUTATIVE_ARITH_P (operands[3])
13102    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13103   "* return output_387_binary_op (insn, operands);"
13104   [(set (attr "type")
13105         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13106            (const_string "fmul")
13107            (const_string "fop")))
13108    (set_attr "mode" "<MODE>")])
13109
13110 (define_insn "*fop_<mode>_1_mixed_avx"
13111   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
13112         (match_operator:MODEF 3 "binary_fp_operator"
13113           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,x")
13114            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
13115   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
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         (cond [(and (eq_attr "alternative" "2")
13121                     (match_operand:MODEF 3 "mult_operator" ""))
13122                  (const_string "ssemul")
13123                (and (eq_attr "alternative" "2")
13124                     (match_operand:MODEF 3 "div_operator" ""))
13125                  (const_string "ssediv")
13126                (eq_attr "alternative" "2")
13127                  (const_string "sseadd")
13128                (match_operand:MODEF 3 "mult_operator" "")
13129                  (const_string "fmul")
13130                (match_operand:MODEF 3 "div_operator" "")
13131                  (const_string "fdiv")
13132               ]
13133               (const_string "fop")))
13134    (set_attr "prefix" "orig,orig,maybe_vex")
13135    (set_attr "mode" "<MODE>")])
13136
13137 (define_insn "*fop_<mode>_1_mixed"
13138   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
13139         (match_operator:MODEF 3 "binary_fp_operator"
13140           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
13141            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
13142   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13143    && !COMMUTATIVE_ARITH_P (operands[3])
13144    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13145   "* return output_387_binary_op (insn, operands);"
13146   [(set (attr "type")
13147         (cond [(and (eq_attr "alternative" "2")
13148                     (match_operand:MODEF 3 "mult_operator" ""))
13149                  (const_string "ssemul")
13150                (and (eq_attr "alternative" "2")
13151                     (match_operand:MODEF 3 "div_operator" ""))
13152                  (const_string "ssediv")
13153                (eq_attr "alternative" "2")
13154                  (const_string "sseadd")
13155                (match_operand:MODEF 3 "mult_operator" "")
13156                  (const_string "fmul")
13157                (match_operand:MODEF 3 "div_operator" "")
13158                  (const_string "fdiv")
13159               ]
13160               (const_string "fop")))
13161    (set_attr "mode" "<MODE>")])
13162
13163 (define_insn "*rcpsf2_sse"
13164   [(set (match_operand:SF 0 "register_operand" "=x")
13165         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13166                    UNSPEC_RCP))]
13167   "TARGET_SSE_MATH"
13168   "%vrcpss\t{%1, %d0|%d0, %1}"
13169   [(set_attr "type" "sse")
13170    (set_attr "atom_sse_attr" "rcp")
13171    (set_attr "prefix" "maybe_vex")
13172    (set_attr "mode" "SF")])
13173
13174 (define_insn "*fop_<mode>_1_avx"
13175   [(set (match_operand:MODEF 0 "register_operand" "=x")
13176         (match_operator:MODEF 3 "binary_fp_operator"
13177           [(match_operand:MODEF 1 "register_operand" "x")
13178            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
13179   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13180    && !COMMUTATIVE_ARITH_P (operands[3])"
13181   "* return output_387_binary_op (insn, operands);"
13182   [(set (attr "type")
13183         (cond [(match_operand:MODEF 3 "mult_operator" "")
13184                  (const_string "ssemul")
13185                (match_operand:MODEF 3 "div_operator" "")
13186                  (const_string "ssediv")
13187               ]
13188               (const_string "sseadd")))
13189    (set_attr "prefix" "vex")
13190    (set_attr "mode" "<MODE>")])
13191
13192 (define_insn "*fop_<mode>_1_sse"
13193   [(set (match_operand:MODEF 0 "register_operand" "=x")
13194         (match_operator:MODEF 3 "binary_fp_operator"
13195           [(match_operand:MODEF 1 "register_operand" "0")
13196            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
13197   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13198    && !COMMUTATIVE_ARITH_P (operands[3])"
13199   "* return output_387_binary_op (insn, operands);"
13200   [(set (attr "type")
13201         (cond [(match_operand:MODEF 3 "mult_operator" "")
13202                  (const_string "ssemul")
13203                (match_operand:MODEF 3 "div_operator" "")
13204                  (const_string "ssediv")
13205               ]
13206               (const_string "sseadd")))
13207    (set_attr "mode" "<MODE>")])
13208
13209 ;; This pattern is not fully shadowed by the pattern above.
13210 (define_insn "*fop_<mode>_1_i387"
13211   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13212         (match_operator:MODEF 3 "binary_fp_operator"
13213           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13214            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13215   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13216    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13217    && !COMMUTATIVE_ARITH_P (operands[3])
13218    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13219   "* return output_387_binary_op (insn, operands);"
13220   [(set (attr "type")
13221         (cond [(match_operand:MODEF 3 "mult_operator" "")
13222                  (const_string "fmul")
13223                (match_operand:MODEF 3 "div_operator" "")
13224                  (const_string "fdiv")
13225               ]
13226               (const_string "fop")))
13227    (set_attr "mode" "<MODE>")])
13228
13229 ;; ??? Add SSE splitters for these!
13230 (define_insn "*fop_<MODEF:mode>_2_i387"
13231   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13232         (match_operator:MODEF 3 "binary_fp_operator"
13233           [(float:MODEF
13234              (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
13235            (match_operand:MODEF 2 "register_operand" "0,0")]))]
13236   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
13237    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13238    && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13239   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13240   [(set (attr "type")
13241         (cond [(match_operand:MODEF 3 "mult_operator" "")
13242                  (const_string "fmul")
13243                (match_operand:MODEF 3 "div_operator" "")
13244                  (const_string "fdiv")
13245               ]
13246               (const_string "fop")))
13247    (set_attr "fp_int_src" "true")
13248    (set_attr "mode" "<X87MODEI12:MODE>")])
13249
13250 (define_insn "*fop_<MODEF:mode>_3_i387"
13251   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13252         (match_operator:MODEF 3 "binary_fp_operator"
13253           [(match_operand:MODEF 1 "register_operand" "0,0")
13254            (float:MODEF
13255              (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
13256   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
13257    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13258    && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13259   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13260   [(set (attr "type")
13261         (cond [(match_operand:MODEF 3 "mult_operator" "")
13262                  (const_string "fmul")
13263                (match_operand:MODEF 3 "div_operator" "")
13264                  (const_string "fdiv")
13265               ]
13266               (const_string "fop")))
13267    (set_attr "fp_int_src" "true")
13268    (set_attr "mode" "<MODE>")])
13269
13270 (define_insn "*fop_df_4_i387"
13271   [(set (match_operand:DF 0 "register_operand" "=f,f")
13272         (match_operator:DF 3 "binary_fp_operator"
13273            [(float_extend:DF
13274              (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13275             (match_operand:DF 2 "register_operand" "0,f")]))]
13276   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13277    && !(TARGET_SSE2 && TARGET_SSE_MATH)
13278    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13279   "* return output_387_binary_op (insn, operands);"
13280   [(set (attr "type")
13281         (cond [(match_operand:DF 3 "mult_operator" "")
13282                  (const_string "fmul")
13283                (match_operand:DF 3 "div_operator" "")
13284                  (const_string "fdiv")
13285               ]
13286               (const_string "fop")))
13287    (set_attr "mode" "SF")])
13288
13289 (define_insn "*fop_df_5_i387"
13290   [(set (match_operand:DF 0 "register_operand" "=f,f")
13291         (match_operator:DF 3 "binary_fp_operator"
13292           [(match_operand:DF 1 "register_operand" "0,f")
13293            (float_extend:DF
13294             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13295   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13296    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13297   "* return output_387_binary_op (insn, operands);"
13298   [(set (attr "type")
13299         (cond [(match_operand:DF 3 "mult_operator" "")
13300                  (const_string "fmul")
13301                (match_operand:DF 3 "div_operator" "")
13302                  (const_string "fdiv")
13303               ]
13304               (const_string "fop")))
13305    (set_attr "mode" "SF")])
13306
13307 (define_insn "*fop_df_6_i387"
13308   [(set (match_operand:DF 0 "register_operand" "=f,f")
13309         (match_operator:DF 3 "binary_fp_operator"
13310           [(float_extend:DF
13311             (match_operand:SF 1 "register_operand" "0,f"))
13312            (float_extend:DF
13313             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13314   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13315    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13316   "* return output_387_binary_op (insn, operands);"
13317   [(set (attr "type")
13318         (cond [(match_operand:DF 3 "mult_operator" "")
13319                  (const_string "fmul")
13320                (match_operand:DF 3 "div_operator" "")
13321                  (const_string "fdiv")
13322               ]
13323               (const_string "fop")))
13324    (set_attr "mode" "SF")])
13325
13326 (define_insn "*fop_xf_comm_i387"
13327   [(set (match_operand:XF 0 "register_operand" "=f")
13328         (match_operator:XF 3 "binary_fp_operator"
13329                         [(match_operand:XF 1 "register_operand" "%0")
13330                          (match_operand:XF 2 "register_operand" "f")]))]
13331   "TARGET_80387
13332    && COMMUTATIVE_ARITH_P (operands[3])"
13333   "* return output_387_binary_op (insn, operands);"
13334   [(set (attr "type")
13335         (if_then_else (match_operand:XF 3 "mult_operator" "")
13336            (const_string "fmul")
13337            (const_string "fop")))
13338    (set_attr "mode" "XF")])
13339
13340 (define_insn "*fop_xf_1_i387"
13341   [(set (match_operand:XF 0 "register_operand" "=f,f")
13342         (match_operator:XF 3 "binary_fp_operator"
13343                         [(match_operand:XF 1 "register_operand" "0,f")
13344                          (match_operand:XF 2 "register_operand" "f,0")]))]
13345   "TARGET_80387
13346    && !COMMUTATIVE_ARITH_P (operands[3])"
13347   "* return output_387_binary_op (insn, operands);"
13348   [(set (attr "type")
13349         (cond [(match_operand:XF 3 "mult_operator" "")
13350                  (const_string "fmul")
13351                (match_operand:XF 3 "div_operator" "")
13352                  (const_string "fdiv")
13353               ]
13354               (const_string "fop")))
13355    (set_attr "mode" "XF")])
13356
13357 (define_insn "*fop_xf_2_i387"
13358   [(set (match_operand:XF 0 "register_operand" "=f,f")
13359         (match_operator:XF 3 "binary_fp_operator"
13360           [(float:XF
13361              (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
13362            (match_operand:XF 2 "register_operand" "0,0")]))]
13363   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13364   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13365   [(set (attr "type")
13366         (cond [(match_operand:XF 3 "mult_operator" "")
13367                  (const_string "fmul")
13368                (match_operand:XF 3 "div_operator" "")
13369                  (const_string "fdiv")
13370               ]
13371               (const_string "fop")))
13372    (set_attr "fp_int_src" "true")
13373    (set_attr "mode" "<MODE>")])
13374
13375 (define_insn "*fop_xf_3_i387"
13376   [(set (match_operand:XF 0 "register_operand" "=f,f")
13377         (match_operator:XF 3 "binary_fp_operator"
13378           [(match_operand:XF 1 "register_operand" "0,0")
13379            (float:XF
13380              (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
13381   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13382   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13383   [(set (attr "type")
13384         (cond [(match_operand:XF 3 "mult_operator" "")
13385                  (const_string "fmul")
13386                (match_operand:XF 3 "div_operator" "")
13387                  (const_string "fdiv")
13388               ]
13389               (const_string "fop")))
13390    (set_attr "fp_int_src" "true")
13391    (set_attr "mode" "<MODE>")])
13392
13393 (define_insn "*fop_xf_4_i387"
13394   [(set (match_operand:XF 0 "register_operand" "=f,f")
13395         (match_operator:XF 3 "binary_fp_operator"
13396            [(float_extend:XF
13397               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13398             (match_operand:XF 2 "register_operand" "0,f")]))]
13399   "TARGET_80387"
13400   "* return output_387_binary_op (insn, operands);"
13401   [(set (attr "type")
13402         (cond [(match_operand:XF 3 "mult_operator" "")
13403                  (const_string "fmul")
13404                (match_operand:XF 3 "div_operator" "")
13405                  (const_string "fdiv")
13406               ]
13407               (const_string "fop")))
13408    (set_attr "mode" "<MODE>")])
13409
13410 (define_insn "*fop_xf_5_i387"
13411   [(set (match_operand:XF 0 "register_operand" "=f,f")
13412         (match_operator:XF 3 "binary_fp_operator"
13413           [(match_operand:XF 1 "register_operand" "0,f")
13414            (float_extend:XF
13415              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13416   "TARGET_80387"
13417   "* return output_387_binary_op (insn, operands);"
13418   [(set (attr "type")
13419         (cond [(match_operand:XF 3 "mult_operator" "")
13420                  (const_string "fmul")
13421                (match_operand:XF 3 "div_operator" "")
13422                  (const_string "fdiv")
13423               ]
13424               (const_string "fop")))
13425    (set_attr "mode" "<MODE>")])
13426
13427 (define_insn "*fop_xf_6_i387"
13428   [(set (match_operand:XF 0 "register_operand" "=f,f")
13429         (match_operator:XF 3 "binary_fp_operator"
13430           [(float_extend:XF
13431              (match_operand:MODEF 1 "register_operand" "0,f"))
13432            (float_extend:XF
13433              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13434   "TARGET_80387"
13435   "* return output_387_binary_op (insn, operands);"
13436   [(set (attr "type")
13437         (cond [(match_operand:XF 3 "mult_operator" "")
13438                  (const_string "fmul")
13439                (match_operand:XF 3 "div_operator" "")
13440                  (const_string "fdiv")
13441               ]
13442               (const_string "fop")))
13443    (set_attr "mode" "<MODE>")])
13444
13445 (define_split
13446   [(set (match_operand 0 "register_operand" "")
13447         (match_operator 3 "binary_fp_operator"
13448            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
13449             (match_operand 2 "register_operand" "")]))]
13450   "reload_completed
13451    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13452    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13453   [(const_int 0)]
13454 {
13455   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13456   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13457   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13458                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
13459                                           GET_MODE (operands[3]),
13460                                           operands[4],
13461                                           operands[2])));
13462   ix86_free_from_memory (GET_MODE (operands[1]));
13463   DONE;
13464 })
13465
13466 (define_split
13467   [(set (match_operand 0 "register_operand" "")
13468         (match_operator 3 "binary_fp_operator"
13469            [(match_operand 1 "register_operand" "")
13470             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
13471   "reload_completed
13472    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13473    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13474   [(const_int 0)]
13475 {
13476   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13477   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13478   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13479                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
13480                                           GET_MODE (operands[3]),
13481                                           operands[1],
13482                                           operands[4])));
13483   ix86_free_from_memory (GET_MODE (operands[2]));
13484   DONE;
13485 })
13486 \f
13487 ;; FPU special functions.
13488
13489 ;; This pattern implements a no-op XFmode truncation for
13490 ;; all fancy i386 XFmode math functions.
13491
13492 (define_insn "truncxf<mode>2_i387_noop_unspec"
13493   [(set (match_operand:MODEF 0 "register_operand" "=f")
13494         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13495         UNSPEC_TRUNC_NOOP))]
13496   "TARGET_USE_FANCY_MATH_387"
13497   "* return output_387_reg_move (insn, operands);"
13498   [(set_attr "type" "fmov")
13499    (set_attr "mode" "<MODE>")])
13500
13501 (define_insn "sqrtxf2"
13502   [(set (match_operand:XF 0 "register_operand" "=f")
13503         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13504   "TARGET_USE_FANCY_MATH_387"
13505   "fsqrt"
13506   [(set_attr "type" "fpspc")
13507    (set_attr "mode" "XF")
13508    (set_attr "athlon_decode" "direct")
13509    (set_attr "amdfam10_decode" "direct")])
13510
13511 (define_insn "sqrt_extend<mode>xf2_i387"
13512   [(set (match_operand:XF 0 "register_operand" "=f")
13513         (sqrt:XF
13514           (float_extend:XF
13515             (match_operand:MODEF 1 "register_operand" "0"))))]
13516   "TARGET_USE_FANCY_MATH_387"
13517   "fsqrt"
13518   [(set_attr "type" "fpspc")
13519    (set_attr "mode" "XF")
13520    (set_attr "athlon_decode" "direct")
13521    (set_attr "amdfam10_decode" "direct")])
13522
13523 (define_insn "*rsqrtsf2_sse"
13524   [(set (match_operand:SF 0 "register_operand" "=x")
13525         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13526                    UNSPEC_RSQRT))]
13527   "TARGET_SSE_MATH"
13528   "%vrsqrtss\t{%1, %d0|%d0, %1}"
13529   [(set_attr "type" "sse")
13530    (set_attr "atom_sse_attr" "rcp")
13531    (set_attr "prefix" "maybe_vex")
13532    (set_attr "mode" "SF")])
13533
13534 (define_expand "rsqrtsf2"
13535   [(set (match_operand:SF 0 "register_operand" "")
13536         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
13537                    UNSPEC_RSQRT))]
13538   "TARGET_SSE_MATH"
13539 {
13540   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13541   DONE;
13542 })
13543
13544 (define_insn "*sqrt<mode>2_sse"
13545   [(set (match_operand:MODEF 0 "register_operand" "=x")
13546         (sqrt:MODEF
13547           (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13548   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13549   "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}"
13550   [(set_attr "type" "sse")
13551    (set_attr "atom_sse_attr" "sqrt")
13552    (set_attr "prefix" "maybe_vex")
13553    (set_attr "mode" "<MODE>")
13554    (set_attr "athlon_decode" "*")
13555    (set_attr "amdfam10_decode" "*")])
13556
13557 (define_expand "sqrt<mode>2"
13558   [(set (match_operand:MODEF 0 "register_operand" "")
13559         (sqrt:MODEF
13560           (match_operand:MODEF 1 "nonimmediate_operand" "")))]
13561   "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13562    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13563 {
13564   if (<MODE>mode == SFmode
13565       && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
13566       && flag_finite_math_only && !flag_trapping_math
13567       && flag_unsafe_math_optimizations)
13568     {
13569       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13570       DONE;
13571     }
13572
13573   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13574     {
13575       rtx op0 = gen_reg_rtx (XFmode);
13576       rtx op1 = force_reg (<MODE>mode, operands[1]);
13577
13578       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13579       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13580       DONE;
13581    }
13582 })
13583
13584 (define_insn "fpremxf4_i387"
13585   [(set (match_operand:XF 0 "register_operand" "=f")
13586         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13587                     (match_operand:XF 3 "register_operand" "1")]
13588                    UNSPEC_FPREM_F))
13589    (set (match_operand:XF 1 "register_operand" "=u")
13590         (unspec:XF [(match_dup 2) (match_dup 3)]
13591                    UNSPEC_FPREM_U))
13592    (set (reg:CCFP FPSR_REG)
13593         (unspec:CCFP [(match_dup 2) (match_dup 3)]
13594                      UNSPEC_C2_FLAG))]
13595   "TARGET_USE_FANCY_MATH_387"
13596   "fprem"
13597   [(set_attr "type" "fpspc")
13598    (set_attr "mode" "XF")])
13599
13600 (define_expand "fmodxf3"
13601   [(use (match_operand:XF 0 "register_operand" ""))
13602    (use (match_operand:XF 1 "general_operand" ""))
13603    (use (match_operand:XF 2 "general_operand" ""))]
13604   "TARGET_USE_FANCY_MATH_387"
13605 {
13606   rtx label = gen_label_rtx ();
13607
13608   rtx op1 = gen_reg_rtx (XFmode);
13609   rtx op2 = gen_reg_rtx (XFmode);
13610
13611   emit_move_insn (op2, operands[2]);
13612   emit_move_insn (op1, operands[1]);
13613
13614   emit_label (label);
13615   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13616   ix86_emit_fp_unordered_jump (label);
13617   LABEL_NUSES (label) = 1;
13618
13619   emit_move_insn (operands[0], op1);
13620   DONE;
13621 })
13622
13623 (define_expand "fmod<mode>3"
13624   [(use (match_operand:MODEF 0 "register_operand" ""))
13625    (use (match_operand:MODEF 1 "general_operand" ""))
13626    (use (match_operand:MODEF 2 "general_operand" ""))]
13627   "TARGET_USE_FANCY_MATH_387"
13628 {
13629   rtx label = gen_label_rtx ();
13630
13631   rtx op1 = gen_reg_rtx (XFmode);
13632   rtx op2 = gen_reg_rtx (XFmode);
13633
13634   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13635   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13636
13637   emit_label (label);
13638   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13639   ix86_emit_fp_unordered_jump (label);
13640   LABEL_NUSES (label) = 1;
13641
13642   /* Truncate the result properly for strict SSE math.  */
13643   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13644       && !TARGET_MIX_SSE_I387)
13645     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
13646   else
13647     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
13648
13649   DONE;
13650 })
13651
13652 (define_insn "fprem1xf4_i387"
13653   [(set (match_operand:XF 0 "register_operand" "=f")
13654         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13655                     (match_operand:XF 3 "register_operand" "1")]
13656                    UNSPEC_FPREM1_F))
13657    (set (match_operand:XF 1 "register_operand" "=u")
13658         (unspec:XF [(match_dup 2) (match_dup 3)]
13659                    UNSPEC_FPREM1_U))
13660    (set (reg:CCFP FPSR_REG)
13661         (unspec:CCFP [(match_dup 2) (match_dup 3)]
13662                      UNSPEC_C2_FLAG))]
13663   "TARGET_USE_FANCY_MATH_387"
13664   "fprem1"
13665   [(set_attr "type" "fpspc")
13666    (set_attr "mode" "XF")])
13667
13668 (define_expand "remainderxf3"
13669   [(use (match_operand:XF 0 "register_operand" ""))
13670    (use (match_operand:XF 1 "general_operand" ""))
13671    (use (match_operand:XF 2 "general_operand" ""))]
13672   "TARGET_USE_FANCY_MATH_387"
13673 {
13674   rtx label = gen_label_rtx ();
13675
13676   rtx op1 = gen_reg_rtx (XFmode);
13677   rtx op2 = gen_reg_rtx (XFmode);
13678
13679   emit_move_insn (op2, operands[2]);
13680   emit_move_insn (op1, operands[1]);
13681
13682   emit_label (label);
13683   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13684   ix86_emit_fp_unordered_jump (label);
13685   LABEL_NUSES (label) = 1;
13686
13687   emit_move_insn (operands[0], op1);
13688   DONE;
13689 })
13690
13691 (define_expand "remainder<mode>3"
13692   [(use (match_operand:MODEF 0 "register_operand" ""))
13693    (use (match_operand:MODEF 1 "general_operand" ""))
13694    (use (match_operand:MODEF 2 "general_operand" ""))]
13695   "TARGET_USE_FANCY_MATH_387"
13696 {
13697   rtx label = gen_label_rtx ();
13698
13699   rtx op1 = gen_reg_rtx (XFmode);
13700   rtx op2 = gen_reg_rtx (XFmode);
13701
13702   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13703   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13704
13705   emit_label (label);
13706
13707   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13708   ix86_emit_fp_unordered_jump (label);
13709   LABEL_NUSES (label) = 1;
13710
13711   /* Truncate the result properly for strict SSE math.  */
13712   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13713       && !TARGET_MIX_SSE_I387)
13714     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
13715   else
13716     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
13717
13718   DONE;
13719 })
13720
13721 (define_insn "*sinxf2_i387"
13722   [(set (match_operand:XF 0 "register_operand" "=f")
13723         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13724   "TARGET_USE_FANCY_MATH_387
13725    && flag_unsafe_math_optimizations"
13726   "fsin"
13727   [(set_attr "type" "fpspc")
13728    (set_attr "mode" "XF")])
13729
13730 (define_insn "*sin_extend<mode>xf2_i387"
13731   [(set (match_operand:XF 0 "register_operand" "=f")
13732         (unspec:XF [(float_extend:XF
13733                       (match_operand:MODEF 1 "register_operand" "0"))]
13734                    UNSPEC_SIN))]
13735   "TARGET_USE_FANCY_MATH_387
13736    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13737        || TARGET_MIX_SSE_I387)
13738    && flag_unsafe_math_optimizations"
13739   "fsin"
13740   [(set_attr "type" "fpspc")
13741    (set_attr "mode" "XF")])
13742
13743 (define_insn "*cosxf2_i387"
13744   [(set (match_operand:XF 0 "register_operand" "=f")
13745         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13746   "TARGET_USE_FANCY_MATH_387
13747    && flag_unsafe_math_optimizations"
13748   "fcos"
13749   [(set_attr "type" "fpspc")
13750    (set_attr "mode" "XF")])
13751
13752 (define_insn "*cos_extend<mode>xf2_i387"
13753   [(set (match_operand:XF 0 "register_operand" "=f")
13754         (unspec:XF [(float_extend:XF
13755                       (match_operand:MODEF 1 "register_operand" "0"))]
13756                    UNSPEC_COS))]
13757   "TARGET_USE_FANCY_MATH_387
13758    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13759        || TARGET_MIX_SSE_I387)
13760    && flag_unsafe_math_optimizations"
13761   "fcos"
13762   [(set_attr "type" "fpspc")
13763    (set_attr "mode" "XF")])
13764
13765 ;; When sincos pattern is defined, sin and cos builtin functions will be
13766 ;; expanded to sincos pattern with one of its outputs left unused.
13767 ;; CSE pass will figure out if two sincos patterns can be combined,
13768 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13769 ;; depending on the unused output.
13770
13771 (define_insn "sincosxf3"
13772   [(set (match_operand:XF 0 "register_operand" "=f")
13773         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13774                    UNSPEC_SINCOS_COS))
13775    (set (match_operand:XF 1 "register_operand" "=u")
13776         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13777   "TARGET_USE_FANCY_MATH_387
13778    && flag_unsafe_math_optimizations"
13779   "fsincos"
13780   [(set_attr "type" "fpspc")
13781    (set_attr "mode" "XF")])
13782
13783 (define_split
13784   [(set (match_operand:XF 0 "register_operand" "")
13785         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13786                    UNSPEC_SINCOS_COS))
13787    (set (match_operand:XF 1 "register_operand" "")
13788         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13789   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13790    && !(reload_completed || reload_in_progress)"
13791   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
13792   "")
13793
13794 (define_split
13795   [(set (match_operand:XF 0 "register_operand" "")
13796         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13797                    UNSPEC_SINCOS_COS))
13798    (set (match_operand:XF 1 "register_operand" "")
13799         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13800   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13801    && !(reload_completed || reload_in_progress)"
13802   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
13803   "")
13804
13805 (define_insn "sincos_extend<mode>xf3_i387"
13806   [(set (match_operand:XF 0 "register_operand" "=f")
13807         (unspec:XF [(float_extend:XF
13808                       (match_operand:MODEF 2 "register_operand" "0"))]
13809                    UNSPEC_SINCOS_COS))
13810    (set (match_operand:XF 1 "register_operand" "=u")
13811         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13812   "TARGET_USE_FANCY_MATH_387
13813    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13814        || TARGET_MIX_SSE_I387)
13815    && flag_unsafe_math_optimizations"
13816   "fsincos"
13817   [(set_attr "type" "fpspc")
13818    (set_attr "mode" "XF")])
13819
13820 (define_split
13821   [(set (match_operand:XF 0 "register_operand" "")
13822         (unspec:XF [(float_extend:XF
13823                       (match_operand:MODEF 2 "register_operand" ""))]
13824                    UNSPEC_SINCOS_COS))
13825    (set (match_operand:XF 1 "register_operand" "")
13826         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13827   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13828    && !(reload_completed || reload_in_progress)"
13829   [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
13830   "")
13831
13832 (define_split
13833   [(set (match_operand:XF 0 "register_operand" "")
13834         (unspec:XF [(float_extend:XF
13835                       (match_operand:MODEF 2 "register_operand" ""))]
13836                    UNSPEC_SINCOS_COS))
13837    (set (match_operand:XF 1 "register_operand" "")
13838         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13839   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13840    && !(reload_completed || reload_in_progress)"
13841   [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
13842   "")
13843
13844 (define_expand "sincos<mode>3"
13845   [(use (match_operand:MODEF 0 "register_operand" ""))
13846    (use (match_operand:MODEF 1 "register_operand" ""))
13847    (use (match_operand:MODEF 2 "register_operand" ""))]
13848   "TARGET_USE_FANCY_MATH_387
13849    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13850        || TARGET_MIX_SSE_I387)
13851    && flag_unsafe_math_optimizations"
13852 {
13853   rtx op0 = gen_reg_rtx (XFmode);
13854   rtx op1 = gen_reg_rtx (XFmode);
13855
13856   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13857   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13858   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13859   DONE;
13860 })
13861
13862 (define_insn "fptanxf4_i387"
13863   [(set (match_operand:XF 0 "register_operand" "=f")
13864         (match_operand:XF 3 "const_double_operand" "F"))
13865    (set (match_operand:XF 1 "register_operand" "=u")
13866         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13867                    UNSPEC_TAN))]
13868   "TARGET_USE_FANCY_MATH_387
13869    && flag_unsafe_math_optimizations
13870    && standard_80387_constant_p (operands[3]) == 2"
13871   "fptan"
13872   [(set_attr "type" "fpspc")
13873    (set_attr "mode" "XF")])
13874
13875 (define_insn "fptan_extend<mode>xf4_i387"
13876   [(set (match_operand:MODEF 0 "register_operand" "=f")
13877         (match_operand:MODEF 3 "const_double_operand" "F"))
13878    (set (match_operand:XF 1 "register_operand" "=u")
13879         (unspec:XF [(float_extend:XF
13880                       (match_operand:MODEF 2 "register_operand" "0"))]
13881                    UNSPEC_TAN))]
13882   "TARGET_USE_FANCY_MATH_387
13883    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13884        || TARGET_MIX_SSE_I387)
13885    && flag_unsafe_math_optimizations
13886    && standard_80387_constant_p (operands[3]) == 2"
13887   "fptan"
13888   [(set_attr "type" "fpspc")
13889    (set_attr "mode" "XF")])
13890
13891 (define_expand "tanxf2"
13892   [(use (match_operand:XF 0 "register_operand" ""))
13893    (use (match_operand:XF 1 "register_operand" ""))]
13894   "TARGET_USE_FANCY_MATH_387
13895    && flag_unsafe_math_optimizations"
13896 {
13897   rtx one = gen_reg_rtx (XFmode);
13898   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13899
13900   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13901   DONE;
13902 })
13903
13904 (define_expand "tan<mode>2"
13905   [(use (match_operand:MODEF 0 "register_operand" ""))
13906    (use (match_operand:MODEF 1 "register_operand" ""))]
13907   "TARGET_USE_FANCY_MATH_387
13908    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13909        || TARGET_MIX_SSE_I387)
13910    && flag_unsafe_math_optimizations"
13911 {
13912   rtx op0 = gen_reg_rtx (XFmode);
13913
13914   rtx one = gen_reg_rtx (<MODE>mode);
13915   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13916
13917   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13918                                              operands[1], op2));
13919   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13920   DONE;
13921 })
13922
13923 (define_insn "*fpatanxf3_i387"
13924   [(set (match_operand:XF 0 "register_operand" "=f")
13925         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13926                     (match_operand:XF 2 "register_operand" "u")]
13927                    UNSPEC_FPATAN))
13928    (clobber (match_scratch:XF 3 "=2"))]
13929   "TARGET_USE_FANCY_MATH_387
13930    && flag_unsafe_math_optimizations"
13931   "fpatan"
13932   [(set_attr "type" "fpspc")
13933    (set_attr "mode" "XF")])
13934
13935 (define_insn "fpatan_extend<mode>xf3_i387"
13936   [(set (match_operand:XF 0 "register_operand" "=f")
13937         (unspec:XF [(float_extend:XF
13938                       (match_operand:MODEF 1 "register_operand" "0"))
13939                     (float_extend:XF
13940                       (match_operand:MODEF 2 "register_operand" "u"))]
13941                    UNSPEC_FPATAN))
13942    (clobber (match_scratch:XF 3 "=2"))]
13943   "TARGET_USE_FANCY_MATH_387
13944    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13945        || TARGET_MIX_SSE_I387)
13946    && flag_unsafe_math_optimizations"
13947   "fpatan"
13948   [(set_attr "type" "fpspc")
13949    (set_attr "mode" "XF")])
13950
13951 (define_expand "atan2xf3"
13952   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13953                    (unspec:XF [(match_operand:XF 2 "register_operand" "")
13954                                (match_operand:XF 1 "register_operand" "")]
13955                               UNSPEC_FPATAN))
13956               (clobber (match_scratch:XF 3 ""))])]
13957   "TARGET_USE_FANCY_MATH_387
13958    && flag_unsafe_math_optimizations"
13959   "")
13960
13961 (define_expand "atan2<mode>3"
13962   [(use (match_operand:MODEF 0 "register_operand" ""))
13963    (use (match_operand:MODEF 1 "register_operand" ""))
13964    (use (match_operand:MODEF 2 "register_operand" ""))]
13965   "TARGET_USE_FANCY_MATH_387
13966    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13967        || TARGET_MIX_SSE_I387)
13968    && flag_unsafe_math_optimizations"
13969 {
13970   rtx op0 = gen_reg_rtx (XFmode);
13971
13972   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13973   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13974   DONE;
13975 })
13976
13977 (define_expand "atanxf2"
13978   [(parallel [(set (match_operand:XF 0 "register_operand" "")
13979                    (unspec:XF [(match_dup 2)
13980                                (match_operand:XF 1 "register_operand" "")]
13981                               UNSPEC_FPATAN))
13982               (clobber (match_scratch:XF 3 ""))])]
13983   "TARGET_USE_FANCY_MATH_387
13984    && flag_unsafe_math_optimizations"
13985 {
13986   operands[2] = gen_reg_rtx (XFmode);
13987   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
13988 })
13989
13990 (define_expand "atan<mode>2"
13991   [(use (match_operand:MODEF 0 "register_operand" ""))
13992    (use (match_operand:MODEF 1 "register_operand" ""))]
13993   "TARGET_USE_FANCY_MATH_387
13994    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13995        || TARGET_MIX_SSE_I387)
13996    && flag_unsafe_math_optimizations"
13997 {
13998   rtx op0 = gen_reg_rtx (XFmode);
13999
14000   rtx op2 = gen_reg_rtx (<MODE>mode);
14001   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
14002
14003   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
14004   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14005   DONE;
14006 })
14007
14008 (define_expand "asinxf2"
14009   [(set (match_dup 2)
14010         (mult:XF (match_operand:XF 1 "register_operand" "")
14011                  (match_dup 1)))
14012    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14013    (set (match_dup 5) (sqrt:XF (match_dup 4)))
14014    (parallel [(set (match_operand:XF 0 "register_operand" "")
14015                    (unspec:XF [(match_dup 5) (match_dup 1)]
14016                               UNSPEC_FPATAN))
14017               (clobber (match_scratch:XF 6 ""))])]
14018   "TARGET_USE_FANCY_MATH_387
14019    && flag_unsafe_math_optimizations"
14020 {
14021   int i;
14022
14023   if (optimize_insn_for_size_p ())
14024     FAIL;
14025
14026   for (i = 2; i < 6; i++)
14027     operands[i] = gen_reg_rtx (XFmode);
14028
14029   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
14030 })
14031
14032 (define_expand "asin<mode>2"
14033   [(use (match_operand:MODEF 0 "register_operand" ""))
14034    (use (match_operand:MODEF 1 "general_operand" ""))]
14035  "TARGET_USE_FANCY_MATH_387
14036    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14037        || TARGET_MIX_SSE_I387)
14038    && flag_unsafe_math_optimizations"
14039 {
14040   rtx op0 = gen_reg_rtx (XFmode);
14041   rtx op1 = gen_reg_rtx (XFmode);
14042
14043   if (optimize_insn_for_size_p ())
14044     FAIL;
14045
14046   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14047   emit_insn (gen_asinxf2 (op0, op1));
14048   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14049   DONE;
14050 })
14051
14052 (define_expand "acosxf2"
14053   [(set (match_dup 2)
14054         (mult:XF (match_operand:XF 1 "register_operand" "")
14055                  (match_dup 1)))
14056    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14057    (set (match_dup 5) (sqrt:XF (match_dup 4)))
14058    (parallel [(set (match_operand:XF 0 "register_operand" "")
14059                    (unspec:XF [(match_dup 1) (match_dup 5)]
14060                               UNSPEC_FPATAN))
14061               (clobber (match_scratch:XF 6 ""))])]
14062   "TARGET_USE_FANCY_MATH_387
14063    && flag_unsafe_math_optimizations"
14064 {
14065   int i;
14066
14067   if (optimize_insn_for_size_p ())
14068     FAIL;
14069
14070   for (i = 2; i < 6; i++)
14071     operands[i] = gen_reg_rtx (XFmode);
14072
14073   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
14074 })
14075
14076 (define_expand "acos<mode>2"
14077   [(use (match_operand:MODEF 0 "register_operand" ""))
14078    (use (match_operand:MODEF 1 "general_operand" ""))]
14079  "TARGET_USE_FANCY_MATH_387
14080    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14081        || TARGET_MIX_SSE_I387)
14082    && flag_unsafe_math_optimizations"
14083 {
14084   rtx op0 = gen_reg_rtx (XFmode);
14085   rtx op1 = gen_reg_rtx (XFmode);
14086
14087   if (optimize_insn_for_size_p ())
14088     FAIL;
14089
14090   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14091   emit_insn (gen_acosxf2 (op0, op1));
14092   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14093   DONE;
14094 })
14095
14096 (define_insn "fyl2xxf3_i387"
14097   [(set (match_operand:XF 0 "register_operand" "=f")
14098         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14099                     (match_operand:XF 2 "register_operand" "u")]
14100                    UNSPEC_FYL2X))
14101    (clobber (match_scratch:XF 3 "=2"))]
14102   "TARGET_USE_FANCY_MATH_387
14103    && flag_unsafe_math_optimizations"
14104   "fyl2x"
14105   [(set_attr "type" "fpspc")
14106    (set_attr "mode" "XF")])
14107
14108 (define_insn "fyl2x_extend<mode>xf3_i387"
14109   [(set (match_operand:XF 0 "register_operand" "=f")
14110         (unspec:XF [(float_extend:XF
14111                       (match_operand:MODEF 1 "register_operand" "0"))
14112                     (match_operand:XF 2 "register_operand" "u")]
14113                    UNSPEC_FYL2X))
14114    (clobber (match_scratch:XF 3 "=2"))]
14115   "TARGET_USE_FANCY_MATH_387
14116    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14117        || TARGET_MIX_SSE_I387)
14118    && flag_unsafe_math_optimizations"
14119   "fyl2x"
14120   [(set_attr "type" "fpspc")
14121    (set_attr "mode" "XF")])
14122
14123 (define_expand "logxf2"
14124   [(parallel [(set (match_operand:XF 0 "register_operand" "")
14125                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
14126                                (match_dup 2)] UNSPEC_FYL2X))
14127               (clobber (match_scratch:XF 3 ""))])]
14128   "TARGET_USE_FANCY_MATH_387
14129    && flag_unsafe_math_optimizations"
14130 {
14131   operands[2] = gen_reg_rtx (XFmode);
14132   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
14133 })
14134
14135 (define_expand "log<mode>2"
14136   [(use (match_operand:MODEF 0 "register_operand" ""))
14137    (use (match_operand:MODEF 1 "register_operand" ""))]
14138   "TARGET_USE_FANCY_MATH_387
14139    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14140        || TARGET_MIX_SSE_I387)
14141    && flag_unsafe_math_optimizations"
14142 {
14143   rtx op0 = gen_reg_rtx (XFmode);
14144
14145   rtx op2 = gen_reg_rtx (XFmode);
14146   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
14147
14148   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14149   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14150   DONE;
14151 })
14152
14153 (define_expand "log10xf2"
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 (3)); /* fldlg2 */
14163 })
14164
14165 (define_expand "log10<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 (3)); /* fldlg2 */
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 "log2xf2"
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], CONST1_RTX (XFmode)); /* fld1 */
14193 })
14194
14195 (define_expand "log2<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, CONST1_RTX (XFmode)); /* fld1 */
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_insn "fyl2xp1xf3_i387"
14214   [(set (match_operand:XF 0 "register_operand" "=f")
14215         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14216                     (match_operand:XF 2 "register_operand" "u")]
14217                    UNSPEC_FYL2XP1))
14218    (clobber (match_scratch:XF 3 "=2"))]
14219   "TARGET_USE_FANCY_MATH_387
14220    && flag_unsafe_math_optimizations"
14221   "fyl2xp1"
14222   [(set_attr "type" "fpspc")
14223    (set_attr "mode" "XF")])
14224
14225 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14226   [(set (match_operand:XF 0 "register_operand" "=f")
14227         (unspec:XF [(float_extend:XF
14228                       (match_operand:MODEF 1 "register_operand" "0"))
14229                     (match_operand:XF 2 "register_operand" "u")]
14230                    UNSPEC_FYL2XP1))
14231    (clobber (match_scratch:XF 3 "=2"))]
14232   "TARGET_USE_FANCY_MATH_387
14233    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14234        || TARGET_MIX_SSE_I387)
14235    && flag_unsafe_math_optimizations"
14236   "fyl2xp1"
14237   [(set_attr "type" "fpspc")
14238    (set_attr "mode" "XF")])
14239
14240 (define_expand "log1pxf2"
14241   [(use (match_operand:XF 0 "register_operand" ""))
14242    (use (match_operand:XF 1 "register_operand" ""))]
14243   "TARGET_USE_FANCY_MATH_387
14244    && flag_unsafe_math_optimizations"
14245 {
14246   if (optimize_insn_for_size_p ())
14247     FAIL;
14248
14249   ix86_emit_i387_log1p (operands[0], operands[1]);
14250   DONE;
14251 })
14252
14253 (define_expand "log1p<mode>2"
14254   [(use (match_operand:MODEF 0 "register_operand" ""))
14255    (use (match_operand:MODEF 1 "register_operand" ""))]
14256   "TARGET_USE_FANCY_MATH_387
14257    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14258        || TARGET_MIX_SSE_I387)
14259    && flag_unsafe_math_optimizations"
14260 {
14261   rtx op0;
14262
14263   if (optimize_insn_for_size_p ())
14264     FAIL;
14265
14266   op0 = gen_reg_rtx (XFmode);
14267
14268   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14269
14270   ix86_emit_i387_log1p (op0, operands[1]);
14271   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14272   DONE;
14273 })
14274
14275 (define_insn "fxtractxf3_i387"
14276   [(set (match_operand:XF 0 "register_operand" "=f")
14277         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14278                    UNSPEC_XTRACT_FRACT))
14279    (set (match_operand:XF 1 "register_operand" "=u")
14280         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14281   "TARGET_USE_FANCY_MATH_387
14282    && flag_unsafe_math_optimizations"
14283   "fxtract"
14284   [(set_attr "type" "fpspc")
14285    (set_attr "mode" "XF")])
14286
14287 (define_insn "fxtract_extend<mode>xf3_i387"
14288   [(set (match_operand:XF 0 "register_operand" "=f")
14289         (unspec:XF [(float_extend:XF
14290                       (match_operand:MODEF 2 "register_operand" "0"))]
14291                    UNSPEC_XTRACT_FRACT))
14292    (set (match_operand:XF 1 "register_operand" "=u")
14293         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14294   "TARGET_USE_FANCY_MATH_387
14295    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14296        || TARGET_MIX_SSE_I387)
14297    && flag_unsafe_math_optimizations"
14298   "fxtract"
14299   [(set_attr "type" "fpspc")
14300    (set_attr "mode" "XF")])
14301
14302 (define_expand "logbxf2"
14303   [(parallel [(set (match_dup 2)
14304                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14305                               UNSPEC_XTRACT_FRACT))
14306               (set (match_operand:XF 0 "register_operand" "")
14307                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14308   "TARGET_USE_FANCY_MATH_387
14309    && flag_unsafe_math_optimizations"
14310 {
14311   operands[2] = gen_reg_rtx (XFmode);
14312 })
14313
14314 (define_expand "logb<mode>2"
14315   [(use (match_operand:MODEF 0 "register_operand" ""))
14316    (use (match_operand:MODEF 1 "register_operand" ""))]
14317   "TARGET_USE_FANCY_MATH_387
14318    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14319        || TARGET_MIX_SSE_I387)
14320    && flag_unsafe_math_optimizations"
14321 {
14322   rtx op0 = gen_reg_rtx (XFmode);
14323   rtx op1 = gen_reg_rtx (XFmode);
14324
14325   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14326   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14327   DONE;
14328 })
14329
14330 (define_expand "ilogbxf2"
14331   [(use (match_operand:SI 0 "register_operand" ""))
14332    (use (match_operand:XF 1 "register_operand" ""))]
14333   "TARGET_USE_FANCY_MATH_387
14334    && flag_unsafe_math_optimizations"
14335 {
14336   rtx op0, op1;
14337
14338   if (optimize_insn_for_size_p ())
14339     FAIL;
14340
14341   op0 = gen_reg_rtx (XFmode);
14342   op1 = gen_reg_rtx (XFmode);
14343
14344   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14345   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14346   DONE;
14347 })
14348
14349 (define_expand "ilogb<mode>2"
14350   [(use (match_operand:SI 0 "register_operand" ""))
14351    (use (match_operand:MODEF 1 "register_operand" ""))]
14352   "TARGET_USE_FANCY_MATH_387
14353    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14354        || TARGET_MIX_SSE_I387)
14355    && flag_unsafe_math_optimizations"
14356 {
14357   rtx op0, op1;
14358
14359   if (optimize_insn_for_size_p ())
14360     FAIL;
14361
14362   op0 = gen_reg_rtx (XFmode);
14363   op1 = gen_reg_rtx (XFmode);
14364
14365   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14366   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14367   DONE;
14368 })
14369
14370 (define_insn "*f2xm1xf2_i387"
14371   [(set (match_operand:XF 0 "register_operand" "=f")
14372         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14373                    UNSPEC_F2XM1))]
14374   "TARGET_USE_FANCY_MATH_387
14375    && flag_unsafe_math_optimizations"
14376   "f2xm1"
14377   [(set_attr "type" "fpspc")
14378    (set_attr "mode" "XF")])
14379
14380 (define_insn "*fscalexf4_i387"
14381   [(set (match_operand:XF 0 "register_operand" "=f")
14382         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14383                     (match_operand:XF 3 "register_operand" "1")]
14384                    UNSPEC_FSCALE_FRACT))
14385    (set (match_operand:XF 1 "register_operand" "=u")
14386         (unspec:XF [(match_dup 2) (match_dup 3)]
14387                    UNSPEC_FSCALE_EXP))]
14388   "TARGET_USE_FANCY_MATH_387
14389    && flag_unsafe_math_optimizations"
14390   "fscale"
14391   [(set_attr "type" "fpspc")
14392    (set_attr "mode" "XF")])
14393
14394 (define_expand "expNcorexf3"
14395   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14396                                (match_operand:XF 2 "register_operand" "")))
14397    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14398    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14399    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14400    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14401    (parallel [(set (match_operand:XF 0 "register_operand" "")
14402                    (unspec:XF [(match_dup 8) (match_dup 4)]
14403                               UNSPEC_FSCALE_FRACT))
14404               (set (match_dup 9)
14405                    (unspec:XF [(match_dup 8) (match_dup 4)]
14406                               UNSPEC_FSCALE_EXP))])]
14407   "TARGET_USE_FANCY_MATH_387
14408    && flag_unsafe_math_optimizations"
14409 {
14410   int i;
14411
14412   if (optimize_insn_for_size_p ())
14413     FAIL;
14414
14415   for (i = 3; i < 10; i++)
14416     operands[i] = gen_reg_rtx (XFmode);
14417
14418   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
14419 })
14420
14421 (define_expand "expxf2"
14422   [(use (match_operand:XF 0 "register_operand" ""))
14423    (use (match_operand:XF 1 "register_operand" ""))]
14424   "TARGET_USE_FANCY_MATH_387
14425    && flag_unsafe_math_optimizations"
14426 {
14427   rtx op2;
14428
14429   if (optimize_insn_for_size_p ())
14430     FAIL;
14431
14432   op2 = gen_reg_rtx (XFmode);
14433   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14434
14435   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14436   DONE;
14437 })
14438
14439 (define_expand "exp<mode>2"
14440   [(use (match_operand:MODEF 0 "register_operand" ""))
14441    (use (match_operand:MODEF 1 "general_operand" ""))]
14442  "TARGET_USE_FANCY_MATH_387
14443    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14444        || TARGET_MIX_SSE_I387)
14445    && flag_unsafe_math_optimizations"
14446 {
14447   rtx op0, op1;
14448
14449   if (optimize_insn_for_size_p ())
14450     FAIL;
14451
14452   op0 = gen_reg_rtx (XFmode);
14453   op1 = gen_reg_rtx (XFmode);
14454
14455   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14456   emit_insn (gen_expxf2 (op0, op1));
14457   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14458   DONE;
14459 })
14460
14461 (define_expand "exp10xf2"
14462   [(use (match_operand:XF 0 "register_operand" ""))
14463    (use (match_operand:XF 1 "register_operand" ""))]
14464   "TARGET_USE_FANCY_MATH_387
14465    && flag_unsafe_math_optimizations"
14466 {
14467   rtx op2;
14468
14469   if (optimize_insn_for_size_p ())
14470     FAIL;
14471
14472   op2 = gen_reg_rtx (XFmode);
14473   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14474
14475   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14476   DONE;
14477 })
14478
14479 (define_expand "exp10<mode>2"
14480   [(use (match_operand:MODEF 0 "register_operand" ""))
14481    (use (match_operand:MODEF 1 "general_operand" ""))]
14482  "TARGET_USE_FANCY_MATH_387
14483    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14484        || TARGET_MIX_SSE_I387)
14485    && flag_unsafe_math_optimizations"
14486 {
14487   rtx op0, op1;
14488
14489   if (optimize_insn_for_size_p ())
14490     FAIL;
14491
14492   op0 = gen_reg_rtx (XFmode);
14493   op1 = gen_reg_rtx (XFmode);
14494
14495   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14496   emit_insn (gen_exp10xf2 (op0, op1));
14497   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14498   DONE;
14499 })
14500
14501 (define_expand "exp2xf2"
14502   [(use (match_operand:XF 0 "register_operand" ""))
14503    (use (match_operand:XF 1 "register_operand" ""))]
14504   "TARGET_USE_FANCY_MATH_387
14505    && flag_unsafe_math_optimizations"
14506 {
14507   rtx op2;
14508
14509   if (optimize_insn_for_size_p ())
14510     FAIL;
14511
14512   op2 = gen_reg_rtx (XFmode);
14513   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
14514
14515   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14516   DONE;
14517 })
14518
14519 (define_expand "exp2<mode>2"
14520   [(use (match_operand:MODEF 0 "register_operand" ""))
14521    (use (match_operand:MODEF 1 "general_operand" ""))]
14522  "TARGET_USE_FANCY_MATH_387
14523    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14524        || TARGET_MIX_SSE_I387)
14525    && flag_unsafe_math_optimizations"
14526 {
14527   rtx op0, op1;
14528
14529   if (optimize_insn_for_size_p ())
14530     FAIL;
14531
14532   op0 = gen_reg_rtx (XFmode);
14533   op1 = gen_reg_rtx (XFmode);
14534
14535   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14536   emit_insn (gen_exp2xf2 (op0, op1));
14537   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14538   DONE;
14539 })
14540
14541 (define_expand "expm1xf2"
14542   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14543                                (match_dup 2)))
14544    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14545    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14546    (set (match_dup 9) (float_extend:XF (match_dup 13)))
14547    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14548    (parallel [(set (match_dup 7)
14549                    (unspec:XF [(match_dup 6) (match_dup 4)]
14550                               UNSPEC_FSCALE_FRACT))
14551               (set (match_dup 8)
14552                    (unspec:XF [(match_dup 6) (match_dup 4)]
14553                               UNSPEC_FSCALE_EXP))])
14554    (parallel [(set (match_dup 10)
14555                    (unspec:XF [(match_dup 9) (match_dup 8)]
14556                               UNSPEC_FSCALE_FRACT))
14557               (set (match_dup 11)
14558                    (unspec:XF [(match_dup 9) (match_dup 8)]
14559                               UNSPEC_FSCALE_EXP))])
14560    (set (match_dup 12) (minus:XF (match_dup 10)
14561                                  (float_extend:XF (match_dup 13))))
14562    (set (match_operand:XF 0 "register_operand" "")
14563         (plus:XF (match_dup 12) (match_dup 7)))]
14564   "TARGET_USE_FANCY_MATH_387
14565    && flag_unsafe_math_optimizations"
14566 {
14567   int i;
14568
14569   if (optimize_insn_for_size_p ())
14570     FAIL;
14571
14572   for (i = 2; i < 13; i++)
14573     operands[i] = gen_reg_rtx (XFmode);
14574
14575   operands[13]
14576     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14577
14578   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14579 })
14580
14581 (define_expand "expm1<mode>2"
14582   [(use (match_operand:MODEF 0 "register_operand" ""))
14583    (use (match_operand:MODEF 1 "general_operand" ""))]
14584  "TARGET_USE_FANCY_MATH_387
14585    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14586        || TARGET_MIX_SSE_I387)
14587    && flag_unsafe_math_optimizations"
14588 {
14589   rtx op0, op1;
14590
14591   if (optimize_insn_for_size_p ())
14592     FAIL;
14593
14594   op0 = gen_reg_rtx (XFmode);
14595   op1 = gen_reg_rtx (XFmode);
14596
14597   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14598   emit_insn (gen_expm1xf2 (op0, op1));
14599   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14600   DONE;
14601 })
14602
14603 (define_expand "ldexpxf3"
14604   [(set (match_dup 3)
14605         (float:XF (match_operand:SI 2 "register_operand" "")))
14606    (parallel [(set (match_operand:XF 0 " register_operand" "")
14607                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
14608                                (match_dup 3)]
14609                               UNSPEC_FSCALE_FRACT))
14610               (set (match_dup 4)
14611                    (unspec:XF [(match_dup 1) (match_dup 3)]
14612                               UNSPEC_FSCALE_EXP))])]
14613   "TARGET_USE_FANCY_MATH_387
14614    && flag_unsafe_math_optimizations"
14615 {
14616   if (optimize_insn_for_size_p ())
14617     FAIL;
14618
14619   operands[3] = gen_reg_rtx (XFmode);
14620   operands[4] = gen_reg_rtx (XFmode);
14621 })
14622
14623 (define_expand "ldexp<mode>3"
14624   [(use (match_operand:MODEF 0 "register_operand" ""))
14625    (use (match_operand:MODEF 1 "general_operand" ""))
14626    (use (match_operand:SI 2 "register_operand" ""))]
14627  "TARGET_USE_FANCY_MATH_387
14628    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14629        || TARGET_MIX_SSE_I387)
14630    && flag_unsafe_math_optimizations"
14631 {
14632   rtx op0, op1;
14633
14634   if (optimize_insn_for_size_p ())
14635     FAIL;
14636
14637   op0 = gen_reg_rtx (XFmode);
14638   op1 = gen_reg_rtx (XFmode);
14639
14640   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14641   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14642   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14643   DONE;
14644 })
14645
14646 (define_expand "scalbxf3"
14647   [(parallel [(set (match_operand:XF 0 " register_operand" "")
14648                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
14649                                (match_operand:XF 2 "register_operand" "")]
14650                               UNSPEC_FSCALE_FRACT))
14651               (set (match_dup 3)
14652                    (unspec:XF [(match_dup 1) (match_dup 2)]
14653                               UNSPEC_FSCALE_EXP))])]
14654   "TARGET_USE_FANCY_MATH_387
14655    && flag_unsafe_math_optimizations"
14656 {
14657   if (optimize_insn_for_size_p ())
14658     FAIL;
14659
14660   operands[3] = gen_reg_rtx (XFmode);
14661 })
14662
14663 (define_expand "scalb<mode>3"
14664   [(use (match_operand:MODEF 0 "register_operand" ""))
14665    (use (match_operand:MODEF 1 "general_operand" ""))
14666    (use (match_operand:MODEF 2 "general_operand" ""))]
14667  "TARGET_USE_FANCY_MATH_387
14668    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14669        || TARGET_MIX_SSE_I387)
14670    && flag_unsafe_math_optimizations"
14671 {
14672   rtx op0, op1, op2;
14673
14674   if (optimize_insn_for_size_p ())
14675     FAIL;
14676
14677   op0 = gen_reg_rtx (XFmode);
14678   op1 = gen_reg_rtx (XFmode);
14679   op2 = gen_reg_rtx (XFmode);
14680
14681   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14682   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14683   emit_insn (gen_scalbxf3 (op0, op1, op2));
14684   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14685   DONE;
14686 })
14687
14688 (define_expand "significandxf2"
14689   [(parallel [(set (match_operand:XF 0 "register_operand" "")
14690                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14691                               UNSPEC_XTRACT_FRACT))
14692               (set (match_dup 2)
14693                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14694   "TARGET_USE_FANCY_MATH_387
14695    && flag_unsafe_math_optimizations"
14696 {
14697   operands[2] = gen_reg_rtx (XFmode);
14698 })
14699
14700 (define_expand "significand<mode>2"
14701   [(use (match_operand:MODEF 0 "register_operand" ""))
14702    (use (match_operand:MODEF 1 "register_operand" ""))]
14703   "TARGET_USE_FANCY_MATH_387
14704    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14705        || TARGET_MIX_SSE_I387)
14706    && flag_unsafe_math_optimizations"
14707 {
14708   rtx op0 = gen_reg_rtx (XFmode);
14709   rtx op1 = gen_reg_rtx (XFmode);
14710
14711   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14712   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14713   DONE;
14714 })
14715 \f
14716
14717 (define_insn "sse4_1_round<mode>2"
14718   [(set (match_operand:MODEF 0 "register_operand" "=x")
14719         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14720                        (match_operand:SI 2 "const_0_to_15_operand" "n")]
14721                       UNSPEC_ROUND))]
14722   "TARGET_ROUND"
14723   "%vrounds<ssemodefsuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14724   [(set_attr "type" "ssecvt")
14725    (set_attr "prefix_extra" "1")
14726    (set_attr "prefix" "maybe_vex")
14727    (set_attr "mode" "<MODE>")])
14728
14729 (define_insn "rintxf2"
14730   [(set (match_operand:XF 0 "register_operand" "=f")
14731         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14732                    UNSPEC_FRNDINT))]
14733   "TARGET_USE_FANCY_MATH_387
14734    && flag_unsafe_math_optimizations"
14735   "frndint"
14736   [(set_attr "type" "fpspc")
14737    (set_attr "mode" "XF")])
14738
14739 (define_expand "rint<mode>2"
14740   [(use (match_operand:MODEF 0 "register_operand" ""))
14741    (use (match_operand:MODEF 1 "register_operand" ""))]
14742   "(TARGET_USE_FANCY_MATH_387
14743     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14744         || TARGET_MIX_SSE_I387)
14745     && flag_unsafe_math_optimizations)
14746    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14747        && !flag_trapping_math)"
14748 {
14749   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14750       && !flag_trapping_math)
14751     {
14752       if (!TARGET_ROUND && optimize_insn_for_size_p ())
14753         FAIL;
14754       if (TARGET_ROUND)
14755         emit_insn (gen_sse4_1_round<mode>2
14756                    (operands[0], operands[1], GEN_INT (0x04)));
14757       else
14758         ix86_expand_rint (operand0, operand1);
14759     }
14760   else
14761     {
14762       rtx op0 = gen_reg_rtx (XFmode);
14763       rtx op1 = gen_reg_rtx (XFmode);
14764
14765       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14766       emit_insn (gen_rintxf2 (op0, op1));
14767
14768       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14769     }
14770   DONE;
14771 })
14772
14773 (define_expand "round<mode>2"
14774   [(match_operand:MODEF 0 "register_operand" "")
14775    (match_operand:MODEF 1 "nonimmediate_operand" "")]
14776   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14777    && !flag_trapping_math && !flag_rounding_math"
14778 {
14779   if (optimize_insn_for_size_p ())
14780     FAIL;
14781   if (TARGET_64BIT || (<MODE>mode != DFmode))
14782     ix86_expand_round (operand0, operand1);
14783   else
14784     ix86_expand_rounddf_32 (operand0, operand1);
14785   DONE;
14786 })
14787
14788 (define_insn_and_split "*fistdi2_1"
14789   [(set (match_operand:DI 0 "nonimmediate_operand" "")
14790         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14791                    UNSPEC_FIST))]
14792   "TARGET_USE_FANCY_MATH_387
14793    && can_create_pseudo_p ()"
14794   "#"
14795   "&& 1"
14796   [(const_int 0)]
14797 {
14798   if (memory_operand (operands[0], VOIDmode))
14799     emit_insn (gen_fistdi2 (operands[0], operands[1]));
14800   else
14801     {
14802       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14803       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14804                                          operands[2]));
14805     }
14806   DONE;
14807 }
14808   [(set_attr "type" "fpspc")
14809    (set_attr "mode" "DI")])
14810
14811 (define_insn "fistdi2"
14812   [(set (match_operand:DI 0 "memory_operand" "=m")
14813         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14814                    UNSPEC_FIST))
14815    (clobber (match_scratch:XF 2 "=&1f"))]
14816   "TARGET_USE_FANCY_MATH_387"
14817   "* return output_fix_trunc (insn, operands, 0);"
14818   [(set_attr "type" "fpspc")
14819    (set_attr "mode" "DI")])
14820
14821 (define_insn "fistdi2_with_temp"
14822   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14823         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14824                    UNSPEC_FIST))
14825    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14826    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14827   "TARGET_USE_FANCY_MATH_387"
14828   "#"
14829   [(set_attr "type" "fpspc")
14830    (set_attr "mode" "DI")])
14831
14832 (define_split
14833   [(set (match_operand:DI 0 "register_operand" "")
14834         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14835                    UNSPEC_FIST))
14836    (clobber (match_operand:DI 2 "memory_operand" ""))
14837    (clobber (match_scratch 3 ""))]
14838   "reload_completed"
14839   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14840               (clobber (match_dup 3))])
14841    (set (match_dup 0) (match_dup 2))]
14842   "")
14843
14844 (define_split
14845   [(set (match_operand:DI 0 "memory_operand" "")
14846         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14847                    UNSPEC_FIST))
14848    (clobber (match_operand:DI 2 "memory_operand" ""))
14849    (clobber (match_scratch 3 ""))]
14850   "reload_completed"
14851   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14852               (clobber (match_dup 3))])]
14853   "")
14854
14855 (define_insn_and_split "*fist<mode>2_1"
14856   [(set (match_operand:X87MODEI12 0 "register_operand" "")
14857         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14858                            UNSPEC_FIST))]
14859   "TARGET_USE_FANCY_MATH_387
14860    && can_create_pseudo_p ()"
14861   "#"
14862   "&& 1"
14863   [(const_int 0)]
14864 {
14865   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14866   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14867                                         operands[2]));
14868   DONE;
14869 }
14870   [(set_attr "type" "fpspc")
14871    (set_attr "mode" "<MODE>")])
14872
14873 (define_insn "fist<mode>2"
14874   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14875         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14876                            UNSPEC_FIST))]
14877   "TARGET_USE_FANCY_MATH_387"
14878   "* return output_fix_trunc (insn, operands, 0);"
14879   [(set_attr "type" "fpspc")
14880    (set_attr "mode" "<MODE>")])
14881
14882 (define_insn "fist<mode>2_with_temp"
14883   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
14884         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14885                            UNSPEC_FIST))
14886    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
14887   "TARGET_USE_FANCY_MATH_387"
14888   "#"
14889   [(set_attr "type" "fpspc")
14890    (set_attr "mode" "<MODE>")])
14891
14892 (define_split
14893   [(set (match_operand:X87MODEI12 0 "register_operand" "")
14894         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14895                            UNSPEC_FIST))
14896    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14897   "reload_completed"
14898   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
14899    (set (match_dup 0) (match_dup 2))]
14900   "")
14901
14902 (define_split
14903   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14904         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14905                            UNSPEC_FIST))
14906    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14907   "reload_completed"
14908   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
14909   "")
14910
14911 (define_expand "lrintxf<mode>2"
14912   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14913      (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14914                       UNSPEC_FIST))]
14915   "TARGET_USE_FANCY_MATH_387"
14916   "")
14917
14918 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
14919   [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14920      (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
14921                         UNSPEC_FIX_NOTRUNC))]
14922   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14923    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
14924   "")
14925
14926 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
14927   [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14928    (match_operand:MODEF 1 "register_operand" "")]
14929   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14930    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
14931    && !flag_trapping_math && !flag_rounding_math"
14932 {
14933   if (optimize_insn_for_size_p ())
14934     FAIL;
14935   ix86_expand_lround (operand0, operand1);
14936   DONE;
14937 })
14938
14939 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14940 (define_insn_and_split "frndintxf2_floor"
14941   [(set (match_operand:XF 0 "register_operand" "")
14942         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14943          UNSPEC_FRNDINT_FLOOR))
14944    (clobber (reg:CC FLAGS_REG))]
14945   "TARGET_USE_FANCY_MATH_387
14946    && flag_unsafe_math_optimizations
14947    && can_create_pseudo_p ()"
14948   "#"
14949   "&& 1"
14950   [(const_int 0)]
14951 {
14952   ix86_optimize_mode_switching[I387_FLOOR] = 1;
14953
14954   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14955   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14956
14957   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14958                                         operands[2], operands[3]));
14959   DONE;
14960 }
14961   [(set_attr "type" "frndint")
14962    (set_attr "i387_cw" "floor")
14963    (set_attr "mode" "XF")])
14964
14965 (define_insn "frndintxf2_floor_i387"
14966   [(set (match_operand:XF 0 "register_operand" "=f")
14967         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14968          UNSPEC_FRNDINT_FLOOR))
14969    (use (match_operand:HI 2 "memory_operand" "m"))
14970    (use (match_operand:HI 3 "memory_operand" "m"))]
14971   "TARGET_USE_FANCY_MATH_387
14972    && flag_unsafe_math_optimizations"
14973   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14974   [(set_attr "type" "frndint")
14975    (set_attr "i387_cw" "floor")
14976    (set_attr "mode" "XF")])
14977
14978 (define_expand "floorxf2"
14979   [(use (match_operand:XF 0 "register_operand" ""))
14980    (use (match_operand:XF 1 "register_operand" ""))]
14981   "TARGET_USE_FANCY_MATH_387
14982    && flag_unsafe_math_optimizations"
14983 {
14984   if (optimize_insn_for_size_p ())
14985     FAIL;
14986   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14987   DONE;
14988 })
14989
14990 (define_expand "floor<mode>2"
14991   [(use (match_operand:MODEF 0 "register_operand" ""))
14992    (use (match_operand:MODEF 1 "register_operand" ""))]
14993   "(TARGET_USE_FANCY_MATH_387
14994     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14995         || TARGET_MIX_SSE_I387)
14996     && flag_unsafe_math_optimizations)
14997    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14998        && !flag_trapping_math)"
14999 {
15000   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15001       && !flag_trapping_math
15002       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
15003     {
15004       if (!TARGET_ROUND && optimize_insn_for_size_p ())
15005         FAIL;
15006       if (TARGET_ROUND)
15007         emit_insn (gen_sse4_1_round<mode>2
15008                    (operands[0], operands[1], GEN_INT (0x01)));
15009       else if (TARGET_64BIT || (<MODE>mode != DFmode))
15010         ix86_expand_floorceil (operand0, operand1, true);
15011       else
15012         ix86_expand_floorceildf_32 (operand0, operand1, true);
15013     }
15014   else
15015     {
15016       rtx op0, op1;
15017
15018       if (optimize_insn_for_size_p ())
15019         FAIL;
15020
15021       op0 = gen_reg_rtx (XFmode);
15022       op1 = gen_reg_rtx (XFmode);
15023       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15024       emit_insn (gen_frndintxf2_floor (op0, op1));
15025
15026       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15027     }
15028   DONE;
15029 })
15030
15031 (define_insn_and_split "*fist<mode>2_floor_1"
15032   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
15033         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
15034          UNSPEC_FIST_FLOOR))
15035    (clobber (reg:CC FLAGS_REG))]
15036   "TARGET_USE_FANCY_MATH_387
15037    && flag_unsafe_math_optimizations
15038    && can_create_pseudo_p ()"
15039   "#"
15040   "&& 1"
15041   [(const_int 0)]
15042 {
15043   ix86_optimize_mode_switching[I387_FLOOR] = 1;
15044
15045   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15046   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
15047   if (memory_operand (operands[0], VOIDmode))
15048     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
15049                                       operands[2], operands[3]));
15050   else
15051     {
15052       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15053       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
15054                                                   operands[2], operands[3],
15055                                                   operands[4]));
15056     }
15057   DONE;
15058 }
15059   [(set_attr "type" "fistp")
15060    (set_attr "i387_cw" "floor")
15061    (set_attr "mode" "<MODE>")])
15062
15063 (define_insn "fistdi2_floor"
15064   [(set (match_operand:DI 0 "memory_operand" "=m")
15065         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15066          UNSPEC_FIST_FLOOR))
15067    (use (match_operand:HI 2 "memory_operand" "m"))
15068    (use (match_operand:HI 3 "memory_operand" "m"))
15069    (clobber (match_scratch:XF 4 "=&1f"))]
15070   "TARGET_USE_FANCY_MATH_387
15071    && flag_unsafe_math_optimizations"
15072   "* return output_fix_trunc (insn, operands, 0);"
15073   [(set_attr "type" "fistp")
15074    (set_attr "i387_cw" "floor")
15075    (set_attr "mode" "DI")])
15076
15077 (define_insn "fistdi2_floor_with_temp"
15078   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15079         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15080          UNSPEC_FIST_FLOOR))
15081    (use (match_operand:HI 2 "memory_operand" "m,m"))
15082    (use (match_operand:HI 3 "memory_operand" "m,m"))
15083    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15084    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15085   "TARGET_USE_FANCY_MATH_387
15086    && flag_unsafe_math_optimizations"
15087   "#"
15088   [(set_attr "type" "fistp")
15089    (set_attr "i387_cw" "floor")
15090    (set_attr "mode" "DI")])
15091
15092 (define_split
15093   [(set (match_operand:DI 0 "register_operand" "")
15094         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15095          UNSPEC_FIST_FLOOR))
15096    (use (match_operand:HI 2 "memory_operand" ""))
15097    (use (match_operand:HI 3 "memory_operand" ""))
15098    (clobber (match_operand:DI 4 "memory_operand" ""))
15099    (clobber (match_scratch 5 ""))]
15100   "reload_completed"
15101   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
15102               (use (match_dup 2))
15103               (use (match_dup 3))
15104               (clobber (match_dup 5))])
15105    (set (match_dup 0) (match_dup 4))]
15106   "")
15107
15108 (define_split
15109   [(set (match_operand:DI 0 "memory_operand" "")
15110         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15111          UNSPEC_FIST_FLOOR))
15112    (use (match_operand:HI 2 "memory_operand" ""))
15113    (use (match_operand:HI 3 "memory_operand" ""))
15114    (clobber (match_operand:DI 4 "memory_operand" ""))
15115    (clobber (match_scratch 5 ""))]
15116   "reload_completed"
15117   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
15118               (use (match_dup 2))
15119               (use (match_dup 3))
15120               (clobber (match_dup 5))])]
15121   "")
15122
15123 (define_insn "fist<mode>2_floor"
15124   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
15125         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
15126          UNSPEC_FIST_FLOOR))
15127    (use (match_operand:HI 2 "memory_operand" "m"))
15128    (use (match_operand:HI 3 "memory_operand" "m"))]
15129   "TARGET_USE_FANCY_MATH_387
15130    && flag_unsafe_math_optimizations"
15131   "* return output_fix_trunc (insn, operands, 0);"
15132   [(set_attr "type" "fistp")
15133    (set_attr "i387_cw" "floor")
15134    (set_attr "mode" "<MODE>")])
15135
15136 (define_insn "fist<mode>2_floor_with_temp"
15137   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
15138         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
15139          UNSPEC_FIST_FLOOR))
15140    (use (match_operand:HI 2 "memory_operand" "m,m"))
15141    (use (match_operand:HI 3 "memory_operand" "m,m"))
15142    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
15143   "TARGET_USE_FANCY_MATH_387
15144    && flag_unsafe_math_optimizations"
15145   "#"
15146   [(set_attr "type" "fistp")
15147    (set_attr "i387_cw" "floor")
15148    (set_attr "mode" "<MODE>")])
15149
15150 (define_split
15151   [(set (match_operand:X87MODEI12 0 "register_operand" "")
15152         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
15153          UNSPEC_FIST_FLOOR))
15154    (use (match_operand:HI 2 "memory_operand" ""))
15155    (use (match_operand:HI 3 "memory_operand" ""))
15156    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
15157   "reload_completed"
15158   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
15159                                   UNSPEC_FIST_FLOOR))
15160               (use (match_dup 2))
15161               (use (match_dup 3))])
15162    (set (match_dup 0) (match_dup 4))]
15163   "")
15164
15165 (define_split
15166   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
15167         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
15168          UNSPEC_FIST_FLOOR))
15169    (use (match_operand:HI 2 "memory_operand" ""))
15170    (use (match_operand:HI 3 "memory_operand" ""))
15171    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
15172   "reload_completed"
15173   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
15174                                   UNSPEC_FIST_FLOOR))
15175               (use (match_dup 2))
15176               (use (match_dup 3))])]
15177   "")
15178
15179 (define_expand "lfloorxf<mode>2"
15180   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
15181                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
15182                     UNSPEC_FIST_FLOOR))
15183               (clobber (reg:CC FLAGS_REG))])]
15184   "TARGET_USE_FANCY_MATH_387
15185    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15186    && flag_unsafe_math_optimizations"
15187   "")
15188
15189 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
15190   [(match_operand:SWI48 0 "nonimmediate_operand" "")
15191    (match_operand:MODEF 1 "register_operand" "")]
15192   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15193    && !flag_trapping_math"
15194 {
15195   if (TARGET_64BIT && optimize_insn_for_size_p ())
15196     FAIL;
15197   ix86_expand_lfloorceil (operand0, operand1, true);
15198   DONE;
15199 })
15200
15201 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15202 (define_insn_and_split "frndintxf2_ceil"
15203   [(set (match_operand:XF 0 "register_operand" "")
15204         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15205          UNSPEC_FRNDINT_CEIL))
15206    (clobber (reg:CC FLAGS_REG))]
15207   "TARGET_USE_FANCY_MATH_387
15208    && flag_unsafe_math_optimizations
15209    && can_create_pseudo_p ()"
15210   "#"
15211   "&& 1"
15212   [(const_int 0)]
15213 {
15214   ix86_optimize_mode_switching[I387_CEIL] = 1;
15215
15216   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15217   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15218
15219   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
15220                                        operands[2], operands[3]));
15221   DONE;
15222 }
15223   [(set_attr "type" "frndint")
15224    (set_attr "i387_cw" "ceil")
15225    (set_attr "mode" "XF")])
15226
15227 (define_insn "frndintxf2_ceil_i387"
15228   [(set (match_operand:XF 0 "register_operand" "=f")
15229         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15230          UNSPEC_FRNDINT_CEIL))
15231    (use (match_operand:HI 2 "memory_operand" "m"))
15232    (use (match_operand:HI 3 "memory_operand" "m"))]
15233   "TARGET_USE_FANCY_MATH_387
15234    && flag_unsafe_math_optimizations"
15235   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15236   [(set_attr "type" "frndint")
15237    (set_attr "i387_cw" "ceil")
15238    (set_attr "mode" "XF")])
15239
15240 (define_expand "ceilxf2"
15241   [(use (match_operand:XF 0 "register_operand" ""))
15242    (use (match_operand:XF 1 "register_operand" ""))]
15243   "TARGET_USE_FANCY_MATH_387
15244    && flag_unsafe_math_optimizations"
15245 {
15246   if (optimize_insn_for_size_p ())
15247     FAIL;
15248   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
15249   DONE;
15250 })
15251
15252 (define_expand "ceil<mode>2"
15253   [(use (match_operand:MODEF 0 "register_operand" ""))
15254    (use (match_operand:MODEF 1 "register_operand" ""))]
15255   "(TARGET_USE_FANCY_MATH_387
15256     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15257         || TARGET_MIX_SSE_I387)
15258     && flag_unsafe_math_optimizations)
15259    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15260        && !flag_trapping_math)"
15261 {
15262   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15263       && !flag_trapping_math
15264       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
15265     {
15266       if (TARGET_ROUND)
15267         emit_insn (gen_sse4_1_round<mode>2
15268                    (operands[0], operands[1], GEN_INT (0x02)));
15269       else if (optimize_insn_for_size_p ())
15270         FAIL;
15271       else if (TARGET_64BIT || (<MODE>mode != DFmode))
15272         ix86_expand_floorceil (operand0, operand1, false);
15273       else
15274         ix86_expand_floorceildf_32 (operand0, operand1, false);
15275     }
15276   else
15277     {
15278       rtx op0, op1;
15279
15280       if (optimize_insn_for_size_p ())
15281         FAIL;
15282
15283       op0 = gen_reg_rtx (XFmode);
15284       op1 = gen_reg_rtx (XFmode);
15285       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15286       emit_insn (gen_frndintxf2_ceil (op0, op1));
15287
15288       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15289     }
15290   DONE;
15291 })
15292
15293 (define_insn_and_split "*fist<mode>2_ceil_1"
15294   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
15295         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
15296          UNSPEC_FIST_CEIL))
15297    (clobber (reg:CC FLAGS_REG))]
15298   "TARGET_USE_FANCY_MATH_387
15299    && flag_unsafe_math_optimizations
15300    && can_create_pseudo_p ()"
15301   "#"
15302   "&& 1"
15303   [(const_int 0)]
15304 {
15305   ix86_optimize_mode_switching[I387_CEIL] = 1;
15306
15307   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15308   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15309   if (memory_operand (operands[0], VOIDmode))
15310     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
15311                                      operands[2], operands[3]));
15312   else
15313     {
15314       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15315       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
15316                                                  operands[2], operands[3],
15317                                                  operands[4]));
15318     }
15319   DONE;
15320 }
15321   [(set_attr "type" "fistp")
15322    (set_attr "i387_cw" "ceil")
15323    (set_attr "mode" "<MODE>")])
15324
15325 (define_insn "fistdi2_ceil"
15326   [(set (match_operand:DI 0 "memory_operand" "=m")
15327         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15328          UNSPEC_FIST_CEIL))
15329    (use (match_operand:HI 2 "memory_operand" "m"))
15330    (use (match_operand:HI 3 "memory_operand" "m"))
15331    (clobber (match_scratch:XF 4 "=&1f"))]
15332   "TARGET_USE_FANCY_MATH_387
15333    && flag_unsafe_math_optimizations"
15334   "* return output_fix_trunc (insn, operands, 0);"
15335   [(set_attr "type" "fistp")
15336    (set_attr "i387_cw" "ceil")
15337    (set_attr "mode" "DI")])
15338
15339 (define_insn "fistdi2_ceil_with_temp"
15340   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15341         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15342          UNSPEC_FIST_CEIL))
15343    (use (match_operand:HI 2 "memory_operand" "m,m"))
15344    (use (match_operand:HI 3 "memory_operand" "m,m"))
15345    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15346    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15347   "TARGET_USE_FANCY_MATH_387
15348    && flag_unsafe_math_optimizations"
15349   "#"
15350   [(set_attr "type" "fistp")
15351    (set_attr "i387_cw" "ceil")
15352    (set_attr "mode" "DI")])
15353
15354 (define_split
15355   [(set (match_operand:DI 0 "register_operand" "")
15356         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15357          UNSPEC_FIST_CEIL))
15358    (use (match_operand:HI 2 "memory_operand" ""))
15359    (use (match_operand:HI 3 "memory_operand" ""))
15360    (clobber (match_operand:DI 4 "memory_operand" ""))
15361    (clobber (match_scratch 5 ""))]
15362   "reload_completed"
15363   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15364               (use (match_dup 2))
15365               (use (match_dup 3))
15366               (clobber (match_dup 5))])
15367    (set (match_dup 0) (match_dup 4))]
15368   "")
15369
15370 (define_split
15371   [(set (match_operand:DI 0 "memory_operand" "")
15372         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15373          UNSPEC_FIST_CEIL))
15374    (use (match_operand:HI 2 "memory_operand" ""))
15375    (use (match_operand:HI 3 "memory_operand" ""))
15376    (clobber (match_operand:DI 4 "memory_operand" ""))
15377    (clobber (match_scratch 5 ""))]
15378   "reload_completed"
15379   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15380               (use (match_dup 2))
15381               (use (match_dup 3))
15382               (clobber (match_dup 5))])]
15383   "")
15384
15385 (define_insn "fist<mode>2_ceil"
15386   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
15387         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
15388          UNSPEC_FIST_CEIL))
15389    (use (match_operand:HI 2 "memory_operand" "m"))
15390    (use (match_operand:HI 3 "memory_operand" "m"))]
15391   "TARGET_USE_FANCY_MATH_387
15392    && flag_unsafe_math_optimizations"
15393   "* return output_fix_trunc (insn, operands, 0);"
15394   [(set_attr "type" "fistp")
15395    (set_attr "i387_cw" "ceil")
15396    (set_attr "mode" "<MODE>")])
15397
15398 (define_insn "fist<mode>2_ceil_with_temp"
15399   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
15400         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
15401          UNSPEC_FIST_CEIL))
15402    (use (match_operand:HI 2 "memory_operand" "m,m"))
15403    (use (match_operand:HI 3 "memory_operand" "m,m"))
15404    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
15405   "TARGET_USE_FANCY_MATH_387
15406    && flag_unsafe_math_optimizations"
15407   "#"
15408   [(set_attr "type" "fistp")
15409    (set_attr "i387_cw" "ceil")
15410    (set_attr "mode" "<MODE>")])
15411
15412 (define_split
15413   [(set (match_operand:X87MODEI12 0 "register_operand" "")
15414         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
15415          UNSPEC_FIST_CEIL))
15416    (use (match_operand:HI 2 "memory_operand" ""))
15417    (use (match_operand:HI 3 "memory_operand" ""))
15418    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
15419   "reload_completed"
15420   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
15421                                   UNSPEC_FIST_CEIL))
15422               (use (match_dup 2))
15423               (use (match_dup 3))])
15424    (set (match_dup 0) (match_dup 4))]
15425   "")
15426
15427 (define_split
15428   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
15429         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
15430          UNSPEC_FIST_CEIL))
15431    (use (match_operand:HI 2 "memory_operand" ""))
15432    (use (match_operand:HI 3 "memory_operand" ""))
15433    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
15434   "reload_completed"
15435   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
15436                                   UNSPEC_FIST_CEIL))
15437               (use (match_dup 2))
15438               (use (match_dup 3))])]
15439   "")
15440
15441 (define_expand "lceilxf<mode>2"
15442   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
15443                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
15444                     UNSPEC_FIST_CEIL))
15445               (clobber (reg:CC FLAGS_REG))])]
15446   "TARGET_USE_FANCY_MATH_387
15447    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15448    && flag_unsafe_math_optimizations"
15449   "")
15450
15451 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
15452   [(match_operand:SWI48 0 "nonimmediate_operand" "")
15453    (match_operand:MODEF 1 "register_operand" "")]
15454   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15455    && !flag_trapping_math"
15456 {
15457   ix86_expand_lfloorceil (operand0, operand1, false);
15458   DONE;
15459 })
15460
15461 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15462 (define_insn_and_split "frndintxf2_trunc"
15463   [(set (match_operand:XF 0 "register_operand" "")
15464         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15465          UNSPEC_FRNDINT_TRUNC))
15466    (clobber (reg:CC FLAGS_REG))]
15467   "TARGET_USE_FANCY_MATH_387
15468    && flag_unsafe_math_optimizations
15469    && can_create_pseudo_p ()"
15470   "#"
15471   "&& 1"
15472   [(const_int 0)]
15473 {
15474   ix86_optimize_mode_switching[I387_TRUNC] = 1;
15475
15476   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15477   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
15478
15479   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
15480                                         operands[2], operands[3]));
15481   DONE;
15482 }
15483   [(set_attr "type" "frndint")
15484    (set_attr "i387_cw" "trunc")
15485    (set_attr "mode" "XF")])
15486
15487 (define_insn "frndintxf2_trunc_i387"
15488   [(set (match_operand:XF 0 "register_operand" "=f")
15489         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15490          UNSPEC_FRNDINT_TRUNC))
15491    (use (match_operand:HI 2 "memory_operand" "m"))
15492    (use (match_operand:HI 3 "memory_operand" "m"))]
15493   "TARGET_USE_FANCY_MATH_387
15494    && flag_unsafe_math_optimizations"
15495   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15496   [(set_attr "type" "frndint")
15497    (set_attr "i387_cw" "trunc")
15498    (set_attr "mode" "XF")])
15499
15500 (define_expand "btruncxf2"
15501   [(use (match_operand:XF 0 "register_operand" ""))
15502    (use (match_operand:XF 1 "register_operand" ""))]
15503   "TARGET_USE_FANCY_MATH_387
15504    && flag_unsafe_math_optimizations"
15505 {
15506   if (optimize_insn_for_size_p ())
15507     FAIL;
15508   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
15509   DONE;
15510 })
15511
15512 (define_expand "btrunc<mode>2"
15513   [(use (match_operand:MODEF 0 "register_operand" ""))
15514    (use (match_operand:MODEF 1 "register_operand" ""))]
15515   "(TARGET_USE_FANCY_MATH_387
15516     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15517         || TARGET_MIX_SSE_I387)
15518     && flag_unsafe_math_optimizations)
15519    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15520        && !flag_trapping_math)"
15521 {
15522   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15523       && !flag_trapping_math
15524       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
15525     {
15526       if (TARGET_ROUND)
15527         emit_insn (gen_sse4_1_round<mode>2
15528                    (operands[0], operands[1], GEN_INT (0x03)));
15529       else if (optimize_insn_for_size_p ())
15530         FAIL;
15531       else if (TARGET_64BIT || (<MODE>mode != DFmode))
15532         ix86_expand_trunc (operand0, operand1);
15533       else
15534         ix86_expand_truncdf_32 (operand0, operand1);
15535     }
15536   else
15537     {
15538       rtx op0, op1;
15539
15540       if (optimize_insn_for_size_p ())
15541         FAIL;
15542
15543       op0 = gen_reg_rtx (XFmode);
15544       op1 = gen_reg_rtx (XFmode);
15545       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15546       emit_insn (gen_frndintxf2_trunc (op0, op1));
15547
15548       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15549     }
15550   DONE;
15551 })
15552
15553 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15554 (define_insn_and_split "frndintxf2_mask_pm"
15555   [(set (match_operand:XF 0 "register_operand" "")
15556         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15557          UNSPEC_FRNDINT_MASK_PM))
15558    (clobber (reg:CC FLAGS_REG))]
15559   "TARGET_USE_FANCY_MATH_387
15560    && flag_unsafe_math_optimizations
15561    && can_create_pseudo_p ()"
15562   "#"
15563   "&& 1"
15564   [(const_int 0)]
15565 {
15566   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15567
15568   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15569   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15570
15571   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15572                                           operands[2], operands[3]));
15573   DONE;
15574 }
15575   [(set_attr "type" "frndint")
15576    (set_attr "i387_cw" "mask_pm")
15577    (set_attr "mode" "XF")])
15578
15579 (define_insn "frndintxf2_mask_pm_i387"
15580   [(set (match_operand:XF 0 "register_operand" "=f")
15581         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15582          UNSPEC_FRNDINT_MASK_PM))
15583    (use (match_operand:HI 2 "memory_operand" "m"))
15584    (use (match_operand:HI 3 "memory_operand" "m"))]
15585   "TARGET_USE_FANCY_MATH_387
15586    && flag_unsafe_math_optimizations"
15587   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15588   [(set_attr "type" "frndint")
15589    (set_attr "i387_cw" "mask_pm")
15590    (set_attr "mode" "XF")])
15591
15592 (define_expand "nearbyintxf2"
15593   [(use (match_operand:XF 0 "register_operand" ""))
15594    (use (match_operand:XF 1 "register_operand" ""))]
15595   "TARGET_USE_FANCY_MATH_387
15596    && flag_unsafe_math_optimizations"
15597 {
15598   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15599
15600   DONE;
15601 })
15602
15603 (define_expand "nearbyint<mode>2"
15604   [(use (match_operand:MODEF 0 "register_operand" ""))
15605    (use (match_operand:MODEF 1 "register_operand" ""))]
15606   "TARGET_USE_FANCY_MATH_387
15607    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15608        || TARGET_MIX_SSE_I387)
15609    && flag_unsafe_math_optimizations"
15610 {
15611   rtx op0 = gen_reg_rtx (XFmode);
15612   rtx op1 = gen_reg_rtx (XFmode);
15613
15614   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15615   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15616
15617   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15618   DONE;
15619 })
15620
15621 (define_insn "fxam<mode>2_i387"
15622   [(set (match_operand:HI 0 "register_operand" "=a")
15623         (unspec:HI
15624           [(match_operand:X87MODEF 1 "register_operand" "f")]
15625           UNSPEC_FXAM))]
15626   "TARGET_USE_FANCY_MATH_387"
15627   "fxam\n\tfnstsw\t%0"
15628   [(set_attr "type" "multi")
15629    (set_attr "length" "4")
15630    (set_attr "unit" "i387")
15631    (set_attr "mode" "<MODE>")])
15632
15633 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15634   [(set (match_operand:HI 0 "register_operand" "")
15635         (unspec:HI
15636           [(match_operand:MODEF 1 "memory_operand" "")]
15637           UNSPEC_FXAM_MEM))]
15638   "TARGET_USE_FANCY_MATH_387
15639    && can_create_pseudo_p ()"
15640   "#"
15641   "&& 1"
15642   [(set (match_dup 2)(match_dup 1))
15643    (set (match_dup 0)
15644         (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15645 {
15646   operands[2] = gen_reg_rtx (<MODE>mode);
15647
15648   MEM_VOLATILE_P (operands[1]) = 1;
15649 }
15650   [(set_attr "type" "multi")
15651    (set_attr "unit" "i387")
15652    (set_attr "mode" "<MODE>")])
15653
15654 (define_expand "isinfxf2"
15655   [(use (match_operand:SI 0 "register_operand" ""))
15656    (use (match_operand:XF 1 "register_operand" ""))]
15657   "TARGET_USE_FANCY_MATH_387
15658    && TARGET_C99_FUNCTIONS"
15659 {
15660   rtx mask = GEN_INT (0x45);
15661   rtx val = GEN_INT (0x05);
15662
15663   rtx cond;
15664
15665   rtx scratch = gen_reg_rtx (HImode);
15666   rtx res = gen_reg_rtx (QImode);
15667
15668   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15669
15670   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15671   emit_insn (gen_cmpqi_ext_3 (scratch, val));
15672   cond = gen_rtx_fmt_ee (EQ, QImode,
15673                          gen_rtx_REG (CCmode, FLAGS_REG),
15674                          const0_rtx);
15675   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15676   emit_insn (gen_zero_extendqisi2 (operands[0], res));
15677   DONE;
15678 })
15679
15680 (define_expand "isinf<mode>2"
15681   [(use (match_operand:SI 0 "register_operand" ""))
15682    (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15683   "TARGET_USE_FANCY_MATH_387
15684    && TARGET_C99_FUNCTIONS
15685    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15686 {
15687   rtx mask = GEN_INT (0x45);
15688   rtx val = GEN_INT (0x05);
15689
15690   rtx cond;
15691
15692   rtx scratch = gen_reg_rtx (HImode);
15693   rtx res = gen_reg_rtx (QImode);
15694
15695   /* Remove excess precision by forcing value through memory. */
15696   if (memory_operand (operands[1], VOIDmode))
15697     emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15698   else
15699     {
15700       enum ix86_stack_slot slot = (virtuals_instantiated
15701                                    ? SLOT_TEMP
15702                                    : SLOT_VIRTUAL);
15703       rtx temp = assign_386_stack_local (<MODE>mode, slot);
15704
15705       emit_move_insn (temp, operands[1]);
15706       emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15707     }
15708
15709   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15710   emit_insn (gen_cmpqi_ext_3 (scratch, val));
15711   cond = gen_rtx_fmt_ee (EQ, QImode,
15712                          gen_rtx_REG (CCmode, FLAGS_REG),
15713                          const0_rtx);
15714   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15715   emit_insn (gen_zero_extendqisi2 (operands[0], res));
15716   DONE;
15717 })
15718
15719 (define_expand "signbit<mode>2"
15720   [(use (match_operand:SI 0 "register_operand" ""))
15721    (use (match_operand:X87MODEF 1 "register_operand" ""))]
15722   "TARGET_USE_FANCY_MATH_387
15723    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15724 {
15725   rtx mask = GEN_INT (0x0200);
15726
15727   rtx scratch = gen_reg_rtx (HImode);
15728
15729   emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
15730   emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
15731   DONE;
15732 })
15733 \f
15734 ;; Block operation instructions
15735
15736 (define_insn "cld"
15737   [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15738   ""
15739   "cld"
15740   [(set_attr "length" "1")
15741    (set_attr "length_immediate" "0")
15742    (set_attr "modrm" "0")])
15743
15744 (define_expand "movmemsi"
15745   [(use (match_operand:BLK 0 "memory_operand" ""))
15746    (use (match_operand:BLK 1 "memory_operand" ""))
15747    (use (match_operand:SI 2 "nonmemory_operand" ""))
15748    (use (match_operand:SI 3 "const_int_operand" ""))
15749    (use (match_operand:SI 4 "const_int_operand" ""))
15750    (use (match_operand:SI 5 "const_int_operand" ""))]
15751   ""
15752 {
15753  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15754                          operands[4], operands[5]))
15755    DONE;
15756  else
15757    FAIL;
15758 })
15759
15760 (define_expand "movmemdi"
15761   [(use (match_operand:BLK 0 "memory_operand" ""))
15762    (use (match_operand:BLK 1 "memory_operand" ""))
15763    (use (match_operand:DI 2 "nonmemory_operand" ""))
15764    (use (match_operand:DI 3 "const_int_operand" ""))
15765    (use (match_operand:SI 4 "const_int_operand" ""))
15766    (use (match_operand:SI 5 "const_int_operand" ""))]
15767   "TARGET_64BIT"
15768 {
15769  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15770                          operands[4], operands[5]))
15771    DONE;
15772  else
15773    FAIL;
15774 })
15775
15776 ;; Most CPUs don't like single string operations
15777 ;; Handle this case here to simplify previous expander.
15778
15779 (define_expand "strmov"
15780   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15781    (set (match_operand 1 "memory_operand" "") (match_dup 4))
15782    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15783               (clobber (reg:CC FLAGS_REG))])
15784    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15785               (clobber (reg:CC FLAGS_REG))])]
15786   ""
15787 {
15788   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15789
15790   /* If .md ever supports :P for Pmode, these can be directly
15791      in the pattern above.  */
15792   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15793   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15794
15795   /* Can't use this if the user has appropriated esi or edi.  */
15796   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15797       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15798     {
15799       emit_insn (gen_strmov_singleop (operands[0], operands[1],
15800                                       operands[2], operands[3],
15801                                       operands[5], operands[6]));
15802       DONE;
15803     }
15804
15805   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15806 })
15807
15808 (define_expand "strmov_singleop"
15809   [(parallel [(set (match_operand 1 "memory_operand" "")
15810                    (match_operand 3 "memory_operand" ""))
15811               (set (match_operand 0 "register_operand" "")
15812                    (match_operand 4 "" ""))
15813               (set (match_operand 2 "register_operand" "")
15814                    (match_operand 5 "" ""))])]
15815   ""
15816   "ix86_current_function_needs_cld = 1;")
15817
15818 (define_insn "*strmovdi_rex_1"
15819   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15820         (mem:DI (match_operand:DI 3 "register_operand" "1")))
15821    (set (match_operand:DI 0 "register_operand" "=D")
15822         (plus:DI (match_dup 2)
15823                  (const_int 8)))
15824    (set (match_operand:DI 1 "register_operand" "=S")
15825         (plus:DI (match_dup 3)
15826                  (const_int 8)))]
15827   "TARGET_64BIT"
15828   "movsq"
15829   [(set_attr "type" "str")
15830    (set_attr "mode" "DI")
15831    (set_attr "memory" "both")])
15832
15833 (define_insn "*strmovsi_1"
15834   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
15835         (mem:SI (match_operand:SI 3 "register_operand" "1")))
15836    (set (match_operand:SI 0 "register_operand" "=D")
15837         (plus:SI (match_dup 2)
15838                  (const_int 4)))
15839    (set (match_operand:SI 1 "register_operand" "=S")
15840         (plus:SI (match_dup 3)
15841                  (const_int 4)))]
15842   "!TARGET_64BIT"
15843   "movs{l|d}"
15844   [(set_attr "type" "str")
15845    (set_attr "mode" "SI")
15846    (set_attr "memory" "both")])
15847
15848 (define_insn "*strmovsi_rex_1"
15849   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
15850         (mem:SI (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 4)))
15854    (set (match_operand:DI 1 "register_operand" "=S")
15855         (plus:DI (match_dup 3)
15856                  (const_int 4)))]
15857   "TARGET_64BIT"
15858   "movs{l|d}"
15859   [(set_attr "type" "str")
15860    (set_attr "mode" "SI")
15861    (set_attr "memory" "both")])
15862
15863 (define_insn "*strmovhi_1"
15864   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
15865         (mem:HI (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 2)))
15869    (set (match_operand:SI 1 "register_operand" "=S")
15870         (plus:SI (match_dup 3)
15871                  (const_int 2)))]
15872   "!TARGET_64BIT"
15873   "movsw"
15874   [(set_attr "type" "str")
15875    (set_attr "memory" "both")
15876    (set_attr "mode" "HI")])
15877
15878 (define_insn "*strmovhi_rex_1"
15879   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
15880         (mem:HI (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 2)))
15884    (set (match_operand:DI 1 "register_operand" "=S")
15885         (plus:DI (match_dup 3)
15886                  (const_int 2)))]
15887   "TARGET_64BIT"
15888   "movsw"
15889   [(set_attr "type" "str")
15890    (set_attr "memory" "both")
15891    (set_attr "mode" "HI")])
15892
15893 (define_insn "*strmovqi_1"
15894   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
15895         (mem:QI (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 1)))
15899    (set (match_operand:SI 1 "register_operand" "=S")
15900         (plus:SI (match_dup 3)
15901                  (const_int 1)))]
15902   "!TARGET_64BIT"
15903   "movsb"
15904   [(set_attr "type" "str")
15905    (set_attr "memory" "both")
15906    (set_attr "mode" "QI")])
15907
15908 (define_insn "*strmovqi_rex_1"
15909   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
15910         (mem:QI (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 1)))
15914    (set (match_operand:DI 1 "register_operand" "=S")
15915         (plus:DI (match_dup 3)
15916                  (const_int 1)))]
15917   "TARGET_64BIT"
15918   "movsb"
15919   [(set_attr "type" "str")
15920    (set_attr "memory" "both")
15921    (set_attr "prefix_rex" "0")
15922    (set_attr "mode" "QI")])
15923
15924 (define_expand "rep_mov"
15925   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15926               (set (match_operand 0 "register_operand" "")
15927                    (match_operand 5 "" ""))
15928               (set (match_operand 2 "register_operand" "")
15929                    (match_operand 6 "" ""))
15930               (set (match_operand 1 "memory_operand" "")
15931                    (match_operand 3 "memory_operand" ""))
15932               (use (match_dup 4))])]
15933   ""
15934   "ix86_current_function_needs_cld = 1;")
15935
15936 (define_insn "*rep_movdi_rex64"
15937   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15938    (set (match_operand:DI 0 "register_operand" "=D")
15939         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15940                             (const_int 3))
15941                  (match_operand:DI 3 "register_operand" "0")))
15942    (set (match_operand:DI 1 "register_operand" "=S")
15943         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15944                  (match_operand:DI 4 "register_operand" "1")))
15945    (set (mem:BLK (match_dup 3))
15946         (mem:BLK (match_dup 4)))
15947    (use (match_dup 5))]
15948   "TARGET_64BIT"
15949   "rep movsq"
15950   [(set_attr "type" "str")
15951    (set_attr "prefix_rep" "1")
15952    (set_attr "memory" "both")
15953    (set_attr "mode" "DI")])
15954
15955 (define_insn "*rep_movsi"
15956   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
15957    (set (match_operand:SI 0 "register_operand" "=D")
15958         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
15959                             (const_int 2))
15960                  (match_operand:SI 3 "register_operand" "0")))
15961    (set (match_operand:SI 1 "register_operand" "=S")
15962         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
15963                  (match_operand:SI 4 "register_operand" "1")))
15964    (set (mem:BLK (match_dup 3))
15965         (mem:BLK (match_dup 4)))
15966    (use (match_dup 5))]
15967   "!TARGET_64BIT"
15968   "rep movs{l|d}"
15969   [(set_attr "type" "str")
15970    (set_attr "prefix_rep" "1")
15971    (set_attr "memory" "both")
15972    (set_attr "mode" "SI")])
15973
15974 (define_insn "*rep_movsi_rex64"
15975   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15976    (set (match_operand:DI 0 "register_operand" "=D")
15977         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15978                             (const_int 2))
15979                  (match_operand:DI 3 "register_operand" "0")))
15980    (set (match_operand:DI 1 "register_operand" "=S")
15981         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
15982                  (match_operand:DI 4 "register_operand" "1")))
15983    (set (mem:BLK (match_dup 3))
15984         (mem:BLK (match_dup 4)))
15985    (use (match_dup 5))]
15986   "TARGET_64BIT"
15987   "rep movs{l|d}"
15988   [(set_attr "type" "str")
15989    (set_attr "prefix_rep" "1")
15990    (set_attr "memory" "both")
15991    (set_attr "mode" "SI")])
15992
15993 (define_insn "*rep_movqi"
15994   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
15995    (set (match_operand:SI 0 "register_operand" "=D")
15996         (plus:SI (match_operand:SI 3 "register_operand" "0")
15997                  (match_operand:SI 5 "register_operand" "2")))
15998    (set (match_operand:SI 1 "register_operand" "=S")
15999         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
16000    (set (mem:BLK (match_dup 3))
16001         (mem:BLK (match_dup 4)))
16002    (use (match_dup 5))]
16003   "!TARGET_64BIT"
16004   "rep movsb"
16005   [(set_attr "type" "str")
16006    (set_attr "prefix_rep" "1")
16007    (set_attr "memory" "both")
16008    (set_attr "mode" "SI")])
16009
16010 (define_insn "*rep_movqi_rex64"
16011   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16012    (set (match_operand:DI 0 "register_operand" "=D")
16013         (plus:DI (match_operand:DI 3 "register_operand" "0")
16014                  (match_operand:DI 5 "register_operand" "2")))
16015    (set (match_operand:DI 1 "register_operand" "=S")
16016         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
16017    (set (mem:BLK (match_dup 3))
16018         (mem:BLK (match_dup 4)))
16019    (use (match_dup 5))]
16020   "TARGET_64BIT"
16021   "rep movsb"
16022   [(set_attr "type" "str")
16023    (set_attr "prefix_rep" "1")
16024    (set_attr "memory" "both")
16025    (set_attr "mode" "SI")])
16026
16027 (define_expand "setmemsi"
16028    [(use (match_operand:BLK 0 "memory_operand" ""))
16029     (use (match_operand:SI 1 "nonmemory_operand" ""))
16030     (use (match_operand 2 "const_int_operand" ""))
16031     (use (match_operand 3 "const_int_operand" ""))
16032     (use (match_operand:SI 4 "const_int_operand" ""))
16033     (use (match_operand:SI 5 "const_int_operand" ""))]
16034   ""
16035 {
16036  if (ix86_expand_setmem (operands[0], operands[1],
16037                          operands[2], operands[3],
16038                          operands[4], operands[5]))
16039    DONE;
16040  else
16041    FAIL;
16042 })
16043
16044 (define_expand "setmemdi"
16045    [(use (match_operand:BLK 0 "memory_operand" ""))
16046     (use (match_operand:DI 1 "nonmemory_operand" ""))
16047     (use (match_operand 2 "const_int_operand" ""))
16048     (use (match_operand 3 "const_int_operand" ""))
16049     (use (match_operand 4 "const_int_operand" ""))
16050     (use (match_operand 5 "const_int_operand" ""))]
16051   "TARGET_64BIT"
16052 {
16053  if (ix86_expand_setmem (operands[0], operands[1],
16054                          operands[2], operands[3],
16055                          operands[4], operands[5]))
16056    DONE;
16057  else
16058    FAIL;
16059 })
16060
16061 ;; Most CPUs don't like single string operations
16062 ;; Handle this case here to simplify previous expander.
16063
16064 (define_expand "strset"
16065   [(set (match_operand 1 "memory_operand" "")
16066         (match_operand 2 "register_operand" ""))
16067    (parallel [(set (match_operand 0 "register_operand" "")
16068                    (match_dup 3))
16069               (clobber (reg:CC FLAGS_REG))])]
16070   ""
16071 {
16072   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
16073     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
16074
16075   /* If .md ever supports :P for Pmode, this can be directly
16076      in the pattern above.  */
16077   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
16078                               GEN_INT (GET_MODE_SIZE (GET_MODE
16079                                                       (operands[2]))));
16080   if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
16081     {
16082       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
16083                                       operands[3]));
16084       DONE;
16085     }
16086 })
16087
16088 (define_expand "strset_singleop"
16089   [(parallel [(set (match_operand 1 "memory_operand" "")
16090                    (match_operand 2 "register_operand" ""))
16091               (set (match_operand 0 "register_operand" "")
16092                    (match_operand 3 "" ""))])]
16093   ""
16094   "ix86_current_function_needs_cld = 1;")
16095
16096 (define_insn "*strsetdi_rex_1"
16097   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
16098         (match_operand:DI 2 "register_operand" "a"))
16099    (set (match_operand:DI 0 "register_operand" "=D")
16100         (plus:DI (match_dup 1)
16101                  (const_int 8)))]
16102   "TARGET_64BIT"
16103   "stosq"
16104   [(set_attr "type" "str")
16105    (set_attr "memory" "store")
16106    (set_attr "mode" "DI")])
16107
16108 (define_insn "*strsetsi_1"
16109   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
16110         (match_operand:SI 2 "register_operand" "a"))
16111    (set (match_operand:SI 0 "register_operand" "=D")
16112         (plus:SI (match_dup 1)
16113                  (const_int 4)))]
16114   "!TARGET_64BIT"
16115   "stos{l|d}"
16116   [(set_attr "type" "str")
16117    (set_attr "memory" "store")
16118    (set_attr "mode" "SI")])
16119
16120 (define_insn "*strsetsi_rex_1"
16121   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
16122         (match_operand:SI 2 "register_operand" "a"))
16123    (set (match_operand:DI 0 "register_operand" "=D")
16124         (plus:DI (match_dup 1)
16125                  (const_int 4)))]
16126   "TARGET_64BIT"
16127   "stos{l|d}"
16128   [(set_attr "type" "str")
16129    (set_attr "memory" "store")
16130    (set_attr "mode" "SI")])
16131
16132 (define_insn "*strsethi_1"
16133   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
16134         (match_operand:HI 2 "register_operand" "a"))
16135    (set (match_operand:SI 0 "register_operand" "=D")
16136         (plus:SI (match_dup 1)
16137                  (const_int 2)))]
16138   "!TARGET_64BIT"
16139   "stosw"
16140   [(set_attr "type" "str")
16141    (set_attr "memory" "store")
16142    (set_attr "mode" "HI")])
16143
16144 (define_insn "*strsethi_rex_1"
16145   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
16146         (match_operand:HI 2 "register_operand" "a"))
16147    (set (match_operand:DI 0 "register_operand" "=D")
16148         (plus:DI (match_dup 1)
16149                  (const_int 2)))]
16150   "TARGET_64BIT"
16151   "stosw"
16152   [(set_attr "type" "str")
16153    (set_attr "memory" "store")
16154    (set_attr "mode" "HI")])
16155
16156 (define_insn "*strsetqi_1"
16157   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
16158         (match_operand:QI 2 "register_operand" "a"))
16159    (set (match_operand:SI 0 "register_operand" "=D")
16160         (plus:SI (match_dup 1)
16161                  (const_int 1)))]
16162   "!TARGET_64BIT"
16163   "stosb"
16164   [(set_attr "type" "str")
16165    (set_attr "memory" "store")
16166    (set_attr "mode" "QI")])
16167
16168 (define_insn "*strsetqi_rex_1"
16169   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
16170         (match_operand:QI 2 "register_operand" "a"))
16171    (set (match_operand:DI 0 "register_operand" "=D")
16172         (plus:DI (match_dup 1)
16173                  (const_int 1)))]
16174   "TARGET_64BIT"
16175   "stosb"
16176   [(set_attr "type" "str")
16177    (set_attr "memory" "store")
16178    (set_attr "prefix_rex" "0")
16179    (set_attr "mode" "QI")])
16180
16181 (define_expand "rep_stos"
16182   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
16183               (set (match_operand 0 "register_operand" "")
16184                    (match_operand 4 "" ""))
16185               (set (match_operand 2 "memory_operand" "") (const_int 0))
16186               (use (match_operand 3 "register_operand" ""))
16187               (use (match_dup 1))])]
16188   ""
16189   "ix86_current_function_needs_cld = 1;")
16190
16191 (define_insn "*rep_stosdi_rex64"
16192   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16193    (set (match_operand:DI 0 "register_operand" "=D")
16194         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
16195                             (const_int 3))
16196                  (match_operand:DI 3 "register_operand" "0")))
16197    (set (mem:BLK (match_dup 3))
16198         (const_int 0))
16199    (use (match_operand:DI 2 "register_operand" "a"))
16200    (use (match_dup 4))]
16201   "TARGET_64BIT"
16202   "rep stosq"
16203   [(set_attr "type" "str")
16204    (set_attr "prefix_rep" "1")
16205    (set_attr "memory" "store")
16206    (set_attr "mode" "DI")])
16207
16208 (define_insn "*rep_stossi"
16209   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
16210    (set (match_operand:SI 0 "register_operand" "=D")
16211         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
16212                             (const_int 2))
16213                  (match_operand:SI 3 "register_operand" "0")))
16214    (set (mem:BLK (match_dup 3))
16215         (const_int 0))
16216    (use (match_operand:SI 2 "register_operand" "a"))
16217    (use (match_dup 4))]
16218   "!TARGET_64BIT"
16219   "rep stos{l|d}"
16220   [(set_attr "type" "str")
16221    (set_attr "prefix_rep" "1")
16222    (set_attr "memory" "store")
16223    (set_attr "mode" "SI")])
16224
16225 (define_insn "*rep_stossi_rex64"
16226   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16227    (set (match_operand:DI 0 "register_operand" "=D")
16228         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
16229                             (const_int 2))
16230                  (match_operand:DI 3 "register_operand" "0")))
16231    (set (mem:BLK (match_dup 3))
16232         (const_int 0))
16233    (use (match_operand:SI 2 "register_operand" "a"))
16234    (use (match_dup 4))]
16235   "TARGET_64BIT"
16236   "rep stos{l|d}"
16237   [(set_attr "type" "str")
16238    (set_attr "prefix_rep" "1")
16239    (set_attr "memory" "store")
16240    (set_attr "mode" "SI")])
16241
16242 (define_insn "*rep_stosqi"
16243   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
16244    (set (match_operand:SI 0 "register_operand" "=D")
16245         (plus:SI (match_operand:SI 3 "register_operand" "0")
16246                  (match_operand:SI 4 "register_operand" "1")))
16247    (set (mem:BLK (match_dup 3))
16248         (const_int 0))
16249    (use (match_operand:QI 2 "register_operand" "a"))
16250    (use (match_dup 4))]
16251   "!TARGET_64BIT"
16252   "rep stosb"
16253   [(set_attr "type" "str")
16254    (set_attr "prefix_rep" "1")
16255    (set_attr "memory" "store")
16256    (set_attr "mode" "QI")])
16257
16258 (define_insn "*rep_stosqi_rex64"
16259   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16260    (set (match_operand:DI 0 "register_operand" "=D")
16261         (plus:DI (match_operand:DI 3 "register_operand" "0")
16262                  (match_operand:DI 4 "register_operand" "1")))
16263    (set (mem:BLK (match_dup 3))
16264         (const_int 0))
16265    (use (match_operand:QI 2 "register_operand" "a"))
16266    (use (match_dup 4))]
16267   "TARGET_64BIT"
16268   "rep stosb"
16269   [(set_attr "type" "str")
16270    (set_attr "prefix_rep" "1")
16271    (set_attr "memory" "store")
16272    (set_attr "prefix_rex" "0")
16273    (set_attr "mode" "QI")])
16274
16275 (define_expand "cmpstrnsi"
16276   [(set (match_operand:SI 0 "register_operand" "")
16277         (compare:SI (match_operand:BLK 1 "general_operand" "")
16278                     (match_operand:BLK 2 "general_operand" "")))
16279    (use (match_operand 3 "general_operand" ""))
16280    (use (match_operand 4 "immediate_operand" ""))]
16281   ""
16282 {
16283   rtx addr1, addr2, out, outlow, count, countreg, align;
16284
16285   if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16286     FAIL;
16287
16288   /* Can't use this if the user has appropriated esi or edi.  */
16289   if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
16290     FAIL;
16291
16292   out = operands[0];
16293   if (!REG_P (out))
16294     out = gen_reg_rtx (SImode);
16295
16296   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
16297   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
16298   if (addr1 != XEXP (operands[1], 0))
16299     operands[1] = replace_equiv_address_nv (operands[1], addr1);
16300   if (addr2 != XEXP (operands[2], 0))
16301     operands[2] = replace_equiv_address_nv (operands[2], addr2);
16302
16303   count = operands[3];
16304   countreg = ix86_zero_extend_to_Pmode (count);
16305
16306   /* %%% Iff we are testing strict equality, we can use known alignment
16307      to good advantage.  This may be possible with combine, particularly
16308      once cc0 is dead.  */
16309   align = operands[4];
16310
16311   if (CONST_INT_P (count))
16312     {
16313       if (INTVAL (count) == 0)
16314         {
16315           emit_move_insn (operands[0], const0_rtx);
16316           DONE;
16317         }
16318       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16319                                      operands[1], operands[2]));
16320     }
16321   else
16322     {
16323       rtx (*cmp_insn)(rtx, rtx);
16324
16325       if (TARGET_64BIT)
16326         cmp_insn = gen_cmpdi_1;
16327       else
16328         cmp_insn = gen_cmpsi_1;
16329       emit_insn (cmp_insn (countreg, countreg));
16330       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16331                                   operands[1], operands[2]));
16332     }
16333
16334   outlow = gen_lowpart (QImode, out);
16335   emit_insn (gen_cmpintqi (outlow));
16336   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16337
16338   if (operands[0] != out)
16339     emit_move_insn (operands[0], out);
16340
16341   DONE;
16342 })
16343
16344 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16345
16346 (define_expand "cmpintqi"
16347   [(set (match_dup 1)
16348         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16349    (set (match_dup 2)
16350         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16351    (parallel [(set (match_operand:QI 0 "register_operand" "")
16352                    (minus:QI (match_dup 1)
16353                              (match_dup 2)))
16354               (clobber (reg:CC FLAGS_REG))])]
16355   ""
16356   "operands[1] = gen_reg_rtx (QImode);
16357    operands[2] = gen_reg_rtx (QImode);")
16358
16359 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
16360 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
16361
16362 (define_expand "cmpstrnqi_nz_1"
16363   [(parallel [(set (reg:CC FLAGS_REG)
16364                    (compare:CC (match_operand 4 "memory_operand" "")
16365                                (match_operand 5 "memory_operand" "")))
16366               (use (match_operand 2 "register_operand" ""))
16367               (use (match_operand:SI 3 "immediate_operand" ""))
16368               (clobber (match_operand 0 "register_operand" ""))
16369               (clobber (match_operand 1 "register_operand" ""))
16370               (clobber (match_dup 2))])]
16371   ""
16372   "ix86_current_function_needs_cld = 1;")
16373
16374 (define_insn "*cmpstrnqi_nz_1"
16375   [(set (reg:CC FLAGS_REG)
16376         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
16377                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
16378    (use (match_operand:SI 6 "register_operand" "2"))
16379    (use (match_operand:SI 3 "immediate_operand" "i"))
16380    (clobber (match_operand:SI 0 "register_operand" "=S"))
16381    (clobber (match_operand:SI 1 "register_operand" "=D"))
16382    (clobber (match_operand:SI 2 "register_operand" "=c"))]
16383   "!TARGET_64BIT"
16384   "repz cmpsb"
16385   [(set_attr "type" "str")
16386    (set_attr "mode" "QI")
16387    (set_attr "prefix_rep" "1")])
16388
16389 (define_insn "*cmpstrnqi_nz_rex_1"
16390   [(set (reg:CC FLAGS_REG)
16391         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
16392                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
16393    (use (match_operand:DI 6 "register_operand" "2"))
16394    (use (match_operand:SI 3 "immediate_operand" "i"))
16395    (clobber (match_operand:DI 0 "register_operand" "=S"))
16396    (clobber (match_operand:DI 1 "register_operand" "=D"))
16397    (clobber (match_operand:DI 2 "register_operand" "=c"))]
16398   "TARGET_64BIT"
16399   "repz cmpsb"
16400   [(set_attr "type" "str")
16401    (set_attr "mode" "QI")
16402    (set_attr "prefix_rex" "0")
16403    (set_attr "prefix_rep" "1")])
16404
16405 ;; The same, but the count is not known to not be zero.
16406
16407 (define_expand "cmpstrnqi_1"
16408   [(parallel [(set (reg:CC FLAGS_REG)
16409                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
16410                                      (const_int 0))
16411                   (compare:CC (match_operand 4 "memory_operand" "")
16412                               (match_operand 5 "memory_operand" ""))
16413                   (const_int 0)))
16414               (use (match_operand:SI 3 "immediate_operand" ""))
16415               (use (reg:CC FLAGS_REG))
16416               (clobber (match_operand 0 "register_operand" ""))
16417               (clobber (match_operand 1 "register_operand" ""))
16418               (clobber (match_dup 2))])]
16419   ""
16420   "ix86_current_function_needs_cld = 1;")
16421
16422 (define_insn "*cmpstrnqi_1"
16423   [(set (reg:CC FLAGS_REG)
16424         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
16425                              (const_int 0))
16426           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
16427                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
16428           (const_int 0)))
16429    (use (match_operand:SI 3 "immediate_operand" "i"))
16430    (use (reg:CC FLAGS_REG))
16431    (clobber (match_operand:SI 0 "register_operand" "=S"))
16432    (clobber (match_operand:SI 1 "register_operand" "=D"))
16433    (clobber (match_operand:SI 2 "register_operand" "=c"))]
16434   "!TARGET_64BIT"
16435   "repz cmpsb"
16436   [(set_attr "type" "str")
16437    (set_attr "mode" "QI")
16438    (set_attr "prefix_rep" "1")])
16439
16440 (define_insn "*cmpstrnqi_rex_1"
16441   [(set (reg:CC FLAGS_REG)
16442         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
16443                              (const_int 0))
16444           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
16445                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
16446           (const_int 0)))
16447    (use (match_operand:SI 3 "immediate_operand" "i"))
16448    (use (reg:CC FLAGS_REG))
16449    (clobber (match_operand:DI 0 "register_operand" "=S"))
16450    (clobber (match_operand:DI 1 "register_operand" "=D"))
16451    (clobber (match_operand:DI 2 "register_operand" "=c"))]
16452   "TARGET_64BIT"
16453   "repz cmpsb"
16454   [(set_attr "type" "str")
16455    (set_attr "mode" "QI")
16456    (set_attr "prefix_rex" "0")
16457    (set_attr "prefix_rep" "1")])
16458
16459 (define_expand "strlensi"
16460   [(set (match_operand:SI 0 "register_operand" "")
16461         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
16462                     (match_operand:QI 2 "immediate_operand" "")
16463                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
16464   ""
16465 {
16466  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16467    DONE;
16468  else
16469    FAIL;
16470 })
16471
16472 (define_expand "strlendi"
16473   [(set (match_operand:DI 0 "register_operand" "")
16474         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
16475                     (match_operand:QI 2 "immediate_operand" "")
16476                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
16477   ""
16478 {
16479  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16480    DONE;
16481  else
16482    FAIL;
16483 })
16484
16485 (define_expand "strlenqi_1"
16486   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
16487               (clobber (match_operand 1 "register_operand" ""))
16488               (clobber (reg:CC FLAGS_REG))])]
16489   ""
16490   "ix86_current_function_needs_cld = 1;")
16491
16492 (define_insn "*strlenqi_1"
16493   [(set (match_operand:SI 0 "register_operand" "=&c")
16494         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
16495                     (match_operand:QI 2 "register_operand" "a")
16496                     (match_operand:SI 3 "immediate_operand" "i")
16497                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
16498    (clobber (match_operand:SI 1 "register_operand" "=D"))
16499    (clobber (reg:CC FLAGS_REG))]
16500   "!TARGET_64BIT"
16501   "repnz scasb"
16502   [(set_attr "type" "str")
16503    (set_attr "mode" "QI")
16504    (set_attr "prefix_rep" "1")])
16505
16506 (define_insn "*strlenqi_rex_1"
16507   [(set (match_operand:DI 0 "register_operand" "=&c")
16508         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
16509                     (match_operand:QI 2 "register_operand" "a")
16510                     (match_operand:DI 3 "immediate_operand" "i")
16511                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
16512    (clobber (match_operand:DI 1 "register_operand" "=D"))
16513    (clobber (reg:CC FLAGS_REG))]
16514   "TARGET_64BIT"
16515   "repnz scasb"
16516   [(set_attr "type" "str")
16517    (set_attr "mode" "QI")
16518    (set_attr "prefix_rex" "0")
16519    (set_attr "prefix_rep" "1")])
16520
16521 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
16522 ;; handled in combine, but it is not currently up to the task.
16523 ;; When used for their truth value, the cmpstrn* expanders generate
16524 ;; code like this:
16525 ;;
16526 ;;   repz cmpsb
16527 ;;   seta       %al
16528 ;;   setb       %dl
16529 ;;   cmpb       %al, %dl
16530 ;;   jcc        label
16531 ;;
16532 ;; The intermediate three instructions are unnecessary.
16533
16534 ;; This one handles cmpstrn*_nz_1...
16535 (define_peephole2
16536   [(parallel[
16537      (set (reg:CC FLAGS_REG)
16538           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16539                       (mem:BLK (match_operand 5 "register_operand" ""))))
16540      (use (match_operand 6 "register_operand" ""))
16541      (use (match_operand:SI 3 "immediate_operand" ""))
16542      (clobber (match_operand 0 "register_operand" ""))
16543      (clobber (match_operand 1 "register_operand" ""))
16544      (clobber (match_operand 2 "register_operand" ""))])
16545    (set (match_operand:QI 7 "register_operand" "")
16546         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16547    (set (match_operand:QI 8 "register_operand" "")
16548         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16549    (set (reg FLAGS_REG)
16550         (compare (match_dup 7) (match_dup 8)))
16551   ]
16552   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16553   [(parallel[
16554      (set (reg:CC FLAGS_REG)
16555           (compare:CC (mem:BLK (match_dup 4))
16556                       (mem:BLK (match_dup 5))))
16557      (use (match_dup 6))
16558      (use (match_dup 3))
16559      (clobber (match_dup 0))
16560      (clobber (match_dup 1))
16561      (clobber (match_dup 2))])]
16562   "")
16563
16564 ;; ...and this one handles cmpstrn*_1.
16565 (define_peephole2
16566   [(parallel[
16567      (set (reg:CC FLAGS_REG)
16568           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
16569                                (const_int 0))
16570             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16571                         (mem:BLK (match_operand 5 "register_operand" "")))
16572             (const_int 0)))
16573      (use (match_operand:SI 3 "immediate_operand" ""))
16574      (use (reg:CC FLAGS_REG))
16575      (clobber (match_operand 0 "register_operand" ""))
16576      (clobber (match_operand 1 "register_operand" ""))
16577      (clobber (match_operand 2 "register_operand" ""))])
16578    (set (match_operand:QI 7 "register_operand" "")
16579         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16580    (set (match_operand:QI 8 "register_operand" "")
16581         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16582    (set (reg FLAGS_REG)
16583         (compare (match_dup 7) (match_dup 8)))
16584   ]
16585   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16586   [(parallel[
16587      (set (reg:CC FLAGS_REG)
16588           (if_then_else:CC (ne (match_dup 6)
16589                                (const_int 0))
16590             (compare:CC (mem:BLK (match_dup 4))
16591                         (mem:BLK (match_dup 5)))
16592             (const_int 0)))
16593      (use (match_dup 3))
16594      (use (reg:CC FLAGS_REG))
16595      (clobber (match_dup 0))
16596      (clobber (match_dup 1))
16597      (clobber (match_dup 2))])]
16598   "")
16599
16600
16601 \f
16602 ;; Conditional move instructions.
16603
16604 (define_expand "mov<mode>cc"
16605   [(set (match_operand:SWIM 0 "register_operand" "")
16606         (if_then_else:SWIM (match_operand 1 "comparison_operator" "")
16607                            (match_operand:SWIM 2 "general_operand" "")
16608                            (match_operand:SWIM 3 "general_operand" "")))]
16609   ""
16610   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16611
16612 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16613 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16614 ;; So just document what we're doing explicitly.
16615
16616 (define_expand "x86_mov<mode>cc_0_m1"
16617   [(parallel
16618     [(set (match_operand:SWI48 0 "register_operand" "")
16619           (if_then_else:SWI48
16620             (match_operator:SWI48 2 "ix86_carry_flag_operator"
16621              [(match_operand 1 "flags_reg_operand" "")
16622               (const_int 0)])
16623             (const_int -1)
16624             (const_int 0)))
16625      (clobber (reg:CC FLAGS_REG))])]
16626   ""
16627   "")
16628
16629 (define_insn "*x86_mov<mode>cc_0_m1"
16630   [(set (match_operand:SWI48 0 "register_operand" "=r")
16631         (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16632                              [(reg FLAGS_REG) (const_int 0)])
16633           (const_int -1)
16634           (const_int 0)))
16635    (clobber (reg:CC FLAGS_REG))]
16636   ""
16637   "sbb{<imodesuffix>}\t%0, %0"
16638   ; Since we don't have the proper number of operands for an alu insn,
16639   ; fill in all the blanks.
16640   [(set_attr "type" "alu")
16641    (set_attr "use_carry" "1")
16642    (set_attr "pent_pair" "pu")
16643    (set_attr "memory" "none")
16644    (set_attr "imm_disp" "false")
16645    (set_attr "mode" "<MODE>")
16646    (set_attr "length_immediate" "0")])
16647
16648 (define_insn "*x86_mov<mode>cc_0_m1_se"
16649   [(set (match_operand:SWI48 0 "register_operand" "=r")
16650         (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16651                              [(reg FLAGS_REG) (const_int 0)])
16652                             (const_int 1)
16653                             (const_int 0)))
16654    (clobber (reg:CC FLAGS_REG))]
16655   ""
16656   "sbb{<imodesuffix>}\t%0, %0"
16657   [(set_attr "type" "alu")
16658    (set_attr "use_carry" "1")
16659    (set_attr "pent_pair" "pu")
16660    (set_attr "memory" "none")
16661    (set_attr "imm_disp" "false")
16662    (set_attr "mode" "<MODE>")
16663    (set_attr "length_immediate" "0")])
16664
16665 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16666   [(set (match_operand:SWI48 0 "register_operand" "=r")
16667         (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16668                     [(reg FLAGS_REG) (const_int 0)])))]
16669   ""
16670   "sbb{<imodesuffix>}\t%0, %0"
16671   [(set_attr "type" "alu")
16672    (set_attr "use_carry" "1")
16673    (set_attr "pent_pair" "pu")
16674    (set_attr "memory" "none")
16675    (set_attr "imm_disp" "false")
16676    (set_attr "mode" "<MODE>")
16677    (set_attr "length_immediate" "0")])
16678
16679 (define_insn "*mov<mode>cc_noc"
16680   [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16681         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16682                                [(reg FLAGS_REG) (const_int 0)])
16683           (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16684           (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16685   "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16686   "@
16687    cmov%O2%C1\t{%2, %0|%0, %2}
16688    cmov%O2%c1\t{%3, %0|%0, %3}"
16689   [(set_attr "type" "icmov")
16690    (set_attr "mode" "<MODE>")])
16691
16692 (define_insn_and_split "*movqicc_noc"
16693   [(set (match_operand:QI 0 "register_operand" "=r,r")
16694         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16695                            [(match_operand 4 "flags_reg_operand" "")
16696                             (const_int 0)])
16697                       (match_operand:QI 2 "register_operand" "r,0")
16698                       (match_operand:QI 3 "register_operand" "0,r")))]
16699   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16700   "#"
16701   "&& reload_completed"
16702   [(set (match_dup 0)
16703         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16704                       (match_dup 2)
16705                       (match_dup 3)))]
16706   "operands[0] = gen_lowpart (SImode, operands[0]);
16707    operands[2] = gen_lowpart (SImode, operands[2]);
16708    operands[3] = gen_lowpart (SImode, operands[3]);"
16709   [(set_attr "type" "icmov")
16710    (set_attr "mode" "SI")])
16711
16712 (define_expand "mov<mode>cc"
16713   [(set (match_operand:X87MODEF 0 "register_operand" "")
16714         (if_then_else:X87MODEF
16715           (match_operand 1 "ix86_fp_comparison_operator" "")
16716           (match_operand:X87MODEF 2 "register_operand" "")
16717           (match_operand:X87MODEF 3 "register_operand" "")))]
16718   "(TARGET_80387 && TARGET_CMOVE)
16719    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16720   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16721
16722 (define_insn "*movsfcc_1_387"
16723   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16724         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16725                                 [(reg FLAGS_REG) (const_int 0)])
16726                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16727                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16728   "TARGET_80387 && TARGET_CMOVE
16729    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16730   "@
16731    fcmov%F1\t{%2, %0|%0, %2}
16732    fcmov%f1\t{%3, %0|%0, %3}
16733    cmov%O2%C1\t{%2, %0|%0, %2}
16734    cmov%O2%c1\t{%3, %0|%0, %3}"
16735   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16736    (set_attr "mode" "SF,SF,SI,SI")])
16737
16738 (define_insn "*movdfcc_1"
16739   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16740         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16741                                 [(reg FLAGS_REG) (const_int 0)])
16742                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16743                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16744   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16745    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16746   "@
16747    fcmov%F1\t{%2, %0|%0, %2}
16748    fcmov%f1\t{%3, %0|%0, %3}
16749    #
16750    #"
16751   [(set_attr "type" "fcmov,fcmov,multi,multi")
16752    (set_attr "mode" "DF")])
16753
16754 (define_insn "*movdfcc_1_rex64"
16755   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16756         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16757                                 [(reg FLAGS_REG) (const_int 0)])
16758                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16759                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16760   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16761    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16762   "@
16763    fcmov%F1\t{%2, %0|%0, %2}
16764    fcmov%f1\t{%3, %0|%0, %3}
16765    cmov%O2%C1\t{%2, %0|%0, %2}
16766    cmov%O2%c1\t{%3, %0|%0, %3}"
16767   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16768    (set_attr "mode" "DF")])
16769
16770 (define_split
16771   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16772         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16773                                 [(match_operand 4 "flags_reg_operand" "")
16774                                  (const_int 0)])
16775                       (match_operand:DF 2 "nonimmediate_operand" "")
16776                       (match_operand:DF 3 "nonimmediate_operand" "")))]
16777   "!TARGET_64BIT && reload_completed"
16778   [(set (match_dup 2)
16779         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16780                       (match_dup 5)
16781                       (match_dup 6)))
16782    (set (match_dup 3)
16783         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16784                       (match_dup 7)
16785                       (match_dup 8)))]
16786   "split_di (&operands[2], 2, &operands[5], &operands[7]);
16787    split_di (&operands[0], 1, &operands[2], &operands[3]);")
16788
16789 (define_insn "*movxfcc_1"
16790   [(set (match_operand:XF 0 "register_operand" "=f,f")
16791         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16792                                 [(reg FLAGS_REG) (const_int 0)])
16793                       (match_operand:XF 2 "register_operand" "f,0")
16794                       (match_operand:XF 3 "register_operand" "0,f")))]
16795   "TARGET_80387 && TARGET_CMOVE"
16796   "@
16797    fcmov%F1\t{%2, %0|%0, %2}
16798    fcmov%f1\t{%3, %0|%0, %3}"
16799   [(set_attr "type" "fcmov")
16800    (set_attr "mode" "XF")])
16801
16802 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16803 ;; the scalar versions to have only XMM registers as operands.
16804
16805 ;; XOP conditional move
16806 (define_insn "*xop_pcmov_<mode>"
16807   [(set (match_operand:MODEF 0 "register_operand" "=x")
16808         (if_then_else:MODEF
16809           (match_operand:MODEF 1 "register_operand" "x")
16810           (match_operand:MODEF 2 "register_operand" "x")
16811           (match_operand:MODEF 3 "register_operand" "x")))]
16812   "TARGET_XOP"
16813   "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16814   [(set_attr "type" "sse4arg")])
16815
16816 ;; These versions of the min/max patterns are intentionally ignorant of
16817 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16818 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16819 ;; are undefined in this condition, we're certain this is correct.
16820
16821 (define_insn "*avx_<code><mode>3"
16822   [(set (match_operand:MODEF 0 "register_operand" "=x")
16823         (smaxmin:MODEF
16824           (match_operand:MODEF 1 "nonimmediate_operand" "%x")
16825           (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
16826   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16827   "v<maxmin_float>s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16828   [(set_attr "type" "sseadd")
16829    (set_attr "prefix" "vex")
16830    (set_attr "mode" "<MODE>")])
16831
16832 (define_insn "<code><mode>3"
16833   [(set (match_operand:MODEF 0 "register_operand" "=x")
16834         (smaxmin:MODEF
16835           (match_operand:MODEF 1 "nonimmediate_operand" "%0")
16836           (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
16837   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16838   "<maxmin_float>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
16839   [(set_attr "type" "sseadd")
16840    (set_attr "mode" "<MODE>")])
16841
16842 ;; These versions of the min/max patterns implement exactly the operations
16843 ;;   min = (op1 < op2 ? op1 : op2)
16844 ;;   max = (!(op1 < op2) ? op1 : op2)
16845 ;; Their operands are not commutative, and thus they may be used in the
16846 ;; presence of -0.0 and NaN.
16847
16848 (define_insn "*avx_ieee_smin<mode>3"
16849   [(set (match_operand:MODEF 0 "register_operand" "=x")
16850         (unspec:MODEF
16851           [(match_operand:MODEF 1 "register_operand" "x")
16852            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16853          UNSPEC_IEEE_MIN))]
16854   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16855   "vmins<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16856   [(set_attr "type" "sseadd")
16857    (set_attr "prefix" "vex")
16858    (set_attr "mode" "<MODE>")])
16859
16860 (define_insn "*ieee_smin<mode>3"
16861   [(set (match_operand:MODEF 0 "register_operand" "=x")
16862         (unspec:MODEF
16863           [(match_operand:MODEF 1 "register_operand" "0")
16864            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16865          UNSPEC_IEEE_MIN))]
16866   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16867   "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
16868   [(set_attr "type" "sseadd")
16869    (set_attr "mode" "<MODE>")])
16870
16871 (define_insn "*avx_ieee_smax<mode>3"
16872   [(set (match_operand:MODEF 0 "register_operand" "=x")
16873         (unspec:MODEF
16874           [(match_operand:MODEF 1 "register_operand" "0")
16875            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16876          UNSPEC_IEEE_MAX))]
16877   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16878   "vmaxs<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16879   [(set_attr "type" "sseadd")
16880    (set_attr "prefix" "vex")
16881    (set_attr "mode" "<MODE>")])
16882
16883 (define_insn "*ieee_smax<mode>3"
16884   [(set (match_operand:MODEF 0 "register_operand" "=x")
16885         (unspec:MODEF
16886           [(match_operand:MODEF 1 "register_operand" "0")
16887            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16888          UNSPEC_IEEE_MAX))]
16889   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16890   "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
16891   [(set_attr "type" "sseadd")
16892    (set_attr "mode" "<MODE>")])
16893
16894 ;; Make two stack loads independent:
16895 ;;   fld aa              fld aa
16896 ;;   fld %st(0)     ->   fld bb
16897 ;;   fmul bb             fmul %st(1), %st
16898 ;;
16899 ;; Actually we only match the last two instructions for simplicity.
16900 (define_peephole2
16901   [(set (match_operand 0 "fp_register_operand" "")
16902         (match_operand 1 "fp_register_operand" ""))
16903    (set (match_dup 0)
16904         (match_operator 2 "binary_fp_operator"
16905            [(match_dup 0)
16906             (match_operand 3 "memory_operand" "")]))]
16907   "REGNO (operands[0]) != REGNO (operands[1])"
16908   [(set (match_dup 0) (match_dup 3))
16909    (set (match_dup 0) (match_dup 4))]
16910
16911   ;; The % modifier is not operational anymore in peephole2's, so we have to
16912   ;; swap the operands manually in the case of addition and multiplication.
16913   "if (COMMUTATIVE_ARITH_P (operands[2]))
16914      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
16915                                  operands[0], operands[1]);
16916    else
16917      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
16918                                  operands[1], operands[0]);")
16919
16920 ;; Conditional addition patterns
16921 (define_expand "add<mode>cc"
16922   [(match_operand:SWI 0 "register_operand" "")
16923    (match_operand 1 "comparison_operator" "")
16924    (match_operand:SWI 2 "register_operand" "")
16925    (match_operand:SWI 3 "const_int_operand" "")]
16926   ""
16927   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16928
16929 \f
16930 ;; Misc patterns (?)
16931
16932 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16933 ;; Otherwise there will be nothing to keep
16934 ;;
16935 ;; [(set (reg ebp) (reg esp))]
16936 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16937 ;;  (clobber (eflags)]
16938 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16939 ;;
16940 ;; in proper program order.
16941 (define_insn "pro_epilogue_adjust_stack_1"
16942   [(set (match_operand:SI 0 "register_operand" "=r,r")
16943         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
16944                  (match_operand:SI 2 "immediate_operand" "i,i")))
16945    (clobber (reg:CC FLAGS_REG))
16946    (clobber (mem:BLK (scratch)))]
16947   "!TARGET_64BIT"
16948 {
16949   switch (get_attr_type (insn))
16950     {
16951     case TYPE_IMOV:
16952       return "mov{l}\t{%1, %0|%0, %1}";
16953
16954     case TYPE_ALU:
16955       if (CONST_INT_P (operands[2])
16956           && (INTVAL (operands[2]) == 128
16957               || (INTVAL (operands[2]) < 0
16958                   && INTVAL (operands[2]) != -128)))
16959         {
16960           operands[2] = GEN_INT (-INTVAL (operands[2]));
16961           return "sub{l}\t{%2, %0|%0, %2}";
16962         }
16963       return "add{l}\t{%2, %0|%0, %2}";
16964
16965     case TYPE_LEA:
16966       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16967       return "lea{l}\t{%a2, %0|%0, %a2}";
16968
16969     default:
16970       gcc_unreachable ();
16971     }
16972 }
16973   [(set (attr "type")
16974         (cond [(and (eq_attr "alternative" "0") 
16975                     (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
16976                  (const_string "alu")
16977                (match_operand:SI 2 "const0_operand" "")
16978                  (const_string "imov")
16979               ]
16980               (const_string "lea")))
16981    (set (attr "length_immediate")
16982         (cond [(eq_attr "type" "imov")
16983                  (const_string "0")
16984                (and (eq_attr "type" "alu")
16985                     (match_operand 2 "const128_operand" ""))
16986                  (const_string "1")
16987               ]
16988               (const_string "*")))
16989    (set_attr "mode" "SI")])
16990
16991 (define_insn "pro_epilogue_adjust_stack_rex64"
16992   [(set (match_operand:DI 0 "register_operand" "=r,r")
16993         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
16994                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
16995    (clobber (reg:CC FLAGS_REG))
16996    (clobber (mem:BLK (scratch)))]
16997   "TARGET_64BIT"
16998 {
16999   switch (get_attr_type (insn))
17000     {
17001     case TYPE_IMOV:
17002       return "mov{q}\t{%1, %0|%0, %1}";
17003
17004     case TYPE_ALU:
17005       if (CONST_INT_P (operands[2])
17006           /* Avoid overflows.  */
17007           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
17008           && (INTVAL (operands[2]) == 128
17009               || (INTVAL (operands[2]) < 0
17010                   && INTVAL (operands[2]) != -128)))
17011         {
17012           operands[2] = GEN_INT (-INTVAL (operands[2]));
17013           return "sub{q}\t{%2, %0|%0, %2}";
17014         }
17015       return "add{q}\t{%2, %0|%0, %2}";
17016
17017     case TYPE_LEA:
17018       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
17019       return "lea{q}\t{%a2, %0|%0, %a2}";
17020
17021     default:
17022       gcc_unreachable ();
17023     }
17024 }
17025   [(set (attr "type")
17026         (cond [(and (eq_attr "alternative" "0")
17027                     (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
17028                  (const_string "alu")
17029                (match_operand:DI 2 "const0_operand" "")
17030                  (const_string "imov")
17031               ]
17032               (const_string "lea")))
17033    (set (attr "length_immediate")
17034         (cond [(eq_attr "type" "imov")
17035                  (const_string "0")
17036                (and (eq_attr "type" "alu")
17037                     (match_operand 2 "const128_operand" ""))
17038                  (const_string "1")
17039               ]
17040               (const_string "*")))
17041    (set_attr "mode" "DI")])
17042
17043 (define_insn "pro_epilogue_adjust_stack_rex64_2"
17044   [(set (match_operand:DI 0 "register_operand" "=r,r")
17045         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
17046                  (match_operand:DI 3 "immediate_operand" "i,i")))
17047    (use (match_operand:DI 2 "register_operand" "r,r"))
17048    (clobber (reg:CC FLAGS_REG))
17049    (clobber (mem:BLK (scratch)))]
17050   "TARGET_64BIT"
17051 {
17052   switch (get_attr_type (insn))
17053     {
17054     case TYPE_ALU:
17055       return "add{q}\t{%2, %0|%0, %2}";
17056
17057     case TYPE_LEA:
17058       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
17059       return "lea{q}\t{%a2, %0|%0, %a2}";
17060
17061     default:
17062       gcc_unreachable ();
17063     }
17064 }
17065   [(set_attr "type" "alu,lea")
17066    (set_attr "mode" "DI")])
17067
17068 (define_insn "allocate_stack_worker_32"
17069   [(set (match_operand:SI 0 "register_operand" "=a")
17070         (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")]
17071                             UNSPECV_STACK_PROBE))
17072    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 1)))
17073    (clobber (reg:CC FLAGS_REG))]
17074   "!TARGET_64BIT && TARGET_STACK_PROBE"
17075   "call\t___chkstk"
17076   [(set_attr "type" "multi")
17077    (set_attr "length" "5")])
17078
17079 (define_insn "allocate_stack_worker_64"
17080   [(set (match_operand:DI 0 "register_operand" "=a")
17081         (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "0")]
17082                             UNSPECV_STACK_PROBE))
17083    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 1)))
17084    (clobber (reg:DI R10_REG))
17085    (clobber (reg:DI R11_REG))
17086    (clobber (reg:CC FLAGS_REG))]
17087   "TARGET_64BIT && TARGET_STACK_PROBE"
17088   "call\t___chkstk"
17089   [(set_attr "type" "multi")
17090    (set_attr "length" "5")])
17091
17092 (define_expand "allocate_stack"
17093   [(match_operand 0 "register_operand" "")
17094    (match_operand 1 "general_operand" "")]
17095   "TARGET_STACK_PROBE"
17096 {
17097   rtx x;
17098
17099 #ifndef CHECK_STACK_LIMIT
17100 #define CHECK_STACK_LIMIT 0
17101 #endif
17102
17103   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
17104       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
17105     {
17106       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
17107                                stack_pointer_rtx, 0, OPTAB_DIRECT);
17108       if (x != stack_pointer_rtx)
17109         emit_move_insn (stack_pointer_rtx, x);
17110     }
17111   else
17112     {
17113       x = copy_to_mode_reg (Pmode, operands[1]);
17114       if (TARGET_64BIT)
17115         x = gen_allocate_stack_worker_64 (x, x);
17116       else
17117         x = gen_allocate_stack_worker_32 (x, x);
17118       emit_insn (x);
17119     }
17120
17121   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
17122   DONE;
17123 })
17124
17125 ;; Use IOR for stack probes, this is shorter.
17126 (define_expand "probe_stack"
17127   [(match_operand 0 "memory_operand" "")]
17128   ""
17129 {
17130   if (GET_MODE (operands[0]) == DImode)
17131     emit_insn (gen_iordi3 (operands[0], operands[0], const0_rtx));
17132   else
17133     emit_insn (gen_iorsi3 (operands[0], operands[0], const0_rtx));
17134   DONE;
17135 })
17136
17137 (define_expand "builtin_setjmp_receiver"
17138   [(label_ref (match_operand 0 "" ""))]
17139   "!TARGET_64BIT && flag_pic"
17140 {
17141 #if TARGET_MACHO
17142   if (TARGET_MACHO)
17143     {
17144       rtx xops[3];
17145       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
17146       rtx label_rtx = gen_label_rtx ();
17147       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
17148       xops[0] = xops[1] = picreg;
17149       xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
17150       ix86_expand_binary_operator (MINUS, SImode, xops);
17151     }
17152   else
17153 #endif
17154     emit_insn (gen_set_got (pic_offset_table_rtx));
17155   DONE;
17156 })
17157 \f
17158 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
17159
17160 (define_split
17161   [(set (match_operand 0 "register_operand" "")
17162         (match_operator 3 "promotable_binary_operator"
17163            [(match_operand 1 "register_operand" "")
17164             (match_operand 2 "aligned_operand" "")]))
17165    (clobber (reg:CC FLAGS_REG))]
17166   "! TARGET_PARTIAL_REG_STALL && reload_completed
17167    && ((GET_MODE (operands[0]) == HImode
17168         && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
17169             /* ??? next two lines just !satisfies_constraint_K (...) */
17170             || !CONST_INT_P (operands[2])
17171             || satisfies_constraint_K (operands[2])))
17172        || (GET_MODE (operands[0]) == QImode
17173            && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
17174   [(parallel [(set (match_dup 0)
17175                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17176               (clobber (reg:CC FLAGS_REG))])]
17177   "operands[0] = gen_lowpart (SImode, operands[0]);
17178    operands[1] = gen_lowpart (SImode, operands[1]);
17179    if (GET_CODE (operands[3]) != ASHIFT)
17180      operands[2] = gen_lowpart (SImode, operands[2]);
17181    PUT_MODE (operands[3], SImode);")
17182
17183 ; Promote the QImode tests, as i386 has encoding of the AND
17184 ; instruction with 32-bit sign-extended immediate and thus the
17185 ; instruction size is unchanged, except in the %eax case for
17186 ; which it is increased by one byte, hence the ! optimize_size.
17187 (define_split
17188   [(set (match_operand 0 "flags_reg_operand" "")
17189         (match_operator 2 "compare_operator"
17190           [(and (match_operand 3 "aligned_operand" "")
17191                 (match_operand 4 "const_int_operand" ""))
17192            (const_int 0)]))
17193    (set (match_operand 1 "register_operand" "")
17194         (and (match_dup 3) (match_dup 4)))]
17195   "! TARGET_PARTIAL_REG_STALL && reload_completed
17196    && optimize_insn_for_speed_p ()
17197    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
17198        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
17199    /* Ensure that the operand will remain sign-extended immediate.  */
17200    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
17201   [(parallel [(set (match_dup 0)
17202                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
17203                                     (const_int 0)]))
17204               (set (match_dup 1)
17205                    (and:SI (match_dup 3) (match_dup 4)))])]
17206 {
17207   operands[4]
17208     = gen_int_mode (INTVAL (operands[4])
17209                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
17210   operands[1] = gen_lowpart (SImode, operands[1]);
17211   operands[3] = gen_lowpart (SImode, operands[3]);
17212 })
17213
17214 ; Don't promote the QImode tests, as i386 doesn't have encoding of
17215 ; the TEST instruction with 32-bit sign-extended immediate and thus
17216 ; the instruction size would at least double, which is not what we
17217 ; want even with ! optimize_size.
17218 (define_split
17219   [(set (match_operand 0 "flags_reg_operand" "")
17220         (match_operator 1 "compare_operator"
17221           [(and (match_operand:HI 2 "aligned_operand" "")
17222                 (match_operand:HI 3 "const_int_operand" ""))
17223            (const_int 0)]))]
17224   "! TARGET_PARTIAL_REG_STALL && reload_completed
17225    && ! TARGET_FAST_PREFIX
17226    && optimize_insn_for_speed_p ()
17227    /* Ensure that the operand will remain sign-extended immediate.  */
17228    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
17229   [(set (match_dup 0)
17230         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17231                          (const_int 0)]))]
17232 {
17233   operands[3]
17234     = gen_int_mode (INTVAL (operands[3])
17235                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
17236   operands[2] = gen_lowpart (SImode, operands[2]);
17237 })
17238
17239 (define_split
17240   [(set (match_operand 0 "register_operand" "")
17241         (neg (match_operand 1 "register_operand" "")))
17242    (clobber (reg:CC FLAGS_REG))]
17243   "! TARGET_PARTIAL_REG_STALL && reload_completed
17244    && (GET_MODE (operands[0]) == HImode
17245        || (GET_MODE (operands[0]) == QImode
17246            && (TARGET_PROMOTE_QImode
17247                || optimize_insn_for_size_p ())))"
17248   [(parallel [(set (match_dup 0)
17249                    (neg:SI (match_dup 1)))
17250               (clobber (reg:CC FLAGS_REG))])]
17251   "operands[0] = gen_lowpart (SImode, operands[0]);
17252    operands[1] = gen_lowpart (SImode, operands[1]);")
17253
17254 (define_split
17255   [(set (match_operand 0 "register_operand" "")
17256         (not (match_operand 1 "register_operand" "")))]
17257   "! TARGET_PARTIAL_REG_STALL && reload_completed
17258    && (GET_MODE (operands[0]) == HImode
17259        || (GET_MODE (operands[0]) == QImode
17260            && (TARGET_PROMOTE_QImode
17261                || optimize_insn_for_size_p ())))"
17262   [(set (match_dup 0)
17263         (not:SI (match_dup 1)))]
17264   "operands[0] = gen_lowpart (SImode, operands[0]);
17265    operands[1] = gen_lowpart (SImode, operands[1]);")
17266
17267 (define_split
17268   [(set (match_operand 0 "register_operand" "")
17269         (if_then_else (match_operator 1 "comparison_operator"
17270                                 [(reg FLAGS_REG) (const_int 0)])
17271                       (match_operand 2 "register_operand" "")
17272                       (match_operand 3 "register_operand" "")))]
17273   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
17274    && (GET_MODE (operands[0]) == HImode
17275        || (GET_MODE (operands[0]) == QImode
17276            && (TARGET_PROMOTE_QImode
17277                || optimize_insn_for_size_p ())))"
17278   [(set (match_dup 0)
17279         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
17280   "operands[0] = gen_lowpart (SImode, operands[0]);
17281    operands[2] = gen_lowpart (SImode, operands[2]);
17282    operands[3] = gen_lowpart (SImode, operands[3]);")
17283
17284 \f
17285 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
17286 ;; transform a complex memory operation into two memory to register operations.
17287
17288 ;; Don't push memory operands
17289 (define_peephole2
17290   [(set (match_operand:SI 0 "push_operand" "")
17291         (match_operand:SI 1 "memory_operand" ""))
17292    (match_scratch:SI 2 "r")]
17293   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
17294    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17295   [(set (match_dup 2) (match_dup 1))
17296    (set (match_dup 0) (match_dup 2))]
17297   "")
17298
17299 (define_peephole2
17300   [(set (match_operand:DI 0 "push_operand" "")
17301         (match_operand:DI 1 "memory_operand" ""))
17302    (match_scratch:DI 2 "r")]
17303   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
17304    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17305   [(set (match_dup 2) (match_dup 1))
17306    (set (match_dup 0) (match_dup 2))]
17307   "")
17308
17309 ;; We need to handle SFmode only, because DFmode and XFmode is split to
17310 ;; SImode pushes.
17311 (define_peephole2
17312   [(set (match_operand:SF 0 "push_operand" "")
17313         (match_operand:SF 1 "memory_operand" ""))
17314    (match_scratch:SF 2 "r")]
17315   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
17316    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17317   [(set (match_dup 2) (match_dup 1))
17318    (set (match_dup 0) (match_dup 2))]
17319   "")
17320
17321 (define_peephole2
17322   [(set (match_operand:HI 0 "push_operand" "")
17323         (match_operand:HI 1 "memory_operand" ""))
17324    (match_scratch:HI 2 "r")]
17325   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
17326    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17327   [(set (match_dup 2) (match_dup 1))
17328    (set (match_dup 0) (match_dup 2))]
17329   "")
17330
17331 (define_peephole2
17332   [(set (match_operand:QI 0 "push_operand" "")
17333         (match_operand:QI 1 "memory_operand" ""))
17334    (match_scratch:QI 2 "q")]
17335   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
17336    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17337   [(set (match_dup 2) (match_dup 1))
17338    (set (match_dup 0) (match_dup 2))]
17339   "")
17340
17341 ;; Don't move an immediate directly to memory when the instruction
17342 ;; gets too big.
17343 (define_peephole2
17344   [(match_scratch:SI 1 "r")
17345    (set (match_operand:SI 0 "memory_operand" "")
17346         (const_int 0))]
17347   "optimize_insn_for_speed_p ()
17348    && ! TARGET_USE_MOV0
17349    && TARGET_SPLIT_LONG_MOVES
17350    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
17351    && peep2_regno_dead_p (0, FLAGS_REG)"
17352   [(parallel [(set (match_dup 1) (const_int 0))
17353               (clobber (reg:CC FLAGS_REG))])
17354    (set (match_dup 0) (match_dup 1))]
17355   "")
17356
17357 (define_peephole2
17358   [(match_scratch:HI 1 "r")
17359    (set (match_operand:HI 0 "memory_operand" "")
17360         (const_int 0))]
17361   "optimize_insn_for_speed_p ()
17362    && ! TARGET_USE_MOV0
17363    && TARGET_SPLIT_LONG_MOVES
17364    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
17365    && peep2_regno_dead_p (0, FLAGS_REG)"
17366   [(parallel [(set (match_dup 2) (const_int 0))
17367               (clobber (reg:CC FLAGS_REG))])
17368    (set (match_dup 0) (match_dup 1))]
17369   "operands[2] = gen_lowpart (SImode, operands[1]);")
17370
17371 (define_peephole2
17372   [(match_scratch:QI 1 "q")
17373    (set (match_operand:QI 0 "memory_operand" "")
17374         (const_int 0))]
17375   "optimize_insn_for_speed_p ()
17376    && ! TARGET_USE_MOV0
17377    && TARGET_SPLIT_LONG_MOVES
17378    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
17379    && peep2_regno_dead_p (0, FLAGS_REG)"
17380   [(parallel [(set (match_dup 2) (const_int 0))
17381               (clobber (reg:CC FLAGS_REG))])
17382    (set (match_dup 0) (match_dup 1))]
17383   "operands[2] = gen_lowpart (SImode, operands[1]);")
17384
17385 (define_peephole2
17386   [(match_scratch:SI 2 "r")
17387    (set (match_operand:SI 0 "memory_operand" "")
17388         (match_operand:SI 1 "immediate_operand" ""))]
17389   "optimize_insn_for_speed_p ()
17390    && TARGET_SPLIT_LONG_MOVES
17391    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
17392   [(set (match_dup 2) (match_dup 1))
17393    (set (match_dup 0) (match_dup 2))]
17394   "")
17395
17396 (define_peephole2
17397   [(match_scratch:HI 2 "r")
17398    (set (match_operand:HI 0 "memory_operand" "")
17399         (match_operand:HI 1 "immediate_operand" ""))]
17400   "optimize_insn_for_speed_p ()
17401    && TARGET_SPLIT_LONG_MOVES
17402    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
17403   [(set (match_dup 2) (match_dup 1))
17404    (set (match_dup 0) (match_dup 2))]
17405   "")
17406
17407 (define_peephole2
17408   [(match_scratch:QI 2 "q")
17409    (set (match_operand:QI 0 "memory_operand" "")
17410         (match_operand:QI 1 "immediate_operand" ""))]
17411   "optimize_insn_for_speed_p ()
17412    && TARGET_SPLIT_LONG_MOVES
17413    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
17414   [(set (match_dup 2) (match_dup 1))
17415    (set (match_dup 0) (match_dup 2))]
17416   "")
17417
17418 ;; Don't compare memory with zero, load and use a test instead.
17419 (define_peephole2
17420   [(set (match_operand 0 "flags_reg_operand" "")
17421         (match_operator 1 "compare_operator"
17422           [(match_operand:SI 2 "memory_operand" "")
17423            (const_int 0)]))
17424    (match_scratch:SI 3 "r")]
17425   "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
17426   [(set (match_dup 3) (match_dup 2))
17427    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
17428   "")
17429
17430 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
17431 ;; Don't split NOTs with a displacement operand, because resulting XOR
17432 ;; will not be pairable anyway.
17433 ;;
17434 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
17435 ;; represented using a modRM byte.  The XOR replacement is long decoded,
17436 ;; so this split helps here as well.
17437 ;;
17438 ;; Note: Can't do this as a regular split because we can't get proper
17439 ;; lifetime information then.
17440
17441 (define_peephole2
17442   [(set (match_operand:SI 0 "nonimmediate_operand" "")
17443         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
17444   "optimize_insn_for_speed_p ()
17445    && ((TARGET_NOT_UNPAIRABLE
17446         && (!MEM_P (operands[0])
17447             || !memory_displacement_operand (operands[0], SImode)))
17448        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
17449    && peep2_regno_dead_p (0, FLAGS_REG)"
17450   [(parallel [(set (match_dup 0)
17451                    (xor:SI (match_dup 1) (const_int -1)))
17452               (clobber (reg:CC FLAGS_REG))])]
17453   "")
17454
17455 (define_peephole2
17456   [(set (match_operand:HI 0 "nonimmediate_operand" "")
17457         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
17458   "optimize_insn_for_speed_p ()
17459    && ((TARGET_NOT_UNPAIRABLE
17460         && (!MEM_P (operands[0])
17461             || !memory_displacement_operand (operands[0], HImode)))
17462        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
17463    && peep2_regno_dead_p (0, FLAGS_REG)"
17464   [(parallel [(set (match_dup 0)
17465                    (xor:HI (match_dup 1) (const_int -1)))
17466               (clobber (reg:CC FLAGS_REG))])]
17467   "")
17468
17469 (define_peephole2
17470   [(set (match_operand:QI 0 "nonimmediate_operand" "")
17471         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
17472   "optimize_insn_for_speed_p ()
17473    && ((TARGET_NOT_UNPAIRABLE
17474         && (!MEM_P (operands[0])
17475             || !memory_displacement_operand (operands[0], QImode)))
17476        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
17477    && peep2_regno_dead_p (0, FLAGS_REG)"
17478   [(parallel [(set (match_dup 0)
17479                    (xor:QI (match_dup 1) (const_int -1)))
17480               (clobber (reg:CC FLAGS_REG))])]
17481   "")
17482
17483 ;; Non pairable "test imm, reg" instructions can be translated to
17484 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
17485 ;; byte opcode instead of two, have a short form for byte operands),
17486 ;; so do it for other CPUs as well.  Given that the value was dead,
17487 ;; this should not create any new dependencies.  Pass on the sub-word
17488 ;; versions if we're concerned about partial register stalls.
17489
17490 (define_peephole2
17491   [(set (match_operand 0 "flags_reg_operand" "")
17492         (match_operator 1 "compare_operator"
17493           [(and:SI (match_operand:SI 2 "register_operand" "")
17494                    (match_operand:SI 3 "immediate_operand" ""))
17495            (const_int 0)]))]
17496   "ix86_match_ccmode (insn, CCNOmode)
17497    && (true_regnum (operands[2]) != AX_REG
17498        || satisfies_constraint_K (operands[3]))
17499    && peep2_reg_dead_p (1, operands[2])"
17500   [(parallel
17501      [(set (match_dup 0)
17502            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17503                             (const_int 0)]))
17504       (set (match_dup 2)
17505            (and:SI (match_dup 2) (match_dup 3)))])]
17506   "")
17507
17508 ;; We don't need to handle HImode case, because it will be promoted to SImode
17509 ;; on ! TARGET_PARTIAL_REG_STALL
17510
17511 (define_peephole2
17512   [(set (match_operand 0 "flags_reg_operand" "")
17513         (match_operator 1 "compare_operator"
17514           [(and:QI (match_operand:QI 2 "register_operand" "")
17515                    (match_operand:QI 3 "immediate_operand" ""))
17516            (const_int 0)]))]
17517   "! TARGET_PARTIAL_REG_STALL
17518    && ix86_match_ccmode (insn, CCNOmode)
17519    && true_regnum (operands[2]) != AX_REG
17520    && peep2_reg_dead_p (1, operands[2])"
17521   [(parallel
17522      [(set (match_dup 0)
17523            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17524                             (const_int 0)]))
17525       (set (match_dup 2)
17526            (and:QI (match_dup 2) (match_dup 3)))])]
17527   "")
17528
17529 (define_peephole2
17530   [(set (match_operand 0 "flags_reg_operand" "")
17531         (match_operator 1 "compare_operator"
17532           [(and:SI
17533              (zero_extract:SI
17534                (match_operand 2 "ext_register_operand" "")
17535                (const_int 8)
17536                (const_int 8))
17537              (match_operand 3 "const_int_operand" ""))
17538            (const_int 0)]))]
17539   "! TARGET_PARTIAL_REG_STALL
17540    && ix86_match_ccmode (insn, CCNOmode)
17541    && true_regnum (operands[2]) != AX_REG
17542    && peep2_reg_dead_p (1, operands[2])"
17543   [(parallel [(set (match_dup 0)
17544                    (match_op_dup 1
17545                      [(and:SI
17546                         (zero_extract:SI
17547                           (match_dup 2)
17548                           (const_int 8)
17549                           (const_int 8))
17550                         (match_dup 3))
17551                       (const_int 0)]))
17552               (set (zero_extract:SI (match_dup 2)
17553                                     (const_int 8)
17554                                     (const_int 8))
17555                    (and:SI
17556                      (zero_extract:SI
17557                        (match_dup 2)
17558                        (const_int 8)
17559                        (const_int 8))
17560                      (match_dup 3)))])]
17561   "")
17562
17563 ;; Don't do logical operations with memory inputs.
17564 (define_peephole2
17565   [(match_scratch:SI 2 "r")
17566    (parallel [(set (match_operand:SI 0 "register_operand" "")
17567                    (match_operator:SI 3 "arith_or_logical_operator"
17568                      [(match_dup 0)
17569                       (match_operand:SI 1 "memory_operand" "")]))
17570               (clobber (reg:CC FLAGS_REG))])]
17571   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
17572   [(set (match_dup 2) (match_dup 1))
17573    (parallel [(set (match_dup 0)
17574                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17575               (clobber (reg:CC FLAGS_REG))])]
17576   "")
17577
17578 (define_peephole2
17579   [(match_scratch:SI 2 "r")
17580    (parallel [(set (match_operand:SI 0 "register_operand" "")
17581                    (match_operator:SI 3 "arith_or_logical_operator"
17582                      [(match_operand:SI 1 "memory_operand" "")
17583                       (match_dup 0)]))
17584               (clobber (reg:CC FLAGS_REG))])]
17585   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
17586   [(set (match_dup 2) (match_dup 1))
17587    (parallel [(set (match_dup 0)
17588                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17589               (clobber (reg:CC FLAGS_REG))])]
17590   "")
17591
17592 ;; Prefer Load+RegOp to Mov+MemOp.  Watch out for cases when the memory address
17593 ;; refers to the destination of the load!
17594
17595 (define_peephole2
17596   [(set (match_operand:SI 0 "register_operand" "")
17597         (match_operand:SI 1 "register_operand" ""))
17598    (parallel [(set (match_dup 0)
17599                    (match_operator:SI 3 "commutative_operator"
17600                      [(match_dup 0)
17601                       (match_operand:SI 2 "memory_operand" "")]))
17602               (clobber (reg:CC FLAGS_REG))])]
17603   "REGNO (operands[0]) != REGNO (operands[1])
17604    && GENERAL_REGNO_P (REGNO (operands[0]))
17605    && GENERAL_REGNO_P (REGNO (operands[1]))"
17606   [(set (match_dup 0) (match_dup 4))
17607    (parallel [(set (match_dup 0)
17608                    (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17609               (clobber (reg:CC FLAGS_REG))])]
17610   "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17611
17612 (define_peephole2
17613   [(set (match_operand 0 "register_operand" "")
17614         (match_operand 1 "register_operand" ""))
17615    (set (match_dup 0)
17616                    (match_operator 3 "commutative_operator"
17617                      [(match_dup 0)
17618                       (match_operand 2 "memory_operand" "")]))]
17619   "REGNO (operands[0]) != REGNO (operands[1])
17620    && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1])) 
17621        || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17622   [(set (match_dup 0) (match_dup 2))
17623    (set (match_dup 0)
17624         (match_op_dup 3 [(match_dup 0) (match_dup 1)]))]
17625   "")
17626
17627 ; Don't do logical operations with memory outputs
17628 ;
17629 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17630 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
17631 ; the same decoder scheduling characteristics as the original.
17632
17633 (define_peephole2
17634   [(match_scratch:SI 2 "r")
17635    (parallel [(set (match_operand:SI 0 "memory_operand" "")
17636                    (match_operator:SI 3 "arith_or_logical_operator"
17637                      [(match_dup 0)
17638                       (match_operand:SI 1 "nonmemory_operand" "")]))
17639               (clobber (reg:CC FLAGS_REG))])]
17640   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
17641    /* Do not split stack checking probes.  */
17642    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17643   [(set (match_dup 2) (match_dup 0))
17644    (parallel [(set (match_dup 2)
17645                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17646               (clobber (reg:CC FLAGS_REG))])
17647    (set (match_dup 0) (match_dup 2))]
17648   "")
17649
17650 (define_peephole2
17651   [(match_scratch:SI 2 "r")
17652    (parallel [(set (match_operand:SI 0 "memory_operand" "")
17653                    (match_operator:SI 3 "arith_or_logical_operator"
17654                      [(match_operand:SI 1 "nonmemory_operand" "")
17655                       (match_dup 0)]))
17656               (clobber (reg:CC FLAGS_REG))])]
17657   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
17658    /* Do not split stack checking probes.  */
17659    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17660   [(set (match_dup 2) (match_dup 0))
17661    (parallel [(set (match_dup 2)
17662                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17663               (clobber (reg:CC FLAGS_REG))])
17664    (set (match_dup 0) (match_dup 2))]
17665   "")
17666
17667 ;; Attempt to always use XOR for zeroing registers.
17668 (define_peephole2
17669   [(set (match_operand 0 "register_operand" "")
17670         (match_operand 1 "const0_operand" ""))]
17671   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17672    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17673    && GENERAL_REG_P (operands[0])
17674    && peep2_regno_dead_p (0, FLAGS_REG)"
17675   [(parallel [(set (match_dup 0) (const_int 0))
17676               (clobber (reg:CC FLAGS_REG))])]
17677 {
17678   operands[0] = gen_lowpart (word_mode, operands[0]);
17679 })
17680
17681 (define_peephole2
17682   [(set (strict_low_part (match_operand 0 "register_operand" ""))
17683         (const_int 0))]
17684   "(GET_MODE (operands[0]) == QImode
17685     || GET_MODE (operands[0]) == HImode)
17686    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17687    && peep2_regno_dead_p (0, FLAGS_REG)"
17688   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17689               (clobber (reg:CC FLAGS_REG))])])
17690
17691 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
17692 (define_peephole2
17693   [(set (match_operand 0 "register_operand" "")
17694         (const_int -1))]
17695   "(GET_MODE (operands[0]) == HImode
17696     || GET_MODE (operands[0]) == SImode
17697     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
17698    && (optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17699    && peep2_regno_dead_p (0, FLAGS_REG)"
17700   [(parallel [(set (match_dup 0) (const_int -1))
17701               (clobber (reg:CC FLAGS_REG))])]
17702   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
17703                               operands[0]);")
17704
17705 ;; Attempt to convert simple leas to adds. These can be created by
17706 ;; move expanders.
17707 (define_peephole2
17708   [(set (match_operand:SI 0 "register_operand" "")
17709         (plus:SI (match_dup 0)
17710                  (match_operand:SI 1 "nonmemory_operand" "")))]
17711   "peep2_regno_dead_p (0, FLAGS_REG)"
17712   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
17713               (clobber (reg:CC FLAGS_REG))])]
17714   "")
17715
17716 (define_peephole2
17717   [(set (match_operand:SI 0 "register_operand" "")
17718         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
17719                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
17720   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
17721   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17722               (clobber (reg:CC FLAGS_REG))])]
17723   "operands[2] = gen_lowpart (SImode, operands[2]);")
17724
17725 (define_peephole2
17726   [(set (match_operand:DI 0 "register_operand" "")
17727         (plus:DI (match_dup 0)
17728                  (match_operand:DI 1 "x86_64_general_operand" "")))]
17729   "peep2_regno_dead_p (0, FLAGS_REG)"
17730   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
17731               (clobber (reg:CC FLAGS_REG))])]
17732   "")
17733
17734 (define_peephole2
17735   [(set (match_operand:SI 0 "register_operand" "")
17736         (mult:SI (match_dup 0)
17737                  (match_operand:SI 1 "const_int_operand" "")))]
17738   "exact_log2 (INTVAL (operands[1])) >= 0
17739    && peep2_regno_dead_p (0, FLAGS_REG)"
17740   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17741               (clobber (reg:CC FLAGS_REG))])]
17742   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17743
17744 (define_peephole2
17745   [(set (match_operand:DI 0 "register_operand" "")
17746         (mult:DI (match_dup 0)
17747                  (match_operand:DI 1 "const_int_operand" "")))]
17748   "exact_log2 (INTVAL (operands[1])) >= 0
17749    && peep2_regno_dead_p (0, FLAGS_REG)"
17750   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
17751               (clobber (reg:CC FLAGS_REG))])]
17752   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17753
17754 (define_peephole2
17755   [(set (match_operand:SI 0 "register_operand" "")
17756         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
17757                    (match_operand:DI 2 "const_int_operand" "")) 0))]
17758   "exact_log2 (INTVAL (operands[2])) >= 0
17759    && REGNO (operands[0]) == REGNO (operands[1])
17760    && peep2_regno_dead_p (0, FLAGS_REG)"
17761   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17762               (clobber (reg:CC FLAGS_REG))])]
17763   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17764
17765 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
17766 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
17767 ;; many CPUs it is also faster, since special hardware to avoid esp
17768 ;; dependencies is present.
17769
17770 ;; While some of these conversions may be done using splitters, we use peepholes
17771 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
17772
17773 ;; Convert prologue esp subtractions to push.
17774 ;; We need register to push.  In order to keep verify_flow_info happy we have
17775 ;; two choices
17776 ;; - use scratch and clobber it in order to avoid dependencies
17777 ;; - use already live register
17778 ;; We can't use the second way right now, since there is no reliable way how to
17779 ;; verify that given register is live.  First choice will also most likely in
17780 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
17781 ;; call clobbered registers are dead.  We may want to use base pointer as an
17782 ;; alternative when no register is available later.
17783
17784 (define_peephole2
17785   [(match_scratch:SI 0 "r")
17786    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
17787               (clobber (reg:CC FLAGS_REG))
17788               (clobber (mem:BLK (scratch)))])]
17789   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
17790   [(clobber (match_dup 0))
17791    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
17792               (clobber (mem:BLK (scratch)))])])
17793
17794 (define_peephole2
17795   [(match_scratch:SI 0 "r")
17796    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
17797               (clobber (reg:CC FLAGS_REG))
17798               (clobber (mem:BLK (scratch)))])]
17799   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
17800   [(clobber (match_dup 0))
17801    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
17802    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
17803               (clobber (mem:BLK (scratch)))])])
17804
17805 ;; Convert esp subtractions to push.
17806 (define_peephole2
17807   [(match_scratch:SI 0 "r")
17808    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
17809               (clobber (reg:CC FLAGS_REG))])]
17810   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
17811   [(clobber (match_dup 0))
17812    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
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 -8)))
17817               (clobber (reg:CC FLAGS_REG))])]
17818   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
17819   [(clobber (match_dup 0))
17820    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
17821    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
17822
17823 ;; Convert epilogue deallocator to pop.
17824 (define_peephole2
17825   [(match_scratch:SI 0 "r")
17826    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
17827               (clobber (reg:CC FLAGS_REG))
17828               (clobber (mem:BLK (scratch)))])]
17829   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
17830   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17831               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
17832               (clobber (mem:BLK (scratch)))])]
17833   "")
17834
17835 ;; Two pops case is tricky, since pop causes dependency on destination register.
17836 ;; We use two registers if available.
17837 (define_peephole2
17838   [(match_scratch:SI 0 "r")
17839    (match_scratch:SI 1 "r")
17840    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
17841               (clobber (reg:CC FLAGS_REG))
17842               (clobber (mem:BLK (scratch)))])]
17843   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
17844   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17845               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
17846               (clobber (mem:BLK (scratch)))])
17847    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
17848               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
17849   "")
17850
17851 (define_peephole2
17852   [(match_scratch:SI 0 "r")
17853    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
17854               (clobber (reg:CC FLAGS_REG))
17855               (clobber (mem:BLK (scratch)))])]
17856   "optimize_insn_for_size_p ()"
17857   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17858               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
17859               (clobber (mem:BLK (scratch)))])
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   "")
17863
17864 ;; Convert esp additions to pop.
17865 (define_peephole2
17866   [(match_scratch:SI 0 "r")
17867    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
17868               (clobber (reg:CC FLAGS_REG))])]
17869   ""
17870   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17871               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
17872   "")
17873
17874 ;; Two pops case is tricky, since pop causes dependency on destination register.
17875 ;; We use two registers if available.
17876 (define_peephole2
17877   [(match_scratch:SI 0 "r")
17878    (match_scratch:SI 1 "r")
17879    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
17880               (clobber (reg:CC FLAGS_REG))])]
17881   ""
17882   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17883               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
17884    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
17885               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
17886   "")
17887
17888 (define_peephole2
17889   [(match_scratch:SI 0 "r")
17890    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
17891               (clobber (reg:CC FLAGS_REG))])]
17892   "optimize_insn_for_size_p ()"
17893   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17894               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
17895    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17896               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
17897   "")
17898 \f
17899 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17900 ;; required and register dies.  Similarly for 128 to -128.
17901 (define_peephole2
17902   [(set (match_operand 0 "flags_reg_operand" "")
17903         (match_operator 1 "compare_operator"
17904           [(match_operand 2 "register_operand" "")
17905            (match_operand 3 "const_int_operand" "")]))]
17906   "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17907      && incdec_operand (operands[3], GET_MODE (operands[3])))
17908     || (!TARGET_FUSE_CMP_AND_BRANCH
17909         && INTVAL (operands[3]) == 128))
17910    && ix86_match_ccmode (insn, CCGCmode)
17911    && peep2_reg_dead_p (1, operands[2])"
17912   [(parallel [(set (match_dup 0)
17913                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17914               (clobber (match_dup 2))])]
17915   "")
17916 \f
17917 (define_peephole2
17918   [(match_scratch:DI 0 "r")
17919    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
17920               (clobber (reg:CC FLAGS_REG))
17921               (clobber (mem:BLK (scratch)))])]
17922   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
17923   [(clobber (match_dup 0))
17924    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
17925               (clobber (mem:BLK (scratch)))])])
17926
17927 (define_peephole2
17928   [(match_scratch:DI 0 "r")
17929    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
17930               (clobber (reg:CC FLAGS_REG))
17931               (clobber (mem:BLK (scratch)))])]
17932   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
17933   [(clobber (match_dup 0))
17934    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
17935    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
17936               (clobber (mem:BLK (scratch)))])])
17937
17938 ;; Convert esp subtractions to push.
17939 (define_peephole2
17940   [(match_scratch:DI 0 "r")
17941    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
17942               (clobber (reg:CC FLAGS_REG))])]
17943   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
17944   [(clobber (match_dup 0))
17945    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
17946
17947 (define_peephole2
17948   [(match_scratch:DI 0 "r")
17949    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
17950               (clobber (reg:CC FLAGS_REG))])]
17951   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
17952   [(clobber (match_dup 0))
17953    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
17954    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
17955
17956 ;; Convert epilogue deallocator to pop.
17957 (define_peephole2
17958   [(match_scratch:DI 0 "r")
17959    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
17960               (clobber (reg:CC FLAGS_REG))
17961               (clobber (mem:BLK (scratch)))])]
17962   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
17963   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17964               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
17965               (clobber (mem:BLK (scratch)))])]
17966   "")
17967
17968 ;; Two pops case is tricky, since pop causes dependency on destination register.
17969 ;; We use two registers if available.
17970 (define_peephole2
17971   [(match_scratch:DI 0 "r")
17972    (match_scratch:DI 1 "r")
17973    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
17974               (clobber (reg:CC FLAGS_REG))
17975               (clobber (mem:BLK (scratch)))])]
17976   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
17977   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17978               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
17979               (clobber (mem:BLK (scratch)))])
17980    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
17981               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
17982   "")
17983
17984 (define_peephole2
17985   [(match_scratch:DI 0 "r")
17986    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
17987               (clobber (reg:CC FLAGS_REG))
17988               (clobber (mem:BLK (scratch)))])]
17989   "optimize_insn_for_size_p ()"
17990   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17991               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
17992               (clobber (mem:BLK (scratch)))])
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   "")
17996
17997 ;; Convert esp additions to pop.
17998 (define_peephole2
17999   [(match_scratch:DI 0 "r")
18000    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
18001               (clobber (reg:CC FLAGS_REG))])]
18002   ""
18003   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18004               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
18005   "")
18006
18007 ;; Two pops case is tricky, since pop causes dependency on destination register.
18008 ;; We use two registers if available.
18009 (define_peephole2
18010   [(match_scratch:DI 0 "r")
18011    (match_scratch:DI 1 "r")
18012    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
18013               (clobber (reg:CC FLAGS_REG))])]
18014   ""
18015   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18016               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
18017    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
18018               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
18019   "")
18020
18021 (define_peephole2
18022   [(match_scratch:DI 0 "r")
18023    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
18024               (clobber (reg:CC FLAGS_REG))])]
18025   "optimize_insn_for_size_p ()"
18026   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18027               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
18028    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18029               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
18030   "")
18031 \f
18032 ;; Convert imul by three, five and nine into lea
18033 (define_peephole2
18034   [(parallel
18035     [(set (match_operand:SI 0 "register_operand" "")
18036           (mult:SI (match_operand:SI 1 "register_operand" "")
18037                    (match_operand:SI 2 "const_int_operand" "")))
18038      (clobber (reg:CC FLAGS_REG))])]
18039   "INTVAL (operands[2]) == 3
18040    || INTVAL (operands[2]) == 5
18041    || INTVAL (operands[2]) == 9"
18042   [(set (match_dup 0)
18043         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
18044                  (match_dup 1)))]
18045   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
18046
18047 (define_peephole2
18048   [(parallel
18049     [(set (match_operand:SI 0 "register_operand" "")
18050           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
18051                    (match_operand:SI 2 "const_int_operand" "")))
18052      (clobber (reg:CC FLAGS_REG))])]
18053   "optimize_insn_for_speed_p ()
18054    && (INTVAL (operands[2]) == 3
18055        || INTVAL (operands[2]) == 5
18056        || INTVAL (operands[2]) == 9)"
18057   [(set (match_dup 0) (match_dup 1))
18058    (set (match_dup 0)
18059         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
18060                  (match_dup 0)))]
18061   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
18062
18063 (define_peephole2
18064   [(parallel
18065     [(set (match_operand:DI 0 "register_operand" "")
18066           (mult:DI (match_operand:DI 1 "register_operand" "")
18067                    (match_operand:DI 2 "const_int_operand" "")))
18068      (clobber (reg:CC FLAGS_REG))])]
18069   "TARGET_64BIT
18070    && (INTVAL (operands[2]) == 3
18071        || INTVAL (operands[2]) == 5
18072        || INTVAL (operands[2]) == 9)"
18073   [(set (match_dup 0)
18074         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
18075                  (match_dup 1)))]
18076   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
18077
18078 (define_peephole2
18079   [(parallel
18080     [(set (match_operand:DI 0 "register_operand" "")
18081           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
18082                    (match_operand:DI 2 "const_int_operand" "")))
18083      (clobber (reg:CC FLAGS_REG))])]
18084   "TARGET_64BIT
18085    && optimize_insn_for_speed_p ()
18086    && (INTVAL (operands[2]) == 3
18087        || INTVAL (operands[2]) == 5
18088        || INTVAL (operands[2]) == 9)"
18089   [(set (match_dup 0) (match_dup 1))
18090    (set (match_dup 0)
18091         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
18092                  (match_dup 0)))]
18093   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
18094
18095 ;; Imul $32bit_imm, mem, reg is vector decoded, while
18096 ;; imul $32bit_imm, reg, reg is direct decoded.
18097 (define_peephole2
18098   [(match_scratch:DI 3 "r")
18099    (parallel [(set (match_operand:DI 0 "register_operand" "")
18100                    (mult:DI (match_operand:DI 1 "memory_operand" "")
18101                             (match_operand:DI 2 "immediate_operand" "")))
18102               (clobber (reg:CC FLAGS_REG))])]
18103   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
18104    && !satisfies_constraint_K (operands[2])"
18105   [(set (match_dup 3) (match_dup 1))
18106    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
18107               (clobber (reg:CC FLAGS_REG))])]
18108 "")
18109
18110 (define_peephole2
18111   [(match_scratch:SI 3 "r")
18112    (parallel [(set (match_operand:SI 0 "register_operand" "")
18113                    (mult:SI (match_operand:SI 1 "memory_operand" "")
18114                             (match_operand:SI 2 "immediate_operand" "")))
18115               (clobber (reg:CC FLAGS_REG))])]
18116   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
18117    && !satisfies_constraint_K (operands[2])"
18118   [(set (match_dup 3) (match_dup 1))
18119    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
18120               (clobber (reg:CC FLAGS_REG))])]
18121 "")
18122
18123 (define_peephole2
18124   [(match_scratch:SI 3 "r")
18125    (parallel [(set (match_operand:DI 0 "register_operand" "")
18126                    (zero_extend:DI
18127                      (mult:SI (match_operand:SI 1 "memory_operand" "")
18128                               (match_operand:SI 2 "immediate_operand" ""))))
18129               (clobber (reg:CC FLAGS_REG))])]
18130   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
18131    && !satisfies_constraint_K (operands[2])"
18132   [(set (match_dup 3) (match_dup 1))
18133    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
18134               (clobber (reg:CC FLAGS_REG))])]
18135 "")
18136
18137 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
18138 ;; Convert it into imul reg, reg
18139 ;; It would be better to force assembler to encode instruction using long
18140 ;; immediate, but there is apparently no way to do so.
18141 (define_peephole2
18142   [(parallel [(set (match_operand:DI 0 "register_operand" "")
18143                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
18144                             (match_operand:DI 2 "const_int_operand" "")))
18145               (clobber (reg:CC FLAGS_REG))])
18146    (match_scratch:DI 3 "r")]
18147   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
18148    && satisfies_constraint_K (operands[2])"
18149   [(set (match_dup 3) (match_dup 2))
18150    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
18151               (clobber (reg:CC FLAGS_REG))])]
18152 {
18153   if (!rtx_equal_p (operands[0], operands[1]))
18154     emit_move_insn (operands[0], operands[1]);
18155 })
18156
18157 (define_peephole2
18158   [(parallel [(set (match_operand:SI 0 "register_operand" "")
18159                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
18160                             (match_operand:SI 2 "const_int_operand" "")))
18161               (clobber (reg:CC FLAGS_REG))])
18162    (match_scratch:SI 3 "r")]
18163   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
18164    && satisfies_constraint_K (operands[2])"
18165   [(set (match_dup 3) (match_dup 2))
18166    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
18167               (clobber (reg:CC FLAGS_REG))])]
18168 {
18169   if (!rtx_equal_p (operands[0], operands[1]))
18170     emit_move_insn (operands[0], operands[1]);
18171 })
18172
18173 (define_peephole2
18174   [(parallel [(set (match_operand:HI 0 "register_operand" "")
18175                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
18176                             (match_operand:HI 2 "immediate_operand" "")))
18177               (clobber (reg:CC FLAGS_REG))])
18178    (match_scratch:HI 3 "r")]
18179   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()"
18180   [(set (match_dup 3) (match_dup 2))
18181    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
18182               (clobber (reg:CC FLAGS_REG))])]
18183 {
18184   if (!rtx_equal_p (operands[0], operands[1]))
18185     emit_move_insn (operands[0], operands[1]);
18186 })
18187
18188 ;; After splitting up read-modify operations, array accesses with memory
18189 ;; operands might end up in form:
18190 ;;  sall    $2, %eax
18191 ;;  movl    4(%esp), %edx
18192 ;;  addl    %edx, %eax
18193 ;; instead of pre-splitting:
18194 ;;  sall    $2, %eax
18195 ;;  addl    4(%esp), %eax
18196 ;; Turn it into:
18197 ;;  movl    4(%esp), %edx
18198 ;;  leal    (%edx,%eax,4), %eax
18199
18200 (define_peephole2
18201   [(parallel [(set (match_operand 0 "register_operand" "")
18202                    (ashift (match_operand 1 "register_operand" "")
18203                            (match_operand 2 "const_int_operand" "")))
18204                (clobber (reg:CC FLAGS_REG))])
18205    (set (match_operand 3 "register_operand")
18206         (match_operand 4 "x86_64_general_operand" ""))
18207    (parallel [(set (match_operand 5 "register_operand" "")
18208                    (plus (match_operand 6 "register_operand" "")
18209                          (match_operand 7 "register_operand" "")))
18210                    (clobber (reg:CC FLAGS_REG))])]
18211   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
18212    /* Validate MODE for lea.  */
18213    && ((!TARGET_PARTIAL_REG_STALL
18214         && (GET_MODE (operands[0]) == QImode
18215             || GET_MODE (operands[0]) == HImode))
18216        || GET_MODE (operands[0]) == SImode
18217        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
18218    /* We reorder load and the shift.  */
18219    && !rtx_equal_p (operands[1], operands[3])
18220    && !reg_overlap_mentioned_p (operands[0], operands[4])
18221    /* Last PLUS must consist of operand 0 and 3.  */
18222    && !rtx_equal_p (operands[0], operands[3])
18223    && (rtx_equal_p (operands[3], operands[6])
18224        || rtx_equal_p (operands[3], operands[7]))
18225    && (rtx_equal_p (operands[0], operands[6])
18226        || rtx_equal_p (operands[0], operands[7]))
18227    /* The intermediate operand 0 must die or be same as output.  */
18228    && (rtx_equal_p (operands[0], operands[5])
18229        || peep2_reg_dead_p (3, operands[0]))"
18230   [(set (match_dup 3) (match_dup 4))
18231    (set (match_dup 0) (match_dup 1))]
18232 {
18233   enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
18234   int scale = 1 << INTVAL (operands[2]);
18235   rtx index = gen_lowpart (Pmode, operands[1]);
18236   rtx base = gen_lowpart (Pmode, operands[3]);
18237   rtx dest = gen_lowpart (mode, operands[5]);
18238
18239   operands[1] = gen_rtx_PLUS (Pmode, base,
18240                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
18241   if (mode != Pmode)
18242     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
18243   operands[0] = dest;
18244 })
18245 \f
18246 ;; Call-value patterns last so that the wildcard operand does not
18247 ;; disrupt insn-recog's switch tables.
18248
18249 (define_insn "*call_value_pop_0"
18250   [(set (match_operand 0 "" "")
18251         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
18252               (match_operand:SI 2 "" "")))
18253    (set (reg:SI SP_REG)
18254         (plus:SI (reg:SI SP_REG)
18255                  (match_operand:SI 3 "immediate_operand" "")))]
18256   "!TARGET_64BIT"
18257 {
18258   if (SIBLING_CALL_P (insn))
18259     return "jmp\t%P1";
18260   else
18261     return "call\t%P1";
18262 }
18263   [(set_attr "type" "callv")])
18264
18265 (define_insn "*call_value_pop_1"
18266   [(set (match_operand 0 "" "")
18267         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
18268               (match_operand:SI 2 "" "")))
18269    (set (reg:SI SP_REG)
18270         (plus:SI (reg:SI SP_REG)
18271                  (match_operand:SI 3 "immediate_operand" "i")))]
18272   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
18273 {
18274   if (constant_call_address_operand (operands[1], Pmode))
18275     return "call\t%P1";
18276   return "call\t%A1";
18277 }
18278   [(set_attr "type" "callv")])
18279
18280 (define_insn "*sibcall_value_pop_1"
18281   [(set (match_operand 0 "" "")
18282         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
18283               (match_operand:SI 2 "" "")))
18284    (set (reg:SI SP_REG)
18285         (plus:SI (reg:SI SP_REG)
18286                  (match_operand:SI 3 "immediate_operand" "i,i")))]
18287   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
18288   "@
18289    jmp\t%P1
18290    jmp\t%A1"
18291   [(set_attr "type" "callv")])
18292
18293 (define_insn "*call_value_0"
18294   [(set (match_operand 0 "" "")
18295         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
18296               (match_operand:SI 2 "" "")))]
18297   "!TARGET_64BIT"
18298 {
18299   if (SIBLING_CALL_P (insn))
18300     return "jmp\t%P1";
18301   else
18302     return "call\t%P1";
18303 }
18304   [(set_attr "type" "callv")])
18305
18306 (define_insn "*call_value_0_rex64"
18307   [(set (match_operand 0 "" "")
18308         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
18309               (match_operand:DI 2 "const_int_operand" "")))]
18310   "TARGET_64BIT"
18311 {
18312   if (SIBLING_CALL_P (insn))
18313     return "jmp\t%P1";
18314   else
18315     return "call\t%P1";
18316 }
18317   [(set_attr "type" "callv")])
18318
18319 (define_insn "*call_value_0_rex64_ms_sysv"
18320   [(set (match_operand 0 "" "")
18321         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
18322               (match_operand:DI 2 "const_int_operand" "")))
18323    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
18324    (clobber (reg:TI XMM6_REG))
18325    (clobber (reg:TI XMM7_REG))
18326    (clobber (reg:TI XMM8_REG))
18327    (clobber (reg:TI XMM9_REG))
18328    (clobber (reg:TI XMM10_REG))
18329    (clobber (reg:TI XMM11_REG))
18330    (clobber (reg:TI XMM12_REG))
18331    (clobber (reg:TI XMM13_REG))
18332    (clobber (reg:TI XMM14_REG))
18333    (clobber (reg:TI XMM15_REG))
18334    (clobber (reg:DI SI_REG))
18335    (clobber (reg:DI DI_REG))]
18336   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
18337 {
18338   if (SIBLING_CALL_P (insn))
18339     return "jmp\t%P1";
18340   else
18341     return "call\t%P1";
18342 }
18343   [(set_attr "type" "callv")])
18344
18345 (define_insn "*call_value_1"
18346   [(set (match_operand 0 "" "")
18347         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
18348               (match_operand:SI 2 "" "")))]
18349   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
18350 {
18351   if (constant_call_address_operand (operands[1], Pmode))
18352     return "call\t%P1";
18353   return "call\t%A1";
18354 }
18355   [(set_attr "type" "callv")])
18356
18357 (define_insn "*sibcall_value_1"
18358   [(set (match_operand 0 "" "")
18359         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
18360               (match_operand:SI 2 "" "")))]
18361   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
18362   "@
18363    jmp\t%P1
18364    jmp\t%A1"
18365   [(set_attr "type" "callv")])
18366
18367 (define_insn "*call_value_1_rex64"
18368   [(set (match_operand 0 "" "")
18369         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
18370               (match_operand:DI 2 "" "")))]
18371   "TARGET_64BIT && !SIBLING_CALL_P (insn)
18372    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
18373 {
18374   if (constant_call_address_operand (operands[1], Pmode))
18375     return "call\t%P1";
18376   return "call\t%A1";
18377 }
18378   [(set_attr "type" "callv")])
18379
18380 (define_insn "*call_value_1_rex64_ms_sysv"
18381   [(set (match_operand 0 "" "")
18382         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
18383               (match_operand:DI 2 "" "")))
18384    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
18385    (clobber (reg:TI XMM6_REG))
18386    (clobber (reg:TI XMM7_REG))
18387    (clobber (reg:TI XMM8_REG))
18388    (clobber (reg:TI XMM9_REG))
18389    (clobber (reg:TI XMM10_REG))
18390    (clobber (reg:TI XMM11_REG))
18391    (clobber (reg:TI XMM12_REG))
18392    (clobber (reg:TI XMM13_REG))
18393    (clobber (reg:TI XMM14_REG))
18394    (clobber (reg:TI XMM15_REG))
18395    (clobber (reg:DI SI_REG))
18396    (clobber (reg:DI DI_REG))]
18397   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
18398 {
18399   if (constant_call_address_operand (operands[1], Pmode))
18400     return "call\t%P1";
18401   return "call\t%A1";
18402 }
18403   [(set_attr "type" "callv")])
18404
18405 (define_insn "*call_value_1_rex64_large"
18406   [(set (match_operand 0 "" "")
18407         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
18408               (match_operand:DI 2 "" "")))]
18409   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
18410   "call\t%A1"
18411   [(set_attr "type" "callv")])
18412
18413 (define_insn "*sibcall_value_1_rex64"
18414   [(set (match_operand 0 "" "")
18415         (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
18416               (match_operand:DI 2 "" "")))]
18417   "TARGET_64BIT && SIBLING_CALL_P (insn)"
18418   "@
18419    jmp\t%P1
18420    jmp\t%A1"
18421   [(set_attr "type" "callv")])
18422 \f
18423 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
18424 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
18425 ;; caught for use by garbage collectors and the like.  Using an insn that
18426 ;; maps to SIGILL makes it more likely the program will rightfully die.
18427 ;; Keeping with tradition, "6" is in honor of #UD.
18428 (define_insn "trap"
18429   [(trap_if (const_int 1) (const_int 6))]
18430   ""
18431   { return ASM_SHORT "0x0b0f"; }
18432   [(set_attr "length" "2")])
18433
18434 (define_expand "sse_prologue_save"
18435   [(parallel [(set (match_operand:BLK 0 "" "")
18436                    (unspec:BLK [(reg:DI XMM0_REG)
18437                                 (reg:DI XMM1_REG)
18438                                 (reg:DI XMM2_REG)
18439                                 (reg:DI XMM3_REG)
18440                                 (reg:DI XMM4_REG)
18441                                 (reg:DI XMM5_REG)
18442                                 (reg:DI XMM6_REG)
18443                                 (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE))
18444               (use (match_operand:DI 1 "register_operand" ""))
18445               (use (match_operand:DI 2 "immediate_operand" ""))
18446               (use (label_ref:DI (match_operand 3 "" "")))])]
18447   "TARGET_64BIT"
18448   "")
18449
18450 (define_insn "*sse_prologue_save_insn"
18451   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
18452                           (match_operand:DI 4 "const_int_operand" "n")))
18453         (unspec:BLK [(reg:DI XMM0_REG)
18454                      (reg:DI XMM1_REG)
18455                      (reg:DI XMM2_REG)
18456                      (reg:DI XMM3_REG)
18457                      (reg:DI XMM4_REG)
18458                      (reg:DI XMM5_REG)
18459                      (reg:DI XMM6_REG)
18460                      (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE))
18461    (use (match_operand:DI 1 "register_operand" "r"))
18462    (use (match_operand:DI 2 "const_int_operand" "i"))
18463    (use (label_ref:DI (match_operand 3 "" "X")))]
18464   "TARGET_64BIT
18465    && INTVAL (operands[4]) + X86_64_SSE_REGPARM_MAX * 16 - 16 < 128
18466    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
18467 {
18468   int i;
18469   operands[0] = gen_rtx_MEM (Pmode,
18470                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
18471   /* VEX instruction with a REX prefix will #UD.  */
18472   if (TARGET_AVX && GET_CODE (XEXP (operands[0], 0)) != PLUS)
18473     gcc_unreachable ();
18474
18475   output_asm_insn ("jmp\t%A1", operands);
18476   for (i = X86_64_SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
18477     {
18478       operands[4] = adjust_address (operands[0], DImode, i*16);
18479       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
18480       PUT_MODE (operands[4], TImode);
18481       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
18482         output_asm_insn ("rex", operands);
18483       output_asm_insn ("%vmovaps\t{%5, %4|%4, %5}", operands);
18484     }
18485   (*targetm.asm_out.internal_label) (asm_out_file, "L",
18486                                      CODE_LABEL_NUMBER (operands[3]));
18487   return "";
18488 }
18489   [(set_attr "type" "other")
18490    (set_attr "length_immediate" "0")
18491    (set_attr "length_address" "0")
18492    (set (attr "length")
18493      (if_then_else
18494        (eq (symbol_ref "TARGET_AVX") (const_int 0))
18495        (const_string "34")
18496        (const_string "42")))
18497    (set_attr "memory" "store")
18498    (set_attr "modrm" "0")
18499    (set_attr "prefix" "maybe_vex")
18500    (set_attr "mode" "DI")])
18501
18502 (define_expand "prefetch"
18503   [(prefetch (match_operand 0 "address_operand" "")
18504              (match_operand:SI 1 "const_int_operand" "")
18505              (match_operand:SI 2 "const_int_operand" ""))]
18506   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
18507 {
18508   int rw = INTVAL (operands[1]);
18509   int locality = INTVAL (operands[2]);
18510
18511   gcc_assert (rw == 0 || rw == 1);
18512   gcc_assert (locality >= 0 && locality <= 3);
18513   gcc_assert (GET_MODE (operands[0]) == Pmode
18514               || GET_MODE (operands[0]) == VOIDmode);
18515
18516   /* Use 3dNOW prefetch in case we are asking for write prefetch not
18517      supported by SSE counterpart or the SSE prefetch is not available
18518      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
18519      of locality.  */
18520   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
18521     operands[2] = GEN_INT (3);
18522   else
18523     operands[1] = const0_rtx;
18524 })
18525
18526 (define_insn "*prefetch_sse"
18527   [(prefetch (match_operand:SI 0 "address_operand" "p")
18528              (const_int 0)
18529              (match_operand:SI 1 "const_int_operand" ""))]
18530   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
18531 {
18532   static const char * const patterns[4] = {
18533    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
18534   };
18535
18536   int locality = INTVAL (operands[1]);
18537   gcc_assert (locality >= 0 && locality <= 3);
18538
18539   return patterns[locality];
18540 }
18541   [(set_attr "type" "sse")
18542    (set_attr "atom_sse_attr" "prefetch")
18543    (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
18544    (set_attr "memory" "none")])
18545
18546 (define_insn "*prefetch_sse_rex"
18547   [(prefetch (match_operand:DI 0 "address_operand" "p")
18548              (const_int 0)
18549              (match_operand:SI 1 "const_int_operand" ""))]
18550   "TARGET_PREFETCH_SSE && TARGET_64BIT"
18551 {
18552   static const char * const patterns[4] = {
18553    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
18554   };
18555
18556   int locality = INTVAL (operands[1]);
18557   gcc_assert (locality >= 0 && locality <= 3);
18558
18559   return patterns[locality];
18560 }
18561   [(set_attr "type" "sse")
18562    (set_attr "atom_sse_attr" "prefetch")
18563    (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
18564    (set_attr "memory" "none")])
18565
18566 (define_insn "*prefetch_3dnow"
18567   [(prefetch (match_operand:SI 0 "address_operand" "p")
18568              (match_operand:SI 1 "const_int_operand" "n")
18569              (const_int 3))]
18570   "TARGET_3DNOW && !TARGET_64BIT"
18571 {
18572   if (INTVAL (operands[1]) == 0)
18573     return "prefetch\t%a0";
18574   else
18575     return "prefetchw\t%a0";
18576 }
18577   [(set_attr "type" "mmx")
18578    (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
18579    (set_attr "memory" "none")])
18580
18581 (define_insn "*prefetch_3dnow_rex"
18582   [(prefetch (match_operand:DI 0 "address_operand" "p")
18583              (match_operand:SI 1 "const_int_operand" "n")
18584              (const_int 3))]
18585   "TARGET_3DNOW && TARGET_64BIT"
18586 {
18587   if (INTVAL (operands[1]) == 0)
18588     return "prefetch\t%a0";
18589   else
18590     return "prefetchw\t%a0";
18591 }
18592   [(set_attr "type" "mmx")
18593    (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
18594    (set_attr "memory" "none")])
18595
18596 (define_expand "stack_protect_set"
18597   [(match_operand 0 "memory_operand" "")
18598    (match_operand 1 "memory_operand" "")]
18599   ""
18600 {
18601 #ifdef TARGET_THREAD_SSP_OFFSET
18602   if (TARGET_64BIT)
18603     emit_insn (gen_stack_tls_protect_set_di (operands[0],
18604                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
18605   else
18606     emit_insn (gen_stack_tls_protect_set_si (operands[0],
18607                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
18608 #else
18609   if (TARGET_64BIT)
18610     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
18611   else
18612     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
18613 #endif
18614   DONE;
18615 })
18616
18617 (define_insn "stack_protect_set_si"
18618   [(set (match_operand:SI 0 "memory_operand" "=m")
18619         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
18620    (set (match_scratch:SI 2 "=&r") (const_int 0))
18621    (clobber (reg:CC FLAGS_REG))]
18622   ""
18623   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
18624   [(set_attr "type" "multi")])
18625
18626 (define_insn "stack_protect_set_di"
18627   [(set (match_operand:DI 0 "memory_operand" "=m")
18628         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
18629    (set (match_scratch:DI 2 "=&r") (const_int 0))
18630    (clobber (reg:CC FLAGS_REG))]
18631   "TARGET_64BIT"
18632   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
18633   [(set_attr "type" "multi")])
18634
18635 (define_insn "stack_tls_protect_set_si"
18636   [(set (match_operand:SI 0 "memory_operand" "=m")
18637         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
18638    (set (match_scratch:SI 2 "=&r") (const_int 0))
18639    (clobber (reg:CC FLAGS_REG))]
18640   ""
18641   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
18642   [(set_attr "type" "multi")])
18643
18644 (define_insn "stack_tls_protect_set_di"
18645   [(set (match_operand:DI 0 "memory_operand" "=m")
18646         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
18647    (set (match_scratch:DI 2 "=&r") (const_int 0))
18648    (clobber (reg:CC FLAGS_REG))]
18649   "TARGET_64BIT"
18650   {
18651      /* The kernel uses a different segment register for performance reasons; a
18652         system call would not have to trash the userspace segment register,
18653         which would be expensive */
18654      if (ix86_cmodel != CM_KERNEL)
18655         return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
18656      else
18657         return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
18658   }
18659   [(set_attr "type" "multi")])
18660
18661 (define_expand "stack_protect_test"
18662   [(match_operand 0 "memory_operand" "")
18663    (match_operand 1 "memory_operand" "")
18664    (match_operand 2 "" "")]
18665   ""
18666 {
18667   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
18668
18669 #ifdef TARGET_THREAD_SSP_OFFSET
18670   if (TARGET_64BIT)
18671     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
18672                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
18673   else
18674     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
18675                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
18676 #else
18677   if (TARGET_64BIT)
18678     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
18679   else
18680     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
18681 #endif
18682
18683   emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
18684                                   flags, const0_rtx, operands[2]));
18685   DONE;
18686 })
18687
18688 (define_insn "stack_protect_test_si"
18689   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
18690         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
18691                      (match_operand:SI 2 "memory_operand" "m")]
18692                     UNSPEC_SP_TEST))
18693    (clobber (match_scratch:SI 3 "=&r"))]
18694   ""
18695   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
18696   [(set_attr "type" "multi")])
18697
18698 (define_insn "stack_protect_test_di"
18699   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
18700         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
18701                      (match_operand:DI 2 "memory_operand" "m")]
18702                     UNSPEC_SP_TEST))
18703    (clobber (match_scratch:DI 3 "=&r"))]
18704   "TARGET_64BIT"
18705   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
18706   [(set_attr "type" "multi")])
18707
18708 (define_insn "stack_tls_protect_test_si"
18709   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
18710         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
18711                      (match_operand:SI 2 "const_int_operand" "i")]
18712                     UNSPEC_SP_TLS_TEST))
18713    (clobber (match_scratch:SI 3 "=r"))]
18714   ""
18715   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
18716   [(set_attr "type" "multi")])
18717
18718 (define_insn "stack_tls_protect_test_di"
18719   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
18720         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
18721                      (match_operand:DI 2 "const_int_operand" "i")]
18722                     UNSPEC_SP_TLS_TEST))
18723    (clobber (match_scratch:DI 3 "=r"))]
18724   "TARGET_64BIT"
18725   {
18726      /* The kernel uses a different segment register for performance reasons; a
18727         system call would not have to trash the userspace segment register,
18728         which would be expensive */
18729      if (ix86_cmodel != CM_KERNEL)
18730         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
18731      else
18732         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
18733   }
18734   [(set_attr "type" "multi")])
18735
18736 (define_insn "sse4_2_crc32<mode>"
18737   [(set (match_operand:SI 0 "register_operand" "=r")
18738         (unspec:SI
18739           [(match_operand:SI 1 "register_operand" "0")
18740            (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
18741           UNSPEC_CRC32))]
18742   "TARGET_SSE4_2 || TARGET_CRC32"
18743   "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
18744   [(set_attr "type" "sselog1")
18745    (set_attr "prefix_rep" "1")
18746    (set_attr "prefix_extra" "1")
18747    (set (attr "prefix_data16")
18748      (if_then_else (match_operand:HI 2 "" "")
18749        (const_string "1")
18750        (const_string "*")))
18751    (set (attr "prefix_rex")
18752      (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
18753        (const_string "1")
18754        (const_string "*")))
18755    (set_attr "mode" "SI")])
18756
18757 (define_insn "sse4_2_crc32di"
18758   [(set (match_operand:DI 0 "register_operand" "=r")
18759         (unspec:DI
18760           [(match_operand:DI 1 "register_operand" "0")
18761            (match_operand:DI 2 "nonimmediate_operand" "rm")]
18762           UNSPEC_CRC32))]
18763   "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
18764   "crc32{q}\t{%2, %0|%0, %2}"
18765   [(set_attr "type" "sselog1")
18766    (set_attr "prefix_rep" "1")
18767    (set_attr "prefix_extra" "1")
18768    (set_attr "mode" "DI")])
18769
18770 (define_expand "rdpmc"
18771   [(match_operand:DI 0 "register_operand" "")
18772    (match_operand:SI 1 "register_operand" "")]
18773   ""
18774 {
18775   rtx reg = gen_reg_rtx (DImode);
18776   rtx si;
18777
18778   /* Force operand 1 into ECX.  */
18779   rtx ecx = gen_rtx_REG (SImode, CX_REG);
18780   emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
18781   si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
18782                                 UNSPECV_RDPMC);
18783
18784   if (TARGET_64BIT)
18785     {
18786       rtvec vec = rtvec_alloc (2);
18787       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18788       rtx upper = gen_reg_rtx (DImode);
18789       rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
18790                                         gen_rtvec (1, const0_rtx),
18791                                         UNSPECV_RDPMC);
18792       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
18793       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
18794       emit_insn (load);
18795       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18796                                    NULL, 1, OPTAB_DIRECT);
18797       reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
18798                                  OPTAB_DIRECT);
18799     }
18800   else
18801     emit_insn (gen_rtx_SET (VOIDmode, reg, si));
18802   emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
18803   DONE;
18804 })
18805
18806 (define_insn "*rdpmc"
18807   [(set (match_operand:DI 0 "register_operand" "=A")
18808         (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
18809                             UNSPECV_RDPMC))]
18810   "!TARGET_64BIT"
18811   "rdpmc"
18812   [(set_attr "type" "other")
18813    (set_attr "length" "2")])
18814
18815 (define_insn "*rdpmc_rex64"
18816   [(set (match_operand:DI 0 "register_operand" "=a")
18817         (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
18818                             UNSPECV_RDPMC))
18819   (set (match_operand:DI 1 "register_operand" "=d")
18820        (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
18821   "TARGET_64BIT"
18822   "rdpmc"
18823   [(set_attr "type" "other")
18824    (set_attr "length" "2")])
18825
18826 (define_expand "rdtsc"
18827   [(set (match_operand:DI 0 "register_operand" "")
18828         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18829   ""
18830 {
18831   if (TARGET_64BIT)
18832     {
18833       rtvec vec = rtvec_alloc (2);
18834       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18835       rtx upper = gen_reg_rtx (DImode);
18836       rtx lower = gen_reg_rtx (DImode);
18837       rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
18838                                          gen_rtvec (1, const0_rtx),
18839                                          UNSPECV_RDTSC);
18840       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
18841       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
18842       emit_insn (load);
18843       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18844                                    NULL, 1, OPTAB_DIRECT);
18845       lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
18846                                    OPTAB_DIRECT);
18847       emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
18848       DONE;
18849     }
18850 })
18851
18852 (define_insn "*rdtsc"
18853   [(set (match_operand:DI 0 "register_operand" "=A")
18854         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18855   "!TARGET_64BIT"
18856   "rdtsc"
18857   [(set_attr "type" "other")
18858    (set_attr "length" "2")])
18859
18860 (define_insn "*rdtsc_rex64"
18861   [(set (match_operand:DI 0 "register_operand" "=a")
18862         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
18863    (set (match_operand:DI 1 "register_operand" "=d")
18864         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18865   "TARGET_64BIT"
18866   "rdtsc"
18867   [(set_attr "type" "other")
18868    (set_attr "length" "2")])
18869
18870 (define_expand "rdtscp"
18871   [(match_operand:DI 0 "register_operand" "")
18872    (match_operand:SI 1 "memory_operand" "")]
18873   ""
18874 {
18875   rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
18876                                     gen_rtvec (1, const0_rtx),
18877                                     UNSPECV_RDTSCP);
18878   rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
18879                                     gen_rtvec (1, const0_rtx),
18880                                     UNSPECV_RDTSCP);
18881   rtx reg = gen_reg_rtx (DImode);
18882   rtx tmp = gen_reg_rtx (SImode);
18883
18884   if (TARGET_64BIT)
18885     {
18886       rtvec vec = rtvec_alloc (3);
18887       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18888       rtx upper = gen_reg_rtx (DImode);
18889       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
18890       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
18891       RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
18892       emit_insn (load);
18893       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18894                                    NULL, 1, OPTAB_DIRECT);
18895       reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
18896                                  OPTAB_DIRECT);
18897     }
18898   else
18899     {
18900       rtvec vec = rtvec_alloc (2);
18901       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18902       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
18903       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
18904       emit_insn (load);
18905     }
18906   emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
18907   emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
18908   DONE;
18909 })
18910
18911 (define_insn "*rdtscp"
18912   [(set (match_operand:DI 0 "register_operand" "=A")
18913         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18914    (set (match_operand:SI 1 "register_operand" "=c")
18915         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18916   "!TARGET_64BIT"
18917   "rdtscp"
18918   [(set_attr "type" "other")
18919    (set_attr "length" "3")])
18920
18921 (define_insn "*rdtscp_rex64"
18922   [(set (match_operand:DI 0 "register_operand" "=a")
18923         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18924    (set (match_operand:DI 1 "register_operand" "=d")
18925         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18926    (set (match_operand:SI 2 "register_operand" "=c")
18927         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18928   "TARGET_64BIT"
18929   "rdtscp"
18930   [(set_attr "type" "other")
18931    (set_attr "length" "3")])
18932
18933 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18934 ;;
18935 ;; LWP instructions
18936 ;;
18937 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18938
18939 (define_expand "lwp_llwpcb"
18940   [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18941                     UNSPECV_LLWP_INTRINSIC)]
18942   "TARGET_LWP"
18943   "")
18944
18945 (define_insn "*lwp_llwpcb<mode>1"
18946   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18947                     UNSPECV_LLWP_INTRINSIC)]
18948   "TARGET_LWP"
18949   "llwpcb\t%0"
18950   [(set_attr "type" "lwp")
18951    (set_attr "mode" "<MODE>")
18952    (set_attr "length" "5")])
18953
18954 (define_expand "lwp_slwpcb"
18955   [(set (match_operand 0 "register_operand" "=r")
18956         (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18957   "TARGET_LWP"
18958   {
18959     if (TARGET_64BIT)
18960       emit_insn (gen_lwp_slwpcbdi (operands[0]));
18961     else
18962       emit_insn (gen_lwp_slwpcbsi (operands[0]));
18963     DONE;
18964   })
18965
18966 (define_insn "lwp_slwpcb<mode>"
18967   [(set (match_operand:P 0 "register_operand" "=r")
18968         (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18969   "TARGET_LWP"
18970   "slwpcb\t%0"
18971   [(set_attr "type" "lwp")
18972    (set_attr "mode" "<MODE>")
18973    (set_attr "length" "5")])
18974
18975 (define_expand "lwp_lwpval<mode>3"
18976   [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18977                      (match_operand:SI 2 "nonimmediate_operand" "rm")
18978                      (match_operand:SI 3 "const_int_operand" "i")]
18979                     UNSPECV_LWPVAL_INTRINSIC)]
18980   "TARGET_LWP"
18981   "/* Avoid unused variable warning.  */
18982    (void) operand0;")
18983
18984 (define_insn "*lwp_lwpval<mode>3_1"
18985   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18986                      (match_operand:SI 1 "nonimmediate_operand" "rm")
18987                      (match_operand:SI 2 "const_int_operand" "i")]
18988                     UNSPECV_LWPVAL_INTRINSIC)]
18989   "TARGET_LWP"
18990   "lwpval\t{%2, %1, %0|%0, %1, %2}"
18991   [(set_attr "type" "lwp")
18992    (set_attr "mode" "<MODE>")
18993    (set (attr "length")
18994         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18995
18996 (define_expand "lwp_lwpins<mode>3"
18997   [(set (reg:CCC FLAGS_REG)
18998         (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18999                               (match_operand:SI 2 "nonimmediate_operand" "rm")
19000                               (match_operand:SI 3 "const_int_operand" "i")]
19001                              UNSPECV_LWPINS_INTRINSIC))
19002    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
19003         (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
19004   "TARGET_LWP"
19005   "")
19006
19007 (define_insn "*lwp_lwpins<mode>3_1"
19008   [(set (reg:CCC FLAGS_REG)
19009         (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
19010                               (match_operand:SI 1 "nonimmediate_operand" "rm")
19011                               (match_operand:SI 2 "const_int_operand" "i")]
19012                              UNSPECV_LWPINS_INTRINSIC))]
19013   "TARGET_LWP"
19014   "lwpins\t{%2, %1, %0|%0, %1, %2}"
19015   [(set_attr "type" "lwp")
19016    (set_attr "mode" "<MODE>")
19017    (set (attr "length")
19018         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
19019
19020 (include "mmx.md")
19021 (include "sse.md")
19022 (include "sync.md")