OSDN Git Service

* config/i386/i386.md (cbranchsi4): Use nonimmediate_operand for
[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
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 ;; E,e -- likewise, but for compare-and-branch fused insn.
34 ;; F,f -- likewise, but for floating-point.
35 ;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
36 ;;      otherwise nothing
37 ;; R -- print the prefix for register names.
38 ;; z -- print the opcode suffix for the size of the current operand.
39 ;; Z -- likewise, with special suffixes for x87 instructions.
40 ;; * -- print a star (in certain assembler syntax)
41 ;; A -- print an absolute memory reference.
42 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
43 ;; s -- print a shift double count, followed by the assemblers argument
44 ;;      delimiter.
45 ;; b -- print the QImode name of the register for the indicated operand.
46 ;;      %b0 would print %al if operands[0] is reg 0.
47 ;; w --  likewise, print the HImode name of the register.
48 ;; k --  likewise, print the SImode name of the register.
49 ;; q --  likewise, print the DImode name of the register.
50 ;; x --  likewise, print the V4SFmode name of the register.
51 ;; t --  likewise, print the V8SFmode name of the register.
52 ;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
53 ;; y -- print "st(0)" instead of "st" as a register.
54 ;; d -- print duplicated register operand for AVX instruction.
55 ;; D -- print condition for SSE cmp instruction.
56 ;; P -- if PIC, print an @PLT suffix.
57 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
58 ;; & -- print some in-use local-dynamic symbol name.
59 ;; H -- print a memory address offset by 8; used for sse high-parts
60 ;; Y -- print condition for XOP pcom* instruction.
61 ;; + -- print a branch hint as 'cs' or 'ds' prefix
62 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
63
64 ;; UNSPEC usage:
65
66 (define_constants
67   [; Relocation specifiers
68    (UNSPEC_GOT                  0)
69    (UNSPEC_GOTOFF               1)
70    (UNSPEC_GOTPCREL             2)
71    (UNSPEC_GOTTPOFF             3)
72    (UNSPEC_TPOFF                4)
73    (UNSPEC_NTPOFF               5)
74    (UNSPEC_DTPOFF               6)
75    (UNSPEC_GOTNTPOFF            7)
76    (UNSPEC_INDNTPOFF            8)
77    (UNSPEC_PLTOFF               9)
78    (UNSPEC_MACHOPIC_OFFSET      10)
79
80    ; Prologue support
81    (UNSPEC_STACK_ALLOC          11)
82    (UNSPEC_SET_GOT              12)
83    (UNSPEC_SSE_PROLOGUE_SAVE    13)
84    (UNSPEC_REG_SAVE             14)
85    (UNSPEC_DEF_CFA              15)
86    (UNSPEC_SET_RIP              16)
87    (UNSPEC_SET_GOT_OFFSET       17)
88    (UNSPEC_MEMORY_BLOCKAGE      18)
89
90    ; TLS support
91    (UNSPEC_TP                   20)
92    (UNSPEC_TLS_GD               21)
93    (UNSPEC_TLS_LD_BASE          22)
94    (UNSPEC_TLSDESC              23)
95
96    ; Other random patterns
97    (UNSPEC_SCAS                 30)
98    (UNSPEC_FNSTSW               31)
99    (UNSPEC_SAHF                 32)
100    (UNSPEC_FSTCW                33)
101    (UNSPEC_ADD_CARRY            34)
102    (UNSPEC_FLDCW                35)
103    (UNSPEC_REP                  36)
104    (UNSPEC_LD_MPIC              38)     ; load_macho_picbase
105    (UNSPEC_TRUNC_NOOP           39)
106
107    ; For SSE/MMX support:
108    (UNSPEC_FIX_NOTRUNC          40)
109    (UNSPEC_MASKMOV              41)
110    (UNSPEC_MOVMSK               42)
111    (UNSPEC_MOVNT                43)
112    (UNSPEC_MOVU                 44)
113    (UNSPEC_RCP                  45)
114    (UNSPEC_RSQRT                46)
115    (UNSPEC_SFENCE               47)
116    (UNSPEC_PFRCP                49)
117    (UNSPEC_PFRCPIT1             40)
118    (UNSPEC_PFRCPIT2             41)
119    (UNSPEC_PFRSQRT              42)
120    (UNSPEC_PFRSQIT1             43)
121    (UNSPEC_MFENCE               44)
122    (UNSPEC_LFENCE               45)
123    (UNSPEC_PSADBW               46)
124    (UNSPEC_LDDQU                47)
125    (UNSPEC_MS_TO_SYSV_CALL      48)
126
127    ; Generic math support
128    (UNSPEC_COPYSIGN             50)
129    (UNSPEC_IEEE_MIN             51)     ; not commutative
130    (UNSPEC_IEEE_MAX             52)     ; not commutative
131
132    ; x87 Floating point
133    (UNSPEC_SIN                  60)
134    (UNSPEC_COS                  61)
135    (UNSPEC_FPATAN               62)
136    (UNSPEC_FYL2X                63)
137    (UNSPEC_FYL2XP1              64)
138    (UNSPEC_FRNDINT              65)
139    (UNSPEC_FIST                 66)
140    (UNSPEC_F2XM1                67)
141    (UNSPEC_TAN                  68)
142    (UNSPEC_FXAM                 69)
143
144    ; x87 Rounding
145    (UNSPEC_FRNDINT_FLOOR        70)
146    (UNSPEC_FRNDINT_CEIL         71)
147    (UNSPEC_FRNDINT_TRUNC        72)
148    (UNSPEC_FRNDINT_MASK_PM      73)
149    (UNSPEC_FIST_FLOOR           74)
150    (UNSPEC_FIST_CEIL            75)
151
152    ; x87 Double output FP
153    (UNSPEC_SINCOS_COS           80)
154    (UNSPEC_SINCOS_SIN           81)
155    (UNSPEC_XTRACT_FRACT         84)
156    (UNSPEC_XTRACT_EXP           85)
157    (UNSPEC_FSCALE_FRACT         86)
158    (UNSPEC_FSCALE_EXP           87)
159    (UNSPEC_FPREM_F              88)
160    (UNSPEC_FPREM_U              89)
161    (UNSPEC_FPREM1_F             90)
162    (UNSPEC_FPREM1_U             91)
163
164    (UNSPEC_C2_FLAG              95)
165    (UNSPEC_FXAM_MEM             96)
166
167    ; SSP patterns
168    (UNSPEC_SP_SET               100)
169    (UNSPEC_SP_TEST              101)
170    (UNSPEC_SP_TLS_SET           102)
171    (UNSPEC_SP_TLS_TEST          103)
172
173    ; SSSE3
174    (UNSPEC_PSHUFB               120)
175    (UNSPEC_PSIGN                121)
176    (UNSPEC_PALIGNR              122)
177
178    ; For SSE4A support
179    (UNSPEC_EXTRQI               130)
180    (UNSPEC_EXTRQ                131)
181    (UNSPEC_INSERTQI             132)
182    (UNSPEC_INSERTQ              133)
183
184    ; For SSE4.1 support
185    (UNSPEC_BLENDV               134)
186    (UNSPEC_INSERTPS             135)
187    (UNSPEC_DP                   136)
188    (UNSPEC_MOVNTDQA             137)
189    (UNSPEC_MPSADBW              138)
190    (UNSPEC_PHMINPOSUW           139)
191    (UNSPEC_PTEST                140)
192    (UNSPEC_ROUND                141)
193
194    ; For SSE4.2 support
195    (UNSPEC_CRC32                143)
196    (UNSPEC_PCMPESTR             144)
197    (UNSPEC_PCMPISTR             145)
198
199    ; For FMA4 support
200    (UNSPEC_FMA4_INTRINSIC       150)
201    (UNSPEC_FMA4_FMADDSUB        151)
202    (UNSPEC_FMA4_FMSUBADD        152)
203    (UNSPEC_XOP_UNSIGNED_CMP     151)
204    (UNSPEC_XOP_TRUEFALSE        152)
205    (UNSPEC_XOP_PERMUTE          153)
206    (UNSPEC_FRCZ                 154)
207    (UNSPEC_LLWP_INTRINSIC       155)
208    (UNSPEC_SLWP_INTRINSIC       156)
209    (UNSPECV_LWPVAL_INTRINSIC    157)
210    (UNSPECV_LWPINS_INTRINSIC    158)
211
212    ; For AES support
213    (UNSPEC_AESENC               159)
214    (UNSPEC_AESENCLAST           160)
215    (UNSPEC_AESDEC               161)
216    (UNSPEC_AESDECLAST           162)
217    (UNSPEC_AESIMC               163)
218    (UNSPEC_AESKEYGENASSIST      164)
219
220    ; For PCLMUL support
221    (UNSPEC_PCLMUL               165)
222
223    ; For AVX support
224    (UNSPEC_PCMP                 166)
225    (UNSPEC_VPERMIL              167)
226    (UNSPEC_VPERMIL2F128         168)
227    (UNSPEC_MASKLOAD             169)
228    (UNSPEC_MASKSTORE            170)
229    (UNSPEC_CAST                 171)
230    (UNSPEC_VTESTP               172)
231   ])
232
233 (define_constants
234   [(UNSPECV_BLOCKAGE            0)
235    (UNSPECV_STACK_PROBE         1)
236    (UNSPECV_EMMS                2)
237    (UNSPECV_LDMXCSR             3)
238    (UNSPECV_STMXCSR             4)
239    (UNSPECV_FEMMS               5)
240    (UNSPECV_CLFLUSH             6)
241    (UNSPECV_ALIGN               7)
242    (UNSPECV_MONITOR             8)
243    (UNSPECV_MWAIT               9)
244    (UNSPECV_CMPXCHG             10)
245    (UNSPECV_XCHG                12)
246    (UNSPECV_LOCK                13)
247    (UNSPECV_PROLOGUE_USE        14)
248    (UNSPECV_CLD                 15)
249    (UNSPECV_VZEROALL            16)
250    (UNSPECV_VZEROUPPER          17)
251    (UNSPECV_RDTSC               18)
252    (UNSPECV_RDTSCP              19)
253    (UNSPECV_RDPMC               20)
254    (UNSPECV_VSWAPMOV    21)
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")
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
700 ;; Mark commutative operators as such in constraints.
701 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
702                         (minus "") (ss_minus "") (us_minus "")])
703
704 ;; Mapping of signed max and min
705 (define_code_iterator smaxmin [smax smin])
706
707 ;; Mapping of unsigned max and min
708 (define_code_iterator umaxmin [umax umin])
709
710 ;; Mapping of signed/unsigned max and min
711 (define_code_iterator maxmin [smax smin umax umin])
712
713 ;; Base name for integer and FP insn mnemonic
714 (define_code_attr maxminiprefix [(smax "maxs") (smin "mins")
715                                  (umax "maxu") (umin "minu")])
716 (define_code_attr maxminfprefix [(smax "max") (smin "min")])
717
718 ;; Mapping of parallel logic operators
719 (define_code_iterator plogic [and ior xor])
720
721 ;; Base name for insn mnemonic.
722 (define_code_attr plogicprefix [(and "and") (ior "or") (xor "xor")])
723
724 ;; Mapping of abs neg operators
725 (define_code_iterator absneg [abs neg])
726
727 ;; Base name for x87 insn mnemonic.
728 (define_code_attr absnegprefix [(abs "abs") (neg "chs")])
729
730 ;; Used in signed and unsigned widening multiplications.
731 (define_code_iterator any_extend [sign_extend zero_extend])
732
733 ;; Used in signed and unsigned divisions.
734 (define_code_iterator any_div [div udiv])
735
736 ;; Various insn prefixes for signed and unsigned operations.
737 (define_code_attr u [(sign_extend "") (zero_extend "u")
738                      (div "") (udiv "u")])
739 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
740
741 ;; Instruction prefix for signed and unsigned operations.
742 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")
743                              (div "i") (udiv "")])
744
745 ;; All single word integer modes.
746 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
747
748 ;; Single word integer modes without QImode.
749 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
750
751 ;; Single word integer modes without QImode and HImode.
752 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
753
754 ;; All math-dependant single and double word integer modes.
755 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
756                              (HI "TARGET_HIMODE_MATH")
757                              SI DI (TI "TARGET_64BIT")])
758
759 ;; Math-dependant single word integer modes.
760 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
761                             (HI "TARGET_HIMODE_MATH")
762                             SI (DI "TARGET_64BIT")])
763
764 ;; Math-dependant single word integer modes without QImode.
765 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
766                                SI (DI "TARGET_64BIT")])
767
768 ;; Half mode for double word integer modes.
769 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
770                             (DI "TARGET_64BIT")])
771
772 ;; Double word integer modes.
773 (define_mode_attr DWI [(SI "DI") (DI "TI")])
774 (define_mode_attr dwi [(SI "di") (DI "ti")])
775
776 ;; Instruction suffix for integer modes.
777 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
778
779 ;; Register class for integer modes.
780 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
781
782 ;; Immediate operand constraint for integer modes.
783 (define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")])
784
785 ;; General operand constraint for word modes.
786 (define_mode_attr g [(SI "g") (DI "rme")])
787
788 ;; Immediate operand constraint for double integer modes.
789 (define_mode_attr di [(SI "iF") (DI "e")])
790
791 ;; General operand predicate for integer modes.
792 (define_mode_attr general_operand
793         [(QI "general_operand")
794          (HI "general_operand")
795          (SI "general_operand")
796          (DI "x86_64_general_operand")
797          (TI "x86_64_general_operand")])
798
799 ;; SSE and x87 SFmode and DFmode floating point modes
800 (define_mode_iterator MODEF [SF DF])
801
802 ;; All x87 floating point modes
803 (define_mode_iterator X87MODEF [SF DF XF])
804
805 ;; All integer modes handled by x87 fisttp operator.
806 (define_mode_iterator X87MODEI [HI SI DI])
807
808 ;; All integer modes handled by integer x87 operators.
809 (define_mode_iterator X87MODEI12 [HI SI])
810
811 ;; All integer modes handled by SSE cvtts?2si* operators.
812 (define_mode_iterator SSEMODEI24 [SI DI])
813
814 ;; SSE asm suffix for floating point modes
815 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
816
817 ;; SSE vector mode corresponding to a scalar mode
818 (define_mode_attr ssevecmode
819   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
820
821 ;; Instruction suffix for REX 64bit operators.
822 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
823
824 ;; This mode iterator allows :P to be used for patterns that operate on
825 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
826 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
827 \f
828 ;; Scheduling descriptions
829
830 (include "pentium.md")
831 (include "ppro.md")
832 (include "k6.md")
833 (include "athlon.md")
834 (include "geode.md")
835 (include "atom.md")
836
837 \f
838 ;; Operand and operator predicates and constraints
839
840 (include "predicates.md")
841 (include "constraints.md")
842
843 \f
844 ;; Compare and branch/compare and store instructions.
845
846 (define_expand "cbranch<mode>4"
847   [(set (reg:CC FLAGS_REG)
848         (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
849                     (match_operand:SDWIM 2 "<general_operand>" "")))
850    (set (pc) (if_then_else
851                (match_operator 0 "comparison_operator"
852                 [(reg:CC FLAGS_REG) (const_int 0)])
853                (label_ref (match_operand 3 "" ""))
854                (pc)))]
855   ""
856 {
857   if (MEM_P (operands[1]) && MEM_P (operands[2]))
858     operands[1] = force_reg (<MODE>mode, operands[1]);
859   ix86_compare_op0 = operands[1];
860   ix86_compare_op1 = operands[2];
861   ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
862   DONE;
863 })
864
865 (define_expand "cstore<mode>4"
866   [(set (reg:CC FLAGS_REG)
867         (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
868                     (match_operand:SWIM 3 "<general_operand>" "")))
869    (set (match_operand:QI 0 "register_operand" "")
870         (match_operator 1 "comparison_operator"
871           [(reg:CC FLAGS_REG) (const_int 0)]))]
872   ""
873 {
874   if (MEM_P (operands[2]) && MEM_P (operands[3]))
875     operands[2] = force_reg (<MODE>mode, operands[2]);
876   ix86_compare_op0 = operands[2];
877   ix86_compare_op1 = operands[3];
878   ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
879   DONE;
880 })
881
882 (define_expand "cmp<mode>_1"
883   [(set (reg:CC FLAGS_REG)
884         (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
885                     (match_operand:SWI48 1 "<general_operand>" "")))]
886   ""
887   "")
888
889 (define_insn "*cmp<mode>_ccno_1"
890   [(set (reg FLAGS_REG)
891         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
892                  (match_operand:SWI 1 "const0_operand" "")))]
893   "ix86_match_ccmode (insn, CCNOmode)"
894   "@
895    test{<imodesuffix>}\t%0, %0
896    cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
897   [(set_attr "type" "test,icmp")
898    (set_attr "length_immediate" "0,1")
899    (set_attr "mode" "<MODE>")])
900
901 (define_insn "*cmp<mode>_1"
902   [(set (reg FLAGS_REG)
903         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
904                  (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
905   "ix86_match_ccmode (insn, CCmode)"
906   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
907   [(set_attr "type" "icmp")
908    (set_attr "mode" "<MODE>")])
909
910 (define_insn "*cmp<mode>_minus_1"
911   [(set (reg FLAGS_REG)
912         (compare
913           (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
914                      (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
915           (const_int 0)))]
916   "ix86_match_ccmode (insn, CCGOCmode)"
917   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
918   [(set_attr "type" "icmp")
919    (set_attr "mode" "<MODE>")])
920
921 (define_insn "*cmpqi_ext_1"
922   [(set (reg FLAGS_REG)
923         (compare
924           (match_operand:QI 0 "general_operand" "Qm")
925           (subreg:QI
926             (zero_extract:SI
927               (match_operand 1 "ext_register_operand" "Q")
928               (const_int 8)
929               (const_int 8)) 0)))]
930   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
931   "cmp{b}\t{%h1, %0|%0, %h1}"
932   [(set_attr "type" "icmp")
933    (set_attr "mode" "QI")])
934
935 (define_insn "*cmpqi_ext_1_rex64"
936   [(set (reg FLAGS_REG)
937         (compare
938           (match_operand:QI 0 "register_operand" "Q")
939           (subreg:QI
940             (zero_extract:SI
941               (match_operand 1 "ext_register_operand" "Q")
942               (const_int 8)
943               (const_int 8)) 0)))]
944   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
945   "cmp{b}\t{%h1, %0|%0, %h1}"
946   [(set_attr "type" "icmp")
947    (set_attr "mode" "QI")])
948
949 (define_insn "*cmpqi_ext_2"
950   [(set (reg FLAGS_REG)
951         (compare
952           (subreg:QI
953             (zero_extract:SI
954               (match_operand 0 "ext_register_operand" "Q")
955               (const_int 8)
956               (const_int 8)) 0)
957           (match_operand:QI 1 "const0_operand" "")))]
958   "ix86_match_ccmode (insn, CCNOmode)"
959   "test{b}\t%h0, %h0"
960   [(set_attr "type" "test")
961    (set_attr "length_immediate" "0")
962    (set_attr "mode" "QI")])
963
964 (define_expand "cmpqi_ext_3"
965   [(set (reg:CC FLAGS_REG)
966         (compare:CC
967           (subreg:QI
968             (zero_extract:SI
969               (match_operand 0 "ext_register_operand" "")
970               (const_int 8)
971               (const_int 8)) 0)
972           (match_operand:QI 1 "immediate_operand" "")))]
973   ""
974   "")
975
976 (define_insn "*cmpqi_ext_3_insn"
977   [(set (reg FLAGS_REG)
978         (compare
979           (subreg:QI
980             (zero_extract:SI
981               (match_operand 0 "ext_register_operand" "Q")
982               (const_int 8)
983               (const_int 8)) 0)
984           (match_operand:QI 1 "general_operand" "Qmn")))]
985   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
986   "cmp{b}\t{%1, %h0|%h0, %1}"
987   [(set_attr "type" "icmp")
988    (set_attr "modrm" "1")
989    (set_attr "mode" "QI")])
990
991 (define_insn "*cmpqi_ext_3_insn_rex64"
992   [(set (reg FLAGS_REG)
993         (compare
994           (subreg:QI
995             (zero_extract:SI
996               (match_operand 0 "ext_register_operand" "Q")
997               (const_int 8)
998               (const_int 8)) 0)
999           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1000   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1001   "cmp{b}\t{%1, %h0|%h0, %1}"
1002   [(set_attr "type" "icmp")
1003    (set_attr "modrm" "1")
1004    (set_attr "mode" "QI")])
1005
1006 (define_insn "*cmpqi_ext_4"
1007   [(set (reg FLAGS_REG)
1008         (compare
1009           (subreg:QI
1010             (zero_extract:SI
1011               (match_operand 0 "ext_register_operand" "Q")
1012               (const_int 8)
1013               (const_int 8)) 0)
1014           (subreg:QI
1015             (zero_extract:SI
1016               (match_operand 1 "ext_register_operand" "Q")
1017               (const_int 8)
1018               (const_int 8)) 0)))]
1019   "ix86_match_ccmode (insn, CCmode)"
1020   "cmp{b}\t{%h1, %h0|%h0, %h1}"
1021   [(set_attr "type" "icmp")
1022    (set_attr "mode" "QI")])
1023
1024 ;; These implement float point compares.
1025 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1026 ;; which would allow mix and match FP modes on the compares.  Which is what
1027 ;; the old patterns did, but with many more of them.
1028
1029 (define_expand "cbranchxf4"
1030   [(set (reg:CC FLAGS_REG)
1031         (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1032                     (match_operand:XF 2 "nonmemory_operand" "")))
1033    (set (pc) (if_then_else
1034               (match_operator 0 "ix86_fp_comparison_operator"
1035                [(reg:CC FLAGS_REG)
1036                 (const_int 0)])
1037               (label_ref (match_operand 3 "" ""))
1038               (pc)))]
1039   "TARGET_80387"
1040 {
1041   ix86_compare_op0 = operands[1];
1042   ix86_compare_op1 = operands[2];
1043   ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1044   DONE;
1045 })
1046
1047 (define_expand "cstorexf4"
1048   [(set (reg:CC FLAGS_REG)
1049         (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1050                     (match_operand:XF 3 "nonmemory_operand" "")))
1051    (set (match_operand:QI 0 "register_operand" "")
1052               (match_operator 1 "ix86_fp_comparison_operator"
1053                [(reg:CC FLAGS_REG)
1054                 (const_int 0)]))]
1055   "TARGET_80387"
1056 {
1057   ix86_compare_op0 = operands[2];
1058   ix86_compare_op1 = operands[3];
1059   ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1060   DONE;
1061 })
1062
1063 (define_expand "cbranch<mode>4"
1064   [(set (reg:CC FLAGS_REG)
1065         (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1066                     (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1067    (set (pc) (if_then_else
1068               (match_operator 0 "ix86_fp_comparison_operator"
1069                [(reg:CC FLAGS_REG)
1070                 (const_int 0)])
1071               (label_ref (match_operand 3 "" ""))
1072               (pc)))]
1073   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1074 {
1075   ix86_compare_op0 = operands[1];
1076   ix86_compare_op1 = operands[2];
1077   ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1078   DONE;
1079 })
1080
1081 (define_expand "cstore<mode>4"
1082   [(set (reg:CC FLAGS_REG)
1083         (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1084                     (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1085    (set (match_operand:QI 0 "register_operand" "")
1086               (match_operator 1 "ix86_fp_comparison_operator"
1087                [(reg:CC FLAGS_REG)
1088                 (const_int 0)]))]
1089   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1090 {
1091   ix86_compare_op0 = operands[2];
1092   ix86_compare_op1 = operands[3];
1093   ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1094   DONE;
1095 })
1096
1097 (define_expand "cbranchcc4"
1098   [(set (pc) (if_then_else
1099               (match_operator 0 "comparison_operator"
1100                [(match_operand 1 "flags_reg_operand" "")
1101                 (match_operand 2 "const0_operand" "")])
1102               (label_ref (match_operand 3 "" ""))
1103               (pc)))]
1104   ""
1105 {
1106   ix86_compare_op0 = operands[1];
1107   ix86_compare_op1 = operands[2];
1108   ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1109   DONE;
1110 })
1111
1112 (define_expand "cstorecc4"
1113   [(set (match_operand:QI 0 "register_operand" "")
1114               (match_operator 1 "comparison_operator"
1115                [(match_operand 2 "flags_reg_operand" "")
1116                 (match_operand 3 "const0_operand" "")]))]
1117   ""
1118 {
1119   ix86_compare_op0 = operands[2];
1120   ix86_compare_op1 = operands[3];
1121   ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1122   DONE;
1123 })
1124
1125
1126 ;; FP compares, step 1:
1127 ;; Set the FP condition codes.
1128 ;;
1129 ;; CCFPmode     compare with exceptions
1130 ;; CCFPUmode    compare with no exceptions
1131
1132 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1133 ;; used to manage the reg stack popping would not be preserved.
1134
1135 (define_insn "*cmpfp_0"
1136   [(set (match_operand:HI 0 "register_operand" "=a")
1137         (unspec:HI
1138           [(compare:CCFP
1139              (match_operand 1 "register_operand" "f")
1140              (match_operand 2 "const0_operand" ""))]
1141         UNSPEC_FNSTSW))]
1142   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1143    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1144   "* return output_fp_compare (insn, operands, 0, 0);"
1145   [(set_attr "type" "multi")
1146    (set_attr "unit" "i387")
1147    (set (attr "mode")
1148      (cond [(match_operand:SF 1 "" "")
1149               (const_string "SF")
1150             (match_operand:DF 1 "" "")
1151               (const_string "DF")
1152            ]
1153            (const_string "XF")))])
1154
1155 (define_insn_and_split "*cmpfp_0_cc"
1156   [(set (reg:CCFP FLAGS_REG)
1157         (compare:CCFP
1158           (match_operand 1 "register_operand" "f")
1159           (match_operand 2 "const0_operand" "")))
1160    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1161   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1162    && TARGET_SAHF && !TARGET_CMOVE
1163    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1164   "#"
1165   "&& reload_completed"
1166   [(set (match_dup 0)
1167         (unspec:HI
1168           [(compare:CCFP (match_dup 1)(match_dup 2))]
1169         UNSPEC_FNSTSW))
1170    (set (reg:CC FLAGS_REG)
1171         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1172   ""
1173   [(set_attr "type" "multi")
1174    (set_attr "unit" "i387")
1175    (set (attr "mode")
1176      (cond [(match_operand:SF 1 "" "")
1177               (const_string "SF")
1178             (match_operand:DF 1 "" "")
1179               (const_string "DF")
1180            ]
1181            (const_string "XF")))])
1182
1183 (define_insn "*cmpfp_xf"
1184   [(set (match_operand:HI 0 "register_operand" "=a")
1185         (unspec:HI
1186           [(compare:CCFP
1187              (match_operand:XF 1 "register_operand" "f")
1188              (match_operand:XF 2 "register_operand" "f"))]
1189           UNSPEC_FNSTSW))]
1190   "TARGET_80387"
1191   "* return output_fp_compare (insn, operands, 0, 0);"
1192   [(set_attr "type" "multi")
1193    (set_attr "unit" "i387")
1194    (set_attr "mode" "XF")])
1195
1196 (define_insn_and_split "*cmpfp_xf_cc"
1197   [(set (reg:CCFP FLAGS_REG)
1198         (compare:CCFP
1199           (match_operand:XF 1 "register_operand" "f")
1200           (match_operand:XF 2 "register_operand" "f")))
1201    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1202   "TARGET_80387
1203    && TARGET_SAHF && !TARGET_CMOVE"
1204   "#"
1205   "&& reload_completed"
1206   [(set (match_dup 0)
1207         (unspec:HI
1208           [(compare:CCFP (match_dup 1)(match_dup 2))]
1209         UNSPEC_FNSTSW))
1210    (set (reg:CC FLAGS_REG)
1211         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1212   ""
1213   [(set_attr "type" "multi")
1214    (set_attr "unit" "i387")
1215    (set_attr "mode" "XF")])
1216
1217 (define_insn "*cmpfp_<mode>"
1218   [(set (match_operand:HI 0 "register_operand" "=a")
1219         (unspec:HI
1220           [(compare:CCFP
1221              (match_operand:MODEF 1 "register_operand" "f")
1222              (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1223           UNSPEC_FNSTSW))]
1224   "TARGET_80387"
1225   "* return output_fp_compare (insn, operands, 0, 0);"
1226   [(set_attr "type" "multi")
1227    (set_attr "unit" "i387")
1228    (set_attr "mode" "<MODE>")])
1229
1230 (define_insn_and_split "*cmpfp_<mode>_cc"
1231   [(set (reg:CCFP FLAGS_REG)
1232         (compare:CCFP
1233           (match_operand:MODEF 1 "register_operand" "f")
1234           (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1235    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1236   "TARGET_80387
1237    && TARGET_SAHF && !TARGET_CMOVE"
1238   "#"
1239   "&& reload_completed"
1240   [(set (match_dup 0)
1241         (unspec:HI
1242           [(compare:CCFP (match_dup 1)(match_dup 2))]
1243         UNSPEC_FNSTSW))
1244    (set (reg:CC FLAGS_REG)
1245         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1246   ""
1247   [(set_attr "type" "multi")
1248    (set_attr "unit" "i387")
1249    (set_attr "mode" "<MODE>")])
1250
1251 (define_insn "*cmpfp_u"
1252   [(set (match_operand:HI 0 "register_operand" "=a")
1253         (unspec:HI
1254           [(compare:CCFPU
1255              (match_operand 1 "register_operand" "f")
1256              (match_operand 2 "register_operand" "f"))]
1257           UNSPEC_FNSTSW))]
1258   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1259    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1260   "* return output_fp_compare (insn, operands, 0, 1);"
1261   [(set_attr "type" "multi")
1262    (set_attr "unit" "i387")
1263    (set (attr "mode")
1264      (cond [(match_operand:SF 1 "" "")
1265               (const_string "SF")
1266             (match_operand:DF 1 "" "")
1267               (const_string "DF")
1268            ]
1269            (const_string "XF")))])
1270
1271 (define_insn_and_split "*cmpfp_u_cc"
1272   [(set (reg:CCFPU FLAGS_REG)
1273         (compare:CCFPU
1274           (match_operand 1 "register_operand" "f")
1275           (match_operand 2 "register_operand" "f")))
1276    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1277   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1278    && TARGET_SAHF && !TARGET_CMOVE
1279    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1280   "#"
1281   "&& reload_completed"
1282   [(set (match_dup 0)
1283         (unspec:HI
1284           [(compare:CCFPU (match_dup 1)(match_dup 2))]
1285         UNSPEC_FNSTSW))
1286    (set (reg:CC FLAGS_REG)
1287         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1288   ""
1289   [(set_attr "type" "multi")
1290    (set_attr "unit" "i387")
1291    (set (attr "mode")
1292      (cond [(match_operand:SF 1 "" "")
1293               (const_string "SF")
1294             (match_operand:DF 1 "" "")
1295               (const_string "DF")
1296            ]
1297            (const_string "XF")))])
1298
1299 (define_insn "*cmpfp_<mode>"
1300   [(set (match_operand:HI 0 "register_operand" "=a")
1301         (unspec:HI
1302           [(compare:CCFP
1303              (match_operand 1 "register_operand" "f")
1304              (match_operator 3 "float_operator"
1305                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1306           UNSPEC_FNSTSW))]
1307   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1308    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1309    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1310   "* return output_fp_compare (insn, operands, 0, 0);"
1311   [(set_attr "type" "multi")
1312    (set_attr "unit" "i387")
1313    (set_attr "fp_int_src" "true")
1314    (set_attr "mode" "<MODE>")])
1315
1316 (define_insn_and_split "*cmpfp_<mode>_cc"
1317   [(set (reg:CCFP FLAGS_REG)
1318         (compare:CCFP
1319           (match_operand 1 "register_operand" "f")
1320           (match_operator 3 "float_operator"
1321             [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1322    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1323   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1324    && TARGET_SAHF && !TARGET_CMOVE
1325    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1326    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1327   "#"
1328   "&& reload_completed"
1329   [(set (match_dup 0)
1330         (unspec:HI
1331           [(compare:CCFP
1332              (match_dup 1)
1333              (match_op_dup 3 [(match_dup 2)]))]
1334         UNSPEC_FNSTSW))
1335    (set (reg:CC FLAGS_REG)
1336         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1337   ""
1338   [(set_attr "type" "multi")
1339    (set_attr "unit" "i387")
1340    (set_attr "fp_int_src" "true")
1341    (set_attr "mode" "<MODE>")])
1342
1343 ;; FP compares, step 2
1344 ;; Move the fpsw to ax.
1345
1346 (define_insn "x86_fnstsw_1"
1347   [(set (match_operand:HI 0 "register_operand" "=a")
1348         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1349   "TARGET_80387"
1350   "fnstsw\t%0"
1351   [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1352    (set_attr "mode" "SI")
1353    (set_attr "unit" "i387")])
1354
1355 ;; FP compares, step 3
1356 ;; Get ax into flags, general case.
1357
1358 (define_insn "x86_sahf_1"
1359   [(set (reg:CC FLAGS_REG)
1360         (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1361                    UNSPEC_SAHF))]
1362   "TARGET_SAHF"
1363 {
1364 #ifdef HAVE_AS_IX86_SAHF
1365   return "sahf";
1366 #else
1367   return ASM_BYTE "0x9e";
1368 #endif
1369 }
1370   [(set_attr "length" "1")
1371    (set_attr "athlon_decode" "vector")
1372    (set_attr "amdfam10_decode" "direct")
1373    (set_attr "mode" "SI")])
1374
1375 ;; Pentium Pro can do steps 1 through 3 in one go.
1376 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1377 (define_insn "*cmpfp_i_mixed"
1378   [(set (reg:CCFP FLAGS_REG)
1379         (compare:CCFP (match_operand 0 "register_operand" "f,x")
1380                       (match_operand 1 "nonimmediate_operand" "f,xm")))]
1381   "TARGET_MIX_SSE_I387
1382    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1383    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1384   "* return output_fp_compare (insn, operands, 1, 0);"
1385   [(set_attr "type" "fcmp,ssecomi")
1386    (set_attr "prefix" "orig,maybe_vex")
1387    (set (attr "mode")
1388      (if_then_else (match_operand:SF 1 "" "")
1389         (const_string "SF")
1390         (const_string "DF")))
1391    (set (attr "prefix_rep")
1392         (if_then_else (eq_attr "type" "ssecomi")
1393                       (const_string "0")
1394                       (const_string "*")))
1395    (set (attr "prefix_data16")
1396         (cond [(eq_attr "type" "fcmp")
1397                  (const_string "*")
1398                (eq_attr "mode" "DF")
1399                  (const_string "1")
1400               ]
1401               (const_string "0")))
1402    (set_attr "athlon_decode" "vector")
1403    (set_attr "amdfam10_decode" "direct")])
1404
1405 (define_insn "*cmpfp_i_sse"
1406   [(set (reg:CCFP FLAGS_REG)
1407         (compare:CCFP (match_operand 0 "register_operand" "x")
1408                       (match_operand 1 "nonimmediate_operand" "xm")))]
1409   "TARGET_SSE_MATH
1410    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1411    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1412   "* return output_fp_compare (insn, operands, 1, 0);"
1413   [(set_attr "type" "ssecomi")
1414    (set_attr "prefix" "maybe_vex")
1415    (set (attr "mode")
1416      (if_then_else (match_operand:SF 1 "" "")
1417         (const_string "SF")
1418         (const_string "DF")))
1419    (set_attr "prefix_rep" "0")
1420    (set (attr "prefix_data16")
1421         (if_then_else (eq_attr "mode" "DF")
1422                       (const_string "1")
1423                       (const_string "0")))
1424    (set_attr "athlon_decode" "vector")
1425    (set_attr "amdfam10_decode" "direct")])
1426
1427 (define_insn "*cmpfp_i_i387"
1428   [(set (reg:CCFP FLAGS_REG)
1429         (compare:CCFP (match_operand 0 "register_operand" "f")
1430                       (match_operand 1 "register_operand" "f")))]
1431   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1432    && TARGET_CMOVE
1433    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1434    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1435   "* return output_fp_compare (insn, operands, 1, 0);"
1436   [(set_attr "type" "fcmp")
1437    (set (attr "mode")
1438      (cond [(match_operand:SF 1 "" "")
1439               (const_string "SF")
1440             (match_operand:DF 1 "" "")
1441               (const_string "DF")
1442            ]
1443            (const_string "XF")))
1444    (set_attr "athlon_decode" "vector")
1445    (set_attr "amdfam10_decode" "direct")])
1446
1447 (define_insn "*cmpfp_iu_mixed"
1448   [(set (reg:CCFPU FLAGS_REG)
1449         (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1450                        (match_operand 1 "nonimmediate_operand" "f,xm")))]
1451   "TARGET_MIX_SSE_I387
1452    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1453    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1454   "* return output_fp_compare (insn, operands, 1, 1);"
1455   [(set_attr "type" "fcmp,ssecomi")
1456    (set_attr "prefix" "orig,maybe_vex")
1457    (set (attr "mode")
1458      (if_then_else (match_operand:SF 1 "" "")
1459         (const_string "SF")
1460         (const_string "DF")))
1461    (set (attr "prefix_rep")
1462         (if_then_else (eq_attr "type" "ssecomi")
1463                       (const_string "0")
1464                       (const_string "*")))
1465    (set (attr "prefix_data16")
1466         (cond [(eq_attr "type" "fcmp")
1467                  (const_string "*")
1468                (eq_attr "mode" "DF")
1469                  (const_string "1")
1470               ]
1471               (const_string "0")))
1472    (set_attr "athlon_decode" "vector")
1473    (set_attr "amdfam10_decode" "direct")])
1474
1475 (define_insn "*cmpfp_iu_sse"
1476   [(set (reg:CCFPU FLAGS_REG)
1477         (compare:CCFPU (match_operand 0 "register_operand" "x")
1478                        (match_operand 1 "nonimmediate_operand" "xm")))]
1479   "TARGET_SSE_MATH
1480    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1481    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1482   "* return output_fp_compare (insn, operands, 1, 1);"
1483   [(set_attr "type" "ssecomi")
1484    (set_attr "prefix" "maybe_vex")
1485    (set (attr "mode")
1486      (if_then_else (match_operand:SF 1 "" "")
1487         (const_string "SF")
1488         (const_string "DF")))
1489    (set_attr "prefix_rep" "0")
1490    (set (attr "prefix_data16")
1491         (if_then_else (eq_attr "mode" "DF")
1492                       (const_string "1")
1493                       (const_string "0")))
1494    (set_attr "athlon_decode" "vector")
1495    (set_attr "amdfam10_decode" "direct")])
1496
1497 (define_insn "*cmpfp_iu_387"
1498   [(set (reg:CCFPU FLAGS_REG)
1499         (compare:CCFPU (match_operand 0 "register_operand" "f")
1500                        (match_operand 1 "register_operand" "f")))]
1501   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1502    && TARGET_CMOVE
1503    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1504    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1505   "* return output_fp_compare (insn, operands, 1, 1);"
1506   [(set_attr "type" "fcmp")
1507    (set (attr "mode")
1508      (cond [(match_operand:SF 1 "" "")
1509               (const_string "SF")
1510             (match_operand:DF 1 "" "")
1511               (const_string "DF")
1512            ]
1513            (const_string "XF")))
1514    (set_attr "athlon_decode" "vector")
1515    (set_attr "amdfam10_decode" "direct")])
1516 \f
1517 ;; Move instructions.
1518
1519 ;; General case of fullword move.
1520
1521 (define_expand "movsi"
1522   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1523         (match_operand:SI 1 "general_operand" ""))]
1524   ""
1525   "ix86_expand_move (SImode, operands); DONE;")
1526
1527 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1528 ;; general_operand.
1529 ;;
1530 ;; %%% We don't use a post-inc memory reference because x86 is not a
1531 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1532 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1533 ;; targets without our curiosities, and it is just as easy to represent
1534 ;; this differently.
1535
1536 (define_insn "*pushsi2"
1537   [(set (match_operand:SI 0 "push_operand" "=<")
1538         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1539   "!TARGET_64BIT"
1540   "push{l}\t%1"
1541   [(set_attr "type" "push")
1542    (set_attr "mode" "SI")])
1543
1544 ;; For 64BIT abi we always round up to 8 bytes.
1545 (define_insn "*pushsi2_rex64"
1546   [(set (match_operand:SI 0 "push_operand" "=X")
1547         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1548   "TARGET_64BIT"
1549   "push{q}\t%q1"
1550   [(set_attr "type" "push")
1551    (set_attr "mode" "SI")])
1552
1553 (define_insn "*pushsi2_prologue"
1554   [(set (match_operand:SI 0 "push_operand" "=<")
1555         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1556    (clobber (mem:BLK (scratch)))]
1557   "!TARGET_64BIT"
1558   "push{l}\t%1"
1559   [(set_attr "type" "push")
1560    (set_attr "mode" "SI")])
1561
1562 (define_insn "*popsi1_epilogue"
1563   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1564         (mem:SI (reg:SI SP_REG)))
1565    (set (reg:SI SP_REG)
1566         (plus:SI (reg:SI SP_REG) (const_int 4)))
1567    (clobber (mem:BLK (scratch)))]
1568   "!TARGET_64BIT"
1569   "pop{l}\t%0"
1570   [(set_attr "type" "pop")
1571    (set_attr "mode" "SI")])
1572
1573 (define_insn "popsi1"
1574   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1575         (mem:SI (reg:SI SP_REG)))
1576    (set (reg:SI SP_REG)
1577         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1578   "!TARGET_64BIT"
1579   "pop{l}\t%0"
1580   [(set_attr "type" "pop")
1581    (set_attr "mode" "SI")])
1582
1583 (define_insn "*movsi_xor"
1584   [(set (match_operand:SI 0 "register_operand" "=r")
1585         (match_operand:SI 1 "const0_operand" ""))
1586    (clobber (reg:CC FLAGS_REG))]
1587   "reload_completed"
1588   "xor{l}\t%0, %0"
1589   [(set_attr "type" "alu1")
1590    (set_attr "mode" "SI")
1591    (set_attr "length_immediate" "0")])
1592
1593 (define_insn "*movsi_or"
1594   [(set (match_operand:SI 0 "register_operand" "=r")
1595         (match_operand:SI 1 "immediate_operand" "i"))
1596    (clobber (reg:CC FLAGS_REG))]
1597   "reload_completed
1598    && operands[1] == constm1_rtx"
1599 {
1600   operands[1] = constm1_rtx;
1601   return "or{l}\t{%1, %0|%0, %1}";
1602 }
1603   [(set_attr "type" "alu1")
1604    (set_attr "mode" "SI")
1605    (set_attr "length_immediate" "1")])
1606
1607 (define_insn "*movsi_1"
1608   [(set (match_operand:SI 0 "nonimmediate_operand"
1609                         "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1610         (match_operand:SI 1 "general_operand"
1611                         "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r   ,m "))]
1612   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1613 {
1614   switch (get_attr_type (insn))
1615     {
1616     case TYPE_SSELOG1:
1617       if (get_attr_mode (insn) == MODE_TI)
1618         return "%vpxor\t%0, %d0";
1619       return "%vxorps\t%0, %d0";
1620
1621     case TYPE_SSEMOV:
1622       switch (get_attr_mode (insn))
1623         {
1624         case MODE_TI:
1625           return "%vmovdqa\t{%1, %0|%0, %1}";
1626         case MODE_V4SF:
1627           return "%vmovaps\t{%1, %0|%0, %1}";
1628         case MODE_SI:
1629           return "%vmovd\t{%1, %0|%0, %1}";
1630         case MODE_SF:
1631           return "%vmovss\t{%1, %0|%0, %1}";
1632         default:
1633           gcc_unreachable ();
1634         }
1635
1636     case TYPE_MMX:
1637       return "pxor\t%0, %0";
1638
1639     case TYPE_MMXMOV:
1640       if (get_attr_mode (insn) == MODE_DI)
1641         return "movq\t{%1, %0|%0, %1}";
1642       return "movd\t{%1, %0|%0, %1}";
1643
1644     case TYPE_LEA:
1645       return "lea{l}\t{%1, %0|%0, %1}";
1646
1647     default:
1648       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1649       return "mov{l}\t{%1, %0|%0, %1}";
1650     }
1651 }
1652   [(set (attr "type")
1653      (cond [(eq_attr "alternative" "2")
1654               (const_string "mmx")
1655             (eq_attr "alternative" "3,4,5")
1656               (const_string "mmxmov")
1657             (eq_attr "alternative" "6")
1658               (const_string "sselog1")
1659             (eq_attr "alternative" "7,8,9,10,11")
1660               (const_string "ssemov")
1661             (match_operand:DI 1 "pic_32bit_operand" "")
1662               (const_string "lea")
1663            ]
1664            (const_string "imov")))
1665    (set (attr "prefix")
1666      (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
1667        (const_string "orig")
1668        (const_string "maybe_vex")))
1669    (set (attr "prefix_data16")
1670      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
1671        (const_string "1")
1672        (const_string "*")))
1673    (set (attr "mode")
1674      (cond [(eq_attr "alternative" "2,3")
1675               (const_string "DI")
1676             (eq_attr "alternative" "6,7")
1677               (if_then_else
1678                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1679                 (const_string "V4SF")
1680                 (const_string "TI"))
1681             (and (eq_attr "alternative" "8,9,10,11")
1682                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1683               (const_string "SF")
1684            ]
1685            (const_string "SI")))])
1686
1687 ;; Stores and loads of ax to arbitrary constant address.
1688 ;; We fake an second form of instruction to force reload to load address
1689 ;; into register when rax is not available
1690 (define_insn "*movabssi_1_rex64"
1691   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1692         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1693   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1694   "@
1695    movabs{l}\t{%1, %P0|%P0, %1}
1696    mov{l}\t{%1, %a0|%a0, %1}"
1697   [(set_attr "type" "imov")
1698    (set_attr "modrm" "0,*")
1699    (set_attr "length_address" "8,0")
1700    (set_attr "length_immediate" "0,*")
1701    (set_attr "memory" "store")
1702    (set_attr "mode" "SI")])
1703
1704 (define_insn "*movabssi_2_rex64"
1705   [(set (match_operand:SI 0 "register_operand" "=a,r")
1706         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1707   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1708   "@
1709    movabs{l}\t{%P1, %0|%0, %P1}
1710    mov{l}\t{%a1, %0|%0, %a1}"
1711   [(set_attr "type" "imov")
1712    (set_attr "modrm" "0,*")
1713    (set_attr "length_address" "8,0")
1714    (set_attr "length_immediate" "0")
1715    (set_attr "memory" "load")
1716    (set_attr "mode" "SI")])
1717
1718 (define_insn "*swapsi"
1719   [(set (match_operand:SI 0 "register_operand" "+r")
1720         (match_operand:SI 1 "register_operand" "+r"))
1721    (set (match_dup 1)
1722         (match_dup 0))]
1723   ""
1724   "xchg{l}\t%1, %0"
1725   [(set_attr "type" "imov")
1726    (set_attr "mode" "SI")
1727    (set_attr "pent_pair" "np")
1728    (set_attr "athlon_decode" "vector")
1729    (set_attr "amdfam10_decode" "double")])
1730
1731 (define_expand "movhi"
1732   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1733         (match_operand:HI 1 "general_operand" ""))]
1734   ""
1735   "ix86_expand_move (HImode, operands); DONE;")
1736
1737 (define_insn "*pushhi2"
1738   [(set (match_operand:HI 0 "push_operand" "=X")
1739         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1740   "!TARGET_64BIT"
1741   "push{l}\t%k1"
1742   [(set_attr "type" "push")
1743    (set_attr "mode" "SI")])
1744
1745 ;; For 64BIT abi we always round up to 8 bytes.
1746 (define_insn "*pushhi2_rex64"
1747   [(set (match_operand:HI 0 "push_operand" "=X")
1748         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1749   "TARGET_64BIT"
1750   "push{q}\t%q1"
1751   [(set_attr "type" "push")
1752    (set_attr "mode" "DI")])
1753
1754 (define_insn "*movhi_1"
1755   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1756         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1757   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1758 {
1759   switch (get_attr_type (insn))
1760     {
1761     case TYPE_IMOVX:
1762       /* movzwl is faster than movw on p2 due to partial word stalls,
1763          though not as fast as an aligned movl.  */
1764       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1765     default:
1766       if (get_attr_mode (insn) == MODE_SI)
1767         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1768       else
1769         return "mov{w}\t{%1, %0|%0, %1}";
1770     }
1771 }
1772   [(set (attr "type")
1773      (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
1774               (const_string "imov")
1775             (and (eq_attr "alternative" "0")
1776                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1777                           (const_int 0))
1778                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1779                           (const_int 0))))
1780               (const_string "imov")
1781             (and (eq_attr "alternative" "1,2")
1782                  (match_operand:HI 1 "aligned_operand" ""))
1783               (const_string "imov")
1784             (and (ne (symbol_ref "TARGET_MOVX")
1785                      (const_int 0))
1786                  (eq_attr "alternative" "0,2"))
1787               (const_string "imovx")
1788            ]
1789            (const_string "imov")))
1790     (set (attr "mode")
1791       (cond [(eq_attr "type" "imovx")
1792                (const_string "SI")
1793              (and (eq_attr "alternative" "1,2")
1794                   (match_operand:HI 1 "aligned_operand" ""))
1795                (const_string "SI")
1796              (and (eq_attr "alternative" "0")
1797                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1798                            (const_int 0))
1799                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1800                            (const_int 0))))
1801                (const_string "SI")
1802             ]
1803             (const_string "HI")))])
1804
1805 ;; Stores and loads of ax to arbitrary constant address.
1806 ;; We fake an second form of instruction to force reload to load address
1807 ;; into register when rax is not available
1808 (define_insn "*movabshi_1_rex64"
1809   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1810         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1811   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1812   "@
1813    movabs{w}\t{%1, %P0|%P0, %1}
1814    mov{w}\t{%1, %a0|%a0, %1}"
1815   [(set_attr "type" "imov")
1816    (set_attr "modrm" "0,*")
1817    (set_attr "length_address" "8,0")
1818    (set_attr "length_immediate" "0,*")
1819    (set_attr "memory" "store")
1820    (set_attr "mode" "HI")])
1821
1822 (define_insn "*movabshi_2_rex64"
1823   [(set (match_operand:HI 0 "register_operand" "=a,r")
1824         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1825   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1826   "@
1827    movabs{w}\t{%P1, %0|%0, %P1}
1828    mov{w}\t{%a1, %0|%0, %a1}"
1829   [(set_attr "type" "imov")
1830    (set_attr "modrm" "0,*")
1831    (set_attr "length_address" "8,0")
1832    (set_attr "length_immediate" "0")
1833    (set_attr "memory" "load")
1834    (set_attr "mode" "HI")])
1835
1836 (define_insn "*swaphi_1"
1837   [(set (match_operand:HI 0 "register_operand" "+r")
1838         (match_operand:HI 1 "register_operand" "+r"))
1839    (set (match_dup 1)
1840         (match_dup 0))]
1841   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
1842   "xchg{l}\t%k1, %k0"
1843   [(set_attr "type" "imov")
1844    (set_attr "mode" "SI")
1845    (set_attr "pent_pair" "np")
1846    (set_attr "athlon_decode" "vector")
1847    (set_attr "amdfam10_decode" "double")])
1848
1849 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1850 (define_insn "*swaphi_2"
1851   [(set (match_operand:HI 0 "register_operand" "+r")
1852         (match_operand:HI 1 "register_operand" "+r"))
1853    (set (match_dup 1)
1854         (match_dup 0))]
1855   "TARGET_PARTIAL_REG_STALL"
1856   "xchg{w}\t%1, %0"
1857   [(set_attr "type" "imov")
1858    (set_attr "mode" "HI")
1859    (set_attr "pent_pair" "np")
1860    (set_attr "athlon_decode" "vector")])
1861
1862 (define_expand "movstricthi"
1863   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1864         (match_operand:HI 1 "general_operand" ""))]
1865   ""
1866 {
1867   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
1868     FAIL;
1869   /* Don't generate memory->memory moves, go through a register */
1870   if (MEM_P (operands[0]) && MEM_P (operands[1]))
1871     operands[1] = force_reg (HImode, operands[1]);
1872 })
1873
1874 (define_insn "*movstricthi_1"
1875   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1876         (match_operand:HI 1 "general_operand" "rn,m"))]
1877   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
1878    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1879   "mov{w}\t{%1, %0|%0, %1}"
1880   [(set_attr "type" "imov")
1881    (set_attr "mode" "HI")])
1882
1883 (define_insn "*movstricthi_xor"
1884   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1885         (match_operand:HI 1 "const0_operand" ""))
1886    (clobber (reg:CC FLAGS_REG))]
1887   "reload_completed"
1888   "xor{w}\t%0, %0"
1889   [(set_attr "type" "alu1")
1890    (set_attr "mode" "HI")
1891    (set_attr "length_immediate" "0")])
1892
1893 (define_expand "movqi"
1894   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1895         (match_operand:QI 1 "general_operand" ""))]
1896   ""
1897   "ix86_expand_move (QImode, operands); DONE;")
1898
1899 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1900 ;; "push a byte".  But actually we use pushl, which has the effect
1901 ;; of rounding the amount pushed up to a word.
1902
1903 (define_insn "*pushqi2"
1904   [(set (match_operand:QI 0 "push_operand" "=X")
1905         (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1906   "!TARGET_64BIT"
1907   "push{l}\t%k1"
1908   [(set_attr "type" "push")
1909    (set_attr "mode" "SI")])
1910
1911 ;; For 64BIT abi we always round up to 8 bytes.
1912 (define_insn "*pushqi2_rex64"
1913   [(set (match_operand:QI 0 "push_operand" "=X")
1914         (match_operand:QI 1 "nonmemory_no_elim_operand" "qn"))]
1915   "TARGET_64BIT"
1916   "push{q}\t%q1"
1917   [(set_attr "type" "push")
1918    (set_attr "mode" "DI")])
1919
1920 ;; Situation is quite tricky about when to choose full sized (SImode) move
1921 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1922 ;; partial register dependency machines (such as AMD Athlon), where QImode
1923 ;; moves issue extra dependency and for partial register stalls machines
1924 ;; that don't use QImode patterns (and QImode move cause stall on the next
1925 ;; instruction).
1926 ;;
1927 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1928 ;; register stall machines with, where we use QImode instructions, since
1929 ;; partial register stall can be caused there.  Then we use movzx.
1930 (define_insn "*movqi_1"
1931   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1932         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1933   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1934 {
1935   switch (get_attr_type (insn))
1936     {
1937     case TYPE_IMOVX:
1938       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
1939       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1940     default:
1941       if (get_attr_mode (insn) == MODE_SI)
1942         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1943       else
1944         return "mov{b}\t{%1, %0|%0, %1}";
1945     }
1946 }
1947   [(set (attr "type")
1948      (cond [(and (eq_attr "alternative" "5")
1949                  (not (match_operand:QI 1 "aligned_operand" "")))
1950               (const_string "imovx")
1951             (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
1952               (const_string "imov")
1953             (and (eq_attr "alternative" "3")
1954                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1955                           (const_int 0))
1956                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1957                           (const_int 0))))
1958               (const_string "imov")
1959             (eq_attr "alternative" "3,5")
1960               (const_string "imovx")
1961             (and (ne (symbol_ref "TARGET_MOVX")
1962                      (const_int 0))
1963                  (eq_attr "alternative" "2"))
1964               (const_string "imovx")
1965            ]
1966            (const_string "imov")))
1967    (set (attr "mode")
1968       (cond [(eq_attr "alternative" "3,4,5")
1969                (const_string "SI")
1970              (eq_attr "alternative" "6")
1971                (const_string "QI")
1972              (eq_attr "type" "imovx")
1973                (const_string "SI")
1974              (and (eq_attr "type" "imov")
1975                   (and (eq_attr "alternative" "0,1")
1976                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1977                                 (const_int 0))
1978                             (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
1979                                      (const_int 0))
1980                                  (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1981                                      (const_int 0))))))
1982                (const_string "SI")
1983              ;; Avoid partial register stalls when not using QImode arithmetic
1984              (and (eq_attr "type" "imov")
1985                   (and (eq_attr "alternative" "0,1")
1986                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1987                                 (const_int 0))
1988                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1989                                 (const_int 0)))))
1990                (const_string "SI")
1991            ]
1992            (const_string "QI")))])
1993
1994 (define_insn "*swapqi_1"
1995   [(set (match_operand:QI 0 "register_operand" "+r")
1996         (match_operand:QI 1 "register_operand" "+r"))
1997    (set (match_dup 1)
1998         (match_dup 0))]
1999   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2000   "xchg{l}\t%k1, %k0"
2001   [(set_attr "type" "imov")
2002    (set_attr "mode" "SI")
2003    (set_attr "pent_pair" "np")
2004    (set_attr "athlon_decode" "vector")
2005    (set_attr "amdfam10_decode" "vector")])
2006
2007 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
2008 (define_insn "*swapqi_2"
2009   [(set (match_operand:QI 0 "register_operand" "+q")
2010         (match_operand:QI 1 "register_operand" "+q"))
2011    (set (match_dup 1)
2012         (match_dup 0))]
2013   "TARGET_PARTIAL_REG_STALL"
2014   "xchg{b}\t%1, %0"
2015   [(set_attr "type" "imov")
2016    (set_attr "mode" "QI")
2017    (set_attr "pent_pair" "np")
2018    (set_attr "athlon_decode" "vector")])
2019
2020 (define_expand "movstrictqi"
2021   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
2022         (match_operand:QI 1 "general_operand" ""))]
2023   ""
2024 {
2025   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2026     FAIL;
2027   /* Don't generate memory->memory moves, go through a register.  */
2028   if (MEM_P (operands[0]) && MEM_P (operands[1]))
2029     operands[1] = force_reg (QImode, operands[1]);
2030 })
2031
2032 (define_insn "*movstrictqi_1"
2033   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
2034         (match_operand:QI 1 "general_operand" "*qn,m"))]
2035   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2036    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2037   "mov{b}\t{%1, %0|%0, %1}"
2038   [(set_attr "type" "imov")
2039    (set_attr "mode" "QI")])
2040
2041 (define_insn "*movstrictqi_xor"
2042   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
2043         (match_operand:QI 1 "const0_operand" ""))
2044    (clobber (reg:CC FLAGS_REG))]
2045   "reload_completed"
2046   "xor{b}\t%0, %0"
2047   [(set_attr "type" "alu1")
2048    (set_attr "mode" "QI")
2049    (set_attr "length_immediate" "0")])
2050
2051 (define_insn "*movsi_extv_1"
2052   [(set (match_operand:SI 0 "register_operand" "=R")
2053         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
2054                          (const_int 8)
2055                          (const_int 8)))]
2056   ""
2057   "movs{bl|x}\t{%h1, %0|%0, %h1}"
2058   [(set_attr "type" "imovx")
2059    (set_attr "mode" "SI")])
2060
2061 (define_insn "*movhi_extv_1"
2062   [(set (match_operand:HI 0 "register_operand" "=R")
2063         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
2064                          (const_int 8)
2065                          (const_int 8)))]
2066   ""
2067   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2068   [(set_attr "type" "imovx")
2069    (set_attr "mode" "SI")])
2070
2071 (define_insn "*movqi_extv_1"
2072   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2073         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2074                          (const_int 8)
2075                          (const_int 8)))]
2076   "!TARGET_64BIT"
2077 {
2078   switch (get_attr_type (insn))
2079     {
2080     case TYPE_IMOVX:
2081       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2082     default:
2083       return "mov{b}\t{%h1, %0|%0, %h1}";
2084     }
2085 }
2086   [(set (attr "type")
2087      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2088                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2089                              (ne (symbol_ref "TARGET_MOVX")
2090                                  (const_int 0))))
2091         (const_string "imovx")
2092         (const_string "imov")))
2093    (set (attr "mode")
2094      (if_then_else (eq_attr "type" "imovx")
2095         (const_string "SI")
2096         (const_string "QI")))])
2097
2098 (define_insn "*movqi_extv_1_rex64"
2099   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2100         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2101                          (const_int 8)
2102                          (const_int 8)))]
2103   "TARGET_64BIT"
2104 {
2105   switch (get_attr_type (insn))
2106     {
2107     case TYPE_IMOVX:
2108       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2109     default:
2110       return "mov{b}\t{%h1, %0|%0, %h1}";
2111     }
2112 }
2113   [(set (attr "type")
2114      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2115                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2116                              (ne (symbol_ref "TARGET_MOVX")
2117                                  (const_int 0))))
2118         (const_string "imovx")
2119         (const_string "imov")))
2120    (set (attr "mode")
2121      (if_then_else (eq_attr "type" "imovx")
2122         (const_string "SI")
2123         (const_string "QI")))])
2124
2125 ;; Stores and loads of ax to arbitrary constant address.
2126 ;; We fake an second form of instruction to force reload to load address
2127 ;; into register when rax is not available
2128 (define_insn "*movabsqi_1_rex64"
2129   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2130         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
2131   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2132   "@
2133    movabs{b}\t{%1, %P0|%P0, %1}
2134    mov{b}\t{%1, %a0|%a0, %1}"
2135   [(set_attr "type" "imov")
2136    (set_attr "modrm" "0,*")
2137    (set_attr "length_address" "8,0")
2138    (set_attr "length_immediate" "0,*")
2139    (set_attr "memory" "store")
2140    (set_attr "mode" "QI")])
2141
2142 (define_insn "*movabsqi_2_rex64"
2143   [(set (match_operand:QI 0 "register_operand" "=a,r")
2144         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2145   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2146   "@
2147    movabs{b}\t{%P1, %0|%0, %P1}
2148    mov{b}\t{%a1, %0|%0, %a1}"
2149   [(set_attr "type" "imov")
2150    (set_attr "modrm" "0,*")
2151    (set_attr "length_address" "8,0")
2152    (set_attr "length_immediate" "0")
2153    (set_attr "memory" "load")
2154    (set_attr "mode" "QI")])
2155
2156 (define_insn "*movdi_extzv_1"
2157   [(set (match_operand:DI 0 "register_operand" "=R")
2158         (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
2159                          (const_int 8)
2160                          (const_int 8)))]
2161   "TARGET_64BIT"
2162   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2163   [(set_attr "type" "imovx")
2164    (set_attr "mode" "SI")])
2165
2166 (define_insn "*movsi_extzv_1"
2167   [(set (match_operand:SI 0 "register_operand" "=R")
2168         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
2169                          (const_int 8)
2170                          (const_int 8)))]
2171   ""
2172   "movz{bl|x}\t{%h1, %0|%0, %h1}"
2173   [(set_attr "type" "imovx")
2174    (set_attr "mode" "SI")])
2175
2176 (define_insn "*movqi_extzv_2"
2177   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2178         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2179                                     (const_int 8)
2180                                     (const_int 8)) 0))]
2181   "!TARGET_64BIT"
2182 {
2183   switch (get_attr_type (insn))
2184     {
2185     case TYPE_IMOVX:
2186       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2187     default:
2188       return "mov{b}\t{%h1, %0|%0, %h1}";
2189     }
2190 }
2191   [(set (attr "type")
2192      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2193                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2194                              (ne (symbol_ref "TARGET_MOVX")
2195                                  (const_int 0))))
2196         (const_string "imovx")
2197         (const_string "imov")))
2198    (set (attr "mode")
2199      (if_then_else (eq_attr "type" "imovx")
2200         (const_string "SI")
2201         (const_string "QI")))])
2202
2203 (define_insn "*movqi_extzv_2_rex64"
2204   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2205         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2206                                     (const_int 8)
2207                                     (const_int 8)) 0))]
2208   "TARGET_64BIT"
2209 {
2210   switch (get_attr_type (insn))
2211     {
2212     case TYPE_IMOVX:
2213       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2214     default:
2215       return "mov{b}\t{%h1, %0|%0, %h1}";
2216     }
2217 }
2218   [(set (attr "type")
2219      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2220                         (ne (symbol_ref "TARGET_MOVX")
2221                             (const_int 0)))
2222         (const_string "imovx")
2223         (const_string "imov")))
2224    (set (attr "mode")
2225      (if_then_else (eq_attr "type" "imovx")
2226         (const_string "SI")
2227         (const_string "QI")))])
2228
2229 (define_insn "movsi_insv_1"
2230   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2231                          (const_int 8)
2232                          (const_int 8))
2233         (match_operand:SI 1 "general_operand" "Qmn"))]
2234   "!TARGET_64BIT"
2235   "mov{b}\t{%b1, %h0|%h0, %b1}"
2236   [(set_attr "type" "imov")
2237    (set_attr "mode" "QI")])
2238
2239 (define_insn "*movsi_insv_1_rex64"
2240   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2241                          (const_int 8)
2242                          (const_int 8))
2243         (match_operand:SI 1 "nonmemory_operand" "Qn"))]
2244   "TARGET_64BIT"
2245   "mov{b}\t{%b1, %h0|%h0, %b1}"
2246   [(set_attr "type" "imov")
2247    (set_attr "mode" "QI")])
2248
2249 (define_insn "movdi_insv_1_rex64"
2250   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
2251                          (const_int 8)
2252                          (const_int 8))
2253         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
2254   "TARGET_64BIT"
2255   "mov{b}\t{%b1, %h0|%h0, %b1}"
2256   [(set_attr "type" "imov")
2257    (set_attr "mode" "QI")])
2258
2259 (define_insn "*movqi_insv_2"
2260   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2261                          (const_int 8)
2262                          (const_int 8))
2263         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2264                      (const_int 8)))]
2265   ""
2266   "mov{b}\t{%h1, %h0|%h0, %h1}"
2267   [(set_attr "type" "imov")
2268    (set_attr "mode" "QI")])
2269
2270 (define_expand "movdi"
2271   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2272         (match_operand:DI 1 "general_operand" ""))]
2273   ""
2274   "ix86_expand_move (DImode, operands); DONE;")
2275
2276 (define_insn "*pushdi"
2277   [(set (match_operand:DI 0 "push_operand" "=<")
2278         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
2279   "!TARGET_64BIT"
2280   "#")
2281
2282 (define_insn "*pushdi2_rex64"
2283   [(set (match_operand:DI 0 "push_operand" "=<,!<")
2284         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
2285   "TARGET_64BIT"
2286   "@
2287    push{q}\t%1
2288    #"
2289   [(set_attr "type" "push,multi")
2290    (set_attr "mode" "DI")])
2291
2292 ;; Convert impossible pushes of immediate to existing instructions.
2293 ;; First try to get scratch register and go through it.  In case this
2294 ;; fails, push sign extended lower part first and then overwrite
2295 ;; upper part by 32bit move.
2296 (define_peephole2
2297   [(match_scratch:DI 2 "r")
2298    (set (match_operand:DI 0 "push_operand" "")
2299         (match_operand:DI 1 "immediate_operand" ""))]
2300   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2301    && !x86_64_immediate_operand (operands[1], DImode)"
2302   [(set (match_dup 2) (match_dup 1))
2303    (set (match_dup 0) (match_dup 2))]
2304   "")
2305
2306 ;; We need to define this as both peepholer and splitter for case
2307 ;; peephole2 pass is not run.
2308 ;; "&& 1" is needed to keep it from matching the previous pattern.
2309 (define_peephole2
2310   [(set (match_operand:DI 0 "push_operand" "")
2311         (match_operand:DI 1 "immediate_operand" ""))]
2312   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2313    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2314   [(set (match_dup 0) (match_dup 1))
2315    (set (match_dup 2) (match_dup 3))]
2316   "split_di (&operands[1], 1, &operands[2], &operands[3]);
2317    operands[1] = gen_lowpart (DImode, operands[2]);
2318    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2319                                                     GEN_INT (4)));
2320   ")
2321
2322 (define_split
2323   [(set (match_operand:DI 0 "push_operand" "")
2324         (match_operand:DI 1 "immediate_operand" ""))]
2325   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2326                     ? epilogue_completed : reload_completed)
2327    && !symbolic_operand (operands[1], DImode)
2328    && !x86_64_immediate_operand (operands[1], DImode)"
2329   [(set (match_dup 0) (match_dup 1))
2330    (set (match_dup 2) (match_dup 3))]
2331   "split_di (&operands[1], 1, &operands[2], &operands[3]);
2332    operands[1] = gen_lowpart (DImode, operands[2]);
2333    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2334                                                     GEN_INT (4)));
2335   ")
2336
2337 (define_insn "*pushdi2_prologue_rex64"
2338   [(set (match_operand:DI 0 "push_operand" "=<")
2339         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
2340    (clobber (mem:BLK (scratch)))]
2341   "TARGET_64BIT"
2342   "push{q}\t%1"
2343   [(set_attr "type" "push")
2344    (set_attr "mode" "DI")])
2345
2346 (define_insn "*popdi1_epilogue_rex64"
2347   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2348         (mem:DI (reg:DI SP_REG)))
2349    (set (reg:DI SP_REG)
2350         (plus:DI (reg:DI SP_REG) (const_int 8)))
2351    (clobber (mem:BLK (scratch)))]
2352   "TARGET_64BIT"
2353   "pop{q}\t%0"
2354   [(set_attr "type" "pop")
2355    (set_attr "mode" "DI")])
2356
2357 (define_insn "popdi1"
2358   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2359         (mem:DI (reg:DI SP_REG)))
2360    (set (reg:DI SP_REG)
2361         (plus:DI (reg:DI SP_REG) (const_int 8)))]
2362   "TARGET_64BIT"
2363   "pop{q}\t%0"
2364   [(set_attr "type" "pop")
2365    (set_attr "mode" "DI")])
2366
2367 (define_insn "*movdi_xor_rex64"
2368   [(set (match_operand:DI 0 "register_operand" "=r")
2369         (match_operand:DI 1 "const0_operand" ""))
2370    (clobber (reg:CC FLAGS_REG))]
2371   "TARGET_64BIT
2372    && reload_completed"
2373   "xor{l}\t%k0, %k0";
2374   [(set_attr "type" "alu1")
2375    (set_attr "mode" "SI")
2376    (set_attr "length_immediate" "0")])
2377
2378 (define_insn "*movdi_or_rex64"
2379   [(set (match_operand:DI 0 "register_operand" "=r")
2380         (match_operand:DI 1 "const_int_operand" "i"))
2381    (clobber (reg:CC FLAGS_REG))]
2382   "TARGET_64BIT
2383    && reload_completed
2384    && operands[1] == constm1_rtx"
2385 {
2386   operands[1] = constm1_rtx;
2387   return "or{q}\t{%1, %0|%0, %1}";
2388 }
2389   [(set_attr "type" "alu1")
2390    (set_attr "mode" "DI")
2391    (set_attr "length_immediate" "1")])
2392
2393 (define_insn "*movdi_2"
2394   [(set (match_operand:DI 0 "nonimmediate_operand"
2395                         "=r  ,o  ,*y,m*y,*y,*Y2,m  ,*Y2,*Y2,*x,m ,*x,*x")
2396         (match_operand:DI 1 "general_operand"
2397                         "riFo,riF,C ,*y ,m ,C  ,*Y2,*Y2,m  ,C ,*x,*x,m "))]
2398   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2399   "@
2400    #
2401    #
2402    pxor\t%0, %0
2403    movq\t{%1, %0|%0, %1}
2404    movq\t{%1, %0|%0, %1}
2405    %vpxor\t%0, %d0
2406    %vmovq\t{%1, %0|%0, %1}
2407    %vmovdqa\t{%1, %0|%0, %1}
2408    %vmovq\t{%1, %0|%0, %1}
2409    xorps\t%0, %0
2410    movlps\t{%1, %0|%0, %1}
2411    movaps\t{%1, %0|%0, %1}
2412    movlps\t{%1, %0|%0, %1}"
2413   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2414    (set (attr "prefix")
2415      (if_then_else (eq_attr "alternative" "5,6,7,8")
2416        (const_string "vex")
2417        (const_string "orig")))
2418    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2419
2420 (define_split
2421   [(set (match_operand:DI 0 "push_operand" "")
2422         (match_operand:DI 1 "general_operand" ""))]
2423   "!TARGET_64BIT && reload_completed
2424    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2425   [(const_int 0)]
2426   "ix86_split_long_move (operands); DONE;")
2427
2428 ;; %%% This multiword shite has got to go.
2429 (define_split
2430   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2431         (match_operand:DI 1 "general_operand" ""))]
2432   "!TARGET_64BIT && reload_completed
2433    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2434    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2435   [(const_int 0)]
2436   "ix86_split_long_move (operands); DONE;")
2437
2438 (define_insn "*movdi_1_rex64"
2439   [(set (match_operand:DI 0 "nonimmediate_operand"
2440           "=r,r  ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2441         (match_operand:DI 1 "general_operand"
2442           "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r   ,m  ,C ,*x,*Yi,*x,r  ,m ,*Ym,*x"))]
2443   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2444 {
2445   switch (get_attr_type (insn))
2446     {
2447     case TYPE_SSECVT:
2448       if (SSE_REG_P (operands[0]))
2449         return "movq2dq\t{%1, %0|%0, %1}";
2450       else
2451         return "movdq2q\t{%1, %0|%0, %1}";
2452
2453     case TYPE_SSEMOV:
2454       if (TARGET_AVX)
2455         {
2456           if (get_attr_mode (insn) == MODE_TI)
2457             return "vmovdqa\t{%1, %0|%0, %1}";
2458           else
2459             return "vmovq\t{%1, %0|%0, %1}";
2460         }
2461
2462       if (get_attr_mode (insn) == MODE_TI)
2463         return "movdqa\t{%1, %0|%0, %1}";
2464       /* FALLTHRU */
2465
2466     case TYPE_MMXMOV:
2467       /* Moves from and into integer register is done using movd
2468          opcode with REX prefix.  */
2469       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2470         return "movd\t{%1, %0|%0, %1}";
2471       return "movq\t{%1, %0|%0, %1}";
2472
2473     case TYPE_SSELOG1:
2474       return "%vpxor\t%0, %d0";
2475
2476     case TYPE_MMX:
2477       return "pxor\t%0, %0";
2478
2479     case TYPE_MULTI:
2480       return "#";
2481
2482     case TYPE_LEA:
2483       return "lea{q}\t{%a1, %0|%0, %a1}";
2484
2485     default:
2486       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2487       if (get_attr_mode (insn) == MODE_SI)
2488         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2489       else if (which_alternative == 2)
2490         return "movabs{q}\t{%1, %0|%0, %1}";
2491       else
2492         return "mov{q}\t{%1, %0|%0, %1}";
2493     }
2494 }
2495   [(set (attr "type")
2496      (cond [(eq_attr "alternative" "5")
2497               (const_string "mmx")
2498             (eq_attr "alternative" "6,7,8,9,10")
2499               (const_string "mmxmov")
2500             (eq_attr "alternative" "11")
2501               (const_string "sselog1")
2502             (eq_attr "alternative" "12,13,14,15,16")
2503               (const_string "ssemov")
2504             (eq_attr "alternative" "17,18")
2505               (const_string "ssecvt")
2506             (eq_attr "alternative" "4")
2507               (const_string "multi")
2508             (match_operand:DI 1 "pic_32bit_operand" "")
2509               (const_string "lea")
2510            ]
2511            (const_string "imov")))
2512    (set (attr "modrm")
2513      (if_then_else
2514        (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2515          (const_string "0")
2516          (const_string "*")))
2517    (set (attr "length_immediate")
2518      (if_then_else
2519        (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2520          (const_string "8")
2521          (const_string "*")))
2522    (set_attr "prefix_rex" "*,*,*,*,*,*,*,1,*,1,*,*,*,*,*,*,*,*,*")
2523    (set_attr "prefix_data16" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,1,*,*,*")
2524    (set (attr "prefix")
2525      (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
2526        (const_string "maybe_vex")
2527        (const_string "orig")))
2528    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2529
2530 ;; Stores and loads of ax to arbitrary constant address.
2531 ;; We fake an second form of instruction to force reload to load address
2532 ;; into register when rax is not available
2533 (define_insn "*movabsdi_1_rex64"
2534   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2535         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2536   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2537   "@
2538    movabs{q}\t{%1, %P0|%P0, %1}
2539    mov{q}\t{%1, %a0|%a0, %1}"
2540   [(set_attr "type" "imov")
2541    (set_attr "modrm" "0,*")
2542    (set_attr "length_address" "8,0")
2543    (set_attr "length_immediate" "0,*")
2544    (set_attr "memory" "store")
2545    (set_attr "mode" "DI")])
2546
2547 (define_insn "*movabsdi_2_rex64"
2548   [(set (match_operand:DI 0 "register_operand" "=a,r")
2549         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2550   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2551   "@
2552    movabs{q}\t{%P1, %0|%0, %P1}
2553    mov{q}\t{%a1, %0|%0, %a1}"
2554   [(set_attr "type" "imov")
2555    (set_attr "modrm" "0,*")
2556    (set_attr "length_address" "8,0")
2557    (set_attr "length_immediate" "0")
2558    (set_attr "memory" "load")
2559    (set_attr "mode" "DI")])
2560
2561 ;; Convert impossible stores of immediate to existing instructions.
2562 ;; First try to get scratch register and go through it.  In case this
2563 ;; fails, move by 32bit parts.
2564 (define_peephole2
2565   [(match_scratch:DI 2 "r")
2566    (set (match_operand:DI 0 "memory_operand" "")
2567         (match_operand:DI 1 "immediate_operand" ""))]
2568   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2569    && !x86_64_immediate_operand (operands[1], DImode)"
2570   [(set (match_dup 2) (match_dup 1))
2571    (set (match_dup 0) (match_dup 2))]
2572   "")
2573
2574 ;; We need to define this as both peepholer and splitter for case
2575 ;; peephole2 pass is not run.
2576 ;; "&& 1" is needed to keep it from matching the previous pattern.
2577 (define_peephole2
2578   [(set (match_operand:DI 0 "memory_operand" "")
2579         (match_operand:DI 1 "immediate_operand" ""))]
2580   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2581    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2582   [(set (match_dup 2) (match_dup 3))
2583    (set (match_dup 4) (match_dup 5))]
2584   "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2585
2586 (define_split
2587   [(set (match_operand:DI 0 "memory_operand" "")
2588         (match_operand:DI 1 "immediate_operand" ""))]
2589   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2590                     ? epilogue_completed : reload_completed)
2591    && !symbolic_operand (operands[1], DImode)
2592    && !x86_64_immediate_operand (operands[1], DImode)"
2593   [(set (match_dup 2) (match_dup 3))
2594    (set (match_dup 4) (match_dup 5))]
2595   "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2596
2597 (define_insn "*swapdi_rex64"
2598   [(set (match_operand:DI 0 "register_operand" "+r")
2599         (match_operand:DI 1 "register_operand" "+r"))
2600    (set (match_dup 1)
2601         (match_dup 0))]
2602   "TARGET_64BIT"
2603   "xchg{q}\t%1, %0"
2604   [(set_attr "type" "imov")
2605    (set_attr "mode" "DI")
2606    (set_attr "pent_pair" "np")
2607    (set_attr "athlon_decode" "vector")
2608    (set_attr "amdfam10_decode" "double")])
2609
2610 (define_expand "movoi"
2611   [(set (match_operand:OI 0 "nonimmediate_operand" "")
2612         (match_operand:OI 1 "general_operand" ""))]
2613   "TARGET_AVX"
2614   "ix86_expand_move (OImode, operands); DONE;")
2615
2616 (define_insn "*movoi_internal"
2617   [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
2618         (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
2619   "TARGET_AVX
2620    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2621 {
2622   switch (which_alternative)
2623     {
2624     case 0:
2625       return "vxorps\t%0, %0, %0";
2626     case 1:
2627     case 2:
2628       if (misaligned_operand (operands[0], OImode)
2629           || misaligned_operand (operands[1], OImode))
2630         return "vmovdqu\t{%1, %0|%0, %1}";
2631       else
2632         return "vmovdqa\t{%1, %0|%0, %1}";
2633     default:
2634       gcc_unreachable ();
2635     }
2636 }
2637   [(set_attr "type" "sselog1,ssemov,ssemov")
2638    (set_attr "prefix" "vex")
2639    (set_attr "mode" "OI")])
2640
2641 (define_expand "movti"
2642   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2643         (match_operand:TI 1 "nonimmediate_operand" ""))]
2644   "TARGET_SSE || TARGET_64BIT"
2645 {
2646   if (TARGET_64BIT)
2647     ix86_expand_move (TImode, operands);
2648   else if (push_operand (operands[0], TImode))
2649     ix86_expand_push (TImode, operands[1]);
2650   else
2651     ix86_expand_vector_move (TImode, operands);
2652   DONE;
2653 })
2654
2655 (define_insn "*movti_internal"
2656   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2657         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2658   "TARGET_SSE && !TARGET_64BIT
2659    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2660 {
2661   switch (which_alternative)
2662     {
2663     case 0:
2664       if (get_attr_mode (insn) == MODE_V4SF)
2665         return "%vxorps\t%0, %d0";
2666       else
2667         return "%vpxor\t%0, %d0";
2668     case 1:
2669     case 2:
2670       /* TDmode values are passed as TImode on the stack.  Moving them
2671          to stack may result in unaligned memory access.  */
2672       if (misaligned_operand (operands[0], TImode)
2673           || misaligned_operand (operands[1], TImode))
2674         {
2675           if (get_attr_mode (insn) == MODE_V4SF)
2676             return "%vmovups\t{%1, %0|%0, %1}";
2677          else
2678            return "%vmovdqu\t{%1, %0|%0, %1}";
2679         }
2680       else
2681         {
2682           if (get_attr_mode (insn) == MODE_V4SF)
2683             return "%vmovaps\t{%1, %0|%0, %1}";
2684          else
2685            return "%vmovdqa\t{%1, %0|%0, %1}";
2686         }
2687     default:
2688       gcc_unreachable ();
2689     }
2690 }
2691   [(set_attr "type" "sselog1,ssemov,ssemov")
2692    (set_attr "prefix" "maybe_vex")
2693    (set (attr "mode")
2694         (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2695                     (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0)))
2696                  (const_string "V4SF")
2697                (and (eq_attr "alternative" "2")
2698                     (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2699                         (const_int 0)))
2700                  (const_string "V4SF")]
2701               (const_string "TI")))])
2702
2703 (define_insn "*movti_rex64"
2704   [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
2705         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2706   "TARGET_64BIT
2707    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2708 {
2709   switch (which_alternative)
2710     {
2711     case 0:
2712     case 1:
2713       return "#";
2714     case 2:
2715       if (get_attr_mode (insn) == MODE_V4SF)
2716         return "%vxorps\t%0, %d0";
2717       else
2718         return "%vpxor\t%0, %d0";
2719     case 3:
2720     case 4:
2721       /* TDmode values are passed as TImode on the stack.  Moving them
2722          to stack may result in unaligned memory access.  */
2723       if (misaligned_operand (operands[0], TImode)
2724           || misaligned_operand (operands[1], TImode))
2725         {
2726           if (get_attr_mode (insn) == MODE_V4SF)
2727             return "%vmovups\t{%1, %0|%0, %1}";
2728          else
2729            return "%vmovdqu\t{%1, %0|%0, %1}";
2730         }
2731       else
2732         {
2733           if (get_attr_mode (insn) == MODE_V4SF)
2734             return "%vmovaps\t{%1, %0|%0, %1}";
2735          else
2736            return "%vmovdqa\t{%1, %0|%0, %1}";
2737         }
2738     default:
2739       gcc_unreachable ();
2740     }
2741 }
2742   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2743    (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
2744    (set (attr "mode")
2745         (cond [(eq_attr "alternative" "2,3")
2746                  (if_then_else
2747                    (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2748                        (const_int 0))
2749                    (const_string "V4SF")
2750                    (const_string "TI"))
2751                (eq_attr "alternative" "4")
2752                  (if_then_else
2753                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2754                             (const_int 0))
2755                         (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2756                             (const_int 0)))
2757                    (const_string "V4SF")
2758                    (const_string "TI"))]
2759                (const_string "DI")))])
2760
2761 (define_split
2762   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2763         (match_operand:TI 1 "general_operand" ""))]
2764   "reload_completed && !SSE_REG_P (operands[0])
2765    && !SSE_REG_P (operands[1])"
2766   [(const_int 0)]
2767   "ix86_split_long_move (operands); DONE;")
2768
2769 ;; This expands to what emit_move_complex would generate if we didn't
2770 ;; have a movti pattern.  Having this avoids problems with reload on
2771 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2772 ;; to have around all the time.
2773 (define_expand "movcdi"
2774   [(set (match_operand:CDI 0 "nonimmediate_operand" "")
2775         (match_operand:CDI 1 "general_operand" ""))]
2776   ""
2777 {
2778   if (push_operand (operands[0], CDImode))
2779     emit_move_complex_push (CDImode, operands[0], operands[1]);
2780   else
2781     emit_move_complex_parts (operands[0], operands[1]);
2782   DONE;
2783 })
2784
2785 (define_expand "movsf"
2786   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2787         (match_operand:SF 1 "general_operand" ""))]
2788   ""
2789   "ix86_expand_move (SFmode, operands); DONE;")
2790
2791 (define_insn "*pushsf"
2792   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2793         (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2794   "!TARGET_64BIT"
2795 {
2796   /* Anything else should be already split before reg-stack.  */
2797   gcc_assert (which_alternative == 1);
2798   return "push{l}\t%1";
2799 }
2800   [(set_attr "type" "multi,push,multi")
2801    (set_attr "unit" "i387,*,*")
2802    (set_attr "mode" "SF,SI,SF")])
2803
2804 (define_insn "*pushsf_rex64"
2805   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2806         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2807   "TARGET_64BIT"
2808 {
2809   /* Anything else should be already split before reg-stack.  */
2810   gcc_assert (which_alternative == 1);
2811   return "push{q}\t%q1";
2812 }
2813   [(set_attr "type" "multi,push,multi")
2814    (set_attr "unit" "i387,*,*")
2815    (set_attr "mode" "SF,DI,SF")])
2816
2817 (define_split
2818   [(set (match_operand:SF 0 "push_operand" "")
2819         (match_operand:SF 1 "memory_operand" ""))]
2820   "reload_completed
2821    && MEM_P (operands[1])
2822    && (operands[2] = find_constant_src (insn))"
2823   [(set (match_dup 0)
2824         (match_dup 2))])
2825
2826 ;; %%% Kill this when call knows how to work this out.
2827 (define_split
2828   [(set (match_operand:SF 0 "push_operand" "")
2829         (match_operand:SF 1 "any_fp_register_operand" ""))]
2830   "!TARGET_64BIT"
2831   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2832    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2833
2834 (define_split
2835   [(set (match_operand:SF 0 "push_operand" "")
2836         (match_operand:SF 1 "any_fp_register_operand" ""))]
2837   "TARGET_64BIT"
2838   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2839    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2840
2841 (define_insn "*movsf_1"
2842   [(set (match_operand:SF 0 "nonimmediate_operand"
2843           "=f,m,f,r  ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
2844         (match_operand:SF 1 "general_operand"
2845           "fm,f,G,rmF,Fr,C,x,xm,x,m  ,*y,*y ,r  ,Yi,r   ,*Ym"))]
2846   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2847    && (reload_in_progress || reload_completed
2848        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2849        || (!TARGET_SSE_MATH && optimize_function_for_size_p (cfun)
2850            && standard_80387_constant_p (operands[1]))
2851        || GET_CODE (operands[1]) != CONST_DOUBLE
2852        || memory_operand (operands[0], SFmode))"
2853 {
2854   switch (which_alternative)
2855     {
2856     case 0:
2857     case 1:
2858       return output_387_reg_move (insn, operands);
2859
2860     case 2:
2861       return standard_80387_constant_opcode (operands[1]);
2862
2863     case 3:
2864     case 4:
2865       return "mov{l}\t{%1, %0|%0, %1}";
2866     case 5:
2867       if (get_attr_mode (insn) == MODE_TI)
2868         return "%vpxor\t%0, %d0";
2869       else
2870         return "%vxorps\t%0, %d0";
2871     case 6:
2872       if (get_attr_mode (insn) == MODE_V4SF)
2873         return "%vmovaps\t{%1, %0|%0, %1}";
2874       else
2875         return "%vmovss\t{%1, %d0|%d0, %1}";
2876     case 7:
2877       if (TARGET_AVX)
2878         return REG_P (operands[1]) ? "vmovss\t{%1, %0, %0|%0, %0, %1}"
2879                                    : "vmovss\t{%1, %0|%0, %1}";
2880       else
2881         return "movss\t{%1, %0|%0, %1}";
2882     case 8:
2883       return "%vmovss\t{%1, %0|%0, %1}";
2884
2885     case 9: case 10: case 14: case 15:
2886       return "movd\t{%1, %0|%0, %1}";
2887     case 12: case 13:
2888       return "%vmovd\t{%1, %0|%0, %1}";
2889
2890     case 11:
2891       return "movq\t{%1, %0|%0, %1}";
2892
2893     default:
2894       gcc_unreachable ();
2895     }
2896 }
2897   [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2898    (set (attr "prefix")
2899      (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
2900        (const_string "maybe_vex")
2901        (const_string "orig")))
2902    (set (attr "mode")
2903         (cond [(eq_attr "alternative" "3,4,9,10")
2904                  (const_string "SI")
2905                (eq_attr "alternative" "5")
2906                  (if_then_else
2907                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2908                                  (const_int 0))
2909                              (ne (symbol_ref "TARGET_SSE2")
2910                                  (const_int 0)))
2911                         (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2912                             (const_int 0)))
2913                    (const_string "TI")
2914                    (const_string "V4SF"))
2915                /* For architectures resolving dependencies on
2916                   whole SSE registers use APS move to break dependency
2917                   chains, otherwise use short move to avoid extra work.
2918
2919                   Do the same for architectures resolving dependencies on
2920                   the parts.  While in DF mode it is better to always handle
2921                   just register parts, the SF mode is different due to lack
2922                   of instructions to load just part of the register.  It is
2923                   better to maintain the whole registers in single format
2924                   to avoid problems on using packed logical operations.  */
2925                (eq_attr "alternative" "6")
2926                  (if_then_else
2927                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2928                             (const_int 0))
2929                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2930                             (const_int 0)))
2931                    (const_string "V4SF")
2932                    (const_string "SF"))
2933                (eq_attr "alternative" "11")
2934                  (const_string "DI")]
2935                (const_string "SF")))])
2936
2937 (define_insn "*swapsf"
2938   [(set (match_operand:SF 0 "fp_register_operand" "+f")
2939         (match_operand:SF 1 "fp_register_operand" "+f"))
2940    (set (match_dup 1)
2941         (match_dup 0))]
2942   "reload_completed || TARGET_80387"
2943 {
2944   if (STACK_TOP_P (operands[0]))
2945     return "fxch\t%1";
2946   else
2947     return "fxch\t%0";
2948 }
2949   [(set_attr "type" "fxch")
2950    (set_attr "mode" "SF")])
2951
2952 (define_expand "movdf"
2953   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2954         (match_operand:DF 1 "general_operand" ""))]
2955   ""
2956   "ix86_expand_move (DFmode, operands); DONE;")
2957
2958 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2959 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2960 ;; On the average, pushdf using integers can be still shorter.  Allow this
2961 ;; pattern for optimize_size too.
2962
2963 (define_insn "*pushdf_nointeger"
2964   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2965         (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2966   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2967 {
2968   /* This insn should be already split before reg-stack.  */
2969   gcc_unreachable ();
2970 }
2971   [(set_attr "type" "multi")
2972    (set_attr "unit" "i387,*,*,*")
2973    (set_attr "mode" "DF,SI,SI,DF")])
2974
2975 (define_insn "*pushdf_integer"
2976   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2977         (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2978   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2979 {
2980   /* This insn should be already split before reg-stack.  */
2981   gcc_unreachable ();
2982 }
2983   [(set_attr "type" "multi")
2984    (set_attr "unit" "i387,*,*")
2985    (set_attr "mode" "DF,SI,DF")])
2986
2987 ;; %%% Kill this when call knows how to work this out.
2988 (define_split
2989   [(set (match_operand:DF 0 "push_operand" "")
2990         (match_operand:DF 1 "any_fp_register_operand" ""))]
2991   "reload_completed"
2992   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2993    (set (mem:DF (reg:P SP_REG)) (match_dup 1))]
2994   "")
2995
2996 (define_split
2997   [(set (match_operand:DF 0 "push_operand" "")
2998         (match_operand:DF 1 "general_operand" ""))]
2999   "reload_completed"
3000   [(const_int 0)]
3001   "ix86_split_long_move (operands); DONE;")
3002
3003 ;; Moving is usually shorter when only FP registers are used. This separate
3004 ;; movdf pattern avoids the use of integer registers for FP operations
3005 ;; when optimizing for size.
3006
3007 (define_insn "*movdf_nointeger"
3008   [(set (match_operand:DF 0 "nonimmediate_operand"
3009                         "=f,m,f,*r  ,o  ,Y2*x,Y2*x,Y2*x ,m  ")
3010         (match_operand:DF 1 "general_operand"
3011                         "fm,f,G,*roF,*Fr,C   ,Y2*x,mY2*x,Y2*x"))]
3012   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3013    && ((optimize_function_for_size_p (cfun)
3014        || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
3015    && (reload_in_progress || reload_completed
3016        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3017        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3018            && optimize_function_for_size_p (cfun)
3019            && !memory_operand (operands[0], DFmode)
3020            && standard_80387_constant_p (operands[1]))
3021        || GET_CODE (operands[1]) != CONST_DOUBLE
3022        || ((optimize_function_for_size_p (cfun)
3023             || !TARGET_MEMORY_MISMATCH_STALL
3024             || reload_in_progress || reload_completed)
3025            && memory_operand (operands[0], DFmode)))"
3026 {
3027   switch (which_alternative)
3028     {
3029     case 0:
3030     case 1:
3031       return output_387_reg_move (insn, operands);
3032
3033     case 2:
3034       return standard_80387_constant_opcode (operands[1]);
3035
3036     case 3:
3037     case 4:
3038       return "#";
3039     case 5:
3040       switch (get_attr_mode (insn))
3041         {
3042         case MODE_V4SF:
3043           return "%vxorps\t%0, %d0";
3044         case MODE_V2DF:
3045           return "%vxorpd\t%0, %d0";
3046         case MODE_TI:
3047           return "%vpxor\t%0, %d0";
3048         default:
3049           gcc_unreachable ();
3050         }
3051     case 6:
3052     case 7:
3053     case 8:
3054       switch (get_attr_mode (insn))
3055         {
3056         case MODE_V4SF:
3057           return "%vmovaps\t{%1, %0|%0, %1}";
3058         case MODE_V2DF:
3059           return "%vmovapd\t{%1, %0|%0, %1}";
3060         case MODE_TI:
3061           return "%vmovdqa\t{%1, %0|%0, %1}";
3062         case MODE_DI:
3063           return "%vmovq\t{%1, %0|%0, %1}";
3064         case MODE_DF:
3065           if (TARGET_AVX)
3066             {
3067               if (REG_P (operands[0]) && REG_P (operands[1]))
3068                 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3069               else
3070                 return "vmovsd\t{%1, %0|%0, %1}";
3071             }
3072           else
3073             return "movsd\t{%1, %0|%0, %1}";
3074         case MODE_V1DF:
3075           if (TARGET_AVX)
3076             {
3077               if (REG_P (operands[0]))
3078                 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
3079               else
3080                 return "vmovlpd\t{%1, %0|%0, %1}";
3081             }
3082           else
3083             return "movlpd\t{%1, %0|%0, %1}";
3084         case MODE_V2SF:
3085           if (TARGET_AVX)
3086             {
3087               if (REG_P (operands[0]))
3088                 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
3089               else
3090                 return "vmovlps\t{%1, %0|%0, %1}";
3091             }
3092           else
3093             return "movlps\t{%1, %0|%0, %1}";
3094         default:
3095           gcc_unreachable ();
3096         }
3097
3098     default:
3099       gcc_unreachable ();
3100     }
3101 }
3102   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3103    (set (attr "prefix")
3104      (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3105        (const_string "orig")
3106        (const_string "maybe_vex")))
3107    (set (attr "prefix_data16")
3108      (if_then_else (eq_attr "mode" "V1DF")
3109        (const_string "1")
3110        (const_string "*")))
3111    (set (attr "mode")
3112         (cond [(eq_attr "alternative" "0,1,2")
3113                  (const_string "DF")
3114                (eq_attr "alternative" "3,4")
3115                  (const_string "SI")
3116
3117                /* For SSE1, we have many fewer alternatives.  */
3118                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3119                  (cond [(eq_attr "alternative" "5,6")
3120                           (const_string "V4SF")
3121                        ]
3122                    (const_string "V2SF"))
3123
3124                /* xorps is one byte shorter.  */
3125                (eq_attr "alternative" "5")
3126                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3127                             (const_int 0))
3128                           (const_string "V4SF")
3129                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3130                             (const_int 0))
3131                           (const_string "TI")
3132                        ]
3133                        (const_string "V2DF"))
3134
3135                /* For architectures resolving dependencies on
3136                   whole SSE registers use APD move to break dependency
3137                   chains, otherwise use short move to avoid extra work.
3138
3139                   movaps encodes one byte shorter.  */
3140                (eq_attr "alternative" "6")
3141                  (cond
3142                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3143                         (const_int 0))
3144                       (const_string "V4SF")
3145                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3146                         (const_int 0))
3147                       (const_string "V2DF")
3148                    ]
3149                    (const_string "DF"))
3150                /* For architectures resolving dependencies on register
3151                   parts we may avoid extra work to zero out upper part
3152                   of register.  */
3153                (eq_attr "alternative" "7")
3154                  (if_then_else
3155                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3156                        (const_int 0))
3157                    (const_string "V1DF")
3158                    (const_string "DF"))
3159               ]
3160               (const_string "DF")))])
3161
3162 (define_insn "*movdf_integer_rex64"
3163   [(set (match_operand:DF 0 "nonimmediate_operand"
3164                 "=f,m,f,r  ,m ,Y2*x,Y2*x,Y2*x,m   ,Yi,r ")
3165         (match_operand:DF 1 "general_operand"
3166                 "fm,f,G,rmF,Fr,C   ,Y2*x,m   ,Y2*x,r ,Yi"))]
3167   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3168    && (reload_in_progress || reload_completed
3169        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3170        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3171            && optimize_function_for_size_p (cfun)
3172            && standard_80387_constant_p (operands[1]))
3173        || GET_CODE (operands[1]) != CONST_DOUBLE
3174        || memory_operand (operands[0], DFmode))"
3175 {
3176   switch (which_alternative)
3177     {
3178     case 0:
3179     case 1:
3180       return output_387_reg_move (insn, operands);
3181
3182     case 2:
3183       return standard_80387_constant_opcode (operands[1]);
3184
3185     case 3:
3186     case 4:
3187       return "#";
3188
3189     case 5:
3190       switch (get_attr_mode (insn))
3191         {
3192         case MODE_V4SF:
3193           return "%vxorps\t%0, %d0";
3194         case MODE_V2DF:
3195           return "%vxorpd\t%0, %d0";
3196         case MODE_TI:
3197           return "%vpxor\t%0, %d0";
3198         default:
3199           gcc_unreachable ();
3200         }
3201     case 6:
3202     case 7:
3203     case 8:
3204       switch (get_attr_mode (insn))
3205         {
3206         case MODE_V4SF:
3207           return "%vmovaps\t{%1, %0|%0, %1}";
3208         case MODE_V2DF:
3209           return "%vmovapd\t{%1, %0|%0, %1}";
3210         case MODE_TI:
3211           return "%vmovdqa\t{%1, %0|%0, %1}";
3212         case MODE_DI:
3213           return "%vmovq\t{%1, %0|%0, %1}";
3214         case MODE_DF:
3215           if (TARGET_AVX)
3216             {
3217               if (REG_P (operands[0]) && REG_P (operands[1]))
3218                 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3219               else
3220                 return "vmovsd\t{%1, %0|%0, %1}";
3221             }
3222           else
3223             return "movsd\t{%1, %0|%0, %1}";
3224         case MODE_V1DF:
3225           return "%vmovlpd\t{%1, %d0|%d0, %1}";
3226         case MODE_V2SF:
3227           return "%vmovlps\t{%1, %d0|%d0, %1}";
3228         default:
3229           gcc_unreachable ();
3230         }
3231
3232     case 9:
3233     case 10:
3234     return "%vmovd\t{%1, %0|%0, %1}";
3235
3236     default:
3237       gcc_unreachable();
3238     }
3239 }
3240   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
3241    (set (attr "prefix")
3242      (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3243        (const_string "orig")
3244        (const_string "maybe_vex")))
3245    (set (attr "prefix_data16")
3246      (if_then_else (eq_attr "mode" "V1DF")
3247        (const_string "1")
3248        (const_string "*")))
3249    (set (attr "mode")
3250         (cond [(eq_attr "alternative" "0,1,2")
3251                  (const_string "DF")
3252                (eq_attr "alternative" "3,4,9,10")
3253                  (const_string "DI")
3254
3255                /* For SSE1, we have many fewer alternatives.  */
3256                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3257                  (cond [(eq_attr "alternative" "5,6")
3258                           (const_string "V4SF")
3259                        ]
3260                    (const_string "V2SF"))
3261
3262                /* xorps is one byte shorter.  */
3263                (eq_attr "alternative" "5")
3264                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3265                             (const_int 0))
3266                           (const_string "V4SF")
3267                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3268                             (const_int 0))
3269                           (const_string "TI")
3270                        ]
3271                        (const_string "V2DF"))
3272
3273                /* For architectures resolving dependencies on
3274                   whole SSE registers use APD move to break dependency
3275                   chains, otherwise use short move to avoid extra work.
3276
3277                   movaps encodes one byte shorter.  */
3278                (eq_attr "alternative" "6")
3279                  (cond
3280                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3281                         (const_int 0))
3282                       (const_string "V4SF")
3283                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3284                         (const_int 0))
3285                       (const_string "V2DF")
3286                    ]
3287                    (const_string "DF"))
3288                /* For architectures resolving dependencies on register
3289                   parts we may avoid extra work to zero out upper part
3290                   of register.  */
3291                (eq_attr "alternative" "7")
3292                  (if_then_else
3293                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3294                        (const_int 0))
3295                    (const_string "V1DF")
3296                    (const_string "DF"))
3297               ]
3298               (const_string "DF")))])
3299
3300 (define_insn "*movdf_integer"
3301   [(set (match_operand:DF 0 "nonimmediate_operand"
3302                 "=f,m,f,r  ,o ,Y2*x,Y2*x,Y2*x,m   ")
3303         (match_operand:DF 1 "general_operand"
3304                 "fm,f,G,roF,Fr,C   ,Y2*x,m   ,Y2*x"))]
3305   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3306    && optimize_function_for_speed_p (cfun)
3307    && TARGET_INTEGER_DFMODE_MOVES
3308    && (reload_in_progress || reload_completed
3309        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3310        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3311            && optimize_function_for_size_p (cfun)
3312            && standard_80387_constant_p (operands[1]))
3313        || GET_CODE (operands[1]) != CONST_DOUBLE
3314        || memory_operand (operands[0], DFmode))"
3315 {
3316   switch (which_alternative)
3317     {
3318     case 0:
3319     case 1:
3320       return output_387_reg_move (insn, operands);
3321
3322     case 2:
3323       return standard_80387_constant_opcode (operands[1]);
3324
3325     case 3:
3326     case 4:
3327       return "#";
3328
3329     case 5:
3330       switch (get_attr_mode (insn))
3331         {
3332         case MODE_V4SF:
3333           return "xorps\t%0, %0";
3334         case MODE_V2DF:
3335           return "xorpd\t%0, %0";
3336         case MODE_TI:
3337           return "pxor\t%0, %0";
3338         default:
3339           gcc_unreachable ();
3340         }
3341     case 6:
3342     case 7:
3343     case 8:
3344       switch (get_attr_mode (insn))
3345         {
3346         case MODE_V4SF:
3347           return "movaps\t{%1, %0|%0, %1}";
3348         case MODE_V2DF:
3349           return "movapd\t{%1, %0|%0, %1}";
3350         case MODE_TI:
3351           return "movdqa\t{%1, %0|%0, %1}";
3352         case MODE_DI:
3353           return "movq\t{%1, %0|%0, %1}";
3354         case MODE_DF:
3355           return "movsd\t{%1, %0|%0, %1}";
3356         case MODE_V1DF:
3357           return "movlpd\t{%1, %0|%0, %1}";
3358         case MODE_V2SF:
3359           return "movlps\t{%1, %0|%0, %1}";
3360         default:
3361           gcc_unreachable ();
3362         }
3363
3364     default:
3365       gcc_unreachable();
3366     }
3367 }
3368   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3369    (set (attr "prefix_data16")
3370      (if_then_else (eq_attr "mode" "V1DF")
3371        (const_string "1")
3372        (const_string "*")))
3373    (set (attr "mode")
3374         (cond [(eq_attr "alternative" "0,1,2")
3375                  (const_string "DF")
3376                (eq_attr "alternative" "3,4")
3377                  (const_string "SI")
3378
3379                /* For SSE1, we have many fewer alternatives.  */
3380                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3381                  (cond [(eq_attr "alternative" "5,6")
3382                           (const_string "V4SF")
3383                        ]
3384                    (const_string "V2SF"))
3385
3386                /* xorps is one byte shorter.  */
3387                (eq_attr "alternative" "5")
3388                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3389                             (const_int 0))
3390                           (const_string "V4SF")
3391                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3392                             (const_int 0))
3393                           (const_string "TI")
3394                        ]
3395                        (const_string "V2DF"))
3396
3397                /* For architectures resolving dependencies on
3398                   whole SSE registers use APD move to break dependency
3399                   chains, otherwise use short move to avoid extra work.
3400
3401                   movaps encodes one byte shorter.  */
3402                (eq_attr "alternative" "6")
3403                  (cond
3404                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3405                         (const_int 0))
3406                       (const_string "V4SF")
3407                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3408                         (const_int 0))
3409                       (const_string "V2DF")
3410                    ]
3411                    (const_string "DF"))
3412                /* For architectures resolving dependencies on register
3413                   parts we may avoid extra work to zero out upper part
3414                   of register.  */
3415                (eq_attr "alternative" "7")
3416                  (if_then_else
3417                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3418                        (const_int 0))
3419                    (const_string "V1DF")
3420                    (const_string "DF"))
3421               ]
3422               (const_string "DF")))])
3423
3424 (define_split
3425   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3426         (match_operand:DF 1 "general_operand" ""))]
3427   "reload_completed
3428    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3429    && ! (ANY_FP_REG_P (operands[0]) ||
3430          (GET_CODE (operands[0]) == SUBREG
3431           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3432    && ! (ANY_FP_REG_P (operands[1]) ||
3433          (GET_CODE (operands[1]) == SUBREG
3434           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3435   [(const_int 0)]
3436   "ix86_split_long_move (operands); DONE;")
3437
3438 (define_insn "*swapdf"
3439   [(set (match_operand:DF 0 "fp_register_operand" "+f")
3440         (match_operand:DF 1 "fp_register_operand" "+f"))
3441    (set (match_dup 1)
3442         (match_dup 0))]
3443   "reload_completed || TARGET_80387"
3444 {
3445   if (STACK_TOP_P (operands[0]))
3446     return "fxch\t%1";
3447   else
3448     return "fxch\t%0";
3449 }
3450   [(set_attr "type" "fxch")
3451    (set_attr "mode" "DF")])
3452
3453 (define_expand "movxf"
3454   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3455         (match_operand:XF 1 "general_operand" ""))]
3456   ""
3457   "ix86_expand_move (XFmode, operands); DONE;")
3458
3459 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3460 ;; Size of pushdf using integer instructions is 3+3*memory operand size
3461 ;; Pushing using integer instructions is longer except for constants
3462 ;; and direct memory references.
3463 ;; (assuming that any given constant is pushed only once, but this ought to be
3464 ;;  handled elsewhere).
3465
3466 (define_insn "*pushxf_nointeger"
3467   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
3468         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
3469   "optimize_function_for_size_p (cfun)"
3470 {
3471   /* This insn should be already split before reg-stack.  */
3472   gcc_unreachable ();
3473 }
3474   [(set_attr "type" "multi")
3475    (set_attr "unit" "i387,*,*")
3476    (set_attr "mode" "XF,SI,SI")])
3477
3478 (define_insn "*pushxf_integer"
3479   [(set (match_operand:XF 0 "push_operand" "=<,<")
3480         (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
3481   "optimize_function_for_speed_p (cfun)"
3482 {
3483   /* This insn should be already split before reg-stack.  */
3484   gcc_unreachable ();
3485 }
3486   [(set_attr "type" "multi")
3487    (set_attr "unit" "i387,*")
3488    (set_attr "mode" "XF,SI")])
3489
3490 (define_split
3491   [(set (match_operand 0 "push_operand" "")
3492         (match_operand 1 "general_operand" ""))]
3493   "reload_completed
3494    && (GET_MODE (operands[0]) == XFmode
3495        || GET_MODE (operands[0]) == DFmode)
3496    && !ANY_FP_REG_P (operands[1])"
3497   [(const_int 0)]
3498   "ix86_split_long_move (operands); DONE;")
3499
3500 (define_split
3501   [(set (match_operand:XF 0 "push_operand" "")
3502         (match_operand:XF 1 "any_fp_register_operand" ""))]
3503   ""
3504   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3505    (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
3506   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3507
3508 ;; Do not use integer registers when optimizing for size
3509 (define_insn "*movxf_nointeger"
3510   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3511         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3512   "optimize_function_for_size_p (cfun)
3513    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3514    && (reload_in_progress || reload_completed
3515        || standard_80387_constant_p (operands[1])
3516        || GET_CODE (operands[1]) != CONST_DOUBLE
3517        || memory_operand (operands[0], XFmode))"
3518 {
3519   switch (which_alternative)
3520     {
3521     case 0:
3522     case 1:
3523       return output_387_reg_move (insn, operands);
3524
3525     case 2:
3526       return standard_80387_constant_opcode (operands[1]);
3527
3528     case 3: case 4:
3529       return "#";
3530     default:
3531       gcc_unreachable ();
3532     }
3533 }
3534   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3535    (set_attr "mode" "XF,XF,XF,SI,SI")])
3536
3537 (define_insn "*movxf_integer"
3538   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
3539         (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
3540   "optimize_function_for_speed_p (cfun)
3541    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3542    && (reload_in_progress || reload_completed
3543        || GET_CODE (operands[1]) != CONST_DOUBLE
3544        || memory_operand (operands[0], XFmode))"
3545 {
3546   switch (which_alternative)
3547     {
3548     case 0:
3549     case 1:
3550       return output_387_reg_move (insn, operands);
3551
3552     case 2:
3553       return standard_80387_constant_opcode (operands[1]);
3554
3555     case 3: case 4:
3556       return "#";
3557
3558     default:
3559       gcc_unreachable ();
3560     }
3561 }
3562   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3563    (set_attr "mode" "XF,XF,XF,SI,SI")])
3564
3565 (define_expand "movtf"
3566   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3567         (match_operand:TF 1 "nonimmediate_operand" ""))]
3568   "TARGET_SSE2"
3569 {
3570   ix86_expand_move (TFmode, operands);
3571   DONE;
3572 })
3573
3574 (define_insn "*movtf_internal"
3575   [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
3576         (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
3577   "TARGET_SSE2
3578    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3579 {
3580   switch (which_alternative)
3581     {
3582     case 0:
3583     case 1:
3584       if (get_attr_mode (insn) == MODE_V4SF)
3585         return "%vmovaps\t{%1, %0|%0, %1}";
3586       else
3587         return "%vmovdqa\t{%1, %0|%0, %1}";
3588     case 2:
3589       if (get_attr_mode (insn) == MODE_V4SF)
3590         return "%vxorps\t%0, %d0";
3591       else
3592         return "%vpxor\t%0, %d0";
3593     case 3:
3594     case 4:
3595         return "#";
3596     default:
3597       gcc_unreachable ();
3598     }
3599 }
3600   [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
3601    (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
3602    (set (attr "mode")
3603         (cond [(eq_attr "alternative" "0,2")
3604                  (if_then_else
3605                    (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3606                        (const_int 0))
3607                    (const_string "V4SF")
3608                    (const_string "TI"))
3609                (eq_attr "alternative" "1")
3610                  (if_then_else
3611                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3612                             (const_int 0))
3613                         (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3614                             (const_int 0)))
3615                    (const_string "V4SF")
3616                    (const_string "TI"))]
3617                (const_string "DI")))])
3618
3619 (define_insn "*pushtf_sse"
3620   [(set (match_operand:TF 0 "push_operand" "=<,<,<")
3621         (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
3622   "TARGET_SSE2"
3623 {
3624   /* This insn should be already split before reg-stack.  */
3625   gcc_unreachable ();
3626 }
3627   [(set_attr "type" "multi")
3628    (set_attr "unit" "sse,*,*")
3629    (set_attr "mode" "TF,SI,SI")])
3630
3631 (define_split
3632   [(set (match_operand:TF 0 "push_operand" "")
3633         (match_operand:TF 1 "general_operand" ""))]
3634   "TARGET_SSE2 && reload_completed
3635    && !SSE_REG_P (operands[1])"
3636   [(const_int 0)]
3637   "ix86_split_long_move (operands); DONE;")
3638
3639 (define_split
3640   [(set (match_operand:TF 0 "push_operand" "")
3641         (match_operand:TF 1 "any_fp_register_operand" ""))]
3642   "TARGET_SSE2"
3643   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3644    (set (mem:TF (reg:P SP_REG)) (match_dup 1))]
3645   "")
3646
3647 (define_split
3648   [(set (match_operand 0 "nonimmediate_operand" "")
3649         (match_operand 1 "general_operand" ""))]
3650   "reload_completed
3651    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3652    && GET_MODE (operands[0]) == XFmode
3653    && ! (ANY_FP_REG_P (operands[0]) ||
3654          (GET_CODE (operands[0]) == SUBREG
3655           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3656    && ! (ANY_FP_REG_P (operands[1]) ||
3657          (GET_CODE (operands[1]) == SUBREG
3658           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3659   [(const_int 0)]
3660   "ix86_split_long_move (operands); DONE;")
3661
3662 (define_split
3663   [(set (match_operand 0 "register_operand" "")
3664         (match_operand 1 "memory_operand" ""))]
3665   "reload_completed
3666    && MEM_P (operands[1])
3667    && (GET_MODE (operands[0]) == TFmode
3668        || GET_MODE (operands[0]) == XFmode
3669        || GET_MODE (operands[0]) == SFmode
3670        || GET_MODE (operands[0]) == DFmode)
3671    && (operands[2] = find_constant_src (insn))"
3672   [(set (match_dup 0) (match_dup 2))]
3673 {
3674   rtx c = operands[2];
3675   rtx r = operands[0];
3676
3677   if (GET_CODE (r) == SUBREG)
3678     r = SUBREG_REG (r);
3679
3680   if (SSE_REG_P (r))
3681     {
3682       if (!standard_sse_constant_p (c))
3683         FAIL;
3684     }
3685   else if (FP_REG_P (r))
3686     {
3687       if (!standard_80387_constant_p (c))
3688         FAIL;
3689     }
3690   else if (MMX_REG_P (r))
3691     FAIL;
3692 })
3693
3694 (define_split
3695   [(set (match_operand 0 "register_operand" "")
3696         (float_extend (match_operand 1 "memory_operand" "")))]
3697   "reload_completed
3698    && MEM_P (operands[1])
3699    && (GET_MODE (operands[0]) == TFmode
3700        || GET_MODE (operands[0]) == XFmode
3701        || GET_MODE (operands[0]) == SFmode
3702        || GET_MODE (operands[0]) == DFmode)
3703    && (operands[2] = find_constant_src (insn))"
3704   [(set (match_dup 0) (match_dup 2))]
3705 {
3706   rtx c = operands[2];
3707   rtx r = operands[0];
3708
3709   if (GET_CODE (r) == SUBREG)
3710     r = SUBREG_REG (r);
3711
3712   if (SSE_REG_P (r))
3713     {
3714       if (!standard_sse_constant_p (c))
3715         FAIL;
3716     }
3717   else if (FP_REG_P (r))
3718     {
3719       if (!standard_80387_constant_p (c))
3720         FAIL;
3721     }
3722   else if (MMX_REG_P (r))
3723     FAIL;
3724 })
3725
3726 (define_insn "swapxf"
3727   [(set (match_operand:XF 0 "register_operand" "+f")
3728         (match_operand:XF 1 "register_operand" "+f"))
3729    (set (match_dup 1)
3730         (match_dup 0))]
3731   "TARGET_80387"
3732 {
3733   if (STACK_TOP_P (operands[0]))
3734     return "fxch\t%1";
3735   else
3736     return "fxch\t%0";
3737 }
3738   [(set_attr "type" "fxch")
3739    (set_attr "mode" "XF")])
3740
3741 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3742 (define_split
3743   [(set (match_operand:X87MODEF 0 "register_operand" "")
3744         (match_operand:X87MODEF 1 "immediate_operand" ""))]
3745   "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3746    && (standard_80387_constant_p (operands[1]) == 8
3747        || standard_80387_constant_p (operands[1]) == 9)"
3748   [(set (match_dup 0)(match_dup 1))
3749    (set (match_dup 0)
3750         (neg:X87MODEF (match_dup 0)))]
3751 {
3752   REAL_VALUE_TYPE r;
3753
3754   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3755   if (real_isnegzero (&r))
3756     operands[1] = CONST0_RTX (<MODE>mode);
3757   else
3758     operands[1] = CONST1_RTX (<MODE>mode);
3759 })
3760
3761 (define_split
3762   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3763         (match_operand:TF 1 "general_operand" ""))]
3764   "reload_completed
3765    && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
3766   [(const_int 0)]
3767   "ix86_split_long_move (operands); DONE;")
3768 \f
3769 ;; Zero extension instructions
3770
3771 (define_expand "zero_extendhisi2"
3772   [(set (match_operand:SI 0 "register_operand" "")
3773      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3774   ""
3775 {
3776   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3777     {
3778       operands[1] = force_reg (HImode, operands[1]);
3779       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3780       DONE;
3781     }
3782 })
3783
3784 (define_insn "zero_extendhisi2_and"
3785   [(set (match_operand:SI 0 "register_operand" "=r")
3786      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3787    (clobber (reg:CC FLAGS_REG))]
3788   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3789   "#"
3790   [(set_attr "type" "alu1")
3791    (set_attr "mode" "SI")])
3792
3793 (define_split
3794   [(set (match_operand:SI 0 "register_operand" "")
3795         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3796    (clobber (reg:CC FLAGS_REG))]
3797   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND
3798    && optimize_function_for_speed_p (cfun)"
3799   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3800               (clobber (reg:CC FLAGS_REG))])]
3801   "")
3802
3803 (define_insn "*zero_extendhisi2_movzwl"
3804   [(set (match_operand:SI 0 "register_operand" "=r")
3805      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3806   "!TARGET_ZERO_EXTEND_WITH_AND
3807    || optimize_function_for_size_p (cfun)"
3808   "movz{wl|x}\t{%1, %0|%0, %1}"
3809   [(set_attr "type" "imovx")
3810    (set_attr "mode" "SI")])
3811
3812 (define_expand "zero_extendqihi2"
3813   [(parallel
3814     [(set (match_operand:HI 0 "register_operand" "")
3815        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3816      (clobber (reg:CC FLAGS_REG))])]
3817   ""
3818   "")
3819
3820 (define_insn "*zero_extendqihi2_and"
3821   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3822      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3823    (clobber (reg:CC FLAGS_REG))]
3824   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3825   "#"
3826   [(set_attr "type" "alu1")
3827    (set_attr "mode" "HI")])
3828
3829 (define_insn "*zero_extendqihi2_movzbw_and"
3830   [(set (match_operand:HI 0 "register_operand" "=r,r")
3831      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3832    (clobber (reg:CC FLAGS_REG))]
3833   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3834   "#"
3835   [(set_attr "type" "imovx,alu1")
3836    (set_attr "mode" "HI")])
3837
3838 ; zero extend to SImode here to avoid partial register stalls
3839 (define_insn "*zero_extendqihi2_movzbl"
3840   [(set (match_operand:HI 0 "register_operand" "=r")
3841      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3842   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3843    && reload_completed"
3844   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3845   [(set_attr "type" "imovx")
3846    (set_attr "mode" "SI")])
3847
3848 ;; For the movzbw case strip only the clobber
3849 (define_split
3850   [(set (match_operand:HI 0 "register_operand" "")
3851         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3852    (clobber (reg:CC FLAGS_REG))]
3853   "reload_completed
3854    && (!TARGET_ZERO_EXTEND_WITH_AND
3855        || optimize_function_for_size_p (cfun))
3856    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3857   [(set (match_operand:HI 0 "register_operand" "")
3858         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3859
3860 ;; When source and destination does not overlap, clear destination
3861 ;; first and then do the movb
3862 (define_split
3863   [(set (match_operand:HI 0 "register_operand" "")
3864         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3865    (clobber (reg:CC FLAGS_REG))]
3866   "reload_completed
3867    && ANY_QI_REG_P (operands[0])
3868    && (TARGET_ZERO_EXTEND_WITH_AND
3869        && optimize_function_for_speed_p (cfun))
3870    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3871   [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3872 {
3873   operands[2] = gen_lowpart (QImode, operands[0]);
3874   ix86_expand_clear (operands[0]);
3875 })
3876
3877 ;; Rest is handled by single and.
3878 (define_split
3879   [(set (match_operand:HI 0 "register_operand" "")
3880         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3881    (clobber (reg:CC FLAGS_REG))]
3882   "reload_completed
3883    && true_regnum (operands[0]) == true_regnum (operands[1])"
3884   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3885               (clobber (reg:CC FLAGS_REG))])]
3886   "")
3887
3888 (define_expand "zero_extendqisi2"
3889   [(parallel
3890     [(set (match_operand:SI 0 "register_operand" "")
3891        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3892      (clobber (reg:CC FLAGS_REG))])]
3893   ""
3894   "")
3895
3896 (define_insn "*zero_extendqisi2_and"
3897   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3898      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3899    (clobber (reg:CC FLAGS_REG))]
3900   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3901   "#"
3902   [(set_attr "type" "alu1")
3903    (set_attr "mode" "SI")])
3904
3905 (define_insn "*zero_extendqisi2_movzbl_and"
3906   [(set (match_operand:SI 0 "register_operand" "=r,r")
3907      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3908    (clobber (reg:CC FLAGS_REG))]
3909   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3910   "#"
3911   [(set_attr "type" "imovx,alu1")
3912    (set_attr "mode" "SI")])
3913
3914 (define_insn "*zero_extendqisi2_movzbl"
3915   [(set (match_operand:SI 0 "register_operand" "=r")
3916      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3917   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3918    && reload_completed"
3919   "movz{bl|x}\t{%1, %0|%0, %1}"
3920   [(set_attr "type" "imovx")
3921    (set_attr "mode" "SI")])
3922
3923 ;; For the movzbl case strip only the clobber
3924 (define_split
3925   [(set (match_operand:SI 0 "register_operand" "")
3926         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3927    (clobber (reg:CC FLAGS_REG))]
3928   "reload_completed
3929    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3930    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3931   [(set (match_dup 0)
3932         (zero_extend:SI (match_dup 1)))])
3933
3934 ;; When source and destination does not overlap, clear destination
3935 ;; first and then do the movb
3936 (define_split
3937   [(set (match_operand:SI 0 "register_operand" "")
3938         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3939    (clobber (reg:CC FLAGS_REG))]
3940   "reload_completed
3941    && ANY_QI_REG_P (operands[0])
3942    && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3943    && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3944    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3945   [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3946 {
3947   operands[2] = gen_lowpart (QImode, operands[0]);
3948   ix86_expand_clear (operands[0]);
3949 })
3950
3951 ;; Rest is handled by single and.
3952 (define_split
3953   [(set (match_operand:SI 0 "register_operand" "")
3954         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3955    (clobber (reg:CC FLAGS_REG))]
3956   "reload_completed
3957    && true_regnum (operands[0]) == true_regnum (operands[1])"
3958   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3959               (clobber (reg:CC FLAGS_REG))])]
3960   "")
3961
3962 ;; %%% Kill me once multi-word ops are sane.
3963 (define_expand "zero_extendsidi2"
3964   [(set (match_operand:DI 0 "register_operand" "")
3965      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3966   ""
3967 {
3968   if (!TARGET_64BIT)
3969     {
3970       emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3971       DONE;
3972     }
3973 })
3974
3975 (define_insn "zero_extendsidi2_32"
3976   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3977         (zero_extend:DI
3978          (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r   ,m  ,r   ,m")))
3979    (clobber (reg:CC FLAGS_REG))]
3980   "!TARGET_64BIT"
3981   "@
3982    #
3983    #
3984    #
3985    movd\t{%1, %0|%0, %1}
3986    movd\t{%1, %0|%0, %1}
3987    %vmovd\t{%1, %0|%0, %1}
3988    %vmovd\t{%1, %0|%0, %1}"
3989   [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3990    (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3991    (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3992
3993 (define_insn "zero_extendsidi2_rex64"
3994   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
3995      (zero_extend:DI
3996        (match_operand:SI 1 "nonimmediate_operand"  "rm,0,r   ,m  ,r   ,m")))]
3997   "TARGET_64BIT"
3998   "@
3999    mov\t{%k1, %k0|%k0, %k1}
4000    #
4001    movd\t{%1, %0|%0, %1}
4002    movd\t{%1, %0|%0, %1}
4003    %vmovd\t{%1, %0|%0, %1}
4004    %vmovd\t{%1, %0|%0, %1}"
4005   [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
4006    (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
4007    (set_attr "prefix_0f" "0,*,*,*,*,*")
4008    (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
4009
4010 (define_split
4011   [(set (match_operand:DI 0 "memory_operand" "")
4012      (zero_extend:DI (match_dup 0)))]
4013   "TARGET_64BIT"
4014   [(set (match_dup 4) (const_int 0))]
4015   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4016
4017 (define_split
4018   [(set (match_operand:DI 0 "register_operand" "")
4019         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
4020    (clobber (reg:CC FLAGS_REG))]
4021   "!TARGET_64BIT && reload_completed
4022    && true_regnum (operands[0]) == true_regnum (operands[1])"
4023   [(set (match_dup 4) (const_int 0))]
4024   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4025
4026 (define_split
4027   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4028         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
4029    (clobber (reg:CC FLAGS_REG))]
4030   "!TARGET_64BIT && reload_completed
4031    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
4032   [(set (match_dup 3) (match_dup 1))
4033    (set (match_dup 4) (const_int 0))]
4034   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4035
4036 (define_insn "zero_extendhidi2"
4037   [(set (match_operand:DI 0 "register_operand" "=r")
4038      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
4039   "TARGET_64BIT"
4040   "movz{wl|x}\t{%1, %k0|%k0, %1}"
4041   [(set_attr "type" "imovx")
4042    (set_attr "mode" "SI")])
4043
4044 (define_insn "zero_extendqidi2"
4045   [(set (match_operand:DI 0 "register_operand" "=r")
4046      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
4047   "TARGET_64BIT"
4048   "movz{bl|x}\t{%1, %k0|%k0, %1}"
4049   [(set_attr "type" "imovx")
4050    (set_attr "mode" "SI")])
4051 \f
4052 ;; Sign extension instructions
4053
4054 (define_expand "extendsidi2"
4055   [(parallel [(set (match_operand:DI 0 "register_operand" "")
4056                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4057               (clobber (reg:CC FLAGS_REG))
4058               (clobber (match_scratch:SI 2 ""))])]
4059   ""
4060 {
4061   if (TARGET_64BIT)
4062     {
4063       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
4064       DONE;
4065     }
4066 })
4067
4068 (define_insn "*extendsidi2_1"
4069   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
4070         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
4071    (clobber (reg:CC FLAGS_REG))
4072    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
4073   "!TARGET_64BIT"
4074   "#")
4075
4076 (define_insn "extendsidi2_rex64"
4077   [(set (match_operand:DI 0 "register_operand" "=*a,r")
4078         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
4079   "TARGET_64BIT"
4080   "@
4081    {cltq|cdqe}
4082    movs{lq|x}\t{%1, %0|%0, %1}"
4083   [(set_attr "type" "imovx")
4084    (set_attr "mode" "DI")
4085    (set_attr "prefix_0f" "0")
4086    (set_attr "modrm" "0,1")])
4087
4088 (define_insn "extendhidi2"
4089   [(set (match_operand:DI 0 "register_operand" "=r")
4090         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
4091   "TARGET_64BIT"
4092   "movs{wq|x}\t{%1, %0|%0, %1}"
4093   [(set_attr "type" "imovx")
4094    (set_attr "mode" "DI")])
4095
4096 (define_insn "extendqidi2"
4097   [(set (match_operand:DI 0 "register_operand" "=r")
4098         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4099   "TARGET_64BIT"
4100   "movs{bq|x}\t{%1, %0|%0, %1}"
4101    [(set_attr "type" "imovx")
4102     (set_attr "mode" "DI")])
4103
4104 ;; Extend to memory case when source register does die.
4105 (define_split
4106   [(set (match_operand:DI 0 "memory_operand" "")
4107         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4108    (clobber (reg:CC FLAGS_REG))
4109    (clobber (match_operand:SI 2 "register_operand" ""))]
4110   "(reload_completed
4111     && dead_or_set_p (insn, operands[1])
4112     && !reg_mentioned_p (operands[1], operands[0]))"
4113   [(set (match_dup 3) (match_dup 1))
4114    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4115               (clobber (reg:CC FLAGS_REG))])
4116    (set (match_dup 4) (match_dup 1))]
4117   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4118
4119 ;; Extend to memory case when source register does not die.
4120 (define_split
4121   [(set (match_operand:DI 0 "memory_operand" "")
4122         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4123    (clobber (reg:CC FLAGS_REG))
4124    (clobber (match_operand:SI 2 "register_operand" ""))]
4125   "reload_completed"
4126   [(const_int 0)]
4127 {
4128   split_di (&operands[0], 1, &operands[3], &operands[4]);
4129
4130   emit_move_insn (operands[3], operands[1]);
4131
4132   /* Generate a cltd if possible and doing so it profitable.  */
4133   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4134       && true_regnum (operands[1]) == AX_REG
4135       && true_regnum (operands[2]) == DX_REG)
4136     {
4137       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
4138     }
4139   else
4140     {
4141       emit_move_insn (operands[2], operands[1]);
4142       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
4143     }
4144   emit_move_insn (operands[4], operands[2]);
4145   DONE;
4146 })
4147
4148 ;; Extend to register case.  Optimize case where source and destination
4149 ;; registers match and cases where we can use cltd.
4150 (define_split
4151   [(set (match_operand:DI 0 "register_operand" "")
4152         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4153    (clobber (reg:CC FLAGS_REG))
4154    (clobber (match_scratch:SI 2 ""))]
4155   "reload_completed"
4156   [(const_int 0)]
4157 {
4158   split_di (&operands[0], 1, &operands[3], &operands[4]);
4159
4160   if (true_regnum (operands[3]) != true_regnum (operands[1]))
4161     emit_move_insn (operands[3], operands[1]);
4162
4163   /* Generate a cltd if possible and doing so it profitable.  */
4164   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4165       && true_regnum (operands[3]) == AX_REG)
4166     {
4167       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
4168       DONE;
4169     }
4170
4171   if (true_regnum (operands[4]) != true_regnum (operands[1]))
4172     emit_move_insn (operands[4], operands[1]);
4173
4174   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
4175   DONE;
4176 })
4177
4178 (define_insn "extendhisi2"
4179   [(set (match_operand:SI 0 "register_operand" "=*a,r")
4180         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4181   ""
4182 {
4183   switch (get_attr_prefix_0f (insn))
4184     {
4185     case 0:
4186       return "{cwtl|cwde}";
4187     default:
4188       return "movs{wl|x}\t{%1, %0|%0, %1}";
4189     }
4190 }
4191   [(set_attr "type" "imovx")
4192    (set_attr "mode" "SI")
4193    (set (attr "prefix_0f")
4194      ;; movsx is short decodable while cwtl is vector decoded.
4195      (if_then_else (and (eq_attr "cpu" "!k6")
4196                         (eq_attr "alternative" "0"))
4197         (const_string "0")
4198         (const_string "1")))
4199    (set (attr "modrm")
4200      (if_then_else (eq_attr "prefix_0f" "0")
4201         (const_string "0")
4202         (const_string "1")))])
4203
4204 (define_insn "*extendhisi2_zext"
4205   [(set (match_operand:DI 0 "register_operand" "=*a,r")
4206         (zero_extend:DI
4207           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4208   "TARGET_64BIT"
4209 {
4210   switch (get_attr_prefix_0f (insn))
4211     {
4212     case 0:
4213       return "{cwtl|cwde}";
4214     default:
4215       return "movs{wl|x}\t{%1, %k0|%k0, %1}";
4216     }
4217 }
4218   [(set_attr "type" "imovx")
4219    (set_attr "mode" "SI")
4220    (set (attr "prefix_0f")
4221      ;; movsx is short decodable while cwtl is vector decoded.
4222      (if_then_else (and (eq_attr "cpu" "!k6")
4223                         (eq_attr "alternative" "0"))
4224         (const_string "0")
4225         (const_string "1")))
4226    (set (attr "modrm")
4227      (if_then_else (eq_attr "prefix_0f" "0")
4228         (const_string "0")
4229         (const_string "1")))])
4230
4231 (define_insn "extendqihi2"
4232   [(set (match_operand:HI 0 "register_operand" "=*a,r")
4233         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4234   ""
4235 {
4236   switch (get_attr_prefix_0f (insn))
4237     {
4238     case 0:
4239       return "{cbtw|cbw}";
4240     default:
4241       return "movs{bw|x}\t{%1, %0|%0, %1}";
4242     }
4243 }
4244   [(set_attr "type" "imovx")
4245    (set_attr "mode" "HI")
4246    (set (attr "prefix_0f")
4247      ;; movsx is short decodable while cwtl is vector decoded.
4248      (if_then_else (and (eq_attr "cpu" "!k6")
4249                         (eq_attr "alternative" "0"))
4250         (const_string "0")
4251         (const_string "1")))
4252    (set (attr "modrm")
4253      (if_then_else (eq_attr "prefix_0f" "0")
4254         (const_string "0")
4255         (const_string "1")))])
4256
4257 (define_insn "extendqisi2"
4258   [(set (match_operand:SI 0 "register_operand" "=r")
4259         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4260   ""
4261   "movs{bl|x}\t{%1, %0|%0, %1}"
4262    [(set_attr "type" "imovx")
4263     (set_attr "mode" "SI")])
4264
4265 (define_insn "*extendqisi2_zext"
4266   [(set (match_operand:DI 0 "register_operand" "=r")
4267         (zero_extend:DI
4268           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4269   "TARGET_64BIT"
4270   "movs{bl|x}\t{%1, %k0|%k0, %1}"
4271    [(set_attr "type" "imovx")
4272     (set_attr "mode" "SI")])
4273 \f
4274 ;; Conversions between float and double.
4275
4276 ;; These are all no-ops in the model used for the 80387.  So just
4277 ;; emit moves.
4278
4279 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4280 (define_insn "*dummy_extendsfdf2"
4281   [(set (match_operand:DF 0 "push_operand" "=<")
4282         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY2")))]
4283   "0"
4284   "#")
4285
4286 (define_split
4287   [(set (match_operand:DF 0 "push_operand" "")
4288         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
4289   ""
4290   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4291    (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4292
4293 (define_insn "*dummy_extendsfxf2"
4294   [(set (match_operand:XF 0 "push_operand" "=<")
4295         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
4296   "0"
4297   "#")
4298
4299 (define_split
4300   [(set (match_operand:XF 0 "push_operand" "")
4301         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
4302   ""
4303   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4304    (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4305   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4306
4307 (define_split
4308   [(set (match_operand:XF 0 "push_operand" "")
4309         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
4310   ""
4311   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4312    (set (mem:DF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4313   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4314
4315 (define_expand "extendsfdf2"
4316   [(set (match_operand:DF 0 "nonimmediate_operand" "")
4317         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
4318   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4319 {
4320   /* ??? Needed for compress_float_constant since all fp constants
4321      are LEGITIMATE_CONSTANT_P.  */
4322   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4323     {
4324       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4325           && standard_80387_constant_p (operands[1]) > 0)
4326         {
4327           operands[1] = simplify_const_unary_operation
4328             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4329           emit_move_insn_1 (operands[0], operands[1]);
4330           DONE;
4331         }
4332       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4333     }
4334 })
4335
4336 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4337    cvtss2sd:
4338       unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4339       cvtps2pd xmm2,xmm1
4340    We do the conversion post reload to avoid producing of 128bit spills
4341    that might lead to ICE on 32bit target.  The sequence unlikely combine
4342    anyway.  */
4343 (define_split
4344   [(set (match_operand:DF 0 "register_operand" "")
4345         (float_extend:DF
4346           (match_operand:SF 1 "nonimmediate_operand" "")))]
4347   "TARGET_USE_VECTOR_FP_CONVERTS
4348    && optimize_insn_for_speed_p ()
4349    && reload_completed && SSE_REG_P (operands[0])"
4350    [(set (match_dup 2)
4351          (float_extend:V2DF
4352            (vec_select:V2SF
4353              (match_dup 3)
4354              (parallel [(const_int 0) (const_int 1)]))))]
4355 {
4356   operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4357   operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4358   /* Use movss for loading from memory, unpcklps reg, reg for registers.
4359      Try to avoid move when unpacking can be done in source.  */
4360   if (REG_P (operands[1]))
4361     {
4362       /* If it is unsafe to overwrite upper half of source, we need
4363          to move to destination and unpack there.  */
4364       if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4365            || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4366           && true_regnum (operands[0]) != true_regnum (operands[1]))
4367         {
4368           rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4369           emit_move_insn (tmp, operands[1]);
4370         }
4371       else
4372         operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4373       emit_insn (gen_sse_unpcklps (operands[3], operands[3], operands[3]));
4374     }
4375   else
4376     emit_insn (gen_vec_setv4sf_0 (operands[3],
4377                                   CONST0_RTX (V4SFmode), operands[1]));
4378 })
4379
4380 (define_insn "*extendsfdf2_mixed"
4381   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4382         (float_extend:DF
4383           (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4384   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4385 {
4386   switch (which_alternative)
4387     {
4388     case 0:
4389     case 1:
4390       return output_387_reg_move (insn, operands);
4391
4392     case 2:
4393       return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4394
4395     default:
4396       gcc_unreachable ();
4397     }
4398 }
4399   [(set_attr "type" "fmov,fmov,ssecvt")
4400    (set_attr "prefix" "orig,orig,maybe_vex")
4401    (set_attr "mode" "SF,XF,DF")])
4402
4403 (define_insn "*extendsfdf2_sse"
4404   [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4405         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4406   "TARGET_SSE2 && TARGET_SSE_MATH"
4407   "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4408   [(set_attr "type" "ssecvt")
4409    (set_attr "prefix" "maybe_vex")
4410    (set_attr "mode" "DF")])
4411
4412 (define_insn "*extendsfdf2_i387"
4413   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4414         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4415   "TARGET_80387"
4416   "* return output_387_reg_move (insn, operands);"
4417   [(set_attr "type" "fmov")
4418    (set_attr "mode" "SF,XF")])
4419
4420 (define_expand "extend<mode>xf2"
4421   [(set (match_operand:XF 0 "nonimmediate_operand" "")
4422         (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4423   "TARGET_80387"
4424 {
4425   /* ??? Needed for compress_float_constant since all fp constants
4426      are LEGITIMATE_CONSTANT_P.  */
4427   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4428     {
4429       if (standard_80387_constant_p (operands[1]) > 0)
4430         {
4431           operands[1] = simplify_const_unary_operation
4432             (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4433           emit_move_insn_1 (operands[0], operands[1]);
4434           DONE;
4435         }
4436       operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4437     }
4438 })
4439
4440 (define_insn "*extend<mode>xf2_i387"
4441   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4442         (float_extend:XF
4443           (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4444   "TARGET_80387"
4445   "* return output_387_reg_move (insn, operands);"
4446   [(set_attr "type" "fmov")
4447    (set_attr "mode" "<MODE>,XF")])
4448
4449 ;; %%% This seems bad bad news.
4450 ;; This cannot output into an f-reg because there is no way to be sure
4451 ;; of truncating in that case.  Otherwise this is just like a simple move
4452 ;; insn.  So we pretend we can output to a reg in order to get better
4453 ;; register preferencing, but we really use a stack slot.
4454
4455 ;; Conversion from DFmode to SFmode.
4456
4457 (define_expand "truncdfsf2"
4458   [(set (match_operand:SF 0 "nonimmediate_operand" "")
4459         (float_truncate:SF
4460           (match_operand:DF 1 "nonimmediate_operand" "")))]
4461   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4462 {
4463   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4464     ;
4465   else if (flag_unsafe_math_optimizations)
4466     ;
4467   else
4468     {
4469       enum ix86_stack_slot slot = (virtuals_instantiated
4470                                    ? SLOT_TEMP
4471                                    : SLOT_VIRTUAL);
4472       rtx temp = assign_386_stack_local (SFmode, slot);
4473       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4474       DONE;
4475     }
4476 })
4477
4478 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4479    cvtsd2ss:
4480       unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4481       cvtpd2ps xmm2,xmm1
4482    We do the conversion post reload to avoid producing of 128bit spills
4483    that might lead to ICE on 32bit target.  The sequence unlikely combine
4484    anyway.  */
4485 (define_split
4486   [(set (match_operand:SF 0 "register_operand" "")
4487         (float_truncate:SF
4488           (match_operand:DF 1 "nonimmediate_operand" "")))]
4489   "TARGET_USE_VECTOR_FP_CONVERTS
4490    && optimize_insn_for_speed_p ()
4491    && reload_completed && SSE_REG_P (operands[0])"
4492    [(set (match_dup 2)
4493          (vec_concat:V4SF
4494            (float_truncate:V2SF
4495              (match_dup 4))
4496            (match_dup 3)))]
4497 {
4498   operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4499   operands[3] = CONST0_RTX (V2SFmode);
4500   operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4501   /* Use movsd for loading from memory, unpcklpd for registers.
4502      Try to avoid move when unpacking can be done in source, or SSE3
4503      movddup is available.  */
4504   if (REG_P (operands[1]))
4505     {
4506       if (!TARGET_SSE3
4507           && true_regnum (operands[0]) != true_regnum (operands[1])
4508           && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4509               || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4510         {
4511           rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4512           emit_move_insn (tmp, operands[1]);
4513           operands[1] = tmp;
4514         }
4515       else if (!TARGET_SSE3)
4516         operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4517       emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4518     }
4519   else
4520     emit_insn (gen_sse2_loadlpd (operands[4],
4521                                  CONST0_RTX (V2DFmode), operands[1]));
4522 })
4523
4524 (define_expand "truncdfsf2_with_temp"
4525   [(parallel [(set (match_operand:SF 0 "" "")
4526                    (float_truncate:SF (match_operand:DF 1 "" "")))
4527               (clobber (match_operand:SF 2 "" ""))])]
4528   "")
4529
4530 (define_insn "*truncdfsf_fast_mixed"
4531   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm,x")
4532         (float_truncate:SF
4533           (match_operand:DF 1 "nonimmediate_operand" "f  ,xm")))]
4534   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4535 {
4536   switch (which_alternative)
4537     {
4538     case 0:
4539       return output_387_reg_move (insn, operands);
4540     case 1:
4541       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4542     default:
4543       gcc_unreachable ();
4544     }
4545 }
4546   [(set_attr "type" "fmov,ssecvt")
4547    (set_attr "prefix" "orig,maybe_vex")
4548    (set_attr "mode" "SF")])
4549
4550 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4551 ;; because nothing we do here is unsafe.
4552 (define_insn "*truncdfsf_fast_sse"
4553   [(set (match_operand:SF 0 "nonimmediate_operand"   "=x")
4554         (float_truncate:SF
4555           (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4556   "TARGET_SSE2 && TARGET_SSE_MATH"
4557   "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4558   [(set_attr "type" "ssecvt")
4559    (set_attr "prefix" "maybe_vex")
4560    (set_attr "mode" "SF")])
4561
4562 (define_insn "*truncdfsf_fast_i387"
4563   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
4564         (float_truncate:SF
4565           (match_operand:DF 1 "nonimmediate_operand" "f")))]
4566   "TARGET_80387 && flag_unsafe_math_optimizations"
4567   "* return output_387_reg_move (insn, operands);"
4568   [(set_attr "type" "fmov")
4569    (set_attr "mode" "SF")])
4570
4571 (define_insn "*truncdfsf_mixed"
4572   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,Y2 ,?f,?x,?*r")
4573         (float_truncate:SF
4574           (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4575    (clobber (match_operand:SF 2 "memory_operand"     "=X,X  ,m ,m ,m"))]
4576   "TARGET_MIX_SSE_I387"
4577 {
4578   switch (which_alternative)
4579     {
4580     case 0:
4581       return output_387_reg_move (insn, operands);
4582     case 1:
4583       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4584
4585     default:
4586       return "#";
4587     }
4588 }
4589   [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4590    (set_attr "unit" "*,*,i387,i387,i387")
4591    (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4592    (set_attr "mode" "SF")])
4593
4594 (define_insn "*truncdfsf_i387"
4595   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?f,?x,?*r")
4596         (float_truncate:SF
4597           (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4598    (clobber (match_operand:SF 2 "memory_operand"     "=X,m ,m ,m"))]
4599   "TARGET_80387"
4600 {
4601   switch (which_alternative)
4602     {
4603     case 0:
4604       return output_387_reg_move (insn, operands);
4605
4606     default:
4607       return "#";
4608     }
4609 }
4610   [(set_attr "type" "fmov,multi,multi,multi")
4611    (set_attr "unit" "*,i387,i387,i387")
4612    (set_attr "mode" "SF")])
4613
4614 (define_insn "*truncdfsf2_i387_1"
4615   [(set (match_operand:SF 0 "memory_operand" "=m")
4616         (float_truncate:SF
4617           (match_operand:DF 1 "register_operand" "f")))]
4618   "TARGET_80387
4619    && !(TARGET_SSE2 && TARGET_SSE_MATH)
4620    && !TARGET_MIX_SSE_I387"
4621   "* return output_387_reg_move (insn, operands);"
4622   [(set_attr "type" "fmov")
4623    (set_attr "mode" "SF")])
4624
4625 (define_split
4626   [(set (match_operand:SF 0 "register_operand" "")
4627         (float_truncate:SF
4628          (match_operand:DF 1 "fp_register_operand" "")))
4629    (clobber (match_operand 2 "" ""))]
4630   "reload_completed"
4631   [(set (match_dup 2) (match_dup 1))
4632    (set (match_dup 0) (match_dup 2))]
4633 {
4634   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4635 })
4636
4637 ;; Conversion from XFmode to {SF,DF}mode
4638
4639 (define_expand "truncxf<mode>2"
4640   [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4641                    (float_truncate:MODEF
4642                      (match_operand:XF 1 "register_operand" "")))
4643               (clobber (match_dup 2))])]
4644   "TARGET_80387"
4645 {
4646   if (flag_unsafe_math_optimizations)
4647     {
4648       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4649       emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4650       if (reg != operands[0])
4651         emit_move_insn (operands[0], reg);
4652       DONE;
4653     }
4654   else
4655     {
4656      enum ix86_stack_slot slot = (virtuals_instantiated
4657                                   ? SLOT_TEMP
4658                                   : SLOT_VIRTUAL);
4659       operands[2] = assign_386_stack_local (<MODE>mode, slot);
4660     }
4661 })
4662
4663 (define_insn "*truncxfsf2_mixed"
4664   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4665         (float_truncate:SF
4666           (match_operand:XF 1 "register_operand"   "f ,f ,f ,f")))
4667    (clobber (match_operand:SF 2 "memory_operand"   "=X,m ,m ,m"))]
4668   "TARGET_80387"
4669 {
4670   gcc_assert (!which_alternative);
4671   return output_387_reg_move (insn, operands);
4672 }
4673   [(set_attr "type" "fmov,multi,multi,multi")
4674    (set_attr "unit" "*,i387,i387,i387")
4675    (set_attr "mode" "SF")])
4676
4677 (define_insn "*truncxfdf2_mixed"
4678   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4679         (float_truncate:DF
4680           (match_operand:XF 1 "register_operand"   "f ,f ,f  ,f")))
4681    (clobber (match_operand:DF 2 "memory_operand"   "=X,m ,m  ,m"))]
4682   "TARGET_80387"
4683 {
4684   gcc_assert (!which_alternative);
4685   return output_387_reg_move (insn, operands);
4686 }
4687   [(set_attr "type" "fmov,multi,multi,multi")
4688    (set_attr "unit" "*,i387,i387,i387")
4689    (set_attr "mode" "DF")])
4690
4691 (define_insn "truncxf<mode>2_i387_noop"
4692   [(set (match_operand:MODEF 0 "register_operand" "=f")
4693         (float_truncate:MODEF
4694           (match_operand:XF 1 "register_operand" "f")))]
4695   "TARGET_80387 && flag_unsafe_math_optimizations"
4696   "* return output_387_reg_move (insn, operands);"
4697   [(set_attr "type" "fmov")
4698    (set_attr "mode" "<MODE>")])
4699
4700 (define_insn "*truncxf<mode>2_i387"
4701   [(set (match_operand:MODEF 0 "memory_operand" "=m")
4702         (float_truncate:MODEF
4703           (match_operand:XF 1 "register_operand" "f")))]
4704   "TARGET_80387"
4705   "* return output_387_reg_move (insn, operands);"
4706   [(set_attr "type" "fmov")
4707    (set_attr "mode" "<MODE>")])
4708
4709 (define_split
4710   [(set (match_operand:MODEF 0 "register_operand" "")
4711         (float_truncate:MODEF
4712           (match_operand:XF 1 "register_operand" "")))
4713    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4714   "TARGET_80387 && reload_completed"
4715   [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4716    (set (match_dup 0) (match_dup 2))]
4717   "")
4718
4719 (define_split
4720   [(set (match_operand:MODEF 0 "memory_operand" "")
4721         (float_truncate:MODEF
4722           (match_operand:XF 1 "register_operand" "")))
4723    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4724   "TARGET_80387"
4725   [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]
4726   "")
4727 \f
4728 ;; Signed conversion to DImode.
4729
4730 (define_expand "fix_truncxfdi2"
4731   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4732                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4733               (clobber (reg:CC FLAGS_REG))])]
4734   "TARGET_80387"
4735 {
4736   if (TARGET_FISTTP)
4737    {
4738      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4739      DONE;
4740    }
4741 })
4742
4743 (define_expand "fix_trunc<mode>di2"
4744   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4745                    (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4746               (clobber (reg:CC FLAGS_REG))])]
4747   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4748 {
4749   if (TARGET_FISTTP
4750       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4751    {
4752      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4753      DONE;
4754    }
4755   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4756    {
4757      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4758      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4759      if (out != operands[0])
4760         emit_move_insn (operands[0], out);
4761      DONE;
4762    }
4763 })
4764
4765 ;; Signed conversion to SImode.
4766
4767 (define_expand "fix_truncxfsi2"
4768   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4769                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4770               (clobber (reg:CC FLAGS_REG))])]
4771   "TARGET_80387"
4772 {
4773   if (TARGET_FISTTP)
4774    {
4775      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4776      DONE;
4777    }
4778 })
4779
4780 (define_expand "fix_trunc<mode>si2"
4781   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4782                    (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4783               (clobber (reg:CC FLAGS_REG))])]
4784   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4785 {
4786   if (TARGET_FISTTP
4787       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4788    {
4789      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4790      DONE;
4791    }
4792   if (SSE_FLOAT_MODE_P (<MODE>mode))
4793    {
4794      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4795      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4796      if (out != operands[0])
4797         emit_move_insn (operands[0], out);
4798      DONE;
4799    }
4800 })
4801
4802 ;; Signed conversion to HImode.
4803
4804 (define_expand "fix_trunc<mode>hi2"
4805   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4806                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4807               (clobber (reg:CC FLAGS_REG))])]
4808   "TARGET_80387
4809    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4810 {
4811   if (TARGET_FISTTP)
4812    {
4813      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4814      DONE;
4815    }
4816 })
4817
4818 ;; Unsigned conversion to SImode.
4819
4820 (define_expand "fixuns_trunc<mode>si2"
4821   [(parallel
4822     [(set (match_operand:SI 0 "register_operand" "")
4823           (unsigned_fix:SI
4824             (match_operand:MODEF 1 "nonimmediate_operand" "")))
4825      (use (match_dup 2))
4826      (clobber (match_scratch:<ssevecmode> 3 ""))
4827      (clobber (match_scratch:<ssevecmode> 4 ""))])]
4828   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4829 {
4830   enum machine_mode mode = <MODE>mode;
4831   enum machine_mode vecmode = <ssevecmode>mode;
4832   REAL_VALUE_TYPE TWO31r;
4833   rtx two31;
4834
4835   if (optimize_insn_for_size_p ())
4836     FAIL;
4837
4838   real_ldexp (&TWO31r, &dconst1, 31);
4839   two31 = const_double_from_real_value (TWO31r, mode);
4840   two31 = ix86_build_const_vector (mode, true, two31);
4841   operands[2] = force_reg (vecmode, two31);
4842 })
4843
4844 (define_insn_and_split "*fixuns_trunc<mode>_1"
4845   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4846         (unsigned_fix:SI
4847           (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4848    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
4849    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4850    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4851   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4852    && optimize_function_for_speed_p (cfun)"
4853   "#"
4854   "&& reload_completed"
4855   [(const_int 0)]
4856 {
4857   ix86_split_convert_uns_si_sse (operands);
4858   DONE;
4859 })
4860
4861 ;; Unsigned conversion to HImode.
4862 ;; Without these patterns, we'll try the unsigned SI conversion which
4863 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4864
4865 (define_expand "fixuns_trunc<mode>hi2"
4866   [(set (match_dup 2)
4867         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4868    (set (match_operand:HI 0 "nonimmediate_operand" "")
4869         (subreg:HI (match_dup 2) 0))]
4870   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4871   "operands[2] = gen_reg_rtx (SImode);")
4872
4873 ;; When SSE is available, it is always faster to use it!
4874 (define_insn "fix_trunc<mode>di_sse"
4875   [(set (match_operand:DI 0 "register_operand" "=r,r")
4876         (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4877   "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4878    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4879   "%vcvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4880   [(set_attr "type" "sseicvt")
4881    (set_attr "prefix" "maybe_vex")
4882    (set_attr "prefix_rex" "1")
4883    (set_attr "mode" "<MODE>")
4884    (set_attr "athlon_decode" "double,vector")
4885    (set_attr "amdfam10_decode" "double,double")])
4886
4887 (define_insn "fix_trunc<mode>si_sse"
4888   [(set (match_operand:SI 0 "register_operand" "=r,r")
4889         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4890   "SSE_FLOAT_MODE_P (<MODE>mode)
4891    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4892   "%vcvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4893   [(set_attr "type" "sseicvt")
4894    (set_attr "prefix" "maybe_vex")
4895    (set_attr "mode" "<MODE>")
4896    (set_attr "athlon_decode" "double,vector")
4897    (set_attr "amdfam10_decode" "double,double")])
4898
4899 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4900 (define_peephole2
4901   [(set (match_operand:MODEF 0 "register_operand" "")
4902         (match_operand:MODEF 1 "memory_operand" ""))
4903    (set (match_operand:SSEMODEI24 2 "register_operand" "")
4904         (fix:SSEMODEI24 (match_dup 0)))]
4905   "TARGET_SHORTEN_X87_SSE
4906    && peep2_reg_dead_p (2, operands[0])"
4907   [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4908   "")
4909
4910 ;; Avoid vector decoded forms of the instruction.
4911 (define_peephole2
4912   [(match_scratch:DF 2 "Y2")
4913    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4914         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4915   "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4916   [(set (match_dup 2) (match_dup 1))
4917    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4918   "")
4919
4920 (define_peephole2
4921   [(match_scratch:SF 2 "x")
4922    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4923         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4924   "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4925   [(set (match_dup 2) (match_dup 1))
4926    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4927   "")
4928
4929 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4930   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4931         (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4932   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4933    && TARGET_FISTTP
4934    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4935          && (TARGET_64BIT || <MODE>mode != DImode))
4936         && TARGET_SSE_MATH)
4937    && can_create_pseudo_p ()"
4938   "#"
4939   "&& 1"
4940   [(const_int 0)]
4941 {
4942   if (memory_operand (operands[0], VOIDmode))
4943     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4944   else
4945     {
4946       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4947       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4948                                                             operands[1],
4949                                                             operands[2]));
4950     }
4951   DONE;
4952 }
4953   [(set_attr "type" "fisttp")
4954    (set_attr "mode" "<MODE>")])
4955
4956 (define_insn "fix_trunc<mode>_i387_fisttp"
4957   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4958         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4959    (clobber (match_scratch:XF 2 "=&1f"))]
4960   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4961    && TARGET_FISTTP
4962    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4963          && (TARGET_64BIT || <MODE>mode != DImode))
4964         && TARGET_SSE_MATH)"
4965   "* return output_fix_trunc (insn, operands, 1);"
4966   [(set_attr "type" "fisttp")
4967    (set_attr "mode" "<MODE>")])
4968
4969 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4970   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4971         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4972    (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
4973    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4974   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4975    && TARGET_FISTTP
4976    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4977         && (TARGET_64BIT || <MODE>mode != DImode))
4978         && TARGET_SSE_MATH)"
4979   "#"
4980   [(set_attr "type" "fisttp")
4981    (set_attr "mode" "<MODE>")])
4982
4983 (define_split
4984   [(set (match_operand:X87MODEI 0 "register_operand" "")
4985         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4986    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4987    (clobber (match_scratch 3 ""))]
4988   "reload_completed"
4989   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4990               (clobber (match_dup 3))])
4991    (set (match_dup 0) (match_dup 2))]
4992   "")
4993
4994 (define_split
4995   [(set (match_operand:X87MODEI 0 "memory_operand" "")
4996         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4997    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4998    (clobber (match_scratch 3 ""))]
4999   "reload_completed"
5000   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
5001               (clobber (match_dup 3))])]
5002   "")
5003
5004 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
5005 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
5006 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
5007 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
5008 ;; function in i386.c.
5009 (define_insn_and_split "*fix_trunc<mode>_i387_1"
5010   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
5011         (fix:X87MODEI (match_operand 1 "register_operand" "")))
5012    (clobber (reg:CC FLAGS_REG))]
5013   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5014    && !TARGET_FISTTP
5015    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5016          && (TARGET_64BIT || <MODE>mode != DImode))
5017    && can_create_pseudo_p ()"
5018   "#"
5019   "&& 1"
5020   [(const_int 0)]
5021 {
5022   ix86_optimize_mode_switching[I387_TRUNC] = 1;
5023
5024   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
5025   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
5026   if (memory_operand (operands[0], VOIDmode))
5027     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
5028                                          operands[2], operands[3]));
5029   else
5030     {
5031       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
5032       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
5033                                                      operands[2], operands[3],
5034                                                      operands[4]));
5035     }
5036   DONE;
5037 }
5038   [(set_attr "type" "fistp")
5039    (set_attr "i387_cw" "trunc")
5040    (set_attr "mode" "<MODE>")])
5041
5042 (define_insn "fix_truncdi_i387"
5043   [(set (match_operand:DI 0 "memory_operand" "=m")
5044         (fix:DI (match_operand 1 "register_operand" "f")))
5045    (use (match_operand:HI 2 "memory_operand" "m"))
5046    (use (match_operand:HI 3 "memory_operand" "m"))
5047    (clobber (match_scratch:XF 4 "=&1f"))]
5048   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5049    && !TARGET_FISTTP
5050    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5051   "* return output_fix_trunc (insn, operands, 0);"
5052   [(set_attr "type" "fistp")
5053    (set_attr "i387_cw" "trunc")
5054    (set_attr "mode" "DI")])
5055
5056 (define_insn "fix_truncdi_i387_with_temp"
5057   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
5058         (fix:DI (match_operand 1 "register_operand" "f,f")))
5059    (use (match_operand:HI 2 "memory_operand" "m,m"))
5060    (use (match_operand:HI 3 "memory_operand" "m,m"))
5061    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
5062    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
5063   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5064    && !TARGET_FISTTP
5065    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5066   "#"
5067   [(set_attr "type" "fistp")
5068    (set_attr "i387_cw" "trunc")
5069    (set_attr "mode" "DI")])
5070
5071 (define_split
5072   [(set (match_operand:DI 0 "register_operand" "")
5073         (fix:DI (match_operand 1 "register_operand" "")))
5074    (use (match_operand:HI 2 "memory_operand" ""))
5075    (use (match_operand:HI 3 "memory_operand" ""))
5076    (clobber (match_operand:DI 4 "memory_operand" ""))
5077    (clobber (match_scratch 5 ""))]
5078   "reload_completed"
5079   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
5080               (use (match_dup 2))
5081               (use (match_dup 3))
5082               (clobber (match_dup 5))])
5083    (set (match_dup 0) (match_dup 4))]
5084   "")
5085
5086 (define_split
5087   [(set (match_operand:DI 0 "memory_operand" "")
5088         (fix:DI (match_operand 1 "register_operand" "")))
5089    (use (match_operand:HI 2 "memory_operand" ""))
5090    (use (match_operand:HI 3 "memory_operand" ""))
5091    (clobber (match_operand:DI 4 "memory_operand" ""))
5092    (clobber (match_scratch 5 ""))]
5093   "reload_completed"
5094   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
5095               (use (match_dup 2))
5096               (use (match_dup 3))
5097               (clobber (match_dup 5))])]
5098   "")
5099
5100 (define_insn "fix_trunc<mode>_i387"
5101   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
5102         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
5103    (use (match_operand:HI 2 "memory_operand" "m"))
5104    (use (match_operand:HI 3 "memory_operand" "m"))]
5105   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5106    && !TARGET_FISTTP
5107    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5108   "* return output_fix_trunc (insn, operands, 0);"
5109   [(set_attr "type" "fistp")
5110    (set_attr "i387_cw" "trunc")
5111    (set_attr "mode" "<MODE>")])
5112
5113 (define_insn "fix_trunc<mode>_i387_with_temp"
5114   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
5115         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
5116    (use (match_operand:HI 2 "memory_operand" "m,m"))
5117    (use (match_operand:HI 3 "memory_operand" "m,m"))
5118    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
5119   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5120    && !TARGET_FISTTP
5121    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5122   "#"
5123   [(set_attr "type" "fistp")
5124    (set_attr "i387_cw" "trunc")
5125    (set_attr "mode" "<MODE>")])
5126
5127 (define_split
5128   [(set (match_operand:X87MODEI12 0 "register_operand" "")
5129         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5130    (use (match_operand:HI 2 "memory_operand" ""))
5131    (use (match_operand:HI 3 "memory_operand" ""))
5132    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5133   "reload_completed"
5134   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
5135               (use (match_dup 2))
5136               (use (match_dup 3))])
5137    (set (match_dup 0) (match_dup 4))]
5138   "")
5139
5140 (define_split
5141   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
5142         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5143    (use (match_operand:HI 2 "memory_operand" ""))
5144    (use (match_operand:HI 3 "memory_operand" ""))
5145    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5146   "reload_completed"
5147   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
5148               (use (match_dup 2))
5149               (use (match_dup 3))])]
5150   "")
5151
5152 (define_insn "x86_fnstcw_1"
5153   [(set (match_operand:HI 0 "memory_operand" "=m")
5154         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
5155   "TARGET_80387"
5156   "fnstcw\t%0"
5157   [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5158    (set_attr "mode" "HI")
5159    (set_attr "unit" "i387")])
5160
5161 (define_insn "x86_fldcw_1"
5162   [(set (reg:HI FPCR_REG)
5163         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
5164   "TARGET_80387"
5165   "fldcw\t%0"
5166   [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5167    (set_attr "mode" "HI")
5168    (set_attr "unit" "i387")
5169    (set_attr "athlon_decode" "vector")
5170    (set_attr "amdfam10_decode" "vector")])
5171 \f
5172 ;; Conversion between fixed point and floating point.
5173
5174 ;; Even though we only accept memory inputs, the backend _really_
5175 ;; wants to be able to do this between registers.
5176
5177 (define_expand "floathi<mode>2"
5178   [(set (match_operand:X87MODEF 0 "register_operand" "")
5179         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
5180   "TARGET_80387
5181    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5182        || TARGET_MIX_SSE_I387)"
5183   "")
5184
5185 ;; Pre-reload splitter to add memory clobber to the pattern.
5186 (define_insn_and_split "*floathi<mode>2_1"
5187   [(set (match_operand:X87MODEF 0 "register_operand" "")
5188         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
5189   "TARGET_80387
5190    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5191        || TARGET_MIX_SSE_I387)
5192    && can_create_pseudo_p ()"
5193   "#"
5194   "&& 1"
5195   [(parallel [(set (match_dup 0)
5196               (float:X87MODEF (match_dup 1)))
5197    (clobber (match_dup 2))])]
5198   "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
5199
5200 (define_insn "*floathi<mode>2_i387_with_temp"
5201   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5202         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
5203   (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
5204   "TARGET_80387
5205    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5206        || TARGET_MIX_SSE_I387)"
5207   "#"
5208   [(set_attr "type" "fmov,multi")
5209    (set_attr "mode" "<MODE>")
5210    (set_attr "unit" "*,i387")
5211    (set_attr "fp_int_src" "true")])
5212
5213 (define_insn "*floathi<mode>2_i387"
5214   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5215         (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
5216   "TARGET_80387
5217    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5218        || TARGET_MIX_SSE_I387)"
5219   "fild%Z1\t%1"
5220   [(set_attr "type" "fmov")
5221    (set_attr "mode" "<MODE>")
5222    (set_attr "fp_int_src" "true")])
5223
5224 (define_split
5225   [(set (match_operand:X87MODEF 0 "register_operand" "")
5226         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
5227    (clobber (match_operand:HI 2 "memory_operand" ""))]
5228   "TARGET_80387
5229    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5230        || TARGET_MIX_SSE_I387)
5231    && reload_completed"
5232   [(set (match_dup 2) (match_dup 1))
5233    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5234   "")
5235
5236 (define_split
5237   [(set (match_operand:X87MODEF 0 "register_operand" "")
5238         (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
5239    (clobber (match_operand:HI 2 "memory_operand" ""))]
5240    "TARGET_80387
5241     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5242         || TARGET_MIX_SSE_I387)
5243     && reload_completed"
5244   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5245   "")
5246
5247 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
5248   [(set (match_operand:X87MODEF 0 "register_operand" "")
5249         (float:X87MODEF
5250           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
5251   "TARGET_80387
5252    || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5253        && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
5254   "
5255 {
5256   if (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5257         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5258       && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode))
5259     {
5260       rtx reg = gen_reg_rtx (XFmode);
5261       rtx insn;
5262
5263       emit_insn (gen_float<SSEMODEI24:mode>xf2 (reg, operands[1]));
5264
5265       if (<X87MODEF:MODE>mode == SFmode)
5266         insn = gen_truncxfsf2 (operands[0], reg);
5267       else if (<X87MODEF:MODE>mode == DFmode)
5268         insn = gen_truncxfdf2 (operands[0], reg);
5269       else
5270         gcc_unreachable ();
5271
5272       emit_insn (insn);
5273       DONE;
5274     }
5275 }")
5276
5277 ;; Pre-reload splitter to add memory clobber to the pattern.
5278 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
5279   [(set (match_operand:X87MODEF 0 "register_operand" "")
5280         (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
5281   "((TARGET_80387
5282      && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5283      && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5284            && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5285          || TARGET_MIX_SSE_I387))
5286     || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5287         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
5288         && ((<SSEMODEI24:MODE>mode == SImode
5289              && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
5290              && optimize_function_for_speed_p (cfun)
5291              && flag_trapping_math)
5292             || !(TARGET_INTER_UNIT_CONVERSIONS
5293                  || optimize_function_for_size_p (cfun)))))
5294    && can_create_pseudo_p ()"
5295   "#"
5296   "&& 1"
5297   [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
5298               (clobber (match_dup 2))])]
5299 {
5300   operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
5301
5302   /* Avoid store forwarding (partial memory) stall penalty
5303      by passing DImode value through XMM registers.  */
5304   if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
5305       && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5306       && optimize_function_for_speed_p (cfun))
5307     {
5308       emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
5309                                                             operands[1],
5310                                                             operands[2]));
5311       DONE;
5312     }
5313 })
5314
5315 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
5316   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
5317         (float:MODEF
5318           (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
5319    (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
5320   "TARGET_SSE2 && TARGET_MIX_SSE_I387
5321    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5322   "#"
5323   [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
5324    (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
5325    (set_attr "unit" "*,i387,*,*,*")
5326    (set_attr "athlon_decode" "*,*,double,direct,double")
5327    (set_attr "amdfam10_decode" "*,*,vector,double,double")
5328    (set_attr "fp_int_src" "true")])
5329
5330 (define_insn "*floatsi<mode>2_vector_mixed"
5331   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5332         (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
5333   "TARGET_SSE2 && TARGET_MIX_SSE_I387
5334    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5335   "@
5336    fild%Z1\t%1
5337    #"
5338   [(set_attr "type" "fmov,sseicvt")
5339    (set_attr "mode" "<MODE>,<ssevecmode>")
5340    (set_attr "unit" "i387,*")
5341    (set_attr "athlon_decode" "*,direct")
5342    (set_attr "amdfam10_decode" "*,double")
5343    (set_attr "fp_int_src" "true")])
5344
5345 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
5346   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
5347         (float:MODEF
5348           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
5349   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
5350   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5351    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
5352   "#"
5353   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5354    (set_attr "mode" "<MODEF:MODE>")
5355    (set_attr "unit" "*,i387,*,*")
5356    (set_attr "athlon_decode" "*,*,double,direct")
5357    (set_attr "amdfam10_decode" "*,*,vector,double")
5358    (set_attr "fp_int_src" "true")])
5359
5360 (define_split
5361   [(set (match_operand:MODEF 0 "register_operand" "")
5362         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5363    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5364   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5365    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5366    && TARGET_INTER_UNIT_CONVERSIONS
5367    && reload_completed
5368    && (SSE_REG_P (operands[0])
5369        || (GET_CODE (operands[0]) == SUBREG
5370            && SSE_REG_P (operands[0])))"
5371   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5372   "")
5373
5374 (define_split
5375   [(set (match_operand:MODEF 0 "register_operand" "")
5376         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5377    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5378   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5379    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5380    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5381    && reload_completed
5382    && (SSE_REG_P (operands[0])
5383        || (GET_CODE (operands[0]) == SUBREG
5384            && SSE_REG_P (operands[0])))"
5385   [(set (match_dup 2) (match_dup 1))
5386    (set (match_dup 0) (float:MODEF (match_dup 2)))]
5387   "")
5388
5389 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5390   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5391         (float:MODEF
5392           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
5393   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5394    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5395    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5396   "@
5397    fild%Z1\t%1
5398    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
5399    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5400   [(set_attr "type" "fmov,sseicvt,sseicvt")
5401    (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5402    (set_attr "mode" "<MODEF:MODE>")
5403    (set (attr "prefix_rex")
5404      (if_then_else
5405        (and (eq_attr "prefix" "maybe_vex")
5406             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5407        (const_string "1")
5408        (const_string "*")))
5409    (set_attr "unit" "i387,*,*")
5410    (set_attr "athlon_decode" "*,double,direct")
5411    (set_attr "amdfam10_decode" "*,vector,double")
5412    (set_attr "fp_int_src" "true")])
5413
5414 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5415   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5416         (float:MODEF
5417           (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5418   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5419    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5420    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5421   "@
5422    fild%Z1\t%1
5423    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5424   [(set_attr "type" "fmov,sseicvt")
5425    (set_attr "prefix" "orig,maybe_vex")
5426    (set_attr "mode" "<MODEF:MODE>")
5427    (set (attr "prefix_rex")
5428      (if_then_else
5429        (and (eq_attr "prefix" "maybe_vex")
5430             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5431        (const_string "1")
5432        (const_string "*")))
5433    (set_attr "athlon_decode" "*,direct")
5434    (set_attr "amdfam10_decode" "*,double")
5435    (set_attr "fp_int_src" "true")])
5436
5437 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5438   [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5439         (float:MODEF
5440           (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5441    (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5442   "TARGET_SSE2 && TARGET_SSE_MATH
5443    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5444   "#"
5445   [(set_attr "type" "sseicvt")
5446    (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5447    (set_attr "athlon_decode" "double,direct,double")
5448    (set_attr "amdfam10_decode" "vector,double,double")
5449    (set_attr "fp_int_src" "true")])
5450
5451 (define_insn "*floatsi<mode>2_vector_sse"
5452   [(set (match_operand:MODEF 0 "register_operand" "=x")
5453         (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5454   "TARGET_SSE2 && TARGET_SSE_MATH
5455    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5456   "#"
5457   [(set_attr "type" "sseicvt")
5458    (set_attr "mode" "<MODE>")
5459    (set_attr "athlon_decode" "direct")
5460    (set_attr "amdfam10_decode" "double")
5461    (set_attr "fp_int_src" "true")])
5462
5463 (define_split
5464   [(set (match_operand:MODEF 0 "register_operand" "")
5465         (float:MODEF (match_operand:SI 1 "register_operand" "")))
5466    (clobber (match_operand:SI 2 "memory_operand" ""))]
5467   "TARGET_SSE2 && TARGET_SSE_MATH
5468    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5469    && reload_completed
5470    && (SSE_REG_P (operands[0])
5471        || (GET_CODE (operands[0]) == SUBREG
5472            && SSE_REG_P (operands[0])))"
5473   [(const_int 0)]
5474 {
5475   rtx op1 = operands[1];
5476
5477   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5478                                      <MODE>mode, 0);
5479   if (GET_CODE (op1) == SUBREG)
5480     op1 = SUBREG_REG (op1);
5481
5482   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5483     {
5484       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5485       emit_insn (gen_sse2_loadld (operands[4],
5486                                   CONST0_RTX (V4SImode), operands[1]));
5487     }
5488   /* We can ignore possible trapping value in the
5489      high part of SSE register for non-trapping math. */
5490   else if (SSE_REG_P (op1) && !flag_trapping_math)
5491     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5492   else
5493     {
5494       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5495       emit_move_insn (operands[2], operands[1]);
5496       emit_insn (gen_sse2_loadld (operands[4],
5497                                   CONST0_RTX (V4SImode), operands[2]));
5498     }
5499   emit_insn
5500     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5501   DONE;
5502 })
5503
5504 (define_split
5505   [(set (match_operand:MODEF 0 "register_operand" "")
5506         (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5507    (clobber (match_operand:SI 2 "memory_operand" ""))]
5508   "TARGET_SSE2 && TARGET_SSE_MATH
5509    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5510    && reload_completed
5511    && (SSE_REG_P (operands[0])
5512        || (GET_CODE (operands[0]) == SUBREG
5513            && SSE_REG_P (operands[0])))"
5514   [(const_int 0)]
5515 {
5516   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5517                                      <MODE>mode, 0);
5518   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5519
5520   emit_insn (gen_sse2_loadld (operands[4],
5521                               CONST0_RTX (V4SImode), operands[1]));
5522   emit_insn
5523     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5524   DONE;
5525 })
5526
5527 (define_split
5528   [(set (match_operand:MODEF 0 "register_operand" "")
5529         (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5530   "TARGET_SSE2 && TARGET_SSE_MATH
5531    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5532    && reload_completed
5533    && (SSE_REG_P (operands[0])
5534        || (GET_CODE (operands[0]) == SUBREG
5535            && SSE_REG_P (operands[0])))"
5536   [(const_int 0)]
5537 {
5538   rtx op1 = operands[1];
5539
5540   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5541                                      <MODE>mode, 0);
5542   if (GET_CODE (op1) == SUBREG)
5543     op1 = SUBREG_REG (op1);
5544
5545   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5546     {
5547       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5548       emit_insn (gen_sse2_loadld (operands[4],
5549                                   CONST0_RTX (V4SImode), operands[1]));
5550     }
5551   /* We can ignore possible trapping value in the
5552      high part of SSE register for non-trapping math. */
5553   else if (SSE_REG_P (op1) && !flag_trapping_math)
5554     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5555   else
5556     gcc_unreachable ();
5557   emit_insn
5558     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5559   DONE;
5560 })
5561
5562 (define_split
5563   [(set (match_operand:MODEF 0 "register_operand" "")
5564         (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5565   "TARGET_SSE2 && TARGET_SSE_MATH
5566    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5567    && reload_completed
5568    && (SSE_REG_P (operands[0])
5569        || (GET_CODE (operands[0]) == SUBREG
5570            && SSE_REG_P (operands[0])))"
5571   [(const_int 0)]
5572 {
5573   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5574                                      <MODE>mode, 0);
5575   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5576
5577   emit_insn (gen_sse2_loadld (operands[4],
5578                               CONST0_RTX (V4SImode), operands[1]));
5579   emit_insn
5580     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5581   DONE;
5582 })
5583
5584 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5585   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5586         (float:MODEF
5587           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5588   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5589   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5590    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5591   "#"
5592   [(set_attr "type" "sseicvt")
5593    (set_attr "mode" "<MODEF:MODE>")
5594    (set_attr "athlon_decode" "double,direct")
5595    (set_attr "amdfam10_decode" "vector,double")
5596    (set_attr "fp_int_src" "true")])
5597
5598 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5599   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5600         (float:MODEF
5601           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5602   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5603    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5604    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5605   "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5606   [(set_attr "type" "sseicvt")
5607    (set_attr "prefix" "maybe_vex")
5608    (set_attr "mode" "<MODEF:MODE>")
5609    (set (attr "prefix_rex")
5610      (if_then_else
5611        (and (eq_attr "prefix" "maybe_vex")
5612             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5613        (const_string "1")
5614        (const_string "*")))
5615    (set_attr "athlon_decode" "double,direct")
5616    (set_attr "amdfam10_decode" "vector,double")
5617    (set_attr "fp_int_src" "true")])
5618
5619 (define_split
5620   [(set (match_operand:MODEF 0 "register_operand" "")
5621         (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5622    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5623   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5624    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5625    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5626    && reload_completed
5627    && (SSE_REG_P (operands[0])
5628        || (GET_CODE (operands[0]) == SUBREG
5629            && SSE_REG_P (operands[0])))"
5630   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5631   "")
5632
5633 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5634   [(set (match_operand:MODEF 0 "register_operand" "=x")
5635         (float:MODEF
5636           (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5637   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5638    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5639    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5640   "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5641   [(set_attr "type" "sseicvt")
5642    (set_attr "prefix" "maybe_vex")
5643    (set_attr "mode" "<MODEF:MODE>")
5644    (set (attr "prefix_rex")
5645      (if_then_else
5646        (and (eq_attr "prefix" "maybe_vex")
5647             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5648        (const_string "1")
5649        (const_string "*")))
5650    (set_attr "athlon_decode" "direct")
5651    (set_attr "amdfam10_decode" "double")
5652    (set_attr "fp_int_src" "true")])
5653
5654 (define_split
5655   [(set (match_operand:MODEF 0 "register_operand" "")
5656         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5657    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5658   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5659    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5660    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5661    && reload_completed
5662    && (SSE_REG_P (operands[0])
5663        || (GET_CODE (operands[0]) == SUBREG
5664            && SSE_REG_P (operands[0])))"
5665   [(set (match_dup 2) (match_dup 1))
5666    (set (match_dup 0) (float:MODEF (match_dup 2)))]
5667   "")
5668
5669 (define_split
5670   [(set (match_operand:MODEF 0 "register_operand" "")
5671         (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5672    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5673   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5674    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5675    && reload_completed
5676    && (SSE_REG_P (operands[0])
5677        || (GET_CODE (operands[0]) == SUBREG
5678            && SSE_REG_P (operands[0])))"
5679   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5680   "")
5681
5682 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5683   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5684         (float:X87MODEF
5685           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5686   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5687   "TARGET_80387
5688    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5689   "@
5690    fild%Z1\t%1
5691    #"
5692   [(set_attr "type" "fmov,multi")
5693    (set_attr "mode" "<X87MODEF:MODE>")
5694    (set_attr "unit" "*,i387")
5695    (set_attr "fp_int_src" "true")])
5696
5697 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5698   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5699         (float:X87MODEF
5700           (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5701   "TARGET_80387
5702    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5703   "fild%Z1\t%1"
5704   [(set_attr "type" "fmov")
5705    (set_attr "mode" "<X87MODEF:MODE>")
5706    (set_attr "fp_int_src" "true")])
5707
5708 (define_split
5709   [(set (match_operand:X87MODEF 0 "register_operand" "")
5710         (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5711    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5712   "TARGET_80387
5713    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5714    && reload_completed
5715    && FP_REG_P (operands[0])"
5716   [(set (match_dup 2) (match_dup 1))
5717    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5718   "")
5719
5720 (define_split
5721   [(set (match_operand:X87MODEF 0 "register_operand" "")
5722         (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5723    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5724   "TARGET_80387
5725    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5726    && reload_completed
5727    && FP_REG_P (operands[0])"
5728   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5729   "")
5730
5731 ;; Avoid store forwarding (partial memory) stall penalty
5732 ;; by passing DImode value through XMM registers.  */
5733
5734 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5735   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5736         (float:X87MODEF
5737           (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5738    (clobber (match_scratch:V4SI 3 "=X,x"))
5739    (clobber (match_scratch:V4SI 4 "=X,x"))
5740    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5741   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5742    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5743    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5744   "#"
5745   [(set_attr "type" "multi")
5746    (set_attr "mode" "<X87MODEF:MODE>")
5747    (set_attr "unit" "i387")
5748    (set_attr "fp_int_src" "true")])
5749
5750 (define_split
5751   [(set (match_operand:X87MODEF 0 "register_operand" "")
5752         (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5753    (clobber (match_scratch:V4SI 3 ""))
5754    (clobber (match_scratch:V4SI 4 ""))
5755    (clobber (match_operand:DI 2 "memory_operand" ""))]
5756   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5757    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5758    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5759    && reload_completed
5760    && FP_REG_P (operands[0])"
5761   [(set (match_dup 2) (match_dup 3))
5762    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5763 {
5764   /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5765      Assemble the 64-bit DImode value in an xmm register.  */
5766   emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5767                               gen_rtx_SUBREG (SImode, operands[1], 0)));
5768   emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5769                               gen_rtx_SUBREG (SImode, operands[1], 4)));
5770   emit_insn (gen_sse2_punpckldq (operands[3], operands[3], operands[4]));
5771
5772   operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5773 })
5774
5775 (define_split
5776   [(set (match_operand:X87MODEF 0 "register_operand" "")
5777         (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5778    (clobber (match_scratch:V4SI 3 ""))
5779    (clobber (match_scratch:V4SI 4 ""))
5780    (clobber (match_operand:DI 2 "memory_operand" ""))]
5781   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5782    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5783    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5784    && reload_completed
5785    && FP_REG_P (operands[0])"
5786   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5787   "")
5788
5789 ;; Avoid store forwarding (partial memory) stall penalty by extending
5790 ;; SImode value to DImode through XMM register instead of pushing two
5791 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5792 ;; targets benefit from this optimization. Also note that fild
5793 ;; loads from memory only.
5794
5795 (define_insn "*floatunssi<mode>2_1"
5796   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5797         (unsigned_float:X87MODEF
5798           (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5799    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5800    (clobber (match_scratch:SI 3 "=X,x"))]
5801   "!TARGET_64BIT
5802    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5803    && TARGET_SSE"
5804   "#"
5805   [(set_attr "type" "multi")
5806    (set_attr "mode" "<MODE>")])
5807
5808 (define_split
5809   [(set (match_operand:X87MODEF 0 "register_operand" "")
5810         (unsigned_float:X87MODEF
5811           (match_operand:SI 1 "register_operand" "")))
5812    (clobber (match_operand:DI 2 "memory_operand" ""))
5813    (clobber (match_scratch:SI 3 ""))]
5814   "!TARGET_64BIT
5815    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5816    && TARGET_SSE
5817    && reload_completed"
5818   [(set (match_dup 2) (match_dup 1))
5819    (set (match_dup 0)
5820         (float:X87MODEF (match_dup 2)))]
5821   "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5822
5823 (define_split
5824   [(set (match_operand:X87MODEF 0 "register_operand" "")
5825         (unsigned_float:X87MODEF
5826           (match_operand:SI 1 "memory_operand" "")))
5827    (clobber (match_operand:DI 2 "memory_operand" ""))
5828    (clobber (match_scratch:SI 3 ""))]
5829   "!TARGET_64BIT
5830    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5831    && TARGET_SSE
5832    && reload_completed"
5833   [(set (match_dup 2) (match_dup 3))
5834    (set (match_dup 0)
5835         (float:X87MODEF (match_dup 2)))]
5836 {
5837   emit_move_insn (operands[3], operands[1]);
5838   operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5839 })
5840
5841 (define_expand "floatunssi<mode>2"
5842   [(parallel
5843      [(set (match_operand:X87MODEF 0 "register_operand" "")
5844            (unsigned_float:X87MODEF
5845              (match_operand:SI 1 "nonimmediate_operand" "")))
5846       (clobber (match_dup 2))
5847       (clobber (match_scratch:SI 3 ""))])]
5848   "!TARGET_64BIT
5849    && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5850         && TARGET_SSE)
5851        || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5852 {
5853   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5854     {
5855       ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5856       DONE;
5857     }
5858   else
5859     {
5860       enum ix86_stack_slot slot = (virtuals_instantiated
5861                                    ? SLOT_TEMP
5862                                    : SLOT_VIRTUAL);
5863       operands[2] = assign_386_stack_local (DImode, slot);
5864     }
5865 })
5866
5867 (define_expand "floatunsdisf2"
5868   [(use (match_operand:SF 0 "register_operand" ""))
5869    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5870   "TARGET_64BIT && TARGET_SSE_MATH"
5871   "x86_emit_floatuns (operands); DONE;")
5872
5873 (define_expand "floatunsdidf2"
5874   [(use (match_operand:DF 0 "register_operand" ""))
5875    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5876   "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5877    && TARGET_SSE2 && TARGET_SSE_MATH"
5878 {
5879   if (TARGET_64BIT)
5880     x86_emit_floatuns (operands);
5881   else
5882     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5883   DONE;
5884 })
5885 \f
5886 ;; Add instructions
5887
5888 (define_expand "add<mode>3"
5889   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5890         (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5891                     (match_operand:SDWIM 2 "<general_operand>" "")))]
5892   ""
5893   "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5894
5895 (define_insn_and_split "*add<dwi>3_doubleword"
5896   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5897         (plus:<DWI>
5898           (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5899           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5900    (clobber (reg:CC FLAGS_REG))]
5901   "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5902   "#"
5903   "reload_completed"
5904   [(parallel [(set (reg:CC FLAGS_REG)
5905                    (unspec:CC [(match_dup 1) (match_dup 2)]
5906                               UNSPEC_ADD_CARRY))
5907               (set (match_dup 0)
5908                    (plus:DWIH (match_dup 1) (match_dup 2)))])
5909    (parallel [(set (match_dup 3)
5910                    (plus:DWIH
5911                      (plus:DWIH
5912                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5913                        (match_dup 4))
5914                      (match_dup 5)))
5915               (clobber (reg:CC FLAGS_REG))])]
5916   "split_<dwi> (&operands[0], 3, &operands[0], &operands[3]);")
5917
5918 (define_insn "add<mode>3_carry"
5919   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
5920         (plus:SWI
5921           (plus:SWI (match_operand:SWI 3 "ix86_carry_flag_operator" "")
5922                     (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
5923           (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
5924    (clobber (reg:CC FLAGS_REG))]
5925   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5926   "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
5927   [(set_attr "type" "alu")
5928    (set_attr "use_carry" "1")
5929    (set_attr "pent_pair" "pu")
5930    (set_attr "mode" "<MODE>")])
5931
5932 (define_insn "*addsi3_carry_zext"
5933   [(set (match_operand:DI 0 "register_operand" "=r")
5934         (zero_extend:DI
5935           (plus:SI
5936             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5937                      (match_operand:SI 1 "nonimmediate_operand" "%0"))
5938           (match_operand:SI 2 "general_operand" "g"))))
5939    (clobber (reg:CC FLAGS_REG))]
5940   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5941   "adc{l}\t{%2, %k0|%k0, %2}"
5942   [(set_attr "type" "alu")
5943    (set_attr "use_carry" "1")
5944    (set_attr "pent_pair" "pu")
5945    (set_attr "mode" "SI")])
5946
5947 (define_insn "*add<mode>3_cc"
5948   [(set (reg:CC FLAGS_REG)
5949         (unspec:CC
5950           [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5951            (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5952           UNSPEC_ADD_CARRY))
5953    (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5954         (plus:SWI48 (match_dup 1) (match_dup 2)))]
5955   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5956   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5957   [(set_attr "type" "alu")
5958    (set_attr "mode" "<MODE>")])
5959
5960 (define_insn "addqi3_cc"
5961   [(set (reg:CC FLAGS_REG)
5962         (unspec:CC
5963           [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5964            (match_operand:QI 2 "general_operand" "qn,qm")]
5965           UNSPEC_ADD_CARRY))
5966    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5967         (plus:QI (match_dup 1) (match_dup 2)))]
5968   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5969   "add{b}\t{%2, %0|%0, %2}"
5970   [(set_attr "type" "alu")
5971    (set_attr "mode" "QI")])
5972
5973 (define_insn "*add<mode>3_cconly_overflow"
5974   [(set (reg:CCC FLAGS_REG)
5975         (compare:CCC
5976           (plus:SWI
5977             (match_operand:SWI 1 "nonimmediate_operand" "%0")
5978             (match_operand:SWI 2 "<general_operand>" "<r><i>m"))
5979           (match_dup 1)))
5980    (clobber (match_scratch:SWI 0 "=<r>"))]
5981   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5982   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5983   [(set_attr "type" "alu")
5984    (set_attr "mode" "<MODE>")])
5985
5986 (define_insn "*lea_1"
5987   [(set (match_operand:DWIH 0 "register_operand" "=r")
5988         (match_operand:DWIH 1 "no_seg_address_operand" "p"))]
5989   ""
5990   "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
5991   [(set_attr "type" "lea")
5992    (set_attr "mode" "<MODE>")])
5993
5994 (define_insn "*lea_2"
5995   [(set (match_operand:SI 0 "register_operand" "=r")
5996         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5997   "TARGET_64BIT"
5998   "lea{l}\t{%a1, %0|%0, %a1}"
5999   [(set_attr "type" "lea")
6000    (set_attr "mode" "SI")])
6001
6002 (define_insn "*lea_2_zext"
6003   [(set (match_operand:DI 0 "register_operand" "=r")
6004         (zero_extend:DI
6005           (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
6006   "TARGET_64BIT"
6007   "lea{l}\t{%a1, %k0|%k0, %a1}"
6008   [(set_attr "type" "lea")
6009    (set_attr "mode" "SI")])
6010
6011 (define_insn "*add<mode>_1"
6012   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
6013         (plus:SWI48
6014           (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
6015           (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,0,l<i>")))
6016    (clobber (reg:CC FLAGS_REG))]
6017   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6018 {
6019   switch (get_attr_type (insn))
6020     {
6021     case TYPE_LEA:
6022       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6023       return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
6024
6025     case TYPE_INCDEC:
6026       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6027       if (operands[2] == const1_rtx)
6028         return "inc{<imodesuffix>}\t%0";
6029       else
6030         {
6031           gcc_assert (operands[2] == constm1_rtx);
6032           return "dec{<imodesuffix>}\t%0";
6033         }
6034
6035     default:
6036       /* Use add as much as possible to replace lea for AGU optimization. */
6037       if (which_alternative == 2 && TARGET_OPT_AGU)
6038         return "add{<imodesuffix>}\t{%1, %0|%0, %1}";
6039         
6040       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6041
6042       /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6043          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6044       if (CONST_INT_P (operands[2])
6045           /* Avoid overflows.  */
6046           && (<MODE>mode != DImode
6047               || ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6048           && (INTVAL (operands[2]) == 128
6049               || (INTVAL (operands[2]) < 0
6050                   && INTVAL (operands[2]) != -128)))
6051         {
6052           operands[2] = GEN_INT (-INTVAL (operands[2]));
6053           return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6054         }
6055       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6056     }
6057 }
6058   [(set (attr "type")
6059      (cond [(and (eq_attr "alternative" "2") 
6060                  (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
6061               (const_string "lea")
6062             (eq_attr "alternative" "3")
6063               (const_string "lea")
6064             ; Current assemblers are broken and do not allow @GOTOFF in
6065             ; ought but a memory context.
6066             (match_operand:SWI48 2 "pic_symbolic_operand" "")
6067               (const_string "lea")
6068             (match_operand:SWI48 2 "incdec_operand" "")
6069               (const_string "incdec")
6070            ]
6071            (const_string "alu")))
6072    (set (attr "length_immediate")
6073       (if_then_else
6074         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6075         (const_string "1")
6076         (const_string "*")))
6077    (set_attr "mode" "<MODE>")])
6078
6079 ;; It may seem that nonimmediate operand is proper one for operand 1.
6080 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6081 ;; we take care in ix86_binary_operator_ok to not allow two memory
6082 ;; operands so proper swapping will be done in reload.  This allow
6083 ;; patterns constructed from addsi_1 to match.
6084
6085 (define_insn "*addsi_1_zext"
6086   [(set (match_operand:DI 0 "register_operand" "=r,r")
6087         (zero_extend:DI
6088           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6089                    (match_operand:SI 2 "general_operand" "g,li"))))
6090    (clobber (reg:CC FLAGS_REG))]
6091   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6092 {
6093   switch (get_attr_type (insn))
6094     {
6095     case TYPE_LEA:
6096       operands[2] = XEXP (SET_SRC (XVECEXP (PATTERN (insn), 0, 0)), 0);
6097       return "lea{l}\t{%a2, %k0|%k0, %a2}";
6098
6099     case TYPE_INCDEC:
6100       if (operands[2] == const1_rtx)
6101         return "inc{l}\t%k0";
6102       else
6103         {
6104           gcc_assert (operands[2] == constm1_rtx);
6105           return "dec{l}\t%k0";
6106         }
6107
6108     default:
6109       /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6110          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6111       if (CONST_INT_P (operands[2])
6112           && (INTVAL (operands[2]) == 128
6113               || (INTVAL (operands[2]) < 0
6114                   && INTVAL (operands[2]) != -128)))
6115         {
6116           operands[2] = GEN_INT (-INTVAL (operands[2]));
6117           return "sub{l}\t{%2, %k0|%k0, %2}";
6118         }
6119       return "add{l}\t{%2, %k0|%k0, %2}";
6120     }
6121 }
6122   [(set (attr "type")
6123      (cond [(eq_attr "alternative" "1")
6124               (const_string "lea")
6125             ; Current assemblers are broken and do not allow @GOTOFF in
6126             ; ought but a memory context.
6127             (match_operand:SI 2 "pic_symbolic_operand" "")
6128               (const_string "lea")
6129             (match_operand:SI 2 "incdec_operand" "")
6130               (const_string "incdec")
6131            ]
6132            (const_string "alu")))
6133    (set (attr "length_immediate")
6134       (if_then_else
6135         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6136         (const_string "1")
6137         (const_string "*")))
6138    (set_attr "mode" "SI")])
6139
6140 (define_insn "*addhi_1"
6141   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6142         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6143                  (match_operand:HI 2 "general_operand" "rn,rm")))
6144    (clobber (reg:CC FLAGS_REG))]
6145   "TARGET_PARTIAL_REG_STALL
6146    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6147 {
6148   switch (get_attr_type (insn))
6149     {
6150     case TYPE_INCDEC:
6151       if (operands[2] == const1_rtx)
6152         return "inc{w}\t%0";
6153       else
6154         {
6155           gcc_assert (operands[2] == constm1_rtx);
6156           return "dec{w}\t%0";
6157         }
6158
6159     default:
6160       /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
6161          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6162       if (CONST_INT_P (operands[2])
6163           && (INTVAL (operands[2]) == 128
6164               || (INTVAL (operands[2]) < 0
6165                   && INTVAL (operands[2]) != -128)))
6166         {
6167           operands[2] = GEN_INT (-INTVAL (operands[2]));
6168           return "sub{w}\t{%2, %0|%0, %2}";
6169         }
6170       return "add{w}\t{%2, %0|%0, %2}";
6171     }
6172 }
6173   [(set (attr "type")
6174      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6175         (const_string "incdec")
6176         (const_string "alu")))
6177    (set (attr "length_immediate")
6178       (if_then_else
6179         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6180         (const_string "1")
6181         (const_string "*")))
6182    (set_attr "mode" "HI")])
6183
6184 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6185 ;; type optimizations enabled by define-splits.  This is not important
6186 ;; for PII, and in fact harmful because of partial register stalls.
6187
6188 (define_insn "*addhi_1_lea"
6189   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6190         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6191                  (match_operand:HI 2 "general_operand" "rn,rm,ln")))
6192    (clobber (reg:CC FLAGS_REG))]
6193   "!TARGET_PARTIAL_REG_STALL
6194    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6195 {
6196   switch (get_attr_type (insn))
6197     {
6198     case TYPE_LEA:
6199       return "#";
6200     case TYPE_INCDEC:
6201       if (operands[2] == const1_rtx)
6202         return "inc{w}\t%0";
6203       else
6204         {
6205           gcc_assert (operands[2] == constm1_rtx);
6206           return "dec{w}\t%0";
6207         }
6208
6209     default:
6210       /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
6211          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6212       if (CONST_INT_P (operands[2])
6213           && (INTVAL (operands[2]) == 128
6214               || (INTVAL (operands[2]) < 0
6215                   && INTVAL (operands[2]) != -128)))
6216         {
6217           operands[2] = GEN_INT (-INTVAL (operands[2]));
6218           return "sub{w}\t{%2, %0|%0, %2}";
6219         }
6220       return "add{w}\t{%2, %0|%0, %2}";
6221     }
6222 }
6223   [(set (attr "type")
6224      (if_then_else (eq_attr "alternative" "2")
6225         (const_string "lea")
6226         (if_then_else (match_operand:HI 2 "incdec_operand" "")
6227            (const_string "incdec")
6228            (const_string "alu"))))
6229    (set (attr "length_immediate")
6230       (if_then_else
6231         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6232         (const_string "1")
6233         (const_string "*")))
6234    (set_attr "mode" "HI,HI,SI")])
6235
6236 (define_insn "*addqi_1"
6237   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6238         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6239                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6240    (clobber (reg:CC FLAGS_REG))]
6241   "TARGET_PARTIAL_REG_STALL
6242    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6243 {
6244   int widen = (which_alternative == 2);
6245   switch (get_attr_type (insn))
6246     {
6247     case TYPE_INCDEC:
6248       if (operands[2] == const1_rtx)
6249         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6250       else
6251         {
6252           gcc_assert (operands[2] == constm1_rtx);
6253           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6254         }
6255
6256     default:
6257       /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'.
6258          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6259       if (CONST_INT_P (operands[2])
6260           && (INTVAL (operands[2]) == 128
6261               || (INTVAL (operands[2]) < 0
6262                   && INTVAL (operands[2]) != -128)))
6263         {
6264           operands[2] = GEN_INT (-INTVAL (operands[2]));
6265           if (widen)
6266             return "sub{l}\t{%2, %k0|%k0, %2}";
6267           else
6268             return "sub{b}\t{%2, %0|%0, %2}";
6269         }
6270       if (widen)
6271         return "add{l}\t{%k2, %k0|%k0, %k2}";
6272       else
6273         return "add{b}\t{%2, %0|%0, %2}";
6274     }
6275 }
6276   [(set (attr "type")
6277      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6278         (const_string "incdec")
6279         (const_string "alu")))
6280    (set (attr "length_immediate")
6281       (if_then_else
6282         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6283         (const_string "1")
6284         (const_string "*")))
6285    (set_attr "mode" "QI,QI,SI")])
6286
6287 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6288 (define_insn "*addqi_1_lea"
6289   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6290         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6291                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6292    (clobber (reg:CC FLAGS_REG))]
6293   "!TARGET_PARTIAL_REG_STALL
6294    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6295 {
6296   int widen = (which_alternative == 2);
6297   switch (get_attr_type (insn))
6298     {
6299     case TYPE_LEA:
6300       return "#";
6301     case TYPE_INCDEC:
6302       if (operands[2] == const1_rtx)
6303         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6304       else
6305         {
6306           gcc_assert (operands[2] == constm1_rtx);
6307           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6308         }
6309
6310     default:
6311       /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'.
6312          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6313       if (CONST_INT_P (operands[2])
6314           && (INTVAL (operands[2]) == 128
6315               || (INTVAL (operands[2]) < 0
6316                   && INTVAL (operands[2]) != -128)))
6317         {
6318           operands[2] = GEN_INT (-INTVAL (operands[2]));
6319           if (widen)
6320             return "sub{l}\t{%2, %k0|%k0, %2}";
6321           else
6322             return "sub{b}\t{%2, %0|%0, %2}";
6323         }
6324       if (widen)
6325         return "add{l}\t{%k2, %k0|%k0, %k2}";
6326       else
6327         return "add{b}\t{%2, %0|%0, %2}";
6328     }
6329 }
6330   [(set (attr "type")
6331      (if_then_else (eq_attr "alternative" "3")
6332         (const_string "lea")
6333         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6334            (const_string "incdec")
6335            (const_string "alu"))))
6336    (set (attr "length_immediate")
6337       (if_then_else
6338         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6339         (const_string "1")
6340         (const_string "*")))
6341    (set_attr "mode" "QI,QI,SI,SI")])
6342
6343 (define_insn "*addqi_1_slp"
6344   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6345         (plus:QI (match_dup 0)
6346                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6347    (clobber (reg:CC FLAGS_REG))]
6348   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6349    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6350 {
6351   switch (get_attr_type (insn))
6352     {
6353     case TYPE_INCDEC:
6354       if (operands[1] == const1_rtx)
6355         return "inc{b}\t%0";
6356       else
6357         {
6358           gcc_assert (operands[1] == constm1_rtx);
6359           return "dec{b}\t%0";
6360         }
6361
6362     default:
6363       /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'.  */
6364       if (CONST_INT_P (operands[1])
6365           && INTVAL (operands[1]) < 0)
6366         {
6367           operands[1] = GEN_INT (-INTVAL (operands[1]));
6368           return "sub{b}\t{%1, %0|%0, %1}";
6369         }
6370       return "add{b}\t{%1, %0|%0, %1}";
6371     }
6372 }
6373   [(set (attr "type")
6374      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6375         (const_string "incdec")
6376         (const_string "alu1")))
6377    (set (attr "memory")
6378      (if_then_else (match_operand 1 "memory_operand" "")
6379         (const_string "load")
6380         (const_string "none")))
6381    (set_attr "mode" "QI")])
6382
6383 (define_insn "*add<mode>_2"
6384   [(set (reg FLAGS_REG)
6385         (compare
6386           (plus:SWI48
6387             (match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
6388             (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>"))
6389           (const_int 0)))
6390    (set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm")
6391         (plus:SWI48 (match_dup 1) (match_dup 2)))]
6392   "ix86_match_ccmode (insn, CCGOCmode)
6393    && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
6394    /* Current assemblers are broken and do not allow @GOTOFF in
6395       ought but a memory context.  */
6396    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6397 {
6398   switch (get_attr_type (insn))
6399     {
6400     case TYPE_INCDEC:
6401       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6402       if (operands[2] == const1_rtx)
6403         return "inc{<imodesuffix>}\t%0";
6404       else
6405         {
6406           gcc_assert (operands[2] == constm1_rtx);
6407           return "dec{<imodesuffix>}\t%0";
6408         }
6409
6410     default:
6411       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6412       /* ???? In DImode, we ought to handle there the 32bit case too
6413          - do we need new constraint?  */
6414       /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6415          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6416       if (CONST_INT_P (operands[2])
6417           /* Avoid overflows.  */
6418           && (<MODE>mode != DImode
6419               || ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6420           && (INTVAL (operands[2]) == 128
6421               || (INTVAL (operands[2]) < 0
6422                   && INTVAL (operands[2]) != -128)))
6423         {
6424           operands[2] = GEN_INT (-INTVAL (operands[2]));
6425           return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6426         }
6427       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6428     }
6429 }
6430   [(set (attr "type")
6431      (if_then_else (match_operand:SWI48 2 "incdec_operand" "")
6432         (const_string "incdec")
6433         (const_string "alu")))
6434    (set (attr "length_immediate")
6435       (if_then_else
6436         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6437         (const_string "1")
6438         (const_string "*")))
6439    (set_attr "mode" "<MODE>")])
6440
6441 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6442 (define_insn "*addsi_2_zext"
6443   [(set (reg FLAGS_REG)
6444         (compare
6445           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6446                    (match_operand:SI 2 "general_operand" "g"))
6447           (const_int 0)))
6448    (set (match_operand:DI 0 "register_operand" "=r")
6449         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6450   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6451    && ix86_binary_operator_ok (PLUS, SImode, operands)
6452    /* Current assemblers are broken and do not allow @GOTOFF in
6453       ought but a memory context.  */
6454    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6455 {
6456   switch (get_attr_type (insn))
6457     {
6458     case TYPE_INCDEC:
6459       if (operands[2] == const1_rtx)
6460         return "inc{l}\t%k0";
6461       else
6462         {
6463           gcc_assert (operands[2] == constm1_rtx);
6464           return "dec{l}\t%k0";
6465         }
6466
6467     default:
6468       /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6469          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6470       if (CONST_INT_P (operands[2])
6471           && (INTVAL (operands[2]) == 128
6472               || (INTVAL (operands[2]) < 0
6473                   && INTVAL (operands[2]) != -128)))
6474         {
6475           operands[2] = GEN_INT (-INTVAL (operands[2]));
6476           return "sub{l}\t{%2, %k0|%k0, %2}";
6477         }
6478       return "add{l}\t{%2, %k0|%k0, %2}";
6479     }
6480 }
6481   [(set (attr "type")
6482      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6483         (const_string "incdec")
6484         (const_string "alu")))
6485    (set (attr "length_immediate")
6486       (if_then_else
6487         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6488         (const_string "1")
6489         (const_string "*")))
6490    (set_attr "mode" "SI")])
6491
6492 (define_insn "*addhi_2"
6493   [(set (reg FLAGS_REG)
6494         (compare
6495           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6496                    (match_operand:HI 2 "general_operand" "rmn,rn"))
6497           (const_int 0)))
6498    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6499         (plus:HI (match_dup 1) (match_dup 2)))]
6500   "ix86_match_ccmode (insn, CCGOCmode)
6501    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6502 {
6503   switch (get_attr_type (insn))
6504     {
6505     case TYPE_INCDEC:
6506       if (operands[2] == const1_rtx)
6507         return "inc{w}\t%0";
6508       else
6509         {
6510           gcc_assert (operands[2] == constm1_rtx);
6511           return "dec{w}\t%0";
6512         }
6513
6514     default:
6515       /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
6516          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6517       if (CONST_INT_P (operands[2])
6518           && (INTVAL (operands[2]) == 128
6519               || (INTVAL (operands[2]) < 0
6520                   && INTVAL (operands[2]) != -128)))
6521         {
6522           operands[2] = GEN_INT (-INTVAL (operands[2]));
6523           return "sub{w}\t{%2, %0|%0, %2}";
6524         }
6525       return "add{w}\t{%2, %0|%0, %2}";
6526     }
6527 }
6528   [(set (attr "type")
6529      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6530         (const_string "incdec")
6531         (const_string "alu")))
6532    (set (attr "length_immediate")
6533       (if_then_else
6534         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6535         (const_string "1")
6536         (const_string "*")))
6537    (set_attr "mode" "HI")])
6538
6539 (define_insn "*addqi_2"
6540   [(set (reg FLAGS_REG)
6541         (compare
6542           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6543                    (match_operand:QI 2 "general_operand" "qmn,qn"))
6544           (const_int 0)))
6545    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6546         (plus:QI (match_dup 1) (match_dup 2)))]
6547   "ix86_match_ccmode (insn, CCGOCmode)
6548    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6549 {
6550   switch (get_attr_type (insn))
6551     {
6552     case TYPE_INCDEC:
6553       if (operands[2] == const1_rtx)
6554         return "inc{b}\t%0";
6555       else
6556         {
6557           gcc_assert (operands[2] == constm1_rtx
6558                       || (CONST_INT_P (operands[2])
6559                           && INTVAL (operands[2]) == 255));
6560           return "dec{b}\t%0";
6561         }
6562
6563     default:
6564       /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'.  */
6565       if (CONST_INT_P (operands[2])
6566           && INTVAL (operands[2]) < 0)
6567         {
6568           operands[2] = GEN_INT (-INTVAL (operands[2]));
6569           return "sub{b}\t{%2, %0|%0, %2}";
6570         }
6571       return "add{b}\t{%2, %0|%0, %2}";
6572     }
6573 }
6574   [(set (attr "type")
6575      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6576         (const_string "incdec")
6577         (const_string "alu")))
6578    (set_attr "mode" "QI")])
6579
6580 (define_insn "*add<mode>_3"
6581   [(set (reg FLAGS_REG)
6582         (compare
6583           (neg:SWI48 (match_operand:SWI48 2 "<general_operand>" "<g>"))
6584           (match_operand:SWI48 1 "nonimmediate_operand" "%0")))
6585    (clobber (match_scratch:SWI48 0 "=r"))]
6586   "ix86_match_ccmode (insn, CCZmode)
6587    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6588    /* Current assemblers are broken and do not allow @GOTOFF in
6589       ought but a memory context.  */
6590    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6591 {
6592   switch (get_attr_type (insn))
6593     {
6594     case TYPE_INCDEC:
6595       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6596       if (operands[2] == const1_rtx)
6597         return "inc{<imodesuffix>}\t%0";
6598       else
6599         {
6600           gcc_assert (operands[2] == constm1_rtx);
6601           return "dec{<imodesuffix>}\t%0";
6602         }
6603
6604     default:
6605       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6606       /* ???? In DImode, we ought to handle there the 32bit case too
6607          - do we need new constraint?  */
6608       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6609          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6610       if (CONST_INT_P (operands[2])
6611           /* Avoid overflows.  */
6612           && (<MODE>mode != DImode
6613               || ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6614           && (INTVAL (operands[2]) == 128
6615               || (INTVAL (operands[2]) < 0
6616                   && INTVAL (operands[2]) != -128)))
6617         {
6618           operands[2] = GEN_INT (-INTVAL (operands[2]));
6619           return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6620         }
6621       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6622     }
6623 }
6624   [(set (attr "type")
6625      (if_then_else (match_operand:SWI48 2 "incdec_operand" "")
6626         (const_string "incdec")
6627         (const_string "alu")))
6628    (set (attr "length_immediate")
6629       (if_then_else
6630         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6631         (const_string "1")
6632         (const_string "*")))
6633    (set_attr "mode" "<MODE>")])
6634
6635 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6636 (define_insn "*addsi_3_zext"
6637   [(set (reg FLAGS_REG)
6638         (compare
6639           (neg:SI (match_operand:SI 2 "general_operand" "g"))
6640           (match_operand:SI 1 "nonimmediate_operand" "%0")))
6641    (set (match_operand:DI 0 "register_operand" "=r")
6642         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6643   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6644    && ix86_binary_operator_ok (PLUS, SImode, operands)
6645    /* Current assemblers are broken and do not allow @GOTOFF in
6646       ought but a memory context.  */
6647    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6648 {
6649   switch (get_attr_type (insn))
6650     {
6651     case TYPE_INCDEC:
6652       if (operands[2] == const1_rtx)
6653         return "inc{l}\t%k0";
6654       else
6655         {
6656           gcc_assert (operands[2] == constm1_rtx);
6657           return "dec{l}\t%k0";
6658         }
6659
6660     default:
6661       /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6662          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6663       if (CONST_INT_P (operands[2])
6664           && (INTVAL (operands[2]) == 128
6665               || (INTVAL (operands[2]) < 0
6666                   && INTVAL (operands[2]) != -128)))
6667         {
6668           operands[2] = GEN_INT (-INTVAL (operands[2]));
6669           return "sub{l}\t{%2, %k0|%k0, %2}";
6670         }
6671       return "add{l}\t{%2, %k0|%k0, %2}";
6672     }
6673 }
6674   [(set (attr "type")
6675      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6676         (const_string "incdec")
6677         (const_string "alu")))
6678    (set (attr "length_immediate")
6679       (if_then_else
6680         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6681         (const_string "1")
6682         (const_string "*")))
6683    (set_attr "mode" "SI")])
6684
6685 (define_insn "*addhi_3"
6686   [(set (reg FLAGS_REG)
6687         (compare
6688           (neg:HI (match_operand:HI 2 "general_operand" "rmn"))
6689           (match_operand:HI 1 "nonimmediate_operand" "%0")))
6690    (clobber (match_scratch:HI 0 "=r"))]
6691   "ix86_match_ccmode (insn, CCZmode)
6692    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6693 {
6694   switch (get_attr_type (insn))
6695     {
6696     case TYPE_INCDEC:
6697       if (operands[2] == const1_rtx)
6698         return "inc{w}\t%0";
6699       else
6700         {
6701           gcc_assert (operands[2] == constm1_rtx);
6702           return "dec{w}\t%0";
6703         }
6704
6705     default:
6706       /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
6707          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6708       if (CONST_INT_P (operands[2])
6709           && (INTVAL (operands[2]) == 128
6710               || (INTVAL (operands[2]) < 0
6711                   && INTVAL (operands[2]) != -128)))
6712         {
6713           operands[2] = GEN_INT (-INTVAL (operands[2]));
6714           return "sub{w}\t{%2, %0|%0, %2}";
6715         }
6716       return "add{w}\t{%2, %0|%0, %2}";
6717     }
6718 }
6719   [(set (attr "type")
6720      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6721         (const_string "incdec")
6722         (const_string "alu")))
6723    (set (attr "length_immediate")
6724       (if_then_else
6725         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6726         (const_string "1")
6727         (const_string "*")))
6728    (set_attr "mode" "HI")])
6729
6730 (define_insn "*addqi_3"
6731   [(set (reg FLAGS_REG)
6732         (compare
6733           (neg:QI (match_operand:QI 2 "general_operand" "qmn"))
6734           (match_operand:QI 1 "nonimmediate_operand" "%0")))
6735    (clobber (match_scratch:QI 0 "=q"))]
6736   "ix86_match_ccmode (insn, CCZmode)
6737    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6738 {
6739   switch (get_attr_type (insn))
6740     {
6741     case TYPE_INCDEC:
6742       if (operands[2] == const1_rtx)
6743         return "inc{b}\t%0";
6744       else
6745         {
6746           gcc_assert (operands[2] == constm1_rtx
6747                       || (CONST_INT_P (operands[2])
6748                           && INTVAL (operands[2]) == 255));
6749           return "dec{b}\t%0";
6750         }
6751
6752     default:
6753       /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'.  */
6754       if (CONST_INT_P (operands[2])
6755           && INTVAL (operands[2]) < 0)
6756         {
6757           operands[2] = GEN_INT (-INTVAL (operands[2]));
6758           return "sub{b}\t{%2, %0|%0, %2}";
6759         }
6760       return "add{b}\t{%2, %0|%0, %2}";
6761     }
6762 }
6763   [(set (attr "type")
6764      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6765         (const_string "incdec")
6766         (const_string "alu")))
6767    (set_attr "mode" "QI")])
6768
6769 ; For comparisons against 1, -1 and 128, we may generate better code
6770 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6771 ; is matched then.  We can't accept general immediate, because for
6772 ; case of overflows,  the result is messed up.
6773 ; This pattern also don't hold of 0x8000000000000000, since the value
6774 ; overflows when negated.
6775 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6776 ; only for comparisons not depending on it.
6777
6778 (define_insn "*adddi_4"
6779   [(set (reg FLAGS_REG)
6780         (compare
6781           (match_operand:DI 1 "nonimmediate_operand" "0")
6782           (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6783    (clobber (match_scratch:DI 0 "=rm"))]
6784   "TARGET_64BIT
6785    && ix86_match_ccmode (insn, CCGCmode)"
6786 {
6787   switch (get_attr_type (insn))
6788     {
6789     case TYPE_INCDEC:
6790       if (operands[2] == constm1_rtx)
6791         return "inc{q}\t%0";
6792       else
6793         {
6794           gcc_assert (operands[2] == const1_rtx);
6795           return "dec{q}\t%0";
6796         }
6797
6798     default:
6799       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6800       /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6801          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6802       if ((INTVAL (operands[2]) == -128
6803            || (INTVAL (operands[2]) > 0
6804                && INTVAL (operands[2]) != 128))
6805           /* Avoid overflows.  */
6806           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6807         return "sub{q}\t{%2, %0|%0, %2}";
6808       operands[2] = GEN_INT (-INTVAL (operands[2]));
6809       return "add{q}\t{%2, %0|%0, %2}";
6810     }
6811 }
6812   [(set (attr "type")
6813      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6814         (const_string "incdec")
6815         (const_string "alu")))
6816    (set (attr "length_immediate")
6817       (if_then_else
6818         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6819         (const_string "1")
6820         (const_string "*")))
6821    (set_attr "mode" "DI")])
6822
6823 ; For comparisons against 1, -1 and 128, we may generate better code
6824 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6825 ; is matched then.  We can't accept general immediate, because for
6826 ; case of overflows,  the result is messed up.
6827 ; This pattern also don't hold of 0x80000000, since the value overflows
6828 ; when negated.
6829 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6830 ; only for comparisons not depending on it.
6831
6832 (define_insn "*addsi_4"
6833   [(set (reg FLAGS_REG)
6834         (compare
6835           (match_operand:SI 1 "nonimmediate_operand" "0")
6836           (match_operand:SI 2 "const_int_operand" "n")))
6837    (clobber (match_scratch:SI 0 "=rm"))]
6838   "ix86_match_ccmode (insn, CCGCmode)
6839    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
6840 {
6841   switch (get_attr_type (insn))
6842     {
6843     case TYPE_INCDEC:
6844       if (operands[2] == constm1_rtx)
6845         return "inc{l}\t%0";
6846       else
6847         {
6848           gcc_assert (operands[2] == const1_rtx);
6849           return "dec{l}\t%0";
6850         }
6851
6852     default:
6853       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6854       /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6855          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6856       if ((INTVAL (operands[2]) == -128
6857            || (INTVAL (operands[2]) > 0
6858                && INTVAL (operands[2]) != 128)))
6859         return "sub{l}\t{%2, %0|%0, %2}";
6860       operands[2] = GEN_INT (-INTVAL (operands[2]));
6861       return "add{l}\t{%2, %0|%0, %2}";
6862     }
6863 }
6864   [(set (attr "type")
6865      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6866         (const_string "incdec")
6867         (const_string "alu")))
6868    (set (attr "length_immediate")
6869       (if_then_else
6870         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6871         (const_string "1")
6872         (const_string "*")))
6873    (set_attr "mode" "SI")])
6874
6875 ; See comments above addsi_4 for details.
6876
6877 (define_insn "*addhi_4"
6878   [(set (reg FLAGS_REG)
6879         (compare
6880           (match_operand:HI 1 "nonimmediate_operand" "0")
6881           (match_operand:HI 2 "const_int_operand" "n")))
6882    (clobber (match_scratch:HI 0 "=rm"))]
6883   "ix86_match_ccmode (insn, CCGCmode)
6884    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6885 {
6886   switch (get_attr_type (insn))
6887     {
6888     case TYPE_INCDEC:
6889       if (operands[2] == constm1_rtx)
6890         return "inc{w}\t%0";
6891       else
6892         {
6893           gcc_assert (operands[2] == const1_rtx);
6894           return "dec{w}\t%0";
6895         }
6896
6897     default:
6898       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6899       /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
6900          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6901       if ((INTVAL (operands[2]) == -128
6902            || (INTVAL (operands[2]) > 0
6903                && INTVAL (operands[2]) != 128)))
6904         return "sub{w}\t{%2, %0|%0, %2}";
6905       operands[2] = GEN_INT (-INTVAL (operands[2]));
6906       return "add{w}\t{%2, %0|%0, %2}";
6907     }
6908 }
6909   [(set (attr "type")
6910      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6911         (const_string "incdec")
6912         (const_string "alu")))
6913    (set (attr "length_immediate")
6914       (if_then_else
6915         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6916         (const_string "1")
6917         (const_string "*")))
6918    (set_attr "mode" "HI")])
6919
6920 ; See comments above addsi_4 for details.
6921
6922 (define_insn "*addqi_4"
6923   [(set (reg FLAGS_REG)
6924         (compare
6925           (match_operand:QI 1 "nonimmediate_operand" "0")
6926           (match_operand:QI 2 "const_int_operand" "n")))
6927    (clobber (match_scratch:QI 0 "=qm"))]
6928   "ix86_match_ccmode (insn, CCGCmode)
6929    && (INTVAL (operands[2]) & 0xff) != 0x80"
6930 {
6931   switch (get_attr_type (insn))
6932     {
6933     case TYPE_INCDEC:
6934       if (operands[2] == constm1_rtx
6935           || (CONST_INT_P (operands[2])
6936               && INTVAL (operands[2]) == 255))
6937         return "inc{b}\t%0";
6938       else
6939         {
6940           gcc_assert (operands[2] == const1_rtx);
6941           return "dec{b}\t%0";
6942         }
6943
6944     default:
6945       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6946       if (INTVAL (operands[2]) < 0)
6947         {
6948           operands[2] = GEN_INT (-INTVAL (operands[2]));
6949           return "add{b}\t{%2, %0|%0, %2}";
6950         }
6951       return "sub{b}\t{%2, %0|%0, %2}";
6952     }
6953 }
6954   [(set (attr "type")
6955      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6956         (const_string "incdec")
6957         (const_string "alu")))
6958    (set_attr "mode" "QI")])
6959
6960 (define_insn "*add<mode>_5"
6961   [(set (reg FLAGS_REG)
6962         (compare
6963           (plus:SWI48
6964             (match_operand:SWI48 1 "nonimmediate_operand" "%0")
6965             (match_operand:SWI48 2 "<general_operand>" "<g>"))
6966           (const_int 0)))
6967    (clobber (match_scratch:SWI48 0 "=r"))]
6968   "ix86_match_ccmode (insn, CCGOCmode)
6969    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6970    /* Current assemblers are broken and do not allow @GOTOFF in
6971       ought but a memory context.  */
6972    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6973 {
6974   switch (get_attr_type (insn))
6975     {
6976     case TYPE_INCDEC:
6977       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6978       if (operands[2] == const1_rtx)
6979         return "inc{<imodesuffix>}\t%0";
6980       else
6981         {
6982           gcc_assert (operands[2] == constm1_rtx);
6983           return "dec{<imodesuffix>}\t%0";
6984         }
6985
6986     default:
6987       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6988       /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6989          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6990       if (CONST_INT_P (operands[2])
6991           /* Avoid overflows.  */
6992           && (<MODE>mode != DImode
6993               || ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6994           && (INTVAL (operands[2]) == 128
6995               || (INTVAL (operands[2]) < 0
6996                   && INTVAL (operands[2]) != -128)))
6997         {
6998           operands[2] = GEN_INT (-INTVAL (operands[2]));
6999           return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
7000         }
7001       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
7002     }
7003 }
7004   [(set (attr "type")
7005      (if_then_else (match_operand:SWI48 2 "incdec_operand" "")
7006         (const_string "incdec")
7007         (const_string "alu")))
7008    (set (attr "length_immediate")
7009       (if_then_else
7010         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7011         (const_string "1")
7012         (const_string "*")))
7013    (set_attr "mode" "<MODE>")])
7014
7015 (define_insn "*addhi_5"
7016   [(set (reg FLAGS_REG)
7017         (compare
7018           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
7019                    (match_operand:HI 2 "general_operand" "rmn"))
7020           (const_int 0)))
7021    (clobber (match_scratch:HI 0 "=r"))]
7022   "ix86_match_ccmode (insn, CCGOCmode)
7023    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7024 {
7025   switch (get_attr_type (insn))
7026     {
7027     case TYPE_INCDEC:
7028       if (operands[2] == const1_rtx)
7029         return "inc{w}\t%0";
7030       else
7031         {
7032           gcc_assert (operands[2] == constm1_rtx);
7033           return "dec{w}\t%0";
7034         }
7035
7036     default:
7037       /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
7038          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
7039       if (CONST_INT_P (operands[2])
7040           && (INTVAL (operands[2]) == 128
7041               || (INTVAL (operands[2]) < 0
7042                   && INTVAL (operands[2]) != -128)))
7043         {
7044           operands[2] = GEN_INT (-INTVAL (operands[2]));
7045           return "sub{w}\t{%2, %0|%0, %2}";
7046         }
7047       return "add{w}\t{%2, %0|%0, %2}";
7048     }
7049 }
7050   [(set (attr "type")
7051      (if_then_else (match_operand:HI 2 "incdec_operand" "")
7052         (const_string "incdec")
7053         (const_string "alu")))
7054    (set (attr "length_immediate")
7055       (if_then_else
7056         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7057         (const_string "1")
7058         (const_string "*")))
7059    (set_attr "mode" "HI")])
7060
7061 (define_insn "*addqi_5"
7062   [(set (reg FLAGS_REG)
7063         (compare
7064           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7065                    (match_operand:QI 2 "general_operand" "qmn"))
7066           (const_int 0)))
7067    (clobber (match_scratch:QI 0 "=q"))]
7068   "ix86_match_ccmode (insn, CCGOCmode)
7069    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7070 {
7071   switch (get_attr_type (insn))
7072     {
7073     case TYPE_INCDEC:
7074       if (operands[2] == const1_rtx)
7075         return "inc{b}\t%0";
7076       else
7077         {
7078           gcc_assert (operands[2] == constm1_rtx
7079                       || (CONST_INT_P (operands[2])
7080                           && INTVAL (operands[2]) == 255));
7081           return "dec{b}\t%0";
7082         }
7083
7084     default:
7085       /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'.  */
7086       if (CONST_INT_P (operands[2])
7087           && INTVAL (operands[2]) < 0)
7088         {
7089           operands[2] = GEN_INT (-INTVAL (operands[2]));
7090           return "sub{b}\t{%2, %0|%0, %2}";
7091         }
7092       return "add{b}\t{%2, %0|%0, %2}";
7093     }
7094 }
7095   [(set (attr "type")
7096      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7097         (const_string "incdec")
7098         (const_string "alu")))
7099    (set_attr "mode" "QI")])
7100
7101 (define_insn "*addqi_ext_1_rex64"
7102   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7103                          (const_int 8)
7104                          (const_int 8))
7105         (plus:SI
7106           (zero_extract:SI
7107             (match_operand 1 "ext_register_operand" "0")
7108             (const_int 8)
7109             (const_int 8))
7110           (match_operand:QI 2 "nonmemory_operand" "Qn")))
7111    (clobber (reg:CC FLAGS_REG))]
7112   "TARGET_64BIT"
7113 {
7114   switch (get_attr_type (insn))
7115     {
7116     case TYPE_INCDEC:
7117       if (operands[2] == const1_rtx)
7118         return "inc{b}\t%h0";
7119       else
7120         {
7121           gcc_assert (operands[2] == constm1_rtx
7122                       || (CONST_INT_P (operands[2])
7123                           && INTVAL (operands[2]) == 255));
7124           return "dec{b}\t%h0";
7125         }
7126
7127     default:
7128       return "add{b}\t{%2, %h0|%h0, %2}";
7129     }
7130 }
7131   [(set (attr "type")
7132      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7133         (const_string "incdec")
7134         (const_string "alu")))
7135    (set_attr "modrm" "1")
7136    (set_attr "mode" "QI")])
7137
7138 (define_insn "addqi_ext_1"
7139   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7140                          (const_int 8)
7141                          (const_int 8))
7142         (plus:SI
7143           (zero_extract:SI
7144             (match_operand 1 "ext_register_operand" "0")
7145             (const_int 8)
7146             (const_int 8))
7147           (match_operand:QI 2 "general_operand" "Qmn")))
7148    (clobber (reg:CC FLAGS_REG))]
7149   "!TARGET_64BIT"
7150 {
7151   switch (get_attr_type (insn))
7152     {
7153     case TYPE_INCDEC:
7154       if (operands[2] == const1_rtx)
7155         return "inc{b}\t%h0";
7156       else
7157         {
7158           gcc_assert (operands[2] == constm1_rtx
7159                       || (CONST_INT_P (operands[2])
7160                           && INTVAL (operands[2]) == 255));
7161           return "dec{b}\t%h0";
7162         }
7163
7164     default:
7165       return "add{b}\t{%2, %h0|%h0, %2}";
7166     }
7167 }
7168   [(set (attr "type")
7169      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7170         (const_string "incdec")
7171         (const_string "alu")))
7172    (set_attr "modrm" "1")
7173    (set_attr "mode" "QI")])
7174
7175 (define_insn "*addqi_ext_2"
7176   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7177                          (const_int 8)
7178                          (const_int 8))
7179         (plus:SI
7180           (zero_extract:SI
7181             (match_operand 1 "ext_register_operand" "%0")
7182             (const_int 8)
7183             (const_int 8))
7184           (zero_extract:SI
7185             (match_operand 2 "ext_register_operand" "Q")
7186             (const_int 8)
7187             (const_int 8))))
7188    (clobber (reg:CC FLAGS_REG))]
7189   ""
7190   "add{b}\t{%h2, %h0|%h0, %h2}"
7191   [(set_attr "type" "alu")
7192    (set_attr "mode" "QI")])
7193
7194 ;; The lea patterns for non-Pmodes needs to be matched by
7195 ;; several insns converted to real lea by splitters.
7196
7197 (define_insn_and_split "*lea_general_1"
7198   [(set (match_operand 0 "register_operand" "=r")
7199         (plus (plus (match_operand 1 "index_register_operand" "l")
7200                     (match_operand 2 "register_operand" "r"))
7201               (match_operand 3 "immediate_operand" "i")))]
7202   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
7203     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
7204    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7205    && GET_MODE (operands[0]) == GET_MODE (operands[1])
7206    && GET_MODE (operands[0]) == GET_MODE (operands[2])
7207    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
7208        || GET_MODE (operands[3]) == VOIDmode)"
7209   "#"
7210   "&& reload_completed"
7211   [(const_int 0)]
7212 {
7213   rtx pat;
7214   operands[0] = gen_lowpart (SImode, operands[0]);
7215   operands[1] = gen_lowpart (Pmode, operands[1]);
7216   operands[2] = gen_lowpart (Pmode, operands[2]);
7217   operands[3] = gen_lowpart (Pmode, operands[3]);
7218   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
7219                       operands[3]);
7220   if (Pmode != SImode)
7221     pat = gen_rtx_SUBREG (SImode, pat, 0);
7222   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7223   DONE;
7224 }
7225   [(set_attr "type" "lea")
7226    (set_attr "mode" "SI")])
7227
7228 (define_insn_and_split "*lea_general_1_zext"
7229   [(set (match_operand:DI 0 "register_operand" "=r")
7230         (zero_extend:DI
7231           (plus:SI (plus:SI
7232                      (match_operand:SI 1 "index_register_operand" "l")
7233                      (match_operand:SI 2 "register_operand" "r"))
7234                    (match_operand:SI 3 "immediate_operand" "i"))))]
7235   "TARGET_64BIT"
7236   "#"
7237   "&& reload_completed"
7238   [(set (match_dup 0)
7239         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
7240                                                      (match_dup 2))
7241                                             (match_dup 3)) 0)))]
7242 {
7243   operands[1] = gen_lowpart (Pmode, operands[1]);
7244   operands[2] = gen_lowpart (Pmode, operands[2]);
7245   operands[3] = gen_lowpart (Pmode, operands[3]);
7246 }
7247   [(set_attr "type" "lea")
7248    (set_attr "mode" "SI")])
7249
7250 (define_insn_and_split "*lea_general_2"
7251   [(set (match_operand 0 "register_operand" "=r")
7252         (plus (mult (match_operand 1 "index_register_operand" "l")
7253                     (match_operand 2 "const248_operand" "i"))
7254               (match_operand 3 "nonmemory_operand" "ri")))]
7255   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
7256     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
7257    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7258    && GET_MODE (operands[0]) == GET_MODE (operands[1])
7259    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
7260        || GET_MODE (operands[3]) == VOIDmode)"
7261   "#"
7262   "&& reload_completed"
7263   [(const_int 0)]
7264 {
7265   rtx pat;
7266   operands[0] = gen_lowpart (SImode, operands[0]);
7267   operands[1] = gen_lowpart (Pmode, operands[1]);
7268   operands[3] = gen_lowpart (Pmode, operands[3]);
7269   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
7270                       operands[3]);
7271   if (Pmode != SImode)
7272     pat = gen_rtx_SUBREG (SImode, pat, 0);
7273   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7274   DONE;
7275 }
7276   [(set_attr "type" "lea")
7277    (set_attr "mode" "SI")])
7278
7279 (define_insn_and_split "*lea_general_2_zext"
7280   [(set (match_operand:DI 0 "register_operand" "=r")
7281         (zero_extend:DI
7282           (plus:SI (mult:SI
7283                      (match_operand:SI 1 "index_register_operand" "l")
7284                      (match_operand:SI 2 "const248_operand" "n"))
7285                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
7286   "TARGET_64BIT"
7287   "#"
7288   "&& reload_completed"
7289   [(set (match_dup 0)
7290         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
7291                                                      (match_dup 2))
7292                                             (match_dup 3)) 0)))]
7293 {
7294   operands[1] = gen_lowpart (Pmode, operands[1]);
7295   operands[3] = gen_lowpart (Pmode, operands[3]);
7296 }
7297   [(set_attr "type" "lea")
7298    (set_attr "mode" "SI")])
7299
7300 (define_insn_and_split "*lea_general_3"
7301   [(set (match_operand 0 "register_operand" "=r")
7302         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
7303                           (match_operand 2 "const248_operand" "i"))
7304                     (match_operand 3 "register_operand" "r"))
7305               (match_operand 4 "immediate_operand" "i")))]
7306   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
7307     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
7308    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7309    && GET_MODE (operands[0]) == GET_MODE (operands[1])
7310    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
7311   "#"
7312   "&& reload_completed"
7313   [(const_int 0)]
7314 {
7315   rtx pat;
7316   operands[0] = gen_lowpart (SImode, operands[0]);
7317   operands[1] = gen_lowpart (Pmode, operands[1]);
7318   operands[3] = gen_lowpart (Pmode, operands[3]);
7319   operands[4] = gen_lowpart (Pmode, operands[4]);
7320   pat = gen_rtx_PLUS (Pmode,
7321                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
7322                                                          operands[2]),
7323                                     operands[3]),
7324                       operands[4]);
7325   if (Pmode != SImode)
7326     pat = gen_rtx_SUBREG (SImode, pat, 0);
7327   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7328   DONE;
7329 }
7330   [(set_attr "type" "lea")
7331    (set_attr "mode" "SI")])
7332
7333 (define_insn_and_split "*lea_general_3_zext"
7334   [(set (match_operand:DI 0 "register_operand" "=r")
7335         (zero_extend:DI
7336           (plus:SI (plus:SI
7337                      (mult:SI
7338                        (match_operand:SI 1 "index_register_operand" "l")
7339                        (match_operand:SI 2 "const248_operand" "n"))
7340                      (match_operand:SI 3 "register_operand" "r"))
7341                    (match_operand:SI 4 "immediate_operand" "i"))))]
7342   "TARGET_64BIT"
7343   "#"
7344   "&& reload_completed"
7345   [(set (match_dup 0)
7346         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
7347                                                               (match_dup 2))
7348                                                      (match_dup 3))
7349                                             (match_dup 4)) 0)))]
7350 {
7351   operands[1] = gen_lowpart (Pmode, operands[1]);
7352   operands[3] = gen_lowpart (Pmode, operands[3]);
7353   operands[4] = gen_lowpart (Pmode, operands[4]);
7354 }
7355   [(set_attr "type" "lea")
7356    (set_attr "mode" "SI")])
7357
7358 ;; Convert lea to the lea pattern to avoid flags dependency.
7359 (define_split
7360   [(set (match_operand:DI 0 "register_operand" "")
7361         (plus:DI (match_operand:DI 1 "register_operand" "")
7362                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
7363    (clobber (reg:CC FLAGS_REG))]
7364   "TARGET_64BIT && reload_completed 
7365    && ix86_lea_for_add_ok (PLUS, insn, operands)"
7366   [(set (match_dup 0)
7367         (plus:DI (match_dup 1)
7368                  (match_dup 2)))]
7369   "")
7370
7371 ;; Convert lea to the lea pattern to avoid flags dependency.
7372 (define_split
7373   [(set (match_operand 0 "register_operand" "")
7374         (plus (match_operand 1 "register_operand" "")
7375               (match_operand 2 "nonmemory_operand" "")))
7376    (clobber (reg:CC FLAGS_REG))]
7377   "reload_completed && ix86_lea_for_add_ok (PLUS, insn, operands)" 
7378   [(const_int 0)]
7379 {
7380   rtx pat;
7381   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
7382      may confuse gen_lowpart.  */
7383   if (GET_MODE (operands[0]) != Pmode)
7384     {
7385       operands[1] = gen_lowpart (Pmode, operands[1]);
7386       operands[2] = gen_lowpart (Pmode, operands[2]);
7387     }
7388   operands[0] = gen_lowpart (SImode, operands[0]);
7389   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
7390   if (Pmode != SImode)
7391     pat = gen_rtx_SUBREG (SImode, pat, 0);
7392   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7393   DONE;
7394 })
7395
7396 ;; Convert lea to the lea pattern to avoid flags dependency.
7397 (define_split
7398   [(set (match_operand:DI 0 "register_operand" "")
7399         (zero_extend:DI
7400           (plus:SI (match_operand:SI 1 "register_operand" "")
7401                    (match_operand:SI 2 "nonmemory_operand" ""))))
7402    (clobber (reg:CC FLAGS_REG))]
7403   "TARGET_64BIT && reload_completed
7404    && true_regnum (operands[0]) != true_regnum (operands[1])"
7405   [(set (match_dup 0)
7406         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
7407 {
7408   operands[1] = gen_lowpart (Pmode, operands[1]);
7409   operands[2] = gen_lowpart (Pmode, operands[2]);
7410 })
7411 \f
7412 ;; Subtract instructions
7413
7414 (define_expand "sub<mode>3"
7415   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
7416         (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
7417                      (match_operand:SDWIM 2 "<general_operand>" "")))]
7418   ""
7419   "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
7420
7421 (define_insn_and_split "*sub<dwi>3_doubleword"
7422   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
7423         (minus:<DWI>
7424           (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
7425           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
7426    (clobber (reg:CC FLAGS_REG))]
7427   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7428   "#"
7429   "reload_completed"
7430   [(parallel [(set (reg:CC FLAGS_REG)
7431                    (compare:CC (match_dup 1) (match_dup 2)))
7432               (set (match_dup 0)
7433                    (minus:DWIH (match_dup 1) (match_dup 2)))])
7434    (parallel [(set (match_dup 3)
7435                    (minus:DWIH
7436                      (match_dup 4)
7437                      (plus:DWIH
7438                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7439                        (match_dup 5))))
7440               (clobber (reg:CC FLAGS_REG))])]
7441   "split_<dwi> (&operands[0], 3, &operands[0], &operands[3]);")
7442
7443 (define_insn "sub<mode>3_carry"
7444   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7445           (minus:SWI
7446             (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7447             (plus:SWI
7448               (match_operand:SWI 3 "ix86_carry_flag_operator" "")
7449               (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
7450    (clobber (reg:CC FLAGS_REG))]
7451   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7452   "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
7453   [(set_attr "type" "alu")
7454    (set_attr "use_carry" "1")
7455    (set_attr "pent_pair" "pu")
7456    (set_attr "mode" "<MODE>")])
7457
7458 (define_insn "*subsi3_carry_zext"
7459   [(set (match_operand:DI 0 "register_operand" "=r")
7460           (zero_extend:DI
7461             (minus:SI (match_operand:SI 1 "register_operand" "0")
7462               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
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
7471 (define_insn "*sub<mode>3_cconly_overflow"
7472   [(set (reg:CCC FLAGS_REG)
7473         (compare:CCC
7474           (minus:SWI
7475             (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
7476             (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
7477           (match_dup 0)))]
7478   ""
7479   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
7480   [(set_attr "type" "icmp")
7481    (set_attr "mode" "<MODE>")])
7482
7483 (define_insn "*sub<mode>_1"
7484   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7485         (minus:SWI
7486           (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7487           (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
7488    (clobber (reg:CC FLAGS_REG))]
7489   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7490   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7491   [(set_attr "type" "alu")
7492    (set_attr "mode" "<MODE>")])
7493
7494 (define_insn "*subsi_1_zext"
7495   [(set (match_operand:DI 0 "register_operand" "=r")
7496         (zero_extend:DI
7497           (minus:SI (match_operand:SI 1 "register_operand" "0")
7498                     (match_operand:SI 2 "general_operand" "g"))))
7499    (clobber (reg:CC FLAGS_REG))]
7500   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7501   "sub{l}\t{%2, %k0|%k0, %2}"
7502   [(set_attr "type" "alu")
7503    (set_attr "mode" "SI")])
7504
7505 (define_insn "*subqi_1_slp"
7506   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7507         (minus:QI (match_dup 0)
7508                   (match_operand:QI 1 "general_operand" "qn,qm")))
7509    (clobber (reg:CC FLAGS_REG))]
7510   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7511    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7512   "sub{b}\t{%1, %0|%0, %1}"
7513   [(set_attr "type" "alu1")
7514    (set_attr "mode" "QI")])
7515
7516 (define_insn "*sub<mode>_2"
7517   [(set (reg FLAGS_REG)
7518         (compare
7519           (minus:SWI
7520             (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7521             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
7522           (const_int 0)))
7523    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7524         (minus:SWI (match_dup 1) (match_dup 2)))]
7525   "ix86_match_ccmode (insn, CCGOCmode)
7526    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7527   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7528   [(set_attr "type" "alu")
7529    (set_attr "mode" "<MODE>")])
7530
7531 (define_insn "*subsi_2_zext"
7532   [(set (reg FLAGS_REG)
7533         (compare
7534           (minus:SI (match_operand:SI 1 "register_operand" "0")
7535                     (match_operand:SI 2 "general_operand" "g"))
7536           (const_int 0)))
7537    (set (match_operand:DI 0 "register_operand" "=r")
7538         (zero_extend:DI
7539           (minus:SI (match_dup 1)
7540                     (match_dup 2))))]
7541   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7542    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7543   "sub{l}\t{%2, %k0|%k0, %2}"
7544   [(set_attr "type" "alu")
7545    (set_attr "mode" "SI")])
7546
7547 (define_insn "*sub<mode>_3"
7548   [(set (reg FLAGS_REG)
7549         (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7550                  (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
7551    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7552         (minus:SWI (match_dup 1) (match_dup 2)))]
7553   "ix86_match_ccmode (insn, CCmode)
7554    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7555   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7556   [(set_attr "type" "alu")
7557    (set_attr "mode" "<MODE>")])
7558
7559 (define_insn "*subsi_3_zext"
7560   [(set (reg FLAGS_REG)
7561         (compare (match_operand:SI 1 "register_operand" "0")
7562                  (match_operand:SI 2 "general_operand" "g")))
7563    (set (match_operand:DI 0 "register_operand" "=r")
7564         (zero_extend:DI
7565           (minus:SI (match_dup 1)
7566                     (match_dup 2))))]
7567   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7568    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7569   "sub{l}\t{%2, %1|%1, %2}"
7570   [(set_attr "type" "alu")
7571    (set_attr "mode" "SI")])
7572
7573
7574 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
7575   [(set (reg:CCC FLAGS_REG)
7576         (compare:CCC
7577             (plusminus:SWI
7578                 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
7579                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
7580             (match_dup 1)))
7581    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7582         (plusminus:SWI (match_dup 1) (match_dup 2)))]
7583   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
7584   "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
7585   [(set_attr "type" "alu")
7586    (set_attr "mode" "<MODE>")])
7587
7588 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
7589   [(set (reg:CCC FLAGS_REG)
7590         (compare:CCC
7591           (plusminus:SI
7592             (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
7593             (match_operand:SI 2 "general_operand" "g"))
7594           (match_dup 1)))
7595    (set (match_operand:DI 0 "register_operand" "=r")
7596         (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
7597   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
7598   "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
7599   [(set_attr "type" "alu")
7600    (set_attr "mode" "SI")])
7601
7602 ;; The patterns that match these are at the end of this file.
7603
7604 (define_expand "<plusminus_insn>xf3"
7605   [(set (match_operand:XF 0 "register_operand" "")
7606         (plusminus:XF
7607           (match_operand:XF 1 "register_operand" "")
7608           (match_operand:XF 2 "register_operand" "")))]
7609   "TARGET_80387"
7610   "")
7611
7612 (define_expand "<plusminus_insn><mode>3"
7613   [(set (match_operand:MODEF 0 "register_operand" "")
7614         (plusminus:MODEF
7615           (match_operand:MODEF 1 "register_operand" "")
7616           (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7617   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7618     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7619   "")
7620 \f
7621 ;; Multiply instructions
7622
7623 (define_expand "mul<mode>3"
7624   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7625                    (mult:SWIM248
7626                      (match_operand:SWIM248 1 "register_operand" "")
7627                      (match_operand:SWIM248 2 "<general_operand>" "")))
7628               (clobber (reg:CC FLAGS_REG))])]
7629   ""
7630   "")
7631
7632 (define_expand "mulqi3"
7633   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7634                    (mult:QI
7635                      (match_operand:QI 1 "register_operand" "")
7636                      (match_operand:QI 2 "nonimmediate_operand" "")))
7637               (clobber (reg:CC FLAGS_REG))])]
7638   "TARGET_QIMODE_MATH"
7639   "")
7640
7641 ;; On AMDFAM10
7642 ;; IMUL reg32/64, reg32/64, imm8        Direct
7643 ;; IMUL reg32/64, mem32/64, imm8        VectorPath
7644 ;; IMUL reg32/64, reg32/64, imm32       Direct
7645 ;; IMUL reg32/64, mem32/64, imm32       VectorPath
7646 ;; IMUL reg32/64, reg32/64              Direct
7647 ;; IMUL reg32/64, mem32/64              Direct
7648
7649 (define_insn "*mul<mode>3_1"
7650   [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
7651         (mult:SWI48
7652           (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
7653           (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
7654    (clobber (reg:CC FLAGS_REG))]
7655   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7656   "@
7657    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7658    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7659    imul{<imodesuffix>}\t{%2, %0|%0, %2}"
7660   [(set_attr "type" "imul")
7661    (set_attr "prefix_0f" "0,0,1")
7662    (set (attr "athlon_decode")
7663         (cond [(eq_attr "cpu" "athlon")
7664                   (const_string "vector")
7665                (eq_attr "alternative" "1")
7666                   (const_string "vector")
7667                (and (eq_attr "alternative" "2")
7668                     (match_operand 1 "memory_operand" ""))
7669                   (const_string "vector")]
7670               (const_string "direct")))
7671    (set (attr "amdfam10_decode")
7672         (cond [(and (eq_attr "alternative" "0,1")
7673                     (match_operand 1 "memory_operand" ""))
7674                   (const_string "vector")]
7675               (const_string "direct")))
7676    (set_attr "mode" "<MODE>")])
7677
7678 (define_insn "*mulsi3_1_zext"
7679   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7680         (zero_extend:DI
7681           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7682                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
7683    (clobber (reg:CC FLAGS_REG))]
7684   "TARGET_64BIT
7685    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7686   "@
7687    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7688    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7689    imul{l}\t{%2, %k0|%k0, %2}"
7690   [(set_attr "type" "imul")
7691    (set_attr "prefix_0f" "0,0,1")
7692    (set (attr "athlon_decode")
7693         (cond [(eq_attr "cpu" "athlon")
7694                   (const_string "vector")
7695                (eq_attr "alternative" "1")
7696                   (const_string "vector")
7697                (and (eq_attr "alternative" "2")
7698                     (match_operand 1 "memory_operand" ""))
7699                   (const_string "vector")]
7700               (const_string "direct")))
7701    (set (attr "amdfam10_decode")
7702         (cond [(and (eq_attr "alternative" "0,1")
7703                     (match_operand 1 "memory_operand" ""))
7704                   (const_string "vector")]
7705               (const_string "direct")))
7706    (set_attr "mode" "SI")])
7707
7708 ;; On AMDFAM10
7709 ;; IMUL reg16, reg16, imm8      VectorPath
7710 ;; IMUL reg16, mem16, imm8      VectorPath
7711 ;; IMUL reg16, reg16, imm16     VectorPath
7712 ;; IMUL reg16, mem16, imm16     VectorPath
7713 ;; IMUL reg16, reg16            Direct
7714 ;; IMUL reg16, mem16            Direct
7715
7716 (define_insn "*mulhi3_1"
7717   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7718         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7719                  (match_operand:HI 2 "general_operand" "K,n,mr")))
7720    (clobber (reg:CC FLAGS_REG))]
7721   "TARGET_HIMODE_MATH
7722    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7723   "@
7724    imul{w}\t{%2, %1, %0|%0, %1, %2}
7725    imul{w}\t{%2, %1, %0|%0, %1, %2}
7726    imul{w}\t{%2, %0|%0, %2}"
7727   [(set_attr "type" "imul")
7728    (set_attr "prefix_0f" "0,0,1")
7729    (set (attr "athlon_decode")
7730         (cond [(eq_attr "cpu" "athlon")
7731                   (const_string "vector")
7732                (eq_attr "alternative" "1,2")
7733                   (const_string "vector")]
7734               (const_string "direct")))
7735    (set (attr "amdfam10_decode")
7736         (cond [(eq_attr "alternative" "0,1")
7737                   (const_string "vector")]
7738               (const_string "direct")))
7739    (set_attr "mode" "HI")])
7740
7741 ;;On AMDFAM10
7742 ;; MUL reg8     Direct
7743 ;; MUL mem8     Direct
7744
7745 (define_insn "*mulqi3_1"
7746   [(set (match_operand:QI 0 "register_operand" "=a")
7747         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7748                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7749    (clobber (reg:CC FLAGS_REG))]
7750   "TARGET_QIMODE_MATH
7751    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7752   "mul{b}\t%2"
7753   [(set_attr "type" "imul")
7754    (set_attr "length_immediate" "0")
7755    (set (attr "athlon_decode")
7756      (if_then_else (eq_attr "cpu" "athlon")
7757         (const_string "vector")
7758         (const_string "direct")))
7759    (set_attr "amdfam10_decode" "direct")
7760    (set_attr "mode" "QI")])
7761
7762 (define_expand "<u>mul<mode><dwi>3"
7763   [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
7764                    (mult:<DWI>
7765                      (any_extend:<DWI>
7766                        (match_operand:DWIH 1 "nonimmediate_operand" ""))
7767                      (any_extend:<DWI>
7768                        (match_operand:DWIH 2 "register_operand" ""))))
7769               (clobber (reg:CC FLAGS_REG))])]
7770   ""
7771   "")
7772
7773 (define_expand "<u>mulqihi3"
7774   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7775                    (mult:HI
7776                      (any_extend:HI
7777                        (match_operand:QI 1 "nonimmediate_operand" ""))
7778                      (any_extend:HI
7779                        (match_operand:QI 2 "register_operand" ""))))
7780               (clobber (reg:CC FLAGS_REG))])]
7781   "TARGET_QIMODE_MATH"
7782   "")
7783
7784 (define_insn "*<u>mul<mode><dwi>3_1"
7785   [(set (match_operand:<DWI> 0 "register_operand" "=A")
7786         (mult:<DWI>
7787           (any_extend:<DWI>
7788             (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
7789           (any_extend:<DWI>
7790             (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7791    (clobber (reg:CC FLAGS_REG))]
7792   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7793   "<sgnprefix>mul{<imodesuffix>}\t%2"
7794   [(set_attr "type" "imul")
7795    (set_attr "length_immediate" "0")
7796    (set (attr "athlon_decode")
7797      (if_then_else (eq_attr "cpu" "athlon")
7798         (const_string "vector")
7799         (const_string "double")))
7800    (set_attr "amdfam10_decode" "double")
7801    (set_attr "mode" "<MODE>")])
7802
7803 (define_insn "*<u>mulqihi3_1"
7804   [(set (match_operand:HI 0 "register_operand" "=a")
7805         (mult:HI
7806           (any_extend:HI
7807             (match_operand:QI 1 "nonimmediate_operand" "%0"))
7808           (any_extend:HI
7809             (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7810    (clobber (reg:CC FLAGS_REG))]
7811   "TARGET_QIMODE_MATH
7812    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7813   "<sgnprefix>mul{b}\t%2"
7814   [(set_attr "type" "imul")
7815    (set_attr "length_immediate" "0")
7816    (set (attr "athlon_decode")
7817      (if_then_else (eq_attr "cpu" "athlon")
7818         (const_string "vector")
7819         (const_string "direct")))
7820    (set_attr "amdfam10_decode" "direct")
7821    (set_attr "mode" "QI")])
7822
7823 (define_expand "<s>mul<mode>3_highpart"
7824   [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
7825                    (truncate:SWI48
7826                      (lshiftrt:<DWI>
7827                        (mult:<DWI>
7828                          (any_extend:<DWI>
7829                            (match_operand:SWI48 1 "nonimmediate_operand" ""))
7830                          (any_extend:<DWI>
7831                            (match_operand:SWI48 2 "register_operand" "")))
7832                        (match_dup 4))))
7833               (clobber (match_scratch:SWI48 3 ""))
7834               (clobber (reg:CC FLAGS_REG))])]
7835   ""
7836   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7837
7838 (define_insn "*<s>muldi3_highpart_1"
7839   [(set (match_operand:DI 0 "register_operand" "=d")
7840         (truncate:DI
7841           (lshiftrt:TI
7842             (mult:TI
7843               (any_extend:TI
7844                 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7845               (any_extend:TI
7846                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7847             (const_int 64))))
7848    (clobber (match_scratch:DI 3 "=1"))
7849    (clobber (reg:CC FLAGS_REG))]
7850   "TARGET_64BIT
7851    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7852   "<sgnprefix>mul{q}\t%2"
7853   [(set_attr "type" "imul")
7854    (set_attr "length_immediate" "0")
7855    (set (attr "athlon_decode")
7856      (if_then_else (eq_attr "cpu" "athlon")
7857         (const_string "vector")
7858         (const_string "double")))
7859    (set_attr "amdfam10_decode" "double")
7860    (set_attr "mode" "DI")])
7861
7862 (define_insn "*<s>mulsi3_highpart_1"
7863   [(set (match_operand:SI 0 "register_operand" "=d")
7864         (truncate:SI
7865           (lshiftrt:DI
7866             (mult:DI
7867               (any_extend:DI
7868                 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7869               (any_extend:DI
7870                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7871             (const_int 32))))
7872    (clobber (match_scratch:SI 3 "=1"))
7873    (clobber (reg:CC FLAGS_REG))]
7874   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7875   "<sgnprefix>mul{l}\t%2"
7876   [(set_attr "type" "imul")
7877    (set_attr "length_immediate" "0")
7878    (set (attr "athlon_decode")
7879      (if_then_else (eq_attr "cpu" "athlon")
7880         (const_string "vector")
7881         (const_string "double")))
7882    (set_attr "amdfam10_decode" "double")
7883    (set_attr "mode" "SI")])
7884
7885 (define_insn "*<s>mulsi3_highpart_zext"
7886   [(set (match_operand:DI 0 "register_operand" "=d")
7887         (zero_extend:DI (truncate:SI
7888           (lshiftrt:DI
7889             (mult:DI (any_extend:DI
7890                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7891                      (any_extend:DI
7892                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7893             (const_int 32)))))
7894    (clobber (match_scratch:SI 3 "=1"))
7895    (clobber (reg:CC FLAGS_REG))]
7896   "TARGET_64BIT
7897    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7898   "<sgnprefix>mul{l}\t%2"
7899   [(set_attr "type" "imul")
7900    (set_attr "length_immediate" "0")
7901    (set (attr "athlon_decode")
7902      (if_then_else (eq_attr "cpu" "athlon")
7903         (const_string "vector")
7904         (const_string "double")))
7905    (set_attr "amdfam10_decode" "double")
7906    (set_attr "mode" "SI")])
7907
7908 ;; The patterns that match these are at the end of this file.
7909
7910 (define_expand "mulxf3"
7911   [(set (match_operand:XF 0 "register_operand" "")
7912         (mult:XF (match_operand:XF 1 "register_operand" "")
7913                  (match_operand:XF 2 "register_operand" "")))]
7914   "TARGET_80387"
7915   "")
7916
7917 (define_expand "mul<mode>3"
7918   [(set (match_operand:MODEF 0 "register_operand" "")
7919         (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
7920                     (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7921   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7922     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7923   "")
7924 \f
7925 ;; Divide instructions
7926
7927 (define_insn "<u>divqi3"
7928   [(set (match_operand:QI 0 "register_operand" "=a")
7929         (any_div:QI
7930           (match_operand:HI 1 "register_operand" "0")
7931           (match_operand:QI 2 "nonimmediate_operand" "qm")))
7932    (clobber (reg:CC FLAGS_REG))]
7933   "TARGET_QIMODE_MATH"
7934   "<sgnprefix>div{b}\t%2"
7935   [(set_attr "type" "idiv")
7936    (set_attr "mode" "QI")])
7937
7938 ;; The patterns that match these are at the end of this file.
7939
7940 (define_expand "divxf3"
7941   [(set (match_operand:XF 0 "register_operand" "")
7942         (div:XF (match_operand:XF 1 "register_operand" "")
7943                 (match_operand:XF 2 "register_operand" "")))]
7944   "TARGET_80387"
7945   "")
7946
7947 (define_expand "divdf3"
7948   [(set (match_operand:DF 0 "register_operand" "")
7949         (div:DF (match_operand:DF 1 "register_operand" "")
7950                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7951    "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7952     || (TARGET_SSE2 && TARGET_SSE_MATH)"
7953    "")
7954
7955 (define_expand "divsf3"
7956   [(set (match_operand:SF 0 "register_operand" "")
7957         (div:SF (match_operand:SF 1 "register_operand" "")
7958                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7959   "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7960     || TARGET_SSE_MATH"
7961 {
7962   if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
7963       && flag_finite_math_only && !flag_trapping_math
7964       && flag_unsafe_math_optimizations)
7965     {
7966       ix86_emit_swdivsf (operands[0], operands[1],
7967                          operands[2], SFmode);
7968       DONE;
7969     }
7970 })
7971 \f
7972 ;; Divmod instructions.
7973
7974 (define_expand "divmod<mode>4"
7975   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7976                    (div:SWIM248
7977                      (match_operand:SWIM248 1 "register_operand" "")
7978                      (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7979               (set (match_operand:SWIM248 3 "register_operand" "")
7980                    (mod:SWIM248 (match_dup 1) (match_dup 2)))
7981               (clobber (reg:CC FLAGS_REG))])]
7982   ""
7983   "")
7984
7985 (define_insn_and_split "*divmod<mode>4"
7986   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7987         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7988                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7989    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7990         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7991    (clobber (reg:CC FLAGS_REG))]
7992   ""
7993   "#"
7994   "&& reload_completed"
7995   [(parallel [(set (match_dup 1)
7996                    (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7997               (clobber (reg:CC FLAGS_REG))])
7998    (parallel [(set (match_dup 0)
7999                    (div:SWIM248 (match_dup 2) (match_dup 3)))
8000               (set (match_dup 1)
8001                    (mod:SWIM248 (match_dup 2) (match_dup 3)))
8002               (use (match_dup 1))
8003               (clobber (reg:CC FLAGS_REG))])]
8004 {
8005   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - 1);
8006
8007   if (<MODE>mode != HImode
8008       && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
8009     operands[4] = operands[2];
8010   else
8011     {
8012       /* Avoid use of cltd in favor of a mov+shift.  */
8013       emit_move_insn (operands[1], operands[2]);
8014       operands[4] = operands[1];
8015     }
8016 }
8017   [(set_attr "type" "multi")
8018    (set_attr "mode" "<MODE>")])
8019
8020 (define_insn "*divmod<mode>4_noext"
8021   [(set (match_operand:SWIM248 0 "register_operand" "=a")
8022         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8023                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8024    (set (match_operand:SWIM248 1 "register_operand" "=d")
8025         (mod:SWIM248 (match_dup 2) (match_dup 3)))
8026    (use (match_operand:SWIM248 4 "register_operand" "1"))
8027    (clobber (reg:CC FLAGS_REG))]
8028   ""
8029   "idiv{<imodesuffix>}\t%3"
8030   [(set_attr "type" "idiv")
8031    (set_attr "mode" "<MODE>")])
8032
8033 (define_expand "udivmod<mode>4"
8034   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
8035                    (udiv:SWIM248
8036                      (match_operand:SWIM248 1 "register_operand" "")
8037                      (match_operand:SWIM248 2 "nonimmediate_operand" "")))
8038               (set (match_operand:SWIM248 3 "register_operand" "")
8039                    (umod:SWIM248 (match_dup 1) (match_dup 2)))
8040               (clobber (reg:CC FLAGS_REG))])]
8041   ""
8042   "")
8043
8044 (define_insn_and_split "*udivmod<mode>4"
8045   [(set (match_operand:SWIM248 0 "register_operand" "=a")
8046         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8047                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8048    (set (match_operand:SWIM248 1 "register_operand" "=&d")
8049         (umod:SWIM248 (match_dup 2) (match_dup 3)))
8050    (clobber (reg:CC FLAGS_REG))]
8051   ""
8052   "#"
8053   "&& reload_completed"
8054   [(set (match_dup 1) (const_int 0))
8055    (parallel [(set (match_dup 0)
8056                    (udiv:SWIM248 (match_dup 2) (match_dup 3)))
8057               (set (match_dup 1)
8058                    (umod:SWIM248 (match_dup 2) (match_dup 3)))
8059               (use (match_dup 1))
8060               (clobber (reg:CC FLAGS_REG))])]
8061   ""
8062   [(set_attr "type" "multi")
8063    (set_attr "mode" "<MODE>")])
8064
8065 (define_insn "*udivmod<mode>4_noext"
8066   [(set (match_operand:SWIM248 0 "register_operand" "=a")
8067         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8068                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8069    (set (match_operand:SWIM248 1 "register_operand" "=d")
8070         (umod:SWIM248 (match_dup 2) (match_dup 3)))
8071    (use (match_operand:SWIM248 4 "register_operand" "1"))
8072    (clobber (reg:CC FLAGS_REG))]
8073   ""
8074   "div{<imodesuffix>}\t%3"
8075   [(set_attr "type" "idiv")
8076    (set_attr "mode" "<MODE>")])
8077
8078 ;; We cannot use div/idiv for double division, because it causes
8079 ;; "division by zero" on the overflow and that's not what we expect
8080 ;; from truncate.  Because true (non truncating) double division is
8081 ;; never generated, we can't create this insn anyway.
8082 ;
8083 ;(define_insn ""
8084 ;  [(set (match_operand:SI 0 "register_operand" "=a")
8085 ;       (truncate:SI
8086 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
8087 ;                  (zero_extend:DI
8088 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8089 ;   (set (match_operand:SI 3 "register_operand" "=d")
8090 ;       (truncate:SI
8091 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8092 ;   (clobber (reg:CC FLAGS_REG))]
8093 ;  ""
8094 ;  "div{l}\t{%2, %0|%0, %2}"
8095 ;  [(set_attr "type" "idiv")])
8096 \f
8097 ;;- Logical AND instructions
8098
8099 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8100 ;; Note that this excludes ah.
8101
8102 (define_insn "*testdi_1_rex64"
8103   [(set (reg FLAGS_REG)
8104         (compare
8105           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8106                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8107           (const_int 0)))]
8108   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8109    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8110   "@
8111    test{l}\t{%k1, %k0|%k0, %k1}
8112    test{l}\t{%k1, %k0|%k0, %k1}
8113    test{q}\t{%1, %0|%0, %1}
8114    test{q}\t{%1, %0|%0, %1}
8115    test{q}\t{%1, %0|%0, %1}"
8116   [(set_attr "type" "test")
8117    (set_attr "modrm" "0,1,0,1,1")
8118    (set_attr "mode" "SI,SI,DI,DI,DI")
8119    (set_attr "pent_pair" "uv,np,uv,np,uv")])
8120
8121 (define_insn "testsi_1"
8122   [(set (reg FLAGS_REG)
8123         (compare
8124           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
8125                   (match_operand:SI 1 "general_operand" "i,i,ri"))
8126           (const_int 0)))]
8127   "ix86_match_ccmode (insn, CCNOmode)
8128    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8129   "test{l}\t{%1, %0|%0, %1}"
8130   [(set_attr "type" "test")
8131    (set_attr "modrm" "0,1,1")
8132    (set_attr "mode" "SI")
8133    (set_attr "pent_pair" "uv,np,uv")])
8134
8135 (define_expand "testsi_ccno_1"
8136   [(set (reg:CCNO FLAGS_REG)
8137         (compare:CCNO
8138           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8139                   (match_operand:SI 1 "nonmemory_operand" ""))
8140           (const_int 0)))]
8141   ""
8142   "")
8143
8144 (define_insn "*testhi_1"
8145   [(set (reg FLAGS_REG)
8146         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
8147                          (match_operand:HI 1 "general_operand" "n,n,rn"))
8148                  (const_int 0)))]
8149   "ix86_match_ccmode (insn, CCNOmode)
8150    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8151   "test{w}\t{%1, %0|%0, %1}"
8152   [(set_attr "type" "test")
8153    (set_attr "modrm" "0,1,1")
8154    (set_attr "mode" "HI")
8155    (set_attr "pent_pair" "uv,np,uv")])
8156
8157 (define_expand "testqi_ccz_1"
8158   [(set (reg:CCZ FLAGS_REG)
8159         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8160                              (match_operand:QI 1 "nonmemory_operand" ""))
8161                  (const_int 0)))]
8162   ""
8163   "")
8164
8165 (define_insn "*testqi_1_maybe_si"
8166   [(set (reg FLAGS_REG)
8167         (compare
8168           (and:QI
8169             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8170             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8171           (const_int 0)))]
8172    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8173     && ix86_match_ccmode (insn,
8174                          CONST_INT_P (operands[1])
8175                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8176 {
8177   if (which_alternative == 3)
8178     {
8179       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8180         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8181       return "test{l}\t{%1, %k0|%k0, %1}";
8182     }
8183   return "test{b}\t{%1, %0|%0, %1}";
8184 }
8185   [(set_attr "type" "test")
8186    (set_attr "modrm" "0,1,1,1")
8187    (set_attr "mode" "QI,QI,QI,SI")
8188    (set_attr "pent_pair" "uv,np,uv,np")])
8189
8190 (define_insn "*testqi_1"
8191   [(set (reg FLAGS_REG)
8192         (compare
8193           (and:QI
8194             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
8195             (match_operand:QI 1 "general_operand" "n,n,qn"))
8196           (const_int 0)))]
8197   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8198    && ix86_match_ccmode (insn, CCNOmode)"
8199   "test{b}\t{%1, %0|%0, %1}"
8200   [(set_attr "type" "test")
8201    (set_attr "modrm" "0,1,1")
8202    (set_attr "mode" "QI")
8203    (set_attr "pent_pair" "uv,np,uv")])
8204
8205 (define_expand "testqi_ext_ccno_0"
8206   [(set (reg:CCNO FLAGS_REG)
8207         (compare:CCNO
8208           (and:SI
8209             (zero_extract:SI
8210               (match_operand 0 "ext_register_operand" "")
8211               (const_int 8)
8212               (const_int 8))
8213             (match_operand 1 "const_int_operand" ""))
8214           (const_int 0)))]
8215   ""
8216   "")
8217
8218 (define_insn "*testqi_ext_0"
8219   [(set (reg FLAGS_REG)
8220         (compare
8221           (and:SI
8222             (zero_extract:SI
8223               (match_operand 0 "ext_register_operand" "Q")
8224               (const_int 8)
8225               (const_int 8))
8226             (match_operand 1 "const_int_operand" "n"))
8227           (const_int 0)))]
8228   "ix86_match_ccmode (insn, CCNOmode)"
8229   "test{b}\t{%1, %h0|%h0, %1}"
8230   [(set_attr "type" "test")
8231    (set_attr "mode" "QI")
8232    (set_attr "length_immediate" "1")
8233    (set_attr "modrm" "1")
8234    (set_attr "pent_pair" "np")])
8235
8236 (define_insn "*testqi_ext_1"
8237   [(set (reg FLAGS_REG)
8238         (compare
8239           (and:SI
8240             (zero_extract:SI
8241               (match_operand 0 "ext_register_operand" "Q")
8242               (const_int 8)
8243               (const_int 8))
8244             (zero_extend:SI
8245               (match_operand:QI 1 "general_operand" "Qm")))
8246           (const_int 0)))]
8247   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8248    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8249   "test{b}\t{%1, %h0|%h0, %1}"
8250   [(set_attr "type" "test")
8251    (set_attr "mode" "QI")])
8252
8253 (define_insn "*testqi_ext_1_rex64"
8254   [(set (reg FLAGS_REG)
8255         (compare
8256           (and:SI
8257             (zero_extract:SI
8258               (match_operand 0 "ext_register_operand" "Q")
8259               (const_int 8)
8260               (const_int 8))
8261             (zero_extend:SI
8262               (match_operand:QI 1 "register_operand" "Q")))
8263           (const_int 0)))]
8264   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8265   "test{b}\t{%1, %h0|%h0, %1}"
8266   [(set_attr "type" "test")
8267    (set_attr "mode" "QI")])
8268
8269 (define_insn "*testqi_ext_2"
8270   [(set (reg FLAGS_REG)
8271         (compare
8272           (and:SI
8273             (zero_extract:SI
8274               (match_operand 0 "ext_register_operand" "Q")
8275               (const_int 8)
8276               (const_int 8))
8277             (zero_extract:SI
8278               (match_operand 1 "ext_register_operand" "Q")
8279               (const_int 8)
8280               (const_int 8)))
8281           (const_int 0)))]
8282   "ix86_match_ccmode (insn, CCNOmode)"
8283   "test{b}\t{%h1, %h0|%h0, %h1}"
8284   [(set_attr "type" "test")
8285    (set_attr "mode" "QI")])
8286
8287 ;; Combine likes to form bit extractions for some tests.  Humor it.
8288 (define_insn "*testqi_ext_3"
8289   [(set (reg FLAGS_REG)
8290         (compare (zero_extract:SI
8291                    (match_operand 0 "nonimmediate_operand" "rm")
8292                    (match_operand:SI 1 "const_int_operand" "")
8293                    (match_operand:SI 2 "const_int_operand" ""))
8294                  (const_int 0)))]
8295   "ix86_match_ccmode (insn, CCNOmode)
8296    && INTVAL (operands[1]) > 0
8297    && INTVAL (operands[2]) >= 0
8298    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8299    && (GET_MODE (operands[0]) == SImode
8300        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8301        || GET_MODE (operands[0]) == HImode
8302        || GET_MODE (operands[0]) == QImode)"
8303   "#")
8304
8305 (define_insn "*testqi_ext_3_rex64"
8306   [(set (reg FLAGS_REG)
8307         (compare (zero_extract:DI
8308                    (match_operand 0 "nonimmediate_operand" "rm")
8309                    (match_operand:DI 1 "const_int_operand" "")
8310                    (match_operand:DI 2 "const_int_operand" ""))
8311                  (const_int 0)))]
8312   "TARGET_64BIT
8313    && ix86_match_ccmode (insn, CCNOmode)
8314    && INTVAL (operands[1]) > 0
8315    && INTVAL (operands[2]) >= 0
8316    /* Ensure that resulting mask is zero or sign extended operand.  */
8317    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8318        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8319            && INTVAL (operands[1]) > 32))
8320    && (GET_MODE (operands[0]) == SImode
8321        || GET_MODE (operands[0]) == DImode
8322        || GET_MODE (operands[0]) == HImode
8323        || GET_MODE (operands[0]) == QImode)"
8324   "#")
8325
8326 (define_split
8327   [(set (match_operand 0 "flags_reg_operand" "")
8328         (match_operator 1 "compare_operator"
8329           [(zero_extract
8330              (match_operand 2 "nonimmediate_operand" "")
8331              (match_operand 3 "const_int_operand" "")
8332              (match_operand 4 "const_int_operand" ""))
8333            (const_int 0)]))]
8334   "ix86_match_ccmode (insn, CCNOmode)"
8335   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8336 {
8337   rtx val = operands[2];
8338   HOST_WIDE_INT len = INTVAL (operands[3]);
8339   HOST_WIDE_INT pos = INTVAL (operands[4]);
8340   HOST_WIDE_INT mask;
8341   enum machine_mode mode, submode;
8342
8343   mode = GET_MODE (val);
8344   if (MEM_P (val))
8345     {
8346       /* ??? Combine likes to put non-volatile mem extractions in QImode
8347          no matter the size of the test.  So find a mode that works.  */
8348       if (! MEM_VOLATILE_P (val))
8349         {
8350           mode = smallest_mode_for_size (pos + len, MODE_INT);
8351           val = adjust_address (val, mode, 0);
8352         }
8353     }
8354   else if (GET_CODE (val) == SUBREG
8355            && (submode = GET_MODE (SUBREG_REG (val)),
8356                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8357            && pos + len <= GET_MODE_BITSIZE (submode)
8358            && GET_MODE_CLASS (submode) == MODE_INT)
8359     {
8360       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
8361       mode = submode;
8362       val = SUBREG_REG (val);
8363     }
8364   else if (mode == HImode && pos + len <= 8)
8365     {
8366       /* Small HImode tests can be converted to QImode.  */
8367       mode = QImode;
8368       val = gen_lowpart (QImode, val);
8369     }
8370
8371   if (len == HOST_BITS_PER_WIDE_INT)
8372     mask = -1;
8373   else
8374     mask = ((HOST_WIDE_INT)1 << len) - 1;
8375   mask <<= pos;
8376
8377   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8378 })
8379
8380 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8381 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8382 ;; this is relatively important trick.
8383 ;; Do the conversion only post-reload to avoid limiting of the register class
8384 ;; to QI regs.
8385 (define_split
8386   [(set (match_operand 0 "flags_reg_operand" "")
8387         (match_operator 1 "compare_operator"
8388           [(and (match_operand 2 "register_operand" "")
8389                 (match_operand 3 "const_int_operand" ""))
8390            (const_int 0)]))]
8391    "reload_completed
8392     && QI_REG_P (operands[2])
8393     && GET_MODE (operands[2]) != QImode
8394     && ((ix86_match_ccmode (insn, CCZmode)
8395          && !(INTVAL (operands[3]) & ~(255 << 8)))
8396         || (ix86_match_ccmode (insn, CCNOmode)
8397             && !(INTVAL (operands[3]) & ~(127 << 8))))"
8398   [(set (match_dup 0)
8399         (match_op_dup 1
8400           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8401                    (match_dup 3))
8402            (const_int 0)]))]
8403   "operands[2] = gen_lowpart (SImode, operands[2]);
8404    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8405
8406 (define_split
8407   [(set (match_operand 0 "flags_reg_operand" "")
8408         (match_operator 1 "compare_operator"
8409           [(and (match_operand 2 "nonimmediate_operand" "")
8410                 (match_operand 3 "const_int_operand" ""))
8411            (const_int 0)]))]
8412    "reload_completed
8413     && GET_MODE (operands[2]) != QImode
8414     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8415     && ((ix86_match_ccmode (insn, CCZmode)
8416          && !(INTVAL (operands[3]) & ~255))
8417         || (ix86_match_ccmode (insn, CCNOmode)
8418             && !(INTVAL (operands[3]) & ~127)))"
8419   [(set (match_dup 0)
8420         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8421                          (const_int 0)]))]
8422   "operands[2] = gen_lowpart (QImode, operands[2]);
8423    operands[3] = gen_lowpart (QImode, operands[3]);")
8424
8425
8426 ;; %%% This used to optimize known byte-wide and operations to memory,
8427 ;; and sometimes to QImode registers.  If this is considered useful,
8428 ;; it should be done with splitters.
8429
8430 (define_expand "anddi3"
8431   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8432         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8433                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))]
8434   "TARGET_64BIT"
8435   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8436
8437 (define_insn "*anddi_1_rex64"
8438   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8439         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8440                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8441    (clobber (reg:CC FLAGS_REG))]
8442   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8443 {
8444   switch (get_attr_type (insn))
8445     {
8446     case TYPE_IMOVX:
8447       {
8448         enum machine_mode mode;
8449
8450         gcc_assert (CONST_INT_P (operands[2]));
8451         if (INTVAL (operands[2]) == 0xff)
8452           mode = QImode;
8453         else
8454           {
8455             gcc_assert (INTVAL (operands[2]) == 0xffff);
8456             mode = HImode;
8457           }
8458
8459         operands[1] = gen_lowpart (mode, operands[1]);
8460         if (mode == QImode)
8461           return "movz{bl|x}\t{%1, %k0|%k0, %1}";
8462         else
8463           return "movz{wl|x}\t{%1, %k0|%k0, %1}";
8464       }
8465
8466     default:
8467       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8468       if (get_attr_mode (insn) == MODE_SI)
8469         return "and{l}\t{%k2, %k0|%k0, %k2}";
8470       else
8471         return "and{q}\t{%2, %0|%0, %2}";
8472     }
8473 }
8474   [(set_attr "type" "alu,alu,alu,imovx")
8475    (set_attr "length_immediate" "*,*,*,0")
8476    (set (attr "prefix_rex")
8477      (if_then_else
8478        (and (eq_attr "type" "imovx")
8479             (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
8480                  (match_operand 1 "ext_QIreg_nomode_operand" "")))
8481        (const_string "1")
8482        (const_string "*")))
8483    (set_attr "mode" "SI,DI,DI,SI")])
8484
8485 (define_insn "*anddi_2"
8486   [(set (reg FLAGS_REG)
8487         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8488                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8489                  (const_int 0)))
8490    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8491         (and:DI (match_dup 1) (match_dup 2)))]
8492   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8493    && ix86_binary_operator_ok (AND, DImode, operands)"
8494   "@
8495    and{l}\t{%k2, %k0|%k0, %k2}
8496    and{q}\t{%2, %0|%0, %2}
8497    and{q}\t{%2, %0|%0, %2}"
8498   [(set_attr "type" "alu")
8499    (set_attr "mode" "SI,DI,DI")])
8500
8501 (define_expand "andsi3"
8502   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8503         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8504                 (match_operand:SI 2 "general_operand" "")))]
8505   ""
8506   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8507
8508 (define_insn "*andsi_1"
8509   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8510         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8511                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8512    (clobber (reg:CC FLAGS_REG))]
8513   "ix86_binary_operator_ok (AND, SImode, operands)"
8514 {
8515   switch (get_attr_type (insn))
8516     {
8517     case TYPE_IMOVX:
8518       {
8519         enum machine_mode mode;
8520
8521         gcc_assert (CONST_INT_P (operands[2]));
8522         if (INTVAL (operands[2]) == 0xff)
8523           mode = QImode;
8524         else
8525           {
8526             gcc_assert (INTVAL (operands[2]) == 0xffff);
8527             mode = HImode;
8528           }
8529
8530         operands[1] = gen_lowpart (mode, operands[1]);
8531         if (mode == QImode)
8532           return "movz{bl|x}\t{%1, %0|%0, %1}";
8533         else
8534           return "movz{wl|x}\t{%1, %0|%0, %1}";
8535       }
8536
8537     default:
8538       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8539       return "and{l}\t{%2, %0|%0, %2}";
8540     }
8541 }
8542   [(set_attr "type" "alu,alu,imovx")
8543    (set (attr "prefix_rex")
8544      (if_then_else
8545        (and (eq_attr "type" "imovx")
8546             (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
8547                  (match_operand 1 "ext_QIreg_nomode_operand" "")))
8548        (const_string "1")
8549        (const_string "*")))
8550    (set_attr "length_immediate" "*,*,0")
8551    (set_attr "mode" "SI")])
8552
8553 (define_split
8554   [(set (match_operand 0 "register_operand" "")
8555         (and (match_dup 0)
8556              (const_int -65536)))
8557    (clobber (reg:CC FLAGS_REG))]
8558   "optimize_function_for_size_p (cfun) || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8559   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8560   "operands[1] = gen_lowpart (HImode, operands[0]);")
8561
8562 (define_split
8563   [(set (match_operand 0 "ext_register_operand" "")
8564         (and (match_dup 0)
8565              (const_int -256)))
8566    (clobber (reg:CC FLAGS_REG))]
8567   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8568   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8569   "operands[1] = gen_lowpart (QImode, operands[0]);")
8570
8571 (define_split
8572   [(set (match_operand 0 "ext_register_operand" "")
8573         (and (match_dup 0)
8574              (const_int -65281)))
8575    (clobber (reg:CC FLAGS_REG))]
8576   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8577   [(parallel [(set (zero_extract:SI (match_dup 0)
8578                                     (const_int 8)
8579                                     (const_int 8))
8580                    (xor:SI
8581                      (zero_extract:SI (match_dup 0)
8582                                       (const_int 8)
8583                                       (const_int 8))
8584                      (zero_extract:SI (match_dup 0)
8585                                       (const_int 8)
8586                                       (const_int 8))))
8587               (clobber (reg:CC FLAGS_REG))])]
8588   "operands[0] = gen_lowpart (SImode, operands[0]);")
8589
8590 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8591 (define_insn "*andsi_1_zext"
8592   [(set (match_operand:DI 0 "register_operand" "=r")
8593         (zero_extend:DI
8594           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8595                   (match_operand:SI 2 "general_operand" "g"))))
8596    (clobber (reg:CC FLAGS_REG))]
8597   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8598   "and{l}\t{%2, %k0|%k0, %2}"
8599   [(set_attr "type" "alu")
8600    (set_attr "mode" "SI")])
8601
8602 (define_insn "*andsi_2"
8603   [(set (reg FLAGS_REG)
8604         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8605                          (match_operand:SI 2 "general_operand" "g,ri"))
8606                  (const_int 0)))
8607    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8608         (and:SI (match_dup 1) (match_dup 2)))]
8609   "ix86_match_ccmode (insn, CCNOmode)
8610    && ix86_binary_operator_ok (AND, SImode, operands)"
8611   "and{l}\t{%2, %0|%0, %2}"
8612   [(set_attr "type" "alu")
8613    (set_attr "mode" "SI")])
8614
8615 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8616 (define_insn "*andsi_2_zext"
8617   [(set (reg FLAGS_REG)
8618         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8619                          (match_operand:SI 2 "general_operand" "g"))
8620                  (const_int 0)))
8621    (set (match_operand:DI 0 "register_operand" "=r")
8622         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8623   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8624    && ix86_binary_operator_ok (AND, SImode, operands)"
8625   "and{l}\t{%2, %k0|%k0, %2}"
8626   [(set_attr "type" "alu")
8627    (set_attr "mode" "SI")])
8628
8629 (define_expand "andhi3"
8630   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8631         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8632                 (match_operand:HI 2 "general_operand" "")))]
8633   "TARGET_HIMODE_MATH"
8634   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8635
8636 (define_insn "*andhi_1"
8637   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8638         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8639                 (match_operand:HI 2 "general_operand" "rn,rm,L")))
8640    (clobber (reg:CC FLAGS_REG))]
8641   "ix86_binary_operator_ok (AND, HImode, operands)"
8642 {
8643   switch (get_attr_type (insn))
8644     {
8645     case TYPE_IMOVX:
8646       gcc_assert (CONST_INT_P (operands[2]));
8647       gcc_assert (INTVAL (operands[2]) == 0xff);
8648       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8649
8650     default:
8651       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8652
8653       return "and{w}\t{%2, %0|%0, %2}";
8654     }
8655 }
8656   [(set_attr "type" "alu,alu,imovx")
8657    (set_attr "length_immediate" "*,*,0")
8658    (set (attr "prefix_rex")
8659      (if_then_else
8660        (and (eq_attr "type" "imovx")
8661             (match_operand 1 "ext_QIreg_nomode_operand" ""))
8662        (const_string "1")
8663        (const_string "*")))
8664    (set_attr "mode" "HI,HI,SI")])
8665
8666 (define_insn "*andhi_2"
8667   [(set (reg FLAGS_REG)
8668         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8669                          (match_operand:HI 2 "general_operand" "rmn,rn"))
8670                  (const_int 0)))
8671    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8672         (and:HI (match_dup 1) (match_dup 2)))]
8673   "ix86_match_ccmode (insn, CCNOmode)
8674    && ix86_binary_operator_ok (AND, HImode, operands)"
8675   "and{w}\t{%2, %0|%0, %2}"
8676   [(set_attr "type" "alu")
8677    (set_attr "mode" "HI")])
8678
8679 (define_expand "andqi3"
8680   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8681         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8682                 (match_operand:QI 2 "general_operand" "")))]
8683   "TARGET_QIMODE_MATH"
8684   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8685
8686 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8687 (define_insn "*andqi_1"
8688   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8689         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8690                 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
8691    (clobber (reg:CC FLAGS_REG))]
8692   "ix86_binary_operator_ok (AND, QImode, operands)"
8693   "@
8694    and{b}\t{%2, %0|%0, %2}
8695    and{b}\t{%2, %0|%0, %2}
8696    and{l}\t{%k2, %k0|%k0, %k2}"
8697   [(set_attr "type" "alu")
8698    (set_attr "mode" "QI,QI,SI")])
8699
8700 (define_insn "*andqi_1_slp"
8701   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8702         (and:QI (match_dup 0)
8703                 (match_operand:QI 1 "general_operand" "qn,qmn")))
8704    (clobber (reg:CC FLAGS_REG))]
8705   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8706    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8707   "and{b}\t{%1, %0|%0, %1}"
8708   [(set_attr "type" "alu1")
8709    (set_attr "mode" "QI")])
8710
8711 (define_insn "*andqi_2_maybe_si"
8712   [(set (reg FLAGS_REG)
8713         (compare (and:QI
8714                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8715                       (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8716                  (const_int 0)))
8717    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8718         (and:QI (match_dup 1) (match_dup 2)))]
8719   "ix86_binary_operator_ok (AND, QImode, operands)
8720    && ix86_match_ccmode (insn,
8721                          CONST_INT_P (operands[2])
8722                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8723 {
8724   if (which_alternative == 2)
8725     {
8726       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8727         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8728       return "and{l}\t{%2, %k0|%k0, %2}";
8729     }
8730   return "and{b}\t{%2, %0|%0, %2}";
8731 }
8732   [(set_attr "type" "alu")
8733    (set_attr "mode" "QI,QI,SI")])
8734
8735 (define_insn "*andqi_2"
8736   [(set (reg FLAGS_REG)
8737         (compare (and:QI
8738                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8739                    (match_operand:QI 2 "general_operand" "qmn,qn"))
8740                  (const_int 0)))
8741    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8742         (and:QI (match_dup 1) (match_dup 2)))]
8743   "ix86_match_ccmode (insn, CCNOmode)
8744    && ix86_binary_operator_ok (AND, QImode, operands)"
8745   "and{b}\t{%2, %0|%0, %2}"
8746   [(set_attr "type" "alu")
8747    (set_attr "mode" "QI")])
8748
8749 (define_insn "*andqi_2_slp"
8750   [(set (reg FLAGS_REG)
8751         (compare (and:QI
8752                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8753                    (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8754                  (const_int 0)))
8755    (set (strict_low_part (match_dup 0))
8756         (and:QI (match_dup 0) (match_dup 1)))]
8757   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8758    && ix86_match_ccmode (insn, CCNOmode)
8759    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8760   "and{b}\t{%1, %0|%0, %1}"
8761   [(set_attr "type" "alu1")
8762    (set_attr "mode" "QI")])
8763
8764 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8765 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8766 ;; for a QImode operand, which of course failed.
8767
8768 (define_insn "andqi_ext_0"
8769   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8770                          (const_int 8)
8771                          (const_int 8))
8772         (and:SI
8773           (zero_extract:SI
8774             (match_operand 1 "ext_register_operand" "0")
8775             (const_int 8)
8776             (const_int 8))
8777           (match_operand 2 "const_int_operand" "n")))
8778    (clobber (reg:CC FLAGS_REG))]
8779   ""
8780   "and{b}\t{%2, %h0|%h0, %2}"
8781   [(set_attr "type" "alu")
8782    (set_attr "length_immediate" "1")
8783    (set_attr "modrm" "1")
8784    (set_attr "mode" "QI")])
8785
8786 ;; Generated by peephole translating test to and.  This shows up
8787 ;; often in fp comparisons.
8788
8789 (define_insn "*andqi_ext_0_cc"
8790   [(set (reg FLAGS_REG)
8791         (compare
8792           (and:SI
8793             (zero_extract:SI
8794               (match_operand 1 "ext_register_operand" "0")
8795               (const_int 8)
8796               (const_int 8))
8797             (match_operand 2 "const_int_operand" "n"))
8798           (const_int 0)))
8799    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8800                          (const_int 8)
8801                          (const_int 8))
8802         (and:SI
8803           (zero_extract:SI
8804             (match_dup 1)
8805             (const_int 8)
8806             (const_int 8))
8807           (match_dup 2)))]
8808   "ix86_match_ccmode (insn, CCNOmode)"
8809   "and{b}\t{%2, %h0|%h0, %2}"
8810   [(set_attr "type" "alu")
8811    (set_attr "length_immediate" "1")
8812    (set_attr "modrm" "1")
8813    (set_attr "mode" "QI")])
8814
8815 (define_insn "*andqi_ext_1"
8816   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8817                          (const_int 8)
8818                          (const_int 8))
8819         (and:SI
8820           (zero_extract:SI
8821             (match_operand 1 "ext_register_operand" "0")
8822             (const_int 8)
8823             (const_int 8))
8824           (zero_extend:SI
8825             (match_operand:QI 2 "general_operand" "Qm"))))
8826    (clobber (reg:CC FLAGS_REG))]
8827   "!TARGET_64BIT"
8828   "and{b}\t{%2, %h0|%h0, %2}"
8829   [(set_attr "type" "alu")
8830    (set_attr "length_immediate" "0")
8831    (set_attr "mode" "QI")])
8832
8833 (define_insn "*andqi_ext_1_rex64"
8834   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8835                          (const_int 8)
8836                          (const_int 8))
8837         (and:SI
8838           (zero_extract:SI
8839             (match_operand 1 "ext_register_operand" "0")
8840             (const_int 8)
8841             (const_int 8))
8842           (zero_extend:SI
8843             (match_operand 2 "ext_register_operand" "Q"))))
8844    (clobber (reg:CC FLAGS_REG))]
8845   "TARGET_64BIT"
8846   "and{b}\t{%2, %h0|%h0, %2}"
8847   [(set_attr "type" "alu")
8848    (set_attr "length_immediate" "0")
8849    (set_attr "mode" "QI")])
8850
8851 (define_insn "*andqi_ext_2"
8852   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8853                          (const_int 8)
8854                          (const_int 8))
8855         (and:SI
8856           (zero_extract:SI
8857             (match_operand 1 "ext_register_operand" "%0")
8858             (const_int 8)
8859             (const_int 8))
8860           (zero_extract:SI
8861             (match_operand 2 "ext_register_operand" "Q")
8862             (const_int 8)
8863             (const_int 8))))
8864    (clobber (reg:CC FLAGS_REG))]
8865   ""
8866   "and{b}\t{%h2, %h0|%h0, %h2}"
8867   [(set_attr "type" "alu")
8868    (set_attr "length_immediate" "0")
8869    (set_attr "mode" "QI")])
8870
8871 ;; Convert wide AND instructions with immediate operand to shorter QImode
8872 ;; equivalents when possible.
8873 ;; Don't do the splitting with memory operands, since it introduces risk
8874 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8875 ;; for size, but that can (should?) be handled by generic code instead.
8876 (define_split
8877   [(set (match_operand 0 "register_operand" "")
8878         (and (match_operand 1 "register_operand" "")
8879              (match_operand 2 "const_int_operand" "")))
8880    (clobber (reg:CC FLAGS_REG))]
8881    "reload_completed
8882     && QI_REG_P (operands[0])
8883     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8884     && !(~INTVAL (operands[2]) & ~(255 << 8))
8885     && GET_MODE (operands[0]) != QImode"
8886   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8887                    (and:SI (zero_extract:SI (match_dup 1)
8888                                             (const_int 8) (const_int 8))
8889                            (match_dup 2)))
8890               (clobber (reg:CC FLAGS_REG))])]
8891   "operands[0] = gen_lowpart (SImode, operands[0]);
8892    operands[1] = gen_lowpart (SImode, operands[1]);
8893    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8894
8895 ;; Since AND can be encoded with sign extended immediate, this is only
8896 ;; profitable when 7th bit is not set.
8897 (define_split
8898   [(set (match_operand 0 "register_operand" "")
8899         (and (match_operand 1 "general_operand" "")
8900              (match_operand 2 "const_int_operand" "")))
8901    (clobber (reg:CC FLAGS_REG))]
8902    "reload_completed
8903     && ANY_QI_REG_P (operands[0])
8904     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8905     && !(~INTVAL (operands[2]) & ~255)
8906     && !(INTVAL (operands[2]) & 128)
8907     && GET_MODE (operands[0]) != QImode"
8908   [(parallel [(set (strict_low_part (match_dup 0))
8909                    (and:QI (match_dup 1)
8910                            (match_dup 2)))
8911               (clobber (reg:CC FLAGS_REG))])]
8912   "operands[0] = gen_lowpart (QImode, operands[0]);
8913    operands[1] = gen_lowpart (QImode, operands[1]);
8914    operands[2] = gen_lowpart (QImode, operands[2]);")
8915 \f
8916 ;; Logical inclusive OR instructions
8917
8918 ;; %%% This used to optimize known byte-wide and operations to memory.
8919 ;; If this is considered useful, it should be done with splitters.
8920
8921 (define_expand "iordi3"
8922   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8923         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8924                 (match_operand:DI 2 "x86_64_general_operand" "")))]
8925   "TARGET_64BIT"
8926   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8927
8928 (define_insn "*iordi_1_rex64"
8929   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8930         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8931                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8932    (clobber (reg:CC FLAGS_REG))]
8933   "TARGET_64BIT
8934    && ix86_binary_operator_ok (IOR, DImode, operands)"
8935   "or{q}\t{%2, %0|%0, %2}"
8936   [(set_attr "type" "alu")
8937    (set_attr "mode" "DI")])
8938
8939 (define_insn "*iordi_2_rex64"
8940   [(set (reg FLAGS_REG)
8941         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8942                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8943                  (const_int 0)))
8944    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8945         (ior:DI (match_dup 1) (match_dup 2)))]
8946   "TARGET_64BIT
8947    && ix86_match_ccmode (insn, CCNOmode)
8948    && ix86_binary_operator_ok (IOR, DImode, operands)"
8949   "or{q}\t{%2, %0|%0, %2}"
8950   [(set_attr "type" "alu")
8951    (set_attr "mode" "DI")])
8952
8953 (define_insn "*iordi_3_rex64"
8954   [(set (reg FLAGS_REG)
8955         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8956                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8957                  (const_int 0)))
8958    (clobber (match_scratch:DI 0 "=r"))]
8959   "TARGET_64BIT
8960    && ix86_match_ccmode (insn, CCNOmode)
8961    && ix86_binary_operator_ok (IOR, DImode, operands)"
8962   "or{q}\t{%2, %0|%0, %2}"
8963   [(set_attr "type" "alu")
8964    (set_attr "mode" "DI")])
8965
8966
8967 (define_expand "iorsi3"
8968   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8969         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8970                 (match_operand:SI 2 "general_operand" "")))]
8971   ""
8972   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8973
8974 (define_insn "*iorsi_1"
8975   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8976         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8977                 (match_operand:SI 2 "general_operand" "ri,g")))
8978    (clobber (reg:CC FLAGS_REG))]
8979   "ix86_binary_operator_ok (IOR, SImode, operands)"
8980   "or{l}\t{%2, %0|%0, %2}"
8981   [(set_attr "type" "alu")
8982    (set_attr "mode" "SI")])
8983
8984 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8985 (define_insn "*iorsi_1_zext"
8986   [(set (match_operand:DI 0 "register_operand" "=r")
8987         (zero_extend:DI
8988           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8989                   (match_operand:SI 2 "general_operand" "g"))))
8990    (clobber (reg:CC FLAGS_REG))]
8991   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8992   "or{l}\t{%2, %k0|%k0, %2}"
8993   [(set_attr "type" "alu")
8994    (set_attr "mode" "SI")])
8995
8996 (define_insn "*iorsi_1_zext_imm"
8997   [(set (match_operand:DI 0 "register_operand" "=r")
8998         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8999                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9000    (clobber (reg:CC FLAGS_REG))]
9001   "TARGET_64BIT"
9002   "or{l}\t{%2, %k0|%k0, %2}"
9003   [(set_attr "type" "alu")
9004    (set_attr "mode" "SI")])
9005
9006 (define_insn "*iorsi_2"
9007   [(set (reg FLAGS_REG)
9008         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9009                          (match_operand:SI 2 "general_operand" "g,ri"))
9010                  (const_int 0)))
9011    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9012         (ior:SI (match_dup 1) (match_dup 2)))]
9013   "ix86_match_ccmode (insn, CCNOmode)
9014    && ix86_binary_operator_ok (IOR, SImode, operands)"
9015   "or{l}\t{%2, %0|%0, %2}"
9016   [(set_attr "type" "alu")
9017    (set_attr "mode" "SI")])
9018
9019 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9020 ;; ??? Special case for immediate operand is missing - it is tricky.
9021 (define_insn "*iorsi_2_zext"
9022   [(set (reg FLAGS_REG)
9023         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9024                          (match_operand:SI 2 "general_operand" "g"))
9025                  (const_int 0)))
9026    (set (match_operand:DI 0 "register_operand" "=r")
9027         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
9028   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9029    && ix86_binary_operator_ok (IOR, SImode, operands)"
9030   "or{l}\t{%2, %k0|%k0, %2}"
9031   [(set_attr "type" "alu")
9032    (set_attr "mode" "SI")])
9033
9034 (define_insn "*iorsi_2_zext_imm"
9035   [(set (reg FLAGS_REG)
9036         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9037                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9038                  (const_int 0)))
9039    (set (match_operand:DI 0 "register_operand" "=r")
9040         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9041   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9042    && ix86_binary_operator_ok (IOR, SImode, operands)"
9043   "or{l}\t{%2, %k0|%k0, %2}"
9044   [(set_attr "type" "alu")
9045    (set_attr "mode" "SI")])
9046
9047 (define_insn "*iorsi_3"
9048   [(set (reg FLAGS_REG)
9049         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9050                          (match_operand:SI 2 "general_operand" "g"))
9051                  (const_int 0)))
9052    (clobber (match_scratch:SI 0 "=r"))]
9053   "ix86_match_ccmode (insn, CCNOmode)
9054    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9055   "or{l}\t{%2, %0|%0, %2}"
9056   [(set_attr "type" "alu")
9057    (set_attr "mode" "SI")])
9058
9059 (define_expand "iorhi3"
9060   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9061         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
9062                 (match_operand:HI 2 "general_operand" "")))]
9063   "TARGET_HIMODE_MATH"
9064   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
9065
9066 (define_insn "*iorhi_1"
9067   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9068         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9069                 (match_operand:HI 2 "general_operand" "rmn,rn")))
9070    (clobber (reg:CC FLAGS_REG))]
9071   "ix86_binary_operator_ok (IOR, HImode, operands)"
9072   "or{w}\t{%2, %0|%0, %2}"
9073   [(set_attr "type" "alu")
9074    (set_attr "mode" "HI")])
9075
9076 (define_insn "*iorhi_2"
9077   [(set (reg FLAGS_REG)
9078         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9079                          (match_operand:HI 2 "general_operand" "rmn,rn"))
9080                  (const_int 0)))
9081    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9082         (ior:HI (match_dup 1) (match_dup 2)))]
9083   "ix86_match_ccmode (insn, CCNOmode)
9084    && ix86_binary_operator_ok (IOR, HImode, operands)"
9085   "or{w}\t{%2, %0|%0, %2}"
9086   [(set_attr "type" "alu")
9087    (set_attr "mode" "HI")])
9088
9089 (define_insn "*iorhi_3"
9090   [(set (reg FLAGS_REG)
9091         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9092                          (match_operand:HI 2 "general_operand" "rmn"))
9093                  (const_int 0)))
9094    (clobber (match_scratch:HI 0 "=r"))]
9095   "ix86_match_ccmode (insn, CCNOmode)
9096    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9097   "or{w}\t{%2, %0|%0, %2}"
9098   [(set_attr "type" "alu")
9099    (set_attr "mode" "HI")])
9100
9101 (define_expand "iorqi3"
9102   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9103         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
9104                 (match_operand:QI 2 "general_operand" "")))]
9105   "TARGET_QIMODE_MATH"
9106   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
9107
9108 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9109 (define_insn "*iorqi_1"
9110   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9111         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9112                 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
9113    (clobber (reg:CC FLAGS_REG))]
9114   "ix86_binary_operator_ok (IOR, QImode, operands)"
9115   "@
9116    or{b}\t{%2, %0|%0, %2}
9117    or{b}\t{%2, %0|%0, %2}
9118    or{l}\t{%k2, %k0|%k0, %k2}"
9119   [(set_attr "type" "alu")
9120    (set_attr "mode" "QI,QI,SI")])
9121
9122 (define_insn "*iorqi_1_slp"
9123   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9124         (ior:QI (match_dup 0)
9125                 (match_operand:QI 1 "general_operand" "qmn,qn")))
9126    (clobber (reg:CC FLAGS_REG))]
9127   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9128    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9129   "or{b}\t{%1, %0|%0, %1}"
9130   [(set_attr "type" "alu1")
9131    (set_attr "mode" "QI")])
9132
9133 (define_insn "*iorqi_2"
9134   [(set (reg FLAGS_REG)
9135         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9136                          (match_operand:QI 2 "general_operand" "qmn,qn"))
9137                  (const_int 0)))
9138    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9139         (ior:QI (match_dup 1) (match_dup 2)))]
9140   "ix86_match_ccmode (insn, CCNOmode)
9141    && ix86_binary_operator_ok (IOR, QImode, operands)"
9142   "or{b}\t{%2, %0|%0, %2}"
9143   [(set_attr "type" "alu")
9144    (set_attr "mode" "QI")])
9145
9146 (define_insn "*iorqi_2_slp"
9147   [(set (reg FLAGS_REG)
9148         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9149                          (match_operand:QI 1 "general_operand" "qmn,qn"))
9150                  (const_int 0)))
9151    (set (strict_low_part (match_dup 0))
9152         (ior:QI (match_dup 0) (match_dup 1)))]
9153   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9154    && ix86_match_ccmode (insn, CCNOmode)
9155    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9156   "or{b}\t{%1, %0|%0, %1}"
9157   [(set_attr "type" "alu1")
9158    (set_attr "mode" "QI")])
9159
9160 (define_insn "*iorqi_3"
9161   [(set (reg FLAGS_REG)
9162         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9163                          (match_operand:QI 2 "general_operand" "qmn"))
9164                  (const_int 0)))
9165    (clobber (match_scratch:QI 0 "=q"))]
9166   "ix86_match_ccmode (insn, CCNOmode)
9167    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9168   "or{b}\t{%2, %0|%0, %2}"
9169   [(set_attr "type" "alu")
9170    (set_attr "mode" "QI")])
9171
9172 (define_insn "*iorqi_ext_0"
9173   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9174                          (const_int 8)
9175                          (const_int 8))
9176         (ior:SI
9177           (zero_extract:SI
9178             (match_operand 1 "ext_register_operand" "0")
9179             (const_int 8)
9180             (const_int 8))
9181           (match_operand 2 "const_int_operand" "n")))
9182    (clobber (reg:CC FLAGS_REG))]
9183   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9184   "or{b}\t{%2, %h0|%h0, %2}"
9185   [(set_attr "type" "alu")
9186    (set_attr "length_immediate" "1")
9187    (set_attr "modrm" "1")
9188    (set_attr "mode" "QI")])
9189
9190 (define_insn "*iorqi_ext_1"
9191   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9192                          (const_int 8)
9193                          (const_int 8))
9194         (ior:SI
9195           (zero_extract:SI
9196             (match_operand 1 "ext_register_operand" "0")
9197             (const_int 8)
9198             (const_int 8))
9199           (zero_extend:SI
9200             (match_operand:QI 2 "general_operand" "Qm"))))
9201    (clobber (reg:CC FLAGS_REG))]
9202   "!TARGET_64BIT
9203    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9204   "or{b}\t{%2, %h0|%h0, %2}"
9205   [(set_attr "type" "alu")
9206    (set_attr "length_immediate" "0")
9207    (set_attr "mode" "QI")])
9208
9209 (define_insn "*iorqi_ext_1_rex64"
9210   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9211                          (const_int 8)
9212                          (const_int 8))
9213         (ior:SI
9214           (zero_extract:SI
9215             (match_operand 1 "ext_register_operand" "0")
9216             (const_int 8)
9217             (const_int 8))
9218           (zero_extend:SI
9219             (match_operand 2 "ext_register_operand" "Q"))))
9220    (clobber (reg:CC FLAGS_REG))]
9221   "TARGET_64BIT
9222    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9223   "or{b}\t{%2, %h0|%h0, %2}"
9224   [(set_attr "type" "alu")
9225    (set_attr "length_immediate" "0")
9226    (set_attr "mode" "QI")])
9227
9228 (define_insn "*iorqi_ext_2"
9229   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9230                          (const_int 8)
9231                          (const_int 8))
9232         (ior:SI
9233           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9234                            (const_int 8)
9235                            (const_int 8))
9236           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9237                            (const_int 8)
9238                            (const_int 8))))
9239    (clobber (reg:CC FLAGS_REG))]
9240   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9241   "ior{b}\t{%h2, %h0|%h0, %h2}"
9242   [(set_attr "type" "alu")
9243    (set_attr "length_immediate" "0")
9244    (set_attr "mode" "QI")])
9245
9246 (define_split
9247   [(set (match_operand 0 "register_operand" "")
9248         (ior (match_operand 1 "register_operand" "")
9249              (match_operand 2 "const_int_operand" "")))
9250    (clobber (reg:CC FLAGS_REG))]
9251    "reload_completed
9252     && QI_REG_P (operands[0])
9253     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9254     && !(INTVAL (operands[2]) & ~(255 << 8))
9255     && GET_MODE (operands[0]) != QImode"
9256   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9257                    (ior:SI (zero_extract:SI (match_dup 1)
9258                                             (const_int 8) (const_int 8))
9259                            (match_dup 2)))
9260               (clobber (reg:CC FLAGS_REG))])]
9261   "operands[0] = gen_lowpart (SImode, operands[0]);
9262    operands[1] = gen_lowpart (SImode, operands[1]);
9263    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9264
9265 ;; Since OR can be encoded with sign extended immediate, this is only
9266 ;; profitable when 7th bit is set.
9267 (define_split
9268   [(set (match_operand 0 "register_operand" "")
9269         (ior (match_operand 1 "general_operand" "")
9270              (match_operand 2 "const_int_operand" "")))
9271    (clobber (reg:CC FLAGS_REG))]
9272    "reload_completed
9273     && ANY_QI_REG_P (operands[0])
9274     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9275     && !(INTVAL (operands[2]) & ~255)
9276     && (INTVAL (operands[2]) & 128)
9277     && GET_MODE (operands[0]) != QImode"
9278   [(parallel [(set (strict_low_part (match_dup 0))
9279                    (ior:QI (match_dup 1)
9280                            (match_dup 2)))
9281               (clobber (reg:CC FLAGS_REG))])]
9282   "operands[0] = gen_lowpart (QImode, operands[0]);
9283    operands[1] = gen_lowpart (QImode, operands[1]);
9284    operands[2] = gen_lowpart (QImode, operands[2]);")
9285 \f
9286 ;; Logical XOR instructions
9287
9288 ;; %%% This used to optimize known byte-wide and operations to memory.
9289 ;; If this is considered useful, it should be done with splitters.
9290
9291 (define_expand "xordi3"
9292   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9293         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
9294                 (match_operand:DI 2 "x86_64_general_operand" "")))]
9295   "TARGET_64BIT"
9296   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
9297
9298 (define_insn "*xordi_1_rex64"
9299   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9300         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9301                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
9302    (clobber (reg:CC FLAGS_REG))]
9303   "TARGET_64BIT
9304    && ix86_binary_operator_ok (XOR, DImode, operands)"
9305   "xor{q}\t{%2, %0|%0, %2}"
9306   [(set_attr "type" "alu")
9307    (set_attr "mode" "DI")])
9308
9309 (define_insn "*xordi_2_rex64"
9310   [(set (reg FLAGS_REG)
9311         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9312                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9313                  (const_int 0)))
9314    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9315         (xor:DI (match_dup 1) (match_dup 2)))]
9316   "TARGET_64BIT
9317    && ix86_match_ccmode (insn, CCNOmode)
9318    && ix86_binary_operator_ok (XOR, DImode, operands)"
9319   "xor{q}\t{%2, %0|%0, %2}"
9320   [(set_attr "type" "alu")
9321    (set_attr "mode" "DI")])
9322
9323 (define_insn "*xordi_3_rex64"
9324   [(set (reg FLAGS_REG)
9325         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9326                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
9327                  (const_int 0)))
9328    (clobber (match_scratch:DI 0 "=r"))]
9329   "TARGET_64BIT
9330    && ix86_match_ccmode (insn, CCNOmode)
9331    && ix86_binary_operator_ok (XOR, DImode, operands)"
9332   "xor{q}\t{%2, %0|%0, %2}"
9333   [(set_attr "type" "alu")
9334    (set_attr "mode" "DI")])
9335
9336 (define_expand "xorsi3"
9337   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9338         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9339                 (match_operand:SI 2 "general_operand" "")))]
9340   ""
9341   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9342
9343 (define_insn "*xorsi_1"
9344   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9345         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9346                 (match_operand:SI 2 "general_operand" "ri,rm")))
9347    (clobber (reg:CC FLAGS_REG))]
9348   "ix86_binary_operator_ok (XOR, SImode, operands)"
9349   "xor{l}\t{%2, %0|%0, %2}"
9350   [(set_attr "type" "alu")
9351    (set_attr "mode" "SI")])
9352
9353 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9354 ;; Add speccase for immediates
9355 (define_insn "*xorsi_1_zext"
9356   [(set (match_operand:DI 0 "register_operand" "=r")
9357         (zero_extend:DI
9358           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9359                   (match_operand:SI 2 "general_operand" "g"))))
9360    (clobber (reg:CC FLAGS_REG))]
9361   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9362   "xor{l}\t{%2, %k0|%k0, %2}"
9363   [(set_attr "type" "alu")
9364    (set_attr "mode" "SI")])
9365
9366 (define_insn "*xorsi_1_zext_imm"
9367   [(set (match_operand:DI 0 "register_operand" "=r")
9368         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9369                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9370    (clobber (reg:CC FLAGS_REG))]
9371   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9372   "xor{l}\t{%2, %k0|%k0, %2}"
9373   [(set_attr "type" "alu")
9374    (set_attr "mode" "SI")])
9375
9376 (define_insn "*xorsi_2"
9377   [(set (reg FLAGS_REG)
9378         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9379                          (match_operand:SI 2 "general_operand" "g,ri"))
9380                  (const_int 0)))
9381    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9382         (xor:SI (match_dup 1) (match_dup 2)))]
9383   "ix86_match_ccmode (insn, CCNOmode)
9384    && ix86_binary_operator_ok (XOR, SImode, operands)"
9385   "xor{l}\t{%2, %0|%0, %2}"
9386   [(set_attr "type" "alu")
9387    (set_attr "mode" "SI")])
9388
9389 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9390 ;; ??? Special case for immediate operand is missing - it is tricky.
9391 (define_insn "*xorsi_2_zext"
9392   [(set (reg FLAGS_REG)
9393         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9394                          (match_operand:SI 2 "general_operand" "g"))
9395                  (const_int 0)))
9396    (set (match_operand:DI 0 "register_operand" "=r")
9397         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9398   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9399    && ix86_binary_operator_ok (XOR, SImode, operands)"
9400   "xor{l}\t{%2, %k0|%k0, %2}"
9401   [(set_attr "type" "alu")
9402    (set_attr "mode" "SI")])
9403
9404 (define_insn "*xorsi_2_zext_imm"
9405   [(set (reg FLAGS_REG)
9406         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9407                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9408                  (const_int 0)))
9409    (set (match_operand:DI 0 "register_operand" "=r")
9410         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9411   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9412    && ix86_binary_operator_ok (XOR, SImode, operands)"
9413   "xor{l}\t{%2, %k0|%k0, %2}"
9414   [(set_attr "type" "alu")
9415    (set_attr "mode" "SI")])
9416
9417 (define_insn "*xorsi_3"
9418   [(set (reg FLAGS_REG)
9419         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9420                          (match_operand:SI 2 "general_operand" "g"))
9421                  (const_int 0)))
9422    (clobber (match_scratch:SI 0 "=r"))]
9423   "ix86_match_ccmode (insn, CCNOmode)
9424    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9425   "xor{l}\t{%2, %0|%0, %2}"
9426   [(set_attr "type" "alu")
9427    (set_attr "mode" "SI")])
9428
9429 (define_expand "xorhi3"
9430   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9431         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9432                 (match_operand:HI 2 "general_operand" "")))]
9433   "TARGET_HIMODE_MATH"
9434   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9435
9436 (define_insn "*xorhi_1"
9437   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9438         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9439                 (match_operand:HI 2 "general_operand" "rmn,rn")))
9440    (clobber (reg:CC FLAGS_REG))]
9441   "ix86_binary_operator_ok (XOR, HImode, operands)"
9442   "xor{w}\t{%2, %0|%0, %2}"
9443   [(set_attr "type" "alu")
9444    (set_attr "mode" "HI")])
9445
9446 (define_insn "*xorhi_2"
9447   [(set (reg FLAGS_REG)
9448         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9449                          (match_operand:HI 2 "general_operand" "rmn,rn"))
9450                  (const_int 0)))
9451    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9452         (xor:HI (match_dup 1) (match_dup 2)))]
9453   "ix86_match_ccmode (insn, CCNOmode)
9454    && ix86_binary_operator_ok (XOR, HImode, operands)"
9455   "xor{w}\t{%2, %0|%0, %2}"
9456   [(set_attr "type" "alu")
9457    (set_attr "mode" "HI")])
9458
9459 (define_insn "*xorhi_3"
9460   [(set (reg FLAGS_REG)
9461         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9462                          (match_operand:HI 2 "general_operand" "rmn"))
9463                  (const_int 0)))
9464    (clobber (match_scratch:HI 0 "=r"))]
9465   "ix86_match_ccmode (insn, CCNOmode)
9466    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9467   "xor{w}\t{%2, %0|%0, %2}"
9468   [(set_attr "type" "alu")
9469    (set_attr "mode" "HI")])
9470
9471 (define_expand "xorqi3"
9472   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9473         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9474                 (match_operand:QI 2 "general_operand" "")))]
9475   "TARGET_QIMODE_MATH"
9476   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9477
9478 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9479 (define_insn "*xorqi_1"
9480   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9481         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9482                 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
9483    (clobber (reg:CC FLAGS_REG))]
9484   "ix86_binary_operator_ok (XOR, QImode, operands)"
9485   "@
9486    xor{b}\t{%2, %0|%0, %2}
9487    xor{b}\t{%2, %0|%0, %2}
9488    xor{l}\t{%k2, %k0|%k0, %k2}"
9489   [(set_attr "type" "alu")
9490    (set_attr "mode" "QI,QI,SI")])
9491
9492 (define_insn "*xorqi_1_slp"
9493   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9494         (xor:QI (match_dup 0)
9495                 (match_operand:QI 1 "general_operand" "qn,qmn")))
9496    (clobber (reg:CC FLAGS_REG))]
9497   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9498    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9499   "xor{b}\t{%1, %0|%0, %1}"
9500   [(set_attr "type" "alu1")
9501    (set_attr "mode" "QI")])
9502
9503 (define_insn "*xorqi_ext_0"
9504   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9505                          (const_int 8)
9506                          (const_int 8))
9507         (xor:SI
9508           (zero_extract:SI
9509             (match_operand 1 "ext_register_operand" "0")
9510             (const_int 8)
9511             (const_int 8))
9512           (match_operand 2 "const_int_operand" "n")))
9513    (clobber (reg:CC FLAGS_REG))]
9514   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9515   "xor{b}\t{%2, %h0|%h0, %2}"
9516   [(set_attr "type" "alu")
9517    (set_attr "length_immediate" "1")
9518    (set_attr "modrm" "1")
9519    (set_attr "mode" "QI")])
9520
9521 (define_insn "*xorqi_ext_1"
9522   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9523                          (const_int 8)
9524                          (const_int 8))
9525         (xor:SI
9526           (zero_extract:SI
9527             (match_operand 1 "ext_register_operand" "0")
9528             (const_int 8)
9529             (const_int 8))
9530           (zero_extend:SI
9531             (match_operand:QI 2 "general_operand" "Qm"))))
9532    (clobber (reg:CC FLAGS_REG))]
9533   "!TARGET_64BIT
9534    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9535   "xor{b}\t{%2, %h0|%h0, %2}"
9536   [(set_attr "type" "alu")
9537    (set_attr "length_immediate" "0")
9538    (set_attr "mode" "QI")])
9539
9540 (define_insn "*xorqi_ext_1_rex64"
9541   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9542                          (const_int 8)
9543                          (const_int 8))
9544         (xor:SI
9545           (zero_extract:SI
9546             (match_operand 1 "ext_register_operand" "0")
9547             (const_int 8)
9548             (const_int 8))
9549           (zero_extend:SI
9550             (match_operand 2 "ext_register_operand" "Q"))))
9551    (clobber (reg:CC FLAGS_REG))]
9552   "TARGET_64BIT
9553    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9554   "xor{b}\t{%2, %h0|%h0, %2}"
9555   [(set_attr "type" "alu")
9556    (set_attr "length_immediate" "0")
9557    (set_attr "mode" "QI")])
9558
9559 (define_insn "*xorqi_ext_2"
9560   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9561                          (const_int 8)
9562                          (const_int 8))
9563         (xor:SI
9564           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9565                            (const_int 8)
9566                            (const_int 8))
9567           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9568                            (const_int 8)
9569                            (const_int 8))))
9570    (clobber (reg:CC FLAGS_REG))]
9571   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9572   "xor{b}\t{%h2, %h0|%h0, %h2}"
9573   [(set_attr "type" "alu")
9574    (set_attr "length_immediate" "0")
9575    (set_attr "mode" "QI")])
9576
9577 (define_insn "*xorqi_cc_1"
9578   [(set (reg FLAGS_REG)
9579         (compare
9580           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9581                   (match_operand:QI 2 "general_operand" "qmn,qn"))
9582           (const_int 0)))
9583    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9584         (xor:QI (match_dup 1) (match_dup 2)))]
9585   "ix86_match_ccmode (insn, CCNOmode)
9586    && ix86_binary_operator_ok (XOR, QImode, operands)"
9587   "xor{b}\t{%2, %0|%0, %2}"
9588   [(set_attr "type" "alu")
9589    (set_attr "mode" "QI")])
9590
9591 (define_insn "*xorqi_2_slp"
9592   [(set (reg FLAGS_REG)
9593         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9594                          (match_operand:QI 1 "general_operand" "qmn,qn"))
9595                  (const_int 0)))
9596    (set (strict_low_part (match_dup 0))
9597         (xor:QI (match_dup 0) (match_dup 1)))]
9598   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9599    && ix86_match_ccmode (insn, CCNOmode)
9600    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9601   "xor{b}\t{%1, %0|%0, %1}"
9602   [(set_attr "type" "alu1")
9603    (set_attr "mode" "QI")])
9604
9605 (define_insn "*xorqi_cc_2"
9606   [(set (reg FLAGS_REG)
9607         (compare
9608           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9609                   (match_operand:QI 2 "general_operand" "qmn"))
9610           (const_int 0)))
9611    (clobber (match_scratch:QI 0 "=q"))]
9612   "ix86_match_ccmode (insn, CCNOmode)
9613    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9614   "xor{b}\t{%2, %0|%0, %2}"
9615   [(set_attr "type" "alu")
9616    (set_attr "mode" "QI")])
9617
9618 (define_insn "*xorqi_cc_ext_1"
9619   [(set (reg FLAGS_REG)
9620         (compare
9621           (xor:SI
9622             (zero_extract:SI
9623               (match_operand 1 "ext_register_operand" "0")
9624               (const_int 8)
9625               (const_int 8))
9626             (match_operand:QI 2 "general_operand" "qmn"))
9627           (const_int 0)))
9628    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9629                          (const_int 8)
9630                          (const_int 8))
9631         (xor:SI
9632           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9633           (match_dup 2)))]
9634   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9635   "xor{b}\t{%2, %h0|%h0, %2}"
9636   [(set_attr "type" "alu")
9637    (set_attr "modrm" "1")
9638    (set_attr "mode" "QI")])
9639
9640 (define_insn "*xorqi_cc_ext_1_rex64"
9641   [(set (reg FLAGS_REG)
9642         (compare
9643           (xor:SI
9644             (zero_extract:SI
9645               (match_operand 1 "ext_register_operand" "0")
9646               (const_int 8)
9647               (const_int 8))
9648             (match_operand:QI 2 "nonmemory_operand" "Qn"))
9649           (const_int 0)))
9650    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9651                          (const_int 8)
9652                          (const_int 8))
9653         (xor:SI
9654           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9655           (match_dup 2)))]
9656   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9657   "xor{b}\t{%2, %h0|%h0, %2}"
9658   [(set_attr "type" "alu")
9659    (set_attr "modrm" "1")
9660    (set_attr "mode" "QI")])
9661
9662 (define_expand "xorqi_cc_ext_1"
9663   [(parallel [
9664      (set (reg:CCNO FLAGS_REG)
9665           (compare:CCNO
9666             (xor:SI
9667               (zero_extract:SI
9668                 (match_operand 1 "ext_register_operand" "")
9669                 (const_int 8)
9670                 (const_int 8))
9671               (match_operand:QI 2 "general_operand" ""))
9672             (const_int 0)))
9673      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9674                            (const_int 8)
9675                            (const_int 8))
9676           (xor:SI
9677             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9678             (match_dup 2)))])]
9679   ""
9680   "")
9681
9682 (define_split
9683   [(set (match_operand 0 "register_operand" "")
9684         (xor (match_operand 1 "register_operand" "")
9685              (match_operand 2 "const_int_operand" "")))
9686    (clobber (reg:CC FLAGS_REG))]
9687    "reload_completed
9688     && QI_REG_P (operands[0])
9689     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9690     && !(INTVAL (operands[2]) & ~(255 << 8))
9691     && GET_MODE (operands[0]) != QImode"
9692   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9693                    (xor:SI (zero_extract:SI (match_dup 1)
9694                                             (const_int 8) (const_int 8))
9695                            (match_dup 2)))
9696               (clobber (reg:CC FLAGS_REG))])]
9697   "operands[0] = gen_lowpart (SImode, operands[0]);
9698    operands[1] = gen_lowpart (SImode, operands[1]);
9699    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9700
9701 ;; Since XOR can be encoded with sign extended immediate, this is only
9702 ;; profitable when 7th bit is set.
9703 (define_split
9704   [(set (match_operand 0 "register_operand" "")
9705         (xor (match_operand 1 "general_operand" "")
9706              (match_operand 2 "const_int_operand" "")))
9707    (clobber (reg:CC FLAGS_REG))]
9708    "reload_completed
9709     && ANY_QI_REG_P (operands[0])
9710     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9711     && !(INTVAL (operands[2]) & ~255)
9712     && (INTVAL (operands[2]) & 128)
9713     && GET_MODE (operands[0]) != QImode"
9714   [(parallel [(set (strict_low_part (match_dup 0))
9715                    (xor:QI (match_dup 1)
9716                            (match_dup 2)))
9717               (clobber (reg:CC FLAGS_REG))])]
9718   "operands[0] = gen_lowpart (QImode, operands[0]);
9719    operands[1] = gen_lowpart (QImode, operands[1]);
9720    operands[2] = gen_lowpart (QImode, operands[2]);")
9721 \f
9722 ;; Negation instructions
9723
9724 (define_expand "negti2"
9725   [(set (match_operand:TI 0 "nonimmediate_operand" "")
9726         (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))]
9727   "TARGET_64BIT"
9728   "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
9729
9730 (define_insn "*negti2_1"
9731   [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
9732         (neg:TI (match_operand:TI 1 "nonimmediate_operand" "0")))
9733    (clobber (reg:CC FLAGS_REG))]
9734   "TARGET_64BIT
9735    && ix86_unary_operator_ok (NEG, TImode, operands)"
9736   "#")
9737
9738 (define_split
9739   [(set (match_operand:TI 0 "nonimmediate_operand" "")
9740         (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9741    (clobber (reg:CC FLAGS_REG))]
9742   "TARGET_64BIT && reload_completed"
9743   [(parallel
9744     [(set (reg:CCZ FLAGS_REG)
9745           (compare:CCZ (neg:DI (match_dup 1)) (const_int 0)))
9746      (set (match_dup 0) (neg:DI (match_dup 1)))])
9747    (parallel
9748     [(set (match_dup 2)
9749           (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
9750                             (match_dup 3))
9751                    (const_int 0)))
9752      (clobber (reg:CC FLAGS_REG))])
9753    (parallel
9754     [(set (match_dup 2)
9755           (neg:DI (match_dup 2)))
9756      (clobber (reg:CC FLAGS_REG))])]
9757   "split_ti (&operands[0], 2, &operands[0], &operands[2]);")
9758
9759 (define_expand "negdi2"
9760   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9761         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
9762   ""
9763   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9764
9765 (define_insn "*negdi2_1"
9766   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9767         (neg:DI (match_operand:DI 1 "general_operand" "0")))
9768    (clobber (reg:CC FLAGS_REG))]
9769   "!TARGET_64BIT
9770    && ix86_unary_operator_ok (NEG, DImode, operands)"
9771   "#")
9772
9773 (define_split
9774   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9775         (neg:DI (match_operand:DI 1 "general_operand" "")))
9776    (clobber (reg:CC FLAGS_REG))]
9777   "!TARGET_64BIT && reload_completed"
9778   [(parallel
9779     [(set (reg:CCZ FLAGS_REG)
9780           (compare:CCZ (neg:SI (match_dup 1)) (const_int 0)))
9781      (set (match_dup 0) (neg:SI (match_dup 1)))])
9782    (parallel
9783     [(set (match_dup 2)
9784           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9785                             (match_dup 3))
9786                    (const_int 0)))
9787      (clobber (reg:CC FLAGS_REG))])
9788    (parallel
9789     [(set (match_dup 2)
9790           (neg:SI (match_dup 2)))
9791      (clobber (reg:CC FLAGS_REG))])]
9792   "split_di (&operands[0], 2, &operands[0], &operands[2]);");
9793
9794 (define_insn "*negdi2_1_rex64"
9795   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9796         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9797    (clobber (reg:CC FLAGS_REG))]
9798   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9799   "neg{q}\t%0"
9800   [(set_attr "type" "negnot")
9801    (set_attr "mode" "DI")])
9802
9803 ;; The problem with neg is that it does not perform (compare x 0),
9804 ;; it really performs (compare 0 x), which leaves us with the zero
9805 ;; flag being the only useful item.
9806
9807 (define_insn "*negdi2_cmpz_rex64"
9808   [(set (reg:CCZ FLAGS_REG)
9809         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9810                      (const_int 0)))
9811    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9812         (neg:DI (match_dup 1)))]
9813   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9814   "neg{q}\t%0"
9815   [(set_attr "type" "negnot")
9816    (set_attr "mode" "DI")])
9817
9818
9819 (define_expand "negsi2"
9820   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9821         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
9822   ""
9823   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9824
9825 (define_insn "*negsi2_1"
9826   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9827         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9828    (clobber (reg:CC FLAGS_REG))]
9829   "ix86_unary_operator_ok (NEG, SImode, operands)"
9830   "neg{l}\t%0"
9831   [(set_attr "type" "negnot")
9832    (set_attr "mode" "SI")])
9833
9834 ;; Combine is quite creative about this pattern.
9835 (define_insn "*negsi2_1_zext"
9836   [(set (match_operand:DI 0 "register_operand" "=r")
9837         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9838                                         (const_int 32)))
9839                      (const_int 32)))
9840    (clobber (reg:CC FLAGS_REG))]
9841   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9842   "neg{l}\t%k0"
9843   [(set_attr "type" "negnot")
9844    (set_attr "mode" "SI")])
9845
9846 ;; The problem with neg is that it does not perform (compare x 0),
9847 ;; it really performs (compare 0 x), which leaves us with the zero
9848 ;; flag being the only useful item.
9849
9850 (define_insn "*negsi2_cmpz"
9851   [(set (reg:CCZ FLAGS_REG)
9852         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9853                      (const_int 0)))
9854    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9855         (neg:SI (match_dup 1)))]
9856   "ix86_unary_operator_ok (NEG, SImode, operands)"
9857   "neg{l}\t%0"
9858   [(set_attr "type" "negnot")
9859    (set_attr "mode" "SI")])
9860
9861 (define_insn "*negsi2_cmpz_zext"
9862   [(set (reg:CCZ FLAGS_REG)
9863         (compare:CCZ (lshiftrt:DI
9864                        (neg:DI (ashift:DI
9865                                  (match_operand:DI 1 "register_operand" "0")
9866                                  (const_int 32)))
9867                        (const_int 32))
9868                      (const_int 0)))
9869    (set (match_operand:DI 0 "register_operand" "=r")
9870         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9871                                         (const_int 32)))
9872                      (const_int 32)))]
9873   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9874   "neg{l}\t%k0"
9875   [(set_attr "type" "negnot")
9876    (set_attr "mode" "SI")])
9877
9878 (define_expand "neghi2"
9879   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9880         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
9881   "TARGET_HIMODE_MATH"
9882   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9883
9884 (define_insn "*neghi2_1"
9885   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9886         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9887    (clobber (reg:CC FLAGS_REG))]
9888   "ix86_unary_operator_ok (NEG, HImode, operands)"
9889   "neg{w}\t%0"
9890   [(set_attr "type" "negnot")
9891    (set_attr "mode" "HI")])
9892
9893 (define_insn "*neghi2_cmpz"
9894   [(set (reg:CCZ FLAGS_REG)
9895         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9896                      (const_int 0)))
9897    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9898         (neg:HI (match_dup 1)))]
9899   "ix86_unary_operator_ok (NEG, HImode, operands)"
9900   "neg{w}\t%0"
9901   [(set_attr "type" "negnot")
9902    (set_attr "mode" "HI")])
9903
9904 (define_expand "negqi2"
9905   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9906         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
9907   "TARGET_QIMODE_MATH"
9908   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9909
9910 (define_insn "*negqi2_1"
9911   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9912         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9913    (clobber (reg:CC FLAGS_REG))]
9914   "ix86_unary_operator_ok (NEG, QImode, operands)"
9915   "neg{b}\t%0"
9916   [(set_attr "type" "negnot")
9917    (set_attr "mode" "QI")])
9918
9919 (define_insn "*negqi2_cmpz"
9920   [(set (reg:CCZ FLAGS_REG)
9921         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9922                      (const_int 0)))
9923    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9924         (neg:QI (match_dup 1)))]
9925   "ix86_unary_operator_ok (NEG, QImode, operands)"
9926   "neg{b}\t%0"
9927   [(set_attr "type" "negnot")
9928    (set_attr "mode" "QI")])
9929
9930 ;; Changing of sign for FP values is doable using integer unit too.
9931
9932 (define_expand "<code><mode>2"
9933   [(set (match_operand:X87MODEF 0 "register_operand" "")
9934         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
9935   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9936   "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
9937
9938 (define_insn "*absneg<mode>2_mixed"
9939   [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
9940         (match_operator:MODEF 3 "absneg_operator"
9941           [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
9942    (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
9943    (clobber (reg:CC FLAGS_REG))]
9944   "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
9945   "#")
9946
9947 (define_insn "*absneg<mode>2_sse"
9948   [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
9949         (match_operator:MODEF 3 "absneg_operator"
9950           [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
9951    (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
9952    (clobber (reg:CC FLAGS_REG))]
9953   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
9954   "#")
9955
9956 (define_insn "*absneg<mode>2_i387"
9957   [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
9958         (match_operator:X87MODEF 3 "absneg_operator"
9959           [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
9960    (use (match_operand 2 "" ""))
9961    (clobber (reg:CC FLAGS_REG))]
9962   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9963   "#")
9964
9965 (define_expand "<code>tf2"
9966   [(set (match_operand:TF 0 "register_operand" "")
9967         (absneg:TF (match_operand:TF 1 "register_operand" "")))]
9968   "TARGET_SSE2"
9969   "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
9970
9971 (define_insn "*absnegtf2_sse"
9972   [(set (match_operand:TF 0 "register_operand" "=x,x")
9973         (match_operator:TF 3 "absneg_operator"
9974           [(match_operand:TF 1 "register_operand" "0,x")]))
9975    (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
9976    (clobber (reg:CC FLAGS_REG))]
9977   "TARGET_SSE2"
9978   "#")
9979
9980 ;; Splitters for fp abs and neg.
9981
9982 (define_split
9983   [(set (match_operand 0 "fp_register_operand" "")
9984         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9985    (use (match_operand 2 "" ""))
9986    (clobber (reg:CC FLAGS_REG))]
9987   "reload_completed"
9988   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9989
9990 (define_split
9991   [(set (match_operand 0 "register_operand" "")
9992         (match_operator 3 "absneg_operator"
9993           [(match_operand 1 "register_operand" "")]))
9994    (use (match_operand 2 "nonimmediate_operand" ""))
9995    (clobber (reg:CC FLAGS_REG))]
9996   "reload_completed && SSE_REG_P (operands[0])"
9997   [(set (match_dup 0) (match_dup 3))]
9998 {
9999   enum machine_mode mode = GET_MODE (operands[0]);
10000   enum machine_mode vmode = GET_MODE (operands[2]);
10001   rtx tmp;
10002
10003   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
10004   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
10005   if (operands_match_p (operands[0], operands[2]))
10006     {
10007       tmp = operands[1];
10008       operands[1] = operands[2];
10009       operands[2] = tmp;
10010     }
10011   if (GET_CODE (operands[3]) == ABS)
10012     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
10013   else
10014     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
10015   operands[3] = tmp;
10016 })
10017
10018 (define_split
10019   [(set (match_operand:SF 0 "register_operand" "")
10020         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
10021    (use (match_operand:V4SF 2 "" ""))
10022    (clobber (reg:CC FLAGS_REG))]
10023   "reload_completed"
10024   [(parallel [(set (match_dup 0) (match_dup 1))
10025               (clobber (reg:CC FLAGS_REG))])]
10026 {
10027   rtx tmp;
10028   operands[0] = gen_lowpart (SImode, operands[0]);
10029   if (GET_CODE (operands[1]) == ABS)
10030     {
10031       tmp = gen_int_mode (0x7fffffff, SImode);
10032       tmp = gen_rtx_AND (SImode, operands[0], tmp);
10033     }
10034   else
10035     {
10036       tmp = gen_int_mode (0x80000000, SImode);
10037       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10038     }
10039   operands[1] = tmp;
10040 })
10041
10042 (define_split
10043   [(set (match_operand:DF 0 "register_operand" "")
10044         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
10045    (use (match_operand 2 "" ""))
10046    (clobber (reg:CC FLAGS_REG))]
10047   "reload_completed"
10048   [(parallel [(set (match_dup 0) (match_dup 1))
10049               (clobber (reg:CC FLAGS_REG))])]
10050 {
10051   rtx tmp;
10052   if (TARGET_64BIT)
10053     {
10054       tmp = gen_lowpart (DImode, operands[0]);
10055       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
10056       operands[0] = tmp;
10057
10058       if (GET_CODE (operands[1]) == ABS)
10059         tmp = const0_rtx;
10060       else
10061         tmp = gen_rtx_NOT (DImode, tmp);
10062     }
10063   else
10064     {
10065       operands[0] = gen_highpart (SImode, operands[0]);
10066       if (GET_CODE (operands[1]) == ABS)
10067         {
10068           tmp = gen_int_mode (0x7fffffff, SImode);
10069           tmp = gen_rtx_AND (SImode, operands[0], tmp);
10070         }
10071       else
10072         {
10073           tmp = gen_int_mode (0x80000000, SImode);
10074           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10075         }
10076     }
10077   operands[1] = tmp;
10078 })
10079
10080 (define_split
10081   [(set (match_operand:XF 0 "register_operand" "")
10082         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
10083    (use (match_operand 2 "" ""))
10084    (clobber (reg:CC FLAGS_REG))]
10085   "reload_completed"
10086   [(parallel [(set (match_dup 0) (match_dup 1))
10087               (clobber (reg:CC FLAGS_REG))])]
10088 {
10089   rtx tmp;
10090   operands[0] = gen_rtx_REG (SImode,
10091                              true_regnum (operands[0])
10092                              + (TARGET_64BIT ? 1 : 2));
10093   if (GET_CODE (operands[1]) == ABS)
10094     {
10095       tmp = GEN_INT (0x7fff);
10096       tmp = gen_rtx_AND (SImode, operands[0], tmp);
10097     }
10098   else
10099     {
10100       tmp = GEN_INT (0x8000);
10101       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10102     }
10103   operands[1] = tmp;
10104 })
10105
10106 ;; Conditionalize these after reload. If they match before reload, we
10107 ;; lose the clobber and ability to use integer instructions.
10108
10109 (define_insn "*<code><mode>2_1"
10110   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
10111         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
10112   "TARGET_80387
10113    && (reload_completed
10114        || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
10115   "f<absnegprefix>"
10116   [(set_attr "type" "fsgn")
10117    (set_attr "mode" "<MODE>")])
10118
10119 (define_insn "*<code>extendsfdf2"
10120   [(set (match_operand:DF 0 "register_operand" "=f")
10121         (absneg:DF (float_extend:DF
10122                      (match_operand:SF 1 "register_operand" "0"))))]
10123   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10124   "f<absnegprefix>"
10125   [(set_attr "type" "fsgn")
10126    (set_attr "mode" "DF")])
10127
10128 (define_insn "*<code>extendsfxf2"
10129   [(set (match_operand:XF 0 "register_operand" "=f")
10130         (absneg:XF (float_extend:XF
10131                      (match_operand:SF 1 "register_operand" "0"))))]
10132   "TARGET_80387"
10133   "f<absnegprefix>"
10134   [(set_attr "type" "fsgn")
10135    (set_attr "mode" "XF")])
10136
10137 (define_insn "*<code>extenddfxf2"
10138   [(set (match_operand:XF 0 "register_operand" "=f")
10139         (absneg:XF (float_extend:XF
10140                       (match_operand:DF 1 "register_operand" "0"))))]
10141   "TARGET_80387"
10142   "f<absnegprefix>"
10143   [(set_attr "type" "fsgn")
10144    (set_attr "mode" "XF")])
10145
10146 ;; Copysign instructions
10147
10148 (define_mode_iterator CSGNMODE [SF DF TF])
10149 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
10150
10151 (define_expand "copysign<mode>3"
10152   [(match_operand:CSGNMODE 0 "register_operand" "")
10153    (match_operand:CSGNMODE 1 "nonmemory_operand" "")
10154    (match_operand:CSGNMODE 2 "register_operand" "")]
10155   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10156    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
10157 {
10158   ix86_expand_copysign (operands);
10159   DONE;
10160 })
10161
10162 (define_insn_and_split "copysign<mode>3_const"
10163   [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
10164         (unspec:CSGNMODE
10165           [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
10166            (match_operand:CSGNMODE 2 "register_operand" "0")
10167            (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
10168           UNSPEC_COPYSIGN))]
10169   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10170    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
10171   "#"
10172   "&& reload_completed"
10173   [(const_int 0)]
10174 {
10175   ix86_split_copysign_const (operands);
10176   DONE;
10177 })
10178
10179 (define_insn "copysign<mode>3_var"
10180   [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
10181         (unspec:CSGNMODE
10182           [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
10183            (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
10184            (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
10185            (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
10186           UNSPEC_COPYSIGN))
10187    (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
10188   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10189    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
10190   "#")
10191
10192 (define_split
10193   [(set (match_operand:CSGNMODE 0 "register_operand" "")
10194         (unspec:CSGNMODE
10195           [(match_operand:CSGNMODE 2 "register_operand" "")
10196            (match_operand:CSGNMODE 3 "register_operand" "")
10197            (match_operand:<CSGNVMODE> 4 "" "")
10198            (match_operand:<CSGNVMODE> 5 "" "")]
10199           UNSPEC_COPYSIGN))
10200    (clobber (match_scratch:<CSGNVMODE> 1 ""))]
10201   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10202     || (TARGET_SSE2 && (<MODE>mode == TFmode)))
10203    && reload_completed"
10204   [(const_int 0)]
10205 {
10206   ix86_split_copysign_var (operands);
10207   DONE;
10208 })
10209 \f
10210 ;; One complement instructions
10211
10212 (define_expand "one_cmpldi2"
10213   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10214         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10215   "TARGET_64BIT"
10216   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10217
10218 (define_insn "*one_cmpldi2_1_rex64"
10219   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10220         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10221   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10222   "not{q}\t%0"
10223   [(set_attr "type" "negnot")
10224    (set_attr "mode" "DI")])
10225
10226 (define_insn "*one_cmpldi2_2_rex64"
10227   [(set (reg FLAGS_REG)
10228         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10229                  (const_int 0)))
10230    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10231         (not:DI (match_dup 1)))]
10232   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10233    && ix86_unary_operator_ok (NOT, DImode, operands)"
10234   "#"
10235   [(set_attr "type" "alu1")
10236    (set_attr "mode" "DI")])
10237
10238 (define_split
10239   [(set (match_operand 0 "flags_reg_operand" "")
10240         (match_operator 2 "compare_operator"
10241           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10242            (const_int 0)]))
10243    (set (match_operand:DI 1 "nonimmediate_operand" "")
10244         (not:DI (match_dup 3)))]
10245   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10246   [(parallel [(set (match_dup 0)
10247                    (match_op_dup 2
10248                      [(xor:DI (match_dup 3) (const_int -1))
10249                       (const_int 0)]))
10250               (set (match_dup 1)
10251                    (xor:DI (match_dup 3) (const_int -1)))])]
10252   "")
10253
10254 (define_expand "one_cmplsi2"
10255   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10256         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10257   ""
10258   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10259
10260 (define_insn "*one_cmplsi2_1"
10261   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10262         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10263   "ix86_unary_operator_ok (NOT, SImode, operands)"
10264   "not{l}\t%0"
10265   [(set_attr "type" "negnot")
10266    (set_attr "mode" "SI")])
10267
10268 ;; ??? Currently never generated - xor is used instead.
10269 (define_insn "*one_cmplsi2_1_zext"
10270   [(set (match_operand:DI 0 "register_operand" "=r")
10271         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10272   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10273   "not{l}\t%k0"
10274   [(set_attr "type" "negnot")
10275    (set_attr "mode" "SI")])
10276
10277 (define_insn "*one_cmplsi2_2"
10278   [(set (reg FLAGS_REG)
10279         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10280                  (const_int 0)))
10281    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10282         (not:SI (match_dup 1)))]
10283   "ix86_match_ccmode (insn, CCNOmode)
10284    && ix86_unary_operator_ok (NOT, SImode, operands)"
10285   "#"
10286   [(set_attr "type" "alu1")
10287    (set_attr "mode" "SI")])
10288
10289 (define_split
10290   [(set (match_operand 0 "flags_reg_operand" "")
10291         (match_operator 2 "compare_operator"
10292           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10293            (const_int 0)]))
10294    (set (match_operand:SI 1 "nonimmediate_operand" "")
10295         (not:SI (match_dup 3)))]
10296   "ix86_match_ccmode (insn, CCNOmode)"
10297   [(parallel [(set (match_dup 0)
10298                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10299                                     (const_int 0)]))
10300               (set (match_dup 1)
10301                    (xor:SI (match_dup 3) (const_int -1)))])]
10302   "")
10303
10304 ;; ??? Currently never generated - xor is used instead.
10305 (define_insn "*one_cmplsi2_2_zext"
10306   [(set (reg FLAGS_REG)
10307         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10308                  (const_int 0)))
10309    (set (match_operand:DI 0 "register_operand" "=r")
10310         (zero_extend:DI (not:SI (match_dup 1))))]
10311   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10312    && ix86_unary_operator_ok (NOT, SImode, operands)"
10313   "#"
10314   [(set_attr "type" "alu1")
10315    (set_attr "mode" "SI")])
10316
10317 (define_split
10318   [(set (match_operand 0 "flags_reg_operand" "")
10319         (match_operator 2 "compare_operator"
10320           [(not:SI (match_operand:SI 3 "register_operand" ""))
10321            (const_int 0)]))
10322    (set (match_operand:DI 1 "register_operand" "")
10323         (zero_extend:DI (not:SI (match_dup 3))))]
10324   "ix86_match_ccmode (insn, CCNOmode)"
10325   [(parallel [(set (match_dup 0)
10326                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10327                                     (const_int 0)]))
10328               (set (match_dup 1)
10329                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10330   "")
10331
10332 (define_expand "one_cmplhi2"
10333   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10334         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10335   "TARGET_HIMODE_MATH"
10336   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10337
10338 (define_insn "*one_cmplhi2_1"
10339   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10340         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10341   "ix86_unary_operator_ok (NOT, HImode, operands)"
10342   "not{w}\t%0"
10343   [(set_attr "type" "negnot")
10344    (set_attr "mode" "HI")])
10345
10346 (define_insn "*one_cmplhi2_2"
10347   [(set (reg FLAGS_REG)
10348         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10349                  (const_int 0)))
10350    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10351         (not:HI (match_dup 1)))]
10352   "ix86_match_ccmode (insn, CCNOmode)
10353    && ix86_unary_operator_ok (NEG, HImode, operands)"
10354   "#"
10355   [(set_attr "type" "alu1")
10356    (set_attr "mode" "HI")])
10357
10358 (define_split
10359   [(set (match_operand 0 "flags_reg_operand" "")
10360         (match_operator 2 "compare_operator"
10361           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10362            (const_int 0)]))
10363    (set (match_operand:HI 1 "nonimmediate_operand" "")
10364         (not:HI (match_dup 3)))]
10365   "ix86_match_ccmode (insn, CCNOmode)"
10366   [(parallel [(set (match_dup 0)
10367                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10368                                     (const_int 0)]))
10369               (set (match_dup 1)
10370                    (xor:HI (match_dup 3) (const_int -1)))])]
10371   "")
10372
10373 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10374 (define_expand "one_cmplqi2"
10375   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10376         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10377   "TARGET_QIMODE_MATH"
10378   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10379
10380 (define_insn "*one_cmplqi2_1"
10381   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10382         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10383   "ix86_unary_operator_ok (NOT, QImode, operands)"
10384   "@
10385    not{b}\t%0
10386    not{l}\t%k0"
10387   [(set_attr "type" "negnot")
10388    (set_attr "mode" "QI,SI")])
10389
10390 (define_insn "*one_cmplqi2_2"
10391   [(set (reg FLAGS_REG)
10392         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10393                  (const_int 0)))
10394    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10395         (not:QI (match_dup 1)))]
10396   "ix86_match_ccmode (insn, CCNOmode)
10397    && ix86_unary_operator_ok (NOT, QImode, operands)"
10398   "#"
10399   [(set_attr "type" "alu1")
10400    (set_attr "mode" "QI")])
10401
10402 (define_split
10403   [(set (match_operand 0 "flags_reg_operand" "")
10404         (match_operator 2 "compare_operator"
10405           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10406            (const_int 0)]))
10407    (set (match_operand:QI 1 "nonimmediate_operand" "")
10408         (not:QI (match_dup 3)))]
10409   "ix86_match_ccmode (insn, CCNOmode)"
10410   [(parallel [(set (match_dup 0)
10411                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10412                                     (const_int 0)]))
10413               (set (match_dup 1)
10414                    (xor:QI (match_dup 3) (const_int -1)))])]
10415   "")
10416 \f
10417 ;; Arithmetic shift instructions
10418
10419 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10420 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10421 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10422 ;; from the assembler input.
10423 ;;
10424 ;; This instruction shifts the target reg/mem as usual, but instead of
10425 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10426 ;; is a left shift double, bits are taken from the high order bits of
10427 ;; reg, else if the insn is a shift right double, bits are taken from the
10428 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10429 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10430 ;;
10431 ;; Since sh[lr]d does not change the `reg' operand, that is done
10432 ;; separately, making all shifts emit pairs of shift double and normal
10433 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10434 ;; support a 63 bit shift, each shift where the count is in a reg expands
10435 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10436 ;;
10437 ;; If the shift count is a constant, we need never emit more than one
10438 ;; shift pair, instead using moves and sign extension for counts greater
10439 ;; than 31.
10440
10441 (define_expand "ashlti3"
10442   [(set (match_operand:TI 0 "register_operand" "")
10443         (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "")
10444                    (match_operand:QI 2 "nonmemory_operand" "")))]
10445   "TARGET_64BIT"
10446   "ix86_expand_binary_operator (ASHIFT, TImode, operands); DONE;")
10447
10448 ;; This pattern must be defined before *ashlti3_1 to prevent
10449 ;; combine pass from converting sse2_ashlti3 to *ashlti3_1.
10450
10451 (define_insn "*avx_ashlti3"
10452   [(set (match_operand:TI 0 "register_operand" "=x")
10453         (ashift:TI (match_operand:TI 1 "register_operand" "x")
10454                    (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
10455   "TARGET_AVX"
10456 {
10457   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
10458   return "vpslldq\t{%2, %1, %0|%0, %1, %2}";
10459 }
10460   [(set_attr "type" "sseishft")
10461    (set_attr "prefix" "vex")
10462    (set_attr "length_immediate" "1")
10463    (set_attr "mode" "TI")])
10464
10465 (define_insn "sse2_ashlti3"
10466   [(set (match_operand:TI 0 "register_operand" "=x")
10467         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10468                    (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
10469   "TARGET_SSE2"
10470 {
10471   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
10472   return "pslldq\t{%2, %0|%0, %2}";
10473 }
10474   [(set_attr "type" "sseishft")
10475    (set_attr "prefix_data16" "1")
10476    (set_attr "length_immediate" "1")
10477    (set_attr "mode" "TI")])
10478
10479 (define_insn "*ashlti3_1"
10480   [(set (match_operand:TI 0 "register_operand" "=&r,r")
10481         (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "n,0")
10482                    (match_operand:QI 2 "nonmemory_operand" "Oc,Oc")))
10483    (clobber (reg:CC FLAGS_REG))]
10484   "TARGET_64BIT"
10485   "#"
10486   [(set_attr "type" "multi")])
10487
10488 (define_peephole2
10489   [(match_scratch:DI 3 "r")
10490    (parallel [(set (match_operand:TI 0 "register_operand" "")
10491                    (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10492                               (match_operand:QI 2 "nonmemory_operand" "")))
10493               (clobber (reg:CC FLAGS_REG))])
10494    (match_dup 3)]
10495   "TARGET_64BIT"
10496   [(const_int 0)]
10497   "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10498
10499 (define_split
10500   [(set (match_operand:TI 0 "register_operand" "")
10501         (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10502                    (match_operand:QI 2 "nonmemory_operand" "")))
10503    (clobber (reg:CC FLAGS_REG))]
10504   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10505                     ? epilogue_completed : reload_completed)"
10506   [(const_int 0)]
10507   "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10508
10509 (define_insn "x86_64_shld"
10510   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
10511         (ior:DI (ashift:DI (match_dup 0)
10512                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
10513                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
10514                   (minus:QI (const_int 64) (match_dup 2)))))
10515    (clobber (reg:CC FLAGS_REG))]
10516   "TARGET_64BIT"
10517   "shld{q}\t{%s2%1, %0|%0, %1, %2}"
10518   [(set_attr "type" "ishift")
10519    (set_attr "prefix_0f" "1")
10520    (set_attr "mode" "DI")
10521    (set_attr "athlon_decode" "vector")
10522    (set_attr "amdfam10_decode" "vector")])
10523
10524 (define_expand "x86_64_shift_adj_1"
10525   [(set (reg:CCZ FLAGS_REG)
10526         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10527                              (const_int 64))
10528                      (const_int 0)))
10529    (set (match_operand:DI 0 "register_operand" "")
10530         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10531                          (match_operand:DI 1 "register_operand" "")
10532                          (match_dup 0)))
10533    (set (match_dup 1)
10534         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10535                          (match_operand:DI 3 "register_operand" "r")
10536                          (match_dup 1)))]
10537   "TARGET_64BIT"
10538   "")
10539
10540 (define_expand "x86_64_shift_adj_2"
10541   [(use (match_operand:DI 0 "register_operand" ""))
10542    (use (match_operand:DI 1 "register_operand" ""))
10543    (use (match_operand:QI 2 "register_operand" ""))]
10544   "TARGET_64BIT"
10545 {
10546   rtx label = gen_label_rtx ();
10547   rtx tmp;
10548
10549   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (64)));
10550
10551   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10552   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10553   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10554                               gen_rtx_LABEL_REF (VOIDmode, label),
10555                               pc_rtx);
10556   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10557   JUMP_LABEL (tmp) = label;
10558
10559   emit_move_insn (operands[0], operands[1]);
10560   ix86_expand_clear (operands[1]);
10561
10562   emit_label (label);
10563   LABEL_NUSES (label) = 1;
10564
10565   DONE;
10566 })
10567
10568 (define_expand "ashldi3"
10569   [(set (match_operand:DI 0 "shiftdi_operand" "")
10570         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10571                    (match_operand:QI 2 "nonmemory_operand" "")))]
10572   ""
10573   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10574
10575 (define_insn "*ashldi3_1_rex64"
10576   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10577         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10578                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10579    (clobber (reg:CC FLAGS_REG))]
10580   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10581 {
10582   switch (get_attr_type (insn))
10583     {
10584     case TYPE_ALU:
10585       gcc_assert (operands[2] == const1_rtx);
10586       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10587       return "add{q}\t%0, %0";
10588
10589     case TYPE_LEA:
10590       gcc_assert (CONST_INT_P (operands[2]));
10591       gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10592       operands[1] = gen_rtx_MULT (DImode, operands[1],
10593                                   GEN_INT (1 << INTVAL (operands[2])));
10594       return "lea{q}\t{%a1, %0|%0, %a1}";
10595
10596     default:
10597       if (REG_P (operands[2]))
10598         return "sal{q}\t{%b2, %0|%0, %b2}";
10599       else if (operands[2] == const1_rtx
10600                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10601         return "sal{q}\t%0";
10602       else
10603         return "sal{q}\t{%2, %0|%0, %2}";
10604     }
10605 }
10606   [(set (attr "type")
10607      (cond [(eq_attr "alternative" "1")
10608               (const_string "lea")
10609             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10610                           (const_int 0))
10611                       (match_operand 0 "register_operand" ""))
10612                  (match_operand 2 "const1_operand" ""))
10613               (const_string "alu")
10614            ]
10615            (const_string "ishift")))
10616    (set (attr "length_immediate")
10617      (if_then_else
10618        (ior (eq_attr "type" "alu")
10619             (and (eq_attr "type" "ishift")
10620                  (and (match_operand 2 "const1_operand" "")
10621                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10622                           (const_int 0)))))
10623        (const_string "0")
10624        (const_string "*")))
10625    (set_attr "mode" "DI")])
10626
10627 ;; Convert lea to the lea pattern to avoid flags dependency.
10628 (define_split
10629   [(set (match_operand:DI 0 "register_operand" "")
10630         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10631                    (match_operand:QI 2 "immediate_operand" "")))
10632    (clobber (reg:CC FLAGS_REG))]
10633   "TARGET_64BIT && reload_completed
10634    && true_regnum (operands[0]) != true_regnum (operands[1])"
10635   [(set (match_dup 0)
10636         (mult:DI (match_dup 1)
10637                  (match_dup 2)))]
10638   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10639
10640 ;; This pattern can't accept a variable shift count, since shifts by
10641 ;; zero don't affect the flags.  We assume that shifts by constant
10642 ;; zero are optimized away.
10643 (define_insn "*ashldi3_cmp_rex64"
10644   [(set (reg FLAGS_REG)
10645         (compare
10646           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10647                      (match_operand:QI 2 "const_1_to_63_operand" "J"))
10648           (const_int 0)))
10649    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10650         (ashift:DI (match_dup 1) (match_dup 2)))]
10651   "TARGET_64BIT
10652    && (optimize_function_for_size_p (cfun)
10653        || !TARGET_PARTIAL_FLAG_REG_STALL
10654        || (operands[2] == const1_rtx
10655            && (TARGET_SHIFT1
10656                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
10657    && ix86_match_ccmode (insn, CCGOCmode)
10658    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10659 {
10660   switch (get_attr_type (insn))
10661     {
10662     case TYPE_ALU:
10663       gcc_assert (operands[2] == const1_rtx);
10664       return "add{q}\t%0, %0";
10665
10666     default:
10667       if (REG_P (operands[2]))
10668         return "sal{q}\t{%b2, %0|%0, %b2}";
10669       else if (operands[2] == const1_rtx
10670                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10671         return "sal{q}\t%0";
10672       else
10673         return "sal{q}\t{%2, %0|%0, %2}";
10674     }
10675 }
10676   [(set (attr "type")
10677      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10678                           (const_int 0))
10679                       (match_operand 0 "register_operand" ""))
10680                  (match_operand 2 "const1_operand" ""))
10681               (const_string "alu")
10682            ]
10683            (const_string "ishift")))
10684    (set (attr "length_immediate")
10685      (if_then_else
10686        (ior (eq_attr "type" "alu")
10687             (and (eq_attr "type" "ishift")
10688                  (and (match_operand 2 "const1_operand" "")
10689                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10690                           (const_int 0)))))
10691        (const_string "0")
10692        (const_string "*")))
10693    (set_attr "mode" "DI")])
10694
10695 (define_insn "*ashldi3_cconly_rex64"
10696   [(set (reg FLAGS_REG)
10697         (compare
10698           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10699                      (match_operand:QI 2 "const_1_to_63_operand" "J"))
10700           (const_int 0)))
10701    (clobber (match_scratch:DI 0 "=r"))]
10702   "TARGET_64BIT
10703    && (optimize_function_for_size_p (cfun)
10704        || !TARGET_PARTIAL_FLAG_REG_STALL
10705        || (operands[2] == const1_rtx
10706            && (TARGET_SHIFT1
10707                || TARGET_DOUBLE_WITH_ADD)))
10708    && ix86_match_ccmode (insn, CCGOCmode)
10709    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10710 {
10711   switch (get_attr_type (insn))
10712     {
10713     case TYPE_ALU:
10714       gcc_assert (operands[2] == const1_rtx);
10715       return "add{q}\t%0, %0";
10716
10717     default:
10718       if (REG_P (operands[2]))
10719         return "sal{q}\t{%b2, %0|%0, %b2}";
10720       else if (operands[2] == const1_rtx
10721                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10722         return "sal{q}\t%0";
10723       else
10724         return "sal{q}\t{%2, %0|%0, %2}";
10725     }
10726 }
10727   [(set (attr "type")
10728      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10729                           (const_int 0))
10730                       (match_operand 0 "register_operand" ""))
10731                  (match_operand 2 "const1_operand" ""))
10732               (const_string "alu")
10733            ]
10734            (const_string "ishift")))
10735    (set (attr "length_immediate")
10736      (if_then_else
10737        (ior (eq_attr "type" "alu")
10738             (and (eq_attr "type" "ishift")
10739                  (and (match_operand 2 "const1_operand" "")
10740                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10741                           (const_int 0)))))
10742        (const_string "0")
10743        (const_string "*")))
10744    (set_attr "mode" "DI")])
10745
10746 (define_insn "*ashldi3_1"
10747   [(set (match_operand:DI 0 "register_operand" "=&r,r")
10748         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10749                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10750    (clobber (reg:CC FLAGS_REG))]
10751   "!TARGET_64BIT"
10752   "#"
10753   [(set_attr "type" "multi")])
10754
10755 ;; By default we don't ask for a scratch register, because when DImode
10756 ;; values are manipulated, registers are already at a premium.  But if
10757 ;; we have one handy, we won't turn it away.
10758 (define_peephole2
10759   [(match_scratch:SI 3 "r")
10760    (parallel [(set (match_operand:DI 0 "register_operand" "")
10761                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10762                               (match_operand:QI 2 "nonmemory_operand" "")))
10763               (clobber (reg:CC FLAGS_REG))])
10764    (match_dup 3)]
10765   "!TARGET_64BIT && TARGET_CMOVE"
10766   [(const_int 0)]
10767   "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10768
10769 (define_split
10770   [(set (match_operand:DI 0 "register_operand" "")
10771         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10772                    (match_operand:QI 2 "nonmemory_operand" "")))
10773    (clobber (reg:CC FLAGS_REG))]
10774   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10775                      ? epilogue_completed : reload_completed)"
10776   [(const_int 0)]
10777   "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10778
10779 (define_insn "x86_shld"
10780   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
10781         (ior:SI (ashift:SI (match_dup 0)
10782                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
10783                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
10784                   (minus:QI (const_int 32) (match_dup 2)))))
10785    (clobber (reg:CC FLAGS_REG))]
10786   ""
10787   "shld{l}\t{%s2%1, %0|%0, %1, %2}"
10788   [(set_attr "type" "ishift")
10789    (set_attr "prefix_0f" "1")
10790    (set_attr "mode" "SI")
10791    (set_attr "pent_pair" "np")
10792    (set_attr "athlon_decode" "vector")
10793    (set_attr "amdfam10_decode" "vector")])
10794
10795 (define_expand "x86_shift_adj_1"
10796   [(set (reg:CCZ FLAGS_REG)
10797         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10798                              (const_int 32))
10799                      (const_int 0)))
10800    (set (match_operand:SI 0 "register_operand" "")
10801         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10802                          (match_operand:SI 1 "register_operand" "")
10803                          (match_dup 0)))
10804    (set (match_dup 1)
10805         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10806                          (match_operand:SI 3 "register_operand" "r")
10807                          (match_dup 1)))]
10808   "TARGET_CMOVE"
10809   "")
10810
10811 (define_expand "x86_shift_adj_2"
10812   [(use (match_operand:SI 0 "register_operand" ""))
10813    (use (match_operand:SI 1 "register_operand" ""))
10814    (use (match_operand:QI 2 "register_operand" ""))]
10815   ""
10816 {
10817   rtx label = gen_label_rtx ();
10818   rtx tmp;
10819
10820   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10821
10822   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10823   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10824   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10825                               gen_rtx_LABEL_REF (VOIDmode, label),
10826                               pc_rtx);
10827   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10828   JUMP_LABEL (tmp) = label;
10829
10830   emit_move_insn (operands[0], operands[1]);
10831   ix86_expand_clear (operands[1]);
10832
10833   emit_label (label);
10834   LABEL_NUSES (label) = 1;
10835
10836   DONE;
10837 })
10838
10839 (define_expand "ashlsi3"
10840   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10841         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10842                    (match_operand:QI 2 "nonmemory_operand" "")))]
10843   ""
10844   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10845
10846 (define_insn "*ashlsi3_1"
10847   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10848         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10849                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10850    (clobber (reg:CC FLAGS_REG))]
10851   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10852 {
10853   switch (get_attr_type (insn))
10854     {
10855     case TYPE_ALU:
10856       gcc_assert (operands[2] == const1_rtx);
10857       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10858       return "add{l}\t%0, %0";
10859
10860     case TYPE_LEA:
10861       return "#";
10862
10863     default:
10864       if (REG_P (operands[2]))
10865         return "sal{l}\t{%b2, %0|%0, %b2}";
10866       else if (operands[2] == const1_rtx
10867                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10868         return "sal{l}\t%0";
10869       else
10870         return "sal{l}\t{%2, %0|%0, %2}";
10871     }
10872 }
10873   [(set (attr "type")
10874      (cond [(eq_attr "alternative" "1")
10875               (const_string "lea")
10876             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10877                           (const_int 0))
10878                       (match_operand 0 "register_operand" ""))
10879                  (match_operand 2 "const1_operand" ""))
10880               (const_string "alu")
10881            ]
10882            (const_string "ishift")))
10883    (set (attr "length_immediate")
10884      (if_then_else
10885        (ior (eq_attr "type" "alu")
10886             (and (eq_attr "type" "ishift")
10887                  (and (match_operand 2 "const1_operand" "")
10888                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10889                           (const_int 0)))))
10890        (const_string "0")
10891        (const_string "*")))
10892    (set_attr "mode" "SI")])
10893
10894 ;; Convert lea to the lea pattern to avoid flags dependency.
10895 (define_split
10896   [(set (match_operand 0 "register_operand" "")
10897         (ashift (match_operand 1 "index_register_operand" "")
10898                 (match_operand:QI 2 "const_int_operand" "")))
10899    (clobber (reg:CC FLAGS_REG))]
10900   "reload_completed
10901    && true_regnum (operands[0]) != true_regnum (operands[1])
10902    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10903   [(const_int 0)]
10904 {
10905   rtx pat;
10906   enum machine_mode mode = GET_MODE (operands[0]);
10907
10908   if (GET_MODE_SIZE (mode) < 4)
10909     operands[0] = gen_lowpart (SImode, operands[0]);
10910   if (mode != Pmode)
10911     operands[1] = gen_lowpart (Pmode, operands[1]);
10912   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10913
10914   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10915   if (Pmode != SImode)
10916     pat = gen_rtx_SUBREG (SImode, pat, 0);
10917   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10918   DONE;
10919 })
10920
10921 ;; Rare case of shifting RSP is handled by generating move and shift
10922 (define_split
10923   [(set (match_operand 0 "register_operand" "")
10924         (ashift (match_operand 1 "register_operand" "")
10925                 (match_operand:QI 2 "const_int_operand" "")))
10926    (clobber (reg:CC FLAGS_REG))]
10927   "reload_completed
10928    && true_regnum (operands[0]) != true_regnum (operands[1])"
10929   [(const_int 0)]
10930 {
10931   rtx pat, clob;
10932   emit_move_insn (operands[0], operands[1]);
10933   pat = gen_rtx_SET (VOIDmode, operands[0],
10934                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
10935                                      operands[0], operands[2]));
10936   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10937   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10938   DONE;
10939 })
10940
10941 (define_insn "*ashlsi3_1_zext"
10942   [(set (match_operand:DI 0 "register_operand" "=r,r")
10943         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10944                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10945    (clobber (reg:CC FLAGS_REG))]
10946   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10947 {
10948   switch (get_attr_type (insn))
10949     {
10950     case TYPE_ALU:
10951       gcc_assert (operands[2] == const1_rtx);
10952       return "add{l}\t%k0, %k0";
10953
10954     case TYPE_LEA:
10955       return "#";
10956
10957     default:
10958       if (REG_P (operands[2]))
10959         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10960       else if (operands[2] == const1_rtx
10961                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10962         return "sal{l}\t%k0";
10963       else
10964         return "sal{l}\t{%2, %k0|%k0, %2}";
10965     }
10966 }
10967   [(set (attr "type")
10968      (cond [(eq_attr "alternative" "1")
10969               (const_string "lea")
10970             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10971                      (const_int 0))
10972                  (match_operand 2 "const1_operand" ""))
10973               (const_string "alu")
10974            ]
10975            (const_string "ishift")))
10976    (set (attr "length_immediate")
10977      (if_then_else
10978        (ior (eq_attr "type" "alu")
10979             (and (eq_attr "type" "ishift")
10980                  (and (match_operand 2 "const1_operand" "")
10981                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10982                           (const_int 0)))))
10983        (const_string "0")
10984        (const_string "*")))
10985    (set_attr "mode" "SI")])
10986
10987 ;; Convert lea to the lea pattern to avoid flags dependency.
10988 (define_split
10989   [(set (match_operand:DI 0 "register_operand" "")
10990         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10991                                 (match_operand:QI 2 "const_int_operand" ""))))
10992    (clobber (reg:CC FLAGS_REG))]
10993   "TARGET_64BIT && reload_completed
10994    && true_regnum (operands[0]) != true_regnum (operands[1])"
10995   [(set (match_dup 0) (zero_extend:DI
10996                         (subreg:SI (mult:SI (match_dup 1)
10997                                             (match_dup 2)) 0)))]
10998 {
10999   operands[1] = gen_lowpart (Pmode, operands[1]);
11000   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11001 })
11002
11003 ;; This pattern can't accept a variable shift count, since shifts by
11004 ;; zero don't affect the flags.  We assume that shifts by constant
11005 ;; zero are optimized away.
11006 (define_insn "*ashlsi3_cmp"
11007   [(set (reg FLAGS_REG)
11008         (compare
11009           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11010                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11011           (const_int 0)))
11012    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11013         (ashift:SI (match_dup 1) (match_dup 2)))]
11014    "(optimize_function_for_size_p (cfun)
11015      || !TARGET_PARTIAL_FLAG_REG_STALL
11016      || (operands[2] == const1_rtx
11017          && (TARGET_SHIFT1
11018              || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11019    && ix86_match_ccmode (insn, CCGOCmode)
11020    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11021 {
11022   switch (get_attr_type (insn))
11023     {
11024     case TYPE_ALU:
11025       gcc_assert (operands[2] == const1_rtx);
11026       return "add{l}\t%0, %0";
11027
11028     default:
11029       if (REG_P (operands[2]))
11030         return "sal{l}\t{%b2, %0|%0, %b2}";
11031       else if (operands[2] == const1_rtx
11032                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11033         return "sal{l}\t%0";
11034       else
11035         return "sal{l}\t{%2, %0|%0, %2}";
11036     }
11037 }
11038   [(set (attr "type")
11039      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11040                           (const_int 0))
11041                       (match_operand 0 "register_operand" ""))
11042                  (match_operand 2 "const1_operand" ""))
11043               (const_string "alu")
11044            ]
11045            (const_string "ishift")))
11046    (set (attr "length_immediate")
11047      (if_then_else
11048        (ior (eq_attr "type" "alu")
11049             (and (eq_attr "type" "ishift")
11050                  (and (match_operand 2 "const1_operand" "")
11051                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11052                           (const_int 0)))))
11053        (const_string "0")
11054        (const_string "*")))
11055    (set_attr "mode" "SI")])
11056
11057 (define_insn "*ashlsi3_cconly"
11058   [(set (reg FLAGS_REG)
11059         (compare
11060           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11061                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11062           (const_int 0)))
11063    (clobber (match_scratch:SI 0 "=r"))]
11064   "(optimize_function_for_size_p (cfun)
11065     || !TARGET_PARTIAL_FLAG_REG_STALL
11066     || (operands[2] == const1_rtx
11067         && (TARGET_SHIFT1
11068             || TARGET_DOUBLE_WITH_ADD)))
11069    && ix86_match_ccmode (insn, CCGOCmode)
11070    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11071 {
11072   switch (get_attr_type (insn))
11073     {
11074     case TYPE_ALU:
11075       gcc_assert (operands[2] == const1_rtx);
11076       return "add{l}\t%0, %0";
11077
11078     default:
11079       if (REG_P (operands[2]))
11080         return "sal{l}\t{%b2, %0|%0, %b2}";
11081       else if (operands[2] == const1_rtx
11082                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11083         return "sal{l}\t%0";
11084       else
11085         return "sal{l}\t{%2, %0|%0, %2}";
11086     }
11087 }
11088   [(set (attr "type")
11089      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11090                           (const_int 0))
11091                       (match_operand 0 "register_operand" ""))
11092                  (match_operand 2 "const1_operand" ""))
11093               (const_string "alu")
11094            ]
11095            (const_string "ishift")))
11096    (set (attr "length_immediate")
11097      (if_then_else
11098        (ior (eq_attr "type" "alu")
11099             (and (eq_attr "type" "ishift")
11100                  (and (match_operand 2 "const1_operand" "")
11101                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11102                           (const_int 0)))))
11103        (const_string "0")
11104        (const_string "*")))
11105    (set_attr "mode" "SI")])
11106
11107 (define_insn "*ashlsi3_cmp_zext"
11108   [(set (reg FLAGS_REG)
11109         (compare
11110           (ashift:SI (match_operand:SI 1 "register_operand" "0")
11111                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11112           (const_int 0)))
11113    (set (match_operand:DI 0 "register_operand" "=r")
11114         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11115   "TARGET_64BIT
11116    && (optimize_function_for_size_p (cfun)
11117        || !TARGET_PARTIAL_FLAG_REG_STALL
11118        || (operands[2] == const1_rtx
11119            && (TARGET_SHIFT1
11120                || TARGET_DOUBLE_WITH_ADD)))
11121    && ix86_match_ccmode (insn, CCGOCmode)
11122    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11123 {
11124   switch (get_attr_type (insn))
11125     {
11126     case TYPE_ALU:
11127       gcc_assert (operands[2] == const1_rtx);
11128       return "add{l}\t%k0, %k0";
11129
11130     default:
11131       if (REG_P (operands[2]))
11132         return "sal{l}\t{%b2, %k0|%k0, %b2}";
11133       else if (operands[2] == const1_rtx
11134                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11135         return "sal{l}\t%k0";
11136       else
11137         return "sal{l}\t{%2, %k0|%k0, %2}";
11138     }
11139 }
11140   [(set (attr "type")
11141      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11142                      (const_int 0))
11143                  (match_operand 2 "const1_operand" ""))
11144               (const_string "alu")
11145            ]
11146            (const_string "ishift")))
11147    (set (attr "length_immediate")
11148      (if_then_else
11149        (ior (eq_attr "type" "alu")
11150             (and (eq_attr "type" "ishift")
11151                  (and (match_operand 2 "const1_operand" "")
11152                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11153                           (const_int 0)))))
11154        (const_string "0")
11155        (const_string "*")))
11156    (set_attr "mode" "SI")])
11157
11158 (define_expand "ashlhi3"
11159   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11160         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11161                    (match_operand:QI 2 "nonmemory_operand" "")))]
11162   "TARGET_HIMODE_MATH"
11163   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11164
11165 (define_insn "*ashlhi3_1_lea"
11166   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11167         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
11168                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11169    (clobber (reg:CC FLAGS_REG))]
11170   "!TARGET_PARTIAL_REG_STALL
11171    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11172 {
11173   switch (get_attr_type (insn))
11174     {
11175     case TYPE_LEA:
11176       return "#";
11177     case TYPE_ALU:
11178       gcc_assert (operands[2] == const1_rtx);
11179       return "add{w}\t%0, %0";
11180
11181     default:
11182       if (REG_P (operands[2]))
11183         return "sal{w}\t{%b2, %0|%0, %b2}";
11184       else if (operands[2] == const1_rtx
11185                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11186         return "sal{w}\t%0";
11187       else
11188         return "sal{w}\t{%2, %0|%0, %2}";
11189     }
11190 }
11191   [(set (attr "type")
11192      (cond [(eq_attr "alternative" "1")
11193               (const_string "lea")
11194             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11195                           (const_int 0))
11196                       (match_operand 0 "register_operand" ""))
11197                  (match_operand 2 "const1_operand" ""))
11198               (const_string "alu")
11199            ]
11200            (const_string "ishift")))
11201    (set (attr "length_immediate")
11202      (if_then_else
11203        (ior (eq_attr "type" "alu")
11204             (and (eq_attr "type" "ishift")
11205                  (and (match_operand 2 "const1_operand" "")
11206                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11207                           (const_int 0)))))
11208        (const_string "0")
11209        (const_string "*")))
11210    (set_attr "mode" "HI,SI")])
11211
11212 (define_insn "*ashlhi3_1"
11213   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11214         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11215                    (match_operand:QI 2 "nonmemory_operand" "cI")))
11216    (clobber (reg:CC FLAGS_REG))]
11217   "TARGET_PARTIAL_REG_STALL
11218    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11219 {
11220   switch (get_attr_type (insn))
11221     {
11222     case TYPE_ALU:
11223       gcc_assert (operands[2] == const1_rtx);
11224       return "add{w}\t%0, %0";
11225
11226     default:
11227       if (REG_P (operands[2]))
11228         return "sal{w}\t{%b2, %0|%0, %b2}";
11229       else if (operands[2] == const1_rtx
11230                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11231         return "sal{w}\t%0";
11232       else
11233         return "sal{w}\t{%2, %0|%0, %2}";
11234     }
11235 }
11236   [(set (attr "type")
11237      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11238                           (const_int 0))
11239                       (match_operand 0 "register_operand" ""))
11240                  (match_operand 2 "const1_operand" ""))
11241               (const_string "alu")
11242            ]
11243            (const_string "ishift")))
11244    (set (attr "length_immediate")
11245      (if_then_else
11246        (ior (eq_attr "type" "alu")
11247             (and (eq_attr "type" "ishift")
11248                  (and (match_operand 2 "const1_operand" "")
11249                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11250                           (const_int 0)))))
11251        (const_string "0")
11252        (const_string "*")))
11253    (set_attr "mode" "HI")])
11254
11255 ;; This pattern can't accept a variable shift count, since shifts by
11256 ;; zero don't affect the flags.  We assume that shifts by constant
11257 ;; zero are optimized away.
11258 (define_insn "*ashlhi3_cmp"
11259   [(set (reg FLAGS_REG)
11260         (compare
11261           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11262                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11263           (const_int 0)))
11264    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11265         (ashift:HI (match_dup 1) (match_dup 2)))]
11266   "(optimize_function_for_size_p (cfun)
11267     || !TARGET_PARTIAL_FLAG_REG_STALL
11268     || (operands[2] == const1_rtx
11269         && (TARGET_SHIFT1
11270             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11271    && ix86_match_ccmode (insn, CCGOCmode)
11272    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11273 {
11274   switch (get_attr_type (insn))
11275     {
11276     case TYPE_ALU:
11277       gcc_assert (operands[2] == const1_rtx);
11278       return "add{w}\t%0, %0";
11279
11280     default:
11281       if (REG_P (operands[2]))
11282         return "sal{w}\t{%b2, %0|%0, %b2}";
11283       else if (operands[2] == const1_rtx
11284                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11285         return "sal{w}\t%0";
11286       else
11287         return "sal{w}\t{%2, %0|%0, %2}";
11288     }
11289 }
11290   [(set (attr "type")
11291      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11292                           (const_int 0))
11293                       (match_operand 0 "register_operand" ""))
11294                  (match_operand 2 "const1_operand" ""))
11295               (const_string "alu")
11296            ]
11297            (const_string "ishift")))
11298    (set (attr "length_immediate")
11299      (if_then_else
11300        (ior (eq_attr "type" "alu")
11301             (and (eq_attr "type" "ishift")
11302                  (and (match_operand 2 "const1_operand" "")
11303                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11304                           (const_int 0)))))
11305        (const_string "0")
11306        (const_string "*")))
11307    (set_attr "mode" "HI")])
11308
11309 (define_insn "*ashlhi3_cconly"
11310   [(set (reg FLAGS_REG)
11311         (compare
11312           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11313                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11314           (const_int 0)))
11315    (clobber (match_scratch:HI 0 "=r"))]
11316   "(optimize_function_for_size_p (cfun)
11317     || !TARGET_PARTIAL_FLAG_REG_STALL
11318     || (operands[2] == const1_rtx
11319         && (TARGET_SHIFT1
11320             || TARGET_DOUBLE_WITH_ADD)))
11321    && ix86_match_ccmode (insn, CCGOCmode)
11322    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11323 {
11324   switch (get_attr_type (insn))
11325     {
11326     case TYPE_ALU:
11327       gcc_assert (operands[2] == const1_rtx);
11328       return "add{w}\t%0, %0";
11329
11330     default:
11331       if (REG_P (operands[2]))
11332         return "sal{w}\t{%b2, %0|%0, %b2}";
11333       else if (operands[2] == const1_rtx
11334                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11335         return "sal{w}\t%0";
11336       else
11337         return "sal{w}\t{%2, %0|%0, %2}";
11338     }
11339 }
11340   [(set (attr "type")
11341      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11342                           (const_int 0))
11343                       (match_operand 0 "register_operand" ""))
11344                  (match_operand 2 "const1_operand" ""))
11345               (const_string "alu")
11346            ]
11347            (const_string "ishift")))
11348    (set (attr "length_immediate")
11349      (if_then_else
11350        (ior (eq_attr "type" "alu")
11351             (and (eq_attr "type" "ishift")
11352                  (and (match_operand 2 "const1_operand" "")
11353                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11354                           (const_int 0)))))
11355        (const_string "0")
11356        (const_string "*")))
11357    (set_attr "mode" "HI")])
11358
11359 (define_expand "ashlqi3"
11360   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11361         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11362                    (match_operand:QI 2 "nonmemory_operand" "")))]
11363   "TARGET_QIMODE_MATH"
11364   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11365
11366 ;; %%% Potential partial reg stall on alternative 2.  What to do?
11367
11368 (define_insn "*ashlqi3_1_lea"
11369   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11370         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11371                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11372    (clobber (reg:CC FLAGS_REG))]
11373   "!TARGET_PARTIAL_REG_STALL
11374    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11375 {
11376   switch (get_attr_type (insn))
11377     {
11378     case TYPE_LEA:
11379       return "#";
11380     case TYPE_ALU:
11381       gcc_assert (operands[2] == const1_rtx);
11382       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11383         return "add{l}\t%k0, %k0";
11384       else
11385         return "add{b}\t%0, %0";
11386
11387     default:
11388       if (REG_P (operands[2]))
11389         {
11390           if (get_attr_mode (insn) == MODE_SI)
11391             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11392           else
11393             return "sal{b}\t{%b2, %0|%0, %b2}";
11394         }
11395       else if (operands[2] == const1_rtx
11396                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11397         {
11398           if (get_attr_mode (insn) == MODE_SI)
11399             return "sal{l}\t%0";
11400           else
11401             return "sal{b}\t%0";
11402         }
11403       else
11404         {
11405           if (get_attr_mode (insn) == MODE_SI)
11406             return "sal{l}\t{%2, %k0|%k0, %2}";
11407           else
11408             return "sal{b}\t{%2, %0|%0, %2}";
11409         }
11410     }
11411 }
11412   [(set (attr "type")
11413      (cond [(eq_attr "alternative" "2")
11414               (const_string "lea")
11415             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11416                           (const_int 0))
11417                       (match_operand 0 "register_operand" ""))
11418                  (match_operand 2 "const1_operand" ""))
11419               (const_string "alu")
11420            ]
11421            (const_string "ishift")))
11422    (set (attr "length_immediate")
11423      (if_then_else
11424        (ior (eq_attr "type" "alu")
11425             (and (eq_attr "type" "ishift")
11426                  (and (match_operand 2 "const1_operand" "")
11427                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11428                           (const_int 0)))))
11429        (const_string "0")
11430        (const_string "*")))
11431    (set_attr "mode" "QI,SI,SI")])
11432
11433 (define_insn "*ashlqi3_1"
11434   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11435         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11436                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11437    (clobber (reg:CC FLAGS_REG))]
11438   "TARGET_PARTIAL_REG_STALL
11439    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11440 {
11441   switch (get_attr_type (insn))
11442     {
11443     case TYPE_ALU:
11444       gcc_assert (operands[2] == const1_rtx);
11445       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11446         return "add{l}\t%k0, %k0";
11447       else
11448         return "add{b}\t%0, %0";
11449
11450     default:
11451       if (REG_P (operands[2]))
11452         {
11453           if (get_attr_mode (insn) == MODE_SI)
11454             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11455           else
11456             return "sal{b}\t{%b2, %0|%0, %b2}";
11457         }
11458       else if (operands[2] == const1_rtx
11459                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11460         {
11461           if (get_attr_mode (insn) == MODE_SI)
11462             return "sal{l}\t%0";
11463           else
11464             return "sal{b}\t%0";
11465         }
11466       else
11467         {
11468           if (get_attr_mode (insn) == MODE_SI)
11469             return "sal{l}\t{%2, %k0|%k0, %2}";
11470           else
11471             return "sal{b}\t{%2, %0|%0, %2}";
11472         }
11473     }
11474 }
11475   [(set (attr "type")
11476      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11477                           (const_int 0))
11478                       (match_operand 0 "register_operand" ""))
11479                  (match_operand 2 "const1_operand" ""))
11480               (const_string "alu")
11481            ]
11482            (const_string "ishift")))
11483    (set (attr "length_immediate")
11484      (if_then_else
11485        (ior (eq_attr "type" "alu")
11486             (and (eq_attr "type" "ishift")
11487                  (and (match_operand 2 "const1_operand" "")
11488                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11489                           (const_int 0)))))
11490        (const_string "0")
11491        (const_string "*")))
11492    (set_attr "mode" "QI,SI")])
11493
11494 ;; This pattern can't accept a variable shift count, since shifts by
11495 ;; zero don't affect the flags.  We assume that shifts by constant
11496 ;; zero are optimized away.
11497 (define_insn "*ashlqi3_cmp"
11498   [(set (reg FLAGS_REG)
11499         (compare
11500           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11501                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11502           (const_int 0)))
11503    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11504         (ashift:QI (match_dup 1) (match_dup 2)))]
11505   "(optimize_function_for_size_p (cfun)
11506     || !TARGET_PARTIAL_FLAG_REG_STALL
11507     || (operands[2] == const1_rtx
11508         && (TARGET_SHIFT1
11509             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11510    && ix86_match_ccmode (insn, CCGOCmode)
11511    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11512 {
11513   switch (get_attr_type (insn))
11514     {
11515     case TYPE_ALU:
11516       gcc_assert (operands[2] == const1_rtx);
11517       return "add{b}\t%0, %0";
11518
11519     default:
11520       if (REG_P (operands[2]))
11521         return "sal{b}\t{%b2, %0|%0, %b2}";
11522       else if (operands[2] == const1_rtx
11523                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11524         return "sal{b}\t%0";
11525       else
11526         return "sal{b}\t{%2, %0|%0, %2}";
11527     }
11528 }
11529   [(set (attr "type")
11530      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11531                           (const_int 0))
11532                       (match_operand 0 "register_operand" ""))
11533                  (match_operand 2 "const1_operand" ""))
11534               (const_string "alu")
11535            ]
11536            (const_string "ishift")))
11537    (set (attr "length_immediate")
11538      (if_then_else
11539        (ior (eq_attr "type" "alu")
11540             (and (eq_attr "type" "ishift")
11541                  (and (match_operand 2 "const1_operand" "")
11542                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11543                           (const_int 0)))))
11544        (const_string "0")
11545        (const_string "*")))
11546    (set_attr "mode" "QI")])
11547
11548 (define_insn "*ashlqi3_cconly"
11549   [(set (reg FLAGS_REG)
11550         (compare
11551           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11552                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11553           (const_int 0)))
11554    (clobber (match_scratch:QI 0 "=q"))]
11555   "(optimize_function_for_size_p (cfun)
11556     || !TARGET_PARTIAL_FLAG_REG_STALL
11557     || (operands[2] == const1_rtx
11558         && (TARGET_SHIFT1
11559             || TARGET_DOUBLE_WITH_ADD)))
11560    && ix86_match_ccmode (insn, CCGOCmode)
11561    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11562 {
11563   switch (get_attr_type (insn))
11564     {
11565     case TYPE_ALU:
11566       gcc_assert (operands[2] == const1_rtx);
11567       return "add{b}\t%0, %0";
11568
11569     default:
11570       if (REG_P (operands[2]))
11571         return "sal{b}\t{%b2, %0|%0, %b2}";
11572       else if (operands[2] == const1_rtx
11573                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11574         return "sal{b}\t%0";
11575       else
11576         return "sal{b}\t{%2, %0|%0, %2}";
11577     }
11578 }
11579   [(set (attr "type")
11580      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11581                           (const_int 0))
11582                       (match_operand 0 "register_operand" ""))
11583                  (match_operand 2 "const1_operand" ""))
11584               (const_string "alu")
11585            ]
11586            (const_string "ishift")))
11587    (set (attr "length_immediate")
11588      (if_then_else
11589        (ior (eq_attr "type" "alu")
11590             (and (eq_attr "type" "ishift")
11591                  (and (match_operand 2 "const1_operand" "")
11592                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11593                           (const_int 0)))))
11594        (const_string "0")
11595        (const_string "*")))
11596    (set_attr "mode" "QI")])
11597
11598 ;; See comment above `ashldi3' about how this works.
11599
11600 (define_expand "ashrti3"
11601   [(set (match_operand:TI 0 "register_operand" "")
11602         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11603                      (match_operand:QI 2 "nonmemory_operand" "")))]
11604   "TARGET_64BIT"
11605   "ix86_expand_binary_operator (ASHIFTRT, TImode, operands); DONE;")
11606
11607 (define_insn "*ashrti3_1"
11608   [(set (match_operand:TI 0 "register_operand" "=r")
11609         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11610                      (match_operand:QI 2 "nonmemory_operand" "Oc")))
11611    (clobber (reg:CC FLAGS_REG))]
11612   "TARGET_64BIT"
11613   "#"
11614   [(set_attr "type" "multi")])
11615
11616 (define_peephole2
11617   [(match_scratch:DI 3 "r")
11618    (parallel [(set (match_operand:TI 0 "register_operand" "")
11619                    (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11620                                 (match_operand:QI 2 "nonmemory_operand" "")))
11621               (clobber (reg:CC FLAGS_REG))])
11622    (match_dup 3)]
11623   "TARGET_64BIT"
11624   [(const_int 0)]
11625   "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11626
11627 (define_split
11628   [(set (match_operand:TI 0 "register_operand" "")
11629         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11630                      (match_operand:QI 2 "nonmemory_operand" "")))
11631    (clobber (reg:CC FLAGS_REG))]
11632   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11633                     ? epilogue_completed : reload_completed)"
11634   [(const_int 0)]
11635   "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11636
11637 (define_insn "x86_64_shrd"
11638   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
11639         (ior:DI (ashiftrt:DI (match_dup 0)
11640                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
11641                 (ashift:DI (match_operand:DI 1 "register_operand" "r")
11642                   (minus:QI (const_int 64) (match_dup 2)))))
11643    (clobber (reg:CC FLAGS_REG))]
11644   "TARGET_64BIT"
11645   "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11646   [(set_attr "type" "ishift")
11647    (set_attr "prefix_0f" "1")
11648    (set_attr "mode" "DI")
11649    (set_attr "athlon_decode" "vector")
11650    (set_attr "amdfam10_decode" "vector")])
11651
11652 (define_expand "ashrdi3"
11653   [(set (match_operand:DI 0 "shiftdi_operand" "")
11654         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11655                      (match_operand:QI 2 "nonmemory_operand" "")))]
11656   ""
11657   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11658
11659 (define_expand "x86_64_shift_adj_3"
11660   [(use (match_operand:DI 0 "register_operand" ""))
11661    (use (match_operand:DI 1 "register_operand" ""))
11662    (use (match_operand:QI 2 "register_operand" ""))]
11663   ""
11664 {
11665   rtx label = gen_label_rtx ();
11666   rtx tmp;
11667
11668   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (64)));
11669
11670   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11671   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11672   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11673                               gen_rtx_LABEL_REF (VOIDmode, label),
11674                               pc_rtx);
11675   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11676   JUMP_LABEL (tmp) = label;
11677
11678   emit_move_insn (operands[0], operands[1]);
11679   emit_insn (gen_ashrdi3_63_rex64 (operands[1], operands[1], GEN_INT (63)));
11680
11681   emit_label (label);
11682   LABEL_NUSES (label) = 1;
11683
11684   DONE;
11685 })
11686
11687 (define_insn "ashrdi3_63_rex64"
11688   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11689         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11690                      (match_operand:DI 2 "const_int_operand" "i,i")))
11691    (clobber (reg:CC FLAGS_REG))]
11692   "TARGET_64BIT && INTVAL (operands[2]) == 63
11693    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
11694    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11695   "@
11696    {cqto|cqo}
11697    sar{q}\t{%2, %0|%0, %2}"
11698   [(set_attr "type" "imovx,ishift")
11699    (set_attr "prefix_0f" "0,*")
11700    (set_attr "length_immediate" "0,*")
11701    (set_attr "modrm" "0,1")
11702    (set_attr "mode" "DI")])
11703
11704 (define_insn "*ashrdi3_1_one_bit_rex64"
11705   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11706         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11707                      (match_operand:QI 2 "const1_operand" "")))
11708    (clobber (reg:CC FLAGS_REG))]
11709   "TARGET_64BIT
11710    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11711    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11712   "sar{q}\t%0"
11713   [(set_attr "type" "ishift")
11714    (set_attr "length_immediate" "0")
11715    (set_attr "mode" "DI")])
11716
11717 (define_insn "*ashrdi3_1_rex64"
11718   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11719         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11720                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11721    (clobber (reg:CC FLAGS_REG))]
11722   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11723   "@
11724    sar{q}\t{%2, %0|%0, %2}
11725    sar{q}\t{%b2, %0|%0, %b2}"
11726   [(set_attr "type" "ishift")
11727    (set_attr "mode" "DI")])
11728
11729 ;; This pattern can't accept a variable shift count, since shifts by
11730 ;; zero don't affect the flags.  We assume that shifts by constant
11731 ;; zero are optimized away.
11732 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11733   [(set (reg FLAGS_REG)
11734         (compare
11735           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11736                        (match_operand:QI 2 "const1_operand" ""))
11737           (const_int 0)))
11738    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11739         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11740   "TARGET_64BIT
11741    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11742    && ix86_match_ccmode (insn, CCGOCmode)
11743    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11744   "sar{q}\t%0"
11745   [(set_attr "type" "ishift")
11746    (set_attr "length_immediate" "0")
11747    (set_attr "mode" "DI")])
11748
11749 (define_insn "*ashrdi3_one_bit_cconly_rex64"
11750   [(set (reg FLAGS_REG)
11751         (compare
11752           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11753                        (match_operand:QI 2 "const1_operand" ""))
11754           (const_int 0)))
11755    (clobber (match_scratch:DI 0 "=r"))]
11756   "TARGET_64BIT
11757    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11758    && ix86_match_ccmode (insn, CCGOCmode)
11759    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11760   "sar{q}\t%0"
11761   [(set_attr "type" "ishift")
11762    (set_attr "length_immediate" "0")
11763    (set_attr "mode" "DI")])
11764
11765 ;; This pattern can't accept a variable shift count, since shifts by
11766 ;; zero don't affect the flags.  We assume that shifts by constant
11767 ;; zero are optimized away.
11768 (define_insn "*ashrdi3_cmp_rex64"
11769   [(set (reg FLAGS_REG)
11770         (compare
11771           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11772                        (match_operand:QI 2 "const_1_to_63_operand" "J"))
11773           (const_int 0)))
11774    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11775         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11776   "TARGET_64BIT
11777    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11778    && ix86_match_ccmode (insn, CCGOCmode)
11779    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11780   "sar{q}\t{%2, %0|%0, %2}"
11781   [(set_attr "type" "ishift")
11782    (set_attr "mode" "DI")])
11783
11784 (define_insn "*ashrdi3_cconly_rex64"
11785   [(set (reg FLAGS_REG)
11786         (compare
11787           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11788                        (match_operand:QI 2 "const_1_to_63_operand" "J"))
11789           (const_int 0)))
11790    (clobber (match_scratch:DI 0 "=r"))]
11791   "TARGET_64BIT
11792    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11793    && ix86_match_ccmode (insn, CCGOCmode)
11794    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11795   "sar{q}\t{%2, %0|%0, %2}"
11796   [(set_attr "type" "ishift")
11797    (set_attr "mode" "DI")])
11798
11799 (define_insn "*ashrdi3_1"
11800   [(set (match_operand:DI 0 "register_operand" "=r")
11801         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11802                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11803    (clobber (reg:CC FLAGS_REG))]
11804   "!TARGET_64BIT"
11805   "#"
11806   [(set_attr "type" "multi")])
11807
11808 ;; By default we don't ask for a scratch register, because when DImode
11809 ;; values are manipulated, registers are already at a premium.  But if
11810 ;; we have one handy, we won't turn it away.
11811 (define_peephole2
11812   [(match_scratch:SI 3 "r")
11813    (parallel [(set (match_operand:DI 0 "register_operand" "")
11814                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11815                                 (match_operand:QI 2 "nonmemory_operand" "")))
11816               (clobber (reg:CC FLAGS_REG))])
11817    (match_dup 3)]
11818   "!TARGET_64BIT && TARGET_CMOVE"
11819   [(const_int 0)]
11820   "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11821
11822 (define_split
11823   [(set (match_operand:DI 0 "register_operand" "")
11824         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11825                      (match_operand:QI 2 "nonmemory_operand" "")))
11826    (clobber (reg:CC FLAGS_REG))]
11827   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11828                      ? epilogue_completed : reload_completed)"
11829   [(const_int 0)]
11830   "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11831
11832 (define_insn "x86_shrd"
11833   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
11834         (ior:SI (ashiftrt:SI (match_dup 0)
11835                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
11836                 (ashift:SI (match_operand:SI 1 "register_operand" "r")
11837                   (minus:QI (const_int 32) (match_dup 2)))))
11838    (clobber (reg:CC FLAGS_REG))]
11839   ""
11840   "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11841   [(set_attr "type" "ishift")
11842    (set_attr "prefix_0f" "1")
11843    (set_attr "pent_pair" "np")
11844    (set_attr "mode" "SI")])
11845
11846 (define_expand "x86_shift_adj_3"
11847   [(use (match_operand:SI 0 "register_operand" ""))
11848    (use (match_operand:SI 1 "register_operand" ""))
11849    (use (match_operand:QI 2 "register_operand" ""))]
11850   ""
11851 {
11852   rtx label = gen_label_rtx ();
11853   rtx tmp;
11854
11855   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11856
11857   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11858   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11859   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11860                               gen_rtx_LABEL_REF (VOIDmode, label),
11861                               pc_rtx);
11862   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11863   JUMP_LABEL (tmp) = label;
11864
11865   emit_move_insn (operands[0], operands[1]);
11866   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11867
11868   emit_label (label);
11869   LABEL_NUSES (label) = 1;
11870
11871   DONE;
11872 })
11873
11874 (define_expand "ashrsi3_31"
11875   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11876                    (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11877                                 (match_operand:SI 2 "const_int_operand" "i,i")))
11878               (clobber (reg:CC FLAGS_REG))])]
11879   "")
11880
11881 (define_insn "*ashrsi3_31"
11882   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11883         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11884                      (match_operand:SI 2 "const_int_operand" "i,i")))
11885    (clobber (reg:CC FLAGS_REG))]
11886   "INTVAL (operands[2]) == 31
11887    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
11888    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11889   "@
11890    {cltd|cdq}
11891    sar{l}\t{%2, %0|%0, %2}"
11892   [(set_attr "type" "imovx,ishift")
11893    (set_attr "prefix_0f" "0,*")
11894    (set_attr "length_immediate" "0,*")
11895    (set_attr "modrm" "0,1")
11896    (set_attr "mode" "SI")])
11897
11898 (define_insn "*ashrsi3_31_zext"
11899   [(set (match_operand:DI 0 "register_operand" "=*d,r")
11900         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11901                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
11902    (clobber (reg:CC FLAGS_REG))]
11903   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
11904    && INTVAL (operands[2]) == 31
11905    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11906   "@
11907    {cltd|cdq}
11908    sar{l}\t{%2, %k0|%k0, %2}"
11909   [(set_attr "type" "imovx,ishift")
11910    (set_attr "prefix_0f" "0,*")
11911    (set_attr "length_immediate" "0,*")
11912    (set_attr "modrm" "0,1")
11913    (set_attr "mode" "SI")])
11914
11915 (define_expand "ashrsi3"
11916   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11917         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11918                      (match_operand:QI 2 "nonmemory_operand" "")))]
11919   ""
11920   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11921
11922 (define_insn "*ashrsi3_1_one_bit"
11923   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11924         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11925                      (match_operand:QI 2 "const1_operand" "")))
11926    (clobber (reg:CC FLAGS_REG))]
11927   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11928    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11929   "sar{l}\t%0"
11930   [(set_attr "type" "ishift")
11931    (set_attr "length_immediate" "0")
11932    (set_attr "mode" "SI")])
11933
11934 (define_insn "*ashrsi3_1_one_bit_zext"
11935   [(set (match_operand:DI 0 "register_operand" "=r")
11936         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11937                                      (match_operand:QI 2 "const1_operand" ""))))
11938    (clobber (reg:CC FLAGS_REG))]
11939   "TARGET_64BIT
11940    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11941    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11942   "sar{l}\t%k0"
11943   [(set_attr "type" "ishift")
11944    (set_attr "length_immediate" "0")
11945    (set_attr "mode" "SI")])
11946
11947 (define_insn "*ashrsi3_1"
11948   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11949         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11950                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11951    (clobber (reg:CC FLAGS_REG))]
11952   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11953   "@
11954    sar{l}\t{%2, %0|%0, %2}
11955    sar{l}\t{%b2, %0|%0, %b2}"
11956   [(set_attr "type" "ishift")
11957    (set_attr "mode" "SI")])
11958
11959 (define_insn "*ashrsi3_1_zext"
11960   [(set (match_operand:DI 0 "register_operand" "=r,r")
11961         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11962                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11963    (clobber (reg:CC FLAGS_REG))]
11964   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11965   "@
11966    sar{l}\t{%2, %k0|%k0, %2}
11967    sar{l}\t{%b2, %k0|%k0, %b2}"
11968   [(set_attr "type" "ishift")
11969    (set_attr "mode" "SI")])
11970
11971 ;; This pattern can't accept a variable shift count, since shifts by
11972 ;; zero don't affect the flags.  We assume that shifts by constant
11973 ;; zero are optimized away.
11974 (define_insn "*ashrsi3_one_bit_cmp"
11975   [(set (reg FLAGS_REG)
11976         (compare
11977           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11978                        (match_operand:QI 2 "const1_operand" ""))
11979           (const_int 0)))
11980    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11981         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11982   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11983    && ix86_match_ccmode (insn, CCGOCmode)
11984    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11985   "sar{l}\t%0"
11986   [(set_attr "type" "ishift")
11987    (set_attr "length_immediate" "0")
11988    (set_attr "mode" "SI")])
11989
11990 (define_insn "*ashrsi3_one_bit_cconly"
11991   [(set (reg FLAGS_REG)
11992         (compare
11993           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11994                        (match_operand:QI 2 "const1_operand" ""))
11995           (const_int 0)))
11996    (clobber (match_scratch:SI 0 "=r"))]
11997   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11998    && ix86_match_ccmode (insn, CCGOCmode)
11999    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12000   "sar{l}\t%0"
12001   [(set_attr "type" "ishift")
12002    (set_attr "length_immediate" "0")
12003    (set_attr "mode" "SI")])
12004
12005 (define_insn "*ashrsi3_one_bit_cmp_zext"
12006   [(set (reg FLAGS_REG)
12007         (compare
12008           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12009                        (match_operand:QI 2 "const1_operand" ""))
12010           (const_int 0)))
12011    (set (match_operand:DI 0 "register_operand" "=r")
12012         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12013   "TARGET_64BIT
12014    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12015    && ix86_match_ccmode (insn, CCmode)
12016    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12017   "sar{l}\t%k0"
12018   [(set_attr "type" "ishift")
12019    (set_attr "length_immediate" "0")
12020    (set_attr "mode" "SI")])
12021
12022 ;; This pattern can't accept a variable shift count, since shifts by
12023 ;; zero don't affect the flags.  We assume that shifts by constant
12024 ;; zero are optimized away.
12025 (define_insn "*ashrsi3_cmp"
12026   [(set (reg FLAGS_REG)
12027         (compare
12028           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12029                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12030           (const_int 0)))
12031    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12032         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12033   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12034    && ix86_match_ccmode (insn, CCGOCmode)
12035    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12036   "sar{l}\t{%2, %0|%0, %2}"
12037   [(set_attr "type" "ishift")
12038    (set_attr "mode" "SI")])
12039
12040 (define_insn "*ashrsi3_cconly"
12041   [(set (reg FLAGS_REG)
12042         (compare
12043           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12044                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12045           (const_int 0)))
12046    (clobber (match_scratch:SI 0 "=r"))]
12047   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12048    && ix86_match_ccmode (insn, CCGOCmode)
12049    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12050   "sar{l}\t{%2, %0|%0, %2}"
12051   [(set_attr "type" "ishift")
12052    (set_attr "mode" "SI")])
12053
12054 (define_insn "*ashrsi3_cmp_zext"
12055   [(set (reg FLAGS_REG)
12056         (compare
12057           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12058                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12059           (const_int 0)))
12060    (set (match_operand:DI 0 "register_operand" "=r")
12061         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12062   "TARGET_64BIT
12063    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12064    && ix86_match_ccmode (insn, CCGOCmode)
12065    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12066   "sar{l}\t{%2, %k0|%k0, %2}"
12067   [(set_attr "type" "ishift")
12068    (set_attr "mode" "SI")])
12069
12070 (define_expand "ashrhi3"
12071   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12072         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12073                      (match_operand:QI 2 "nonmemory_operand" "")))]
12074   "TARGET_HIMODE_MATH"
12075   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
12076
12077 (define_insn "*ashrhi3_1_one_bit"
12078   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12079         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12080                      (match_operand:QI 2 "const1_operand" "")))
12081    (clobber (reg:CC FLAGS_REG))]
12082   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12083    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12084   "sar{w}\t%0"
12085   [(set_attr "type" "ishift")
12086    (set_attr "length_immediate" "0")
12087    (set_attr "mode" "HI")])
12088
12089 (define_insn "*ashrhi3_1"
12090   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12091         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12092                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12093    (clobber (reg:CC FLAGS_REG))]
12094   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12095   "@
12096    sar{w}\t{%2, %0|%0, %2}
12097    sar{w}\t{%b2, %0|%0, %b2}"
12098   [(set_attr "type" "ishift")
12099    (set_attr "mode" "HI")])
12100
12101 ;; This pattern can't accept a variable shift count, since shifts by
12102 ;; zero don't affect the flags.  We assume that shifts by constant
12103 ;; zero are optimized away.
12104 (define_insn "*ashrhi3_one_bit_cmp"
12105   [(set (reg FLAGS_REG)
12106         (compare
12107           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12108                        (match_operand:QI 2 "const1_operand" ""))
12109           (const_int 0)))
12110    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12111         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12112   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12113    && ix86_match_ccmode (insn, CCGOCmode)
12114    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12115   "sar{w}\t%0"
12116   [(set_attr "type" "ishift")
12117    (set_attr "length_immediate" "0")
12118    (set_attr "mode" "HI")])
12119
12120 (define_insn "*ashrhi3_one_bit_cconly"
12121   [(set (reg FLAGS_REG)
12122         (compare
12123           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12124                        (match_operand:QI 2 "const1_operand" ""))
12125           (const_int 0)))
12126    (clobber (match_scratch:HI 0 "=r"))]
12127   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12128    && ix86_match_ccmode (insn, CCGOCmode)
12129    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12130   "sar{w}\t%0"
12131   [(set_attr "type" "ishift")
12132    (set_attr "length_immediate" "0")
12133    (set_attr "mode" "HI")])
12134
12135 ;; This pattern can't accept a variable shift count, since shifts by
12136 ;; zero don't affect the flags.  We assume that shifts by constant
12137 ;; zero are optimized away.
12138 (define_insn "*ashrhi3_cmp"
12139   [(set (reg FLAGS_REG)
12140         (compare
12141           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12142                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12143           (const_int 0)))
12144    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12145         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12146   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12147    && ix86_match_ccmode (insn, CCGOCmode)
12148    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12149   "sar{w}\t{%2, %0|%0, %2}"
12150   [(set_attr "type" "ishift")
12151    (set_attr "mode" "HI")])
12152
12153 (define_insn "*ashrhi3_cconly"
12154   [(set (reg FLAGS_REG)
12155         (compare
12156           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12157                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12158           (const_int 0)))
12159    (clobber (match_scratch:HI 0 "=r"))]
12160   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12161    && ix86_match_ccmode (insn, CCGOCmode)
12162    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12163   "sar{w}\t{%2, %0|%0, %2}"
12164   [(set_attr "type" "ishift")
12165    (set_attr "mode" "HI")])
12166
12167 (define_expand "ashrqi3"
12168   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12169         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12170                      (match_operand:QI 2 "nonmemory_operand" "")))]
12171   "TARGET_QIMODE_MATH"
12172   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
12173
12174 (define_insn "*ashrqi3_1_one_bit"
12175   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12176         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12177                      (match_operand:QI 2 "const1_operand" "")))
12178    (clobber (reg:CC FLAGS_REG))]
12179   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12180    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12181   "sar{b}\t%0"
12182   [(set_attr "type" "ishift")
12183    (set_attr "length_immediate" "0")
12184    (set_attr "mode" "QI")])
12185
12186 (define_insn "*ashrqi3_1_one_bit_slp"
12187   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12188         (ashiftrt:QI (match_dup 0)
12189                      (match_operand:QI 1 "const1_operand" "")))
12190    (clobber (reg:CC FLAGS_REG))]
12191   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12192    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12193    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12194   "sar{b}\t%0"
12195   [(set_attr "type" "ishift1")
12196    (set_attr "length_immediate" "0")
12197    (set_attr "mode" "QI")])
12198
12199 (define_insn "*ashrqi3_1"
12200   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12201         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12202                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12203    (clobber (reg:CC FLAGS_REG))]
12204   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12205   "@
12206    sar{b}\t{%2, %0|%0, %2}
12207    sar{b}\t{%b2, %0|%0, %b2}"
12208   [(set_attr "type" "ishift")
12209    (set_attr "mode" "QI")])
12210
12211 (define_insn "*ashrqi3_1_slp"
12212   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12213         (ashiftrt:QI (match_dup 0)
12214                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12215    (clobber (reg:CC FLAGS_REG))]
12216   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12217    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12218   "@
12219    sar{b}\t{%1, %0|%0, %1}
12220    sar{b}\t{%b1, %0|%0, %b1}"
12221   [(set_attr "type" "ishift1")
12222    (set_attr "mode" "QI")])
12223
12224 ;; This pattern can't accept a variable shift count, since shifts by
12225 ;; zero don't affect the flags.  We assume that shifts by constant
12226 ;; zero are optimized away.
12227 (define_insn "*ashrqi3_one_bit_cmp"
12228   [(set (reg FLAGS_REG)
12229         (compare
12230           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12231                        (match_operand:QI 2 "const1_operand" "I"))
12232           (const_int 0)))
12233    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12234         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12235   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12236    && ix86_match_ccmode (insn, CCGOCmode)
12237    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12238   "sar{b}\t%0"
12239   [(set_attr "type" "ishift")
12240    (set_attr "length_immediate" "0")
12241    (set_attr "mode" "QI")])
12242
12243 (define_insn "*ashrqi3_one_bit_cconly"
12244   [(set (reg FLAGS_REG)
12245         (compare
12246           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12247                        (match_operand:QI 2 "const1_operand" ""))
12248           (const_int 0)))
12249    (clobber (match_scratch:QI 0 "=q"))]
12250   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12251    && ix86_match_ccmode (insn, CCGOCmode)
12252    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12253   "sar{b}\t%0"
12254   [(set_attr "type" "ishift")
12255    (set_attr "length_immediate" "0")
12256    (set_attr "mode" "QI")])
12257
12258 ;; This pattern can't accept a variable shift count, since shifts by
12259 ;; zero don't affect the flags.  We assume that shifts by constant
12260 ;; zero are optimized away.
12261 (define_insn "*ashrqi3_cmp"
12262   [(set (reg FLAGS_REG)
12263         (compare
12264           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12265                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12266           (const_int 0)))
12267    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12268         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12269   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12270    && ix86_match_ccmode (insn, CCGOCmode)
12271    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12272   "sar{b}\t{%2, %0|%0, %2}"
12273   [(set_attr "type" "ishift")
12274    (set_attr "mode" "QI")])
12275
12276 (define_insn "*ashrqi3_cconly"
12277   [(set (reg FLAGS_REG)
12278         (compare
12279           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12280                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12281           (const_int 0)))
12282    (clobber (match_scratch:QI 0 "=q"))]
12283   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12284    && ix86_match_ccmode (insn, CCGOCmode)
12285    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12286   "sar{b}\t{%2, %0|%0, %2}"
12287   [(set_attr "type" "ishift")
12288    (set_attr "mode" "QI")])
12289
12290 \f
12291 ;; Logical shift instructions
12292
12293 ;; See comment above `ashldi3' about how this works.
12294
12295 (define_expand "lshrti3"
12296   [(set (match_operand:TI 0 "register_operand" "")
12297         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12298                      (match_operand:QI 2 "nonmemory_operand" "")))]
12299   "TARGET_64BIT"
12300   "ix86_expand_binary_operator (LSHIFTRT, TImode, operands); DONE;")
12301
12302 ;; This pattern must be defined before *lshrti3_1 to prevent
12303 ;; combine pass from converting sse2_lshrti3 to *lshrti3_1.
12304
12305 (define_insn "*avx_lshrti3"
12306   [(set (match_operand:TI 0 "register_operand" "=x")
12307         (lshiftrt:TI (match_operand:TI 1 "register_operand" "x")
12308                      (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
12309   "TARGET_AVX"
12310 {
12311   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
12312   return "vpsrldq\t{%2, %1, %0|%0, %1, %2}";
12313 }
12314   [(set_attr "type" "sseishft")
12315    (set_attr "prefix" "vex")
12316    (set_attr "length_immediate" "1")
12317    (set_attr "mode" "TI")])
12318
12319 (define_insn "sse2_lshrti3"
12320   [(set (match_operand:TI 0 "register_operand" "=x")
12321         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12322                      (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
12323   "TARGET_SSE2"
12324 {
12325   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
12326   return "psrldq\t{%2, %0|%0, %2}";
12327 }
12328   [(set_attr "type" "sseishft")
12329    (set_attr "prefix_data16" "1")
12330    (set_attr "length_immediate" "1")
12331    (set_attr "mode" "TI")])
12332
12333 (define_insn "*lshrti3_1"
12334   [(set (match_operand:TI 0 "register_operand" "=r")
12335         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12336                      (match_operand:QI 2 "nonmemory_operand" "Oc")))
12337    (clobber (reg:CC FLAGS_REG))]
12338   "TARGET_64BIT"
12339   "#"
12340   [(set_attr "type" "multi")])
12341
12342 (define_peephole2
12343   [(match_scratch:DI 3 "r")
12344    (parallel [(set (match_operand:TI 0 "register_operand" "")
12345                    (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12346                                 (match_operand:QI 2 "nonmemory_operand" "")))
12347               (clobber (reg:CC FLAGS_REG))])
12348    (match_dup 3)]
12349   "TARGET_64BIT"
12350   [(const_int 0)]
12351   "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12352
12353 (define_split
12354   [(set (match_operand:TI 0 "register_operand" "")
12355         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12356                      (match_operand:QI 2 "nonmemory_operand" "")))
12357    (clobber (reg:CC FLAGS_REG))]
12358   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12359                     ? epilogue_completed : reload_completed)"
12360   [(const_int 0)]
12361   "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12362
12363 (define_expand "lshrdi3"
12364   [(set (match_operand:DI 0 "shiftdi_operand" "")
12365         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12366                      (match_operand:QI 2 "nonmemory_operand" "")))]
12367   ""
12368   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12369
12370 (define_insn "*lshrdi3_1_one_bit_rex64"
12371   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12372         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12373                      (match_operand:QI 2 "const1_operand" "")))
12374    (clobber (reg:CC FLAGS_REG))]
12375   "TARGET_64BIT
12376    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12377    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12378   "shr{q}\t%0"
12379   [(set_attr "type" "ishift")
12380    (set_attr "length_immediate" "0")
12381    (set_attr "mode" "DI")])
12382
12383 (define_insn "*lshrdi3_1_rex64"
12384   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12385         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12386                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12387    (clobber (reg:CC FLAGS_REG))]
12388   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12389   "@
12390    shr{q}\t{%2, %0|%0, %2}
12391    shr{q}\t{%b2, %0|%0, %b2}"
12392   [(set_attr "type" "ishift")
12393    (set_attr "mode" "DI")])
12394
12395 ;; This pattern can't accept a variable shift count, since shifts by
12396 ;; zero don't affect the flags.  We assume that shifts by constant
12397 ;; zero are optimized away.
12398 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12399   [(set (reg FLAGS_REG)
12400         (compare
12401           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12402                        (match_operand:QI 2 "const1_operand" ""))
12403           (const_int 0)))
12404    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12405         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12406   "TARGET_64BIT
12407    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12408    && ix86_match_ccmode (insn, CCGOCmode)
12409    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12410   "shr{q}\t%0"
12411   [(set_attr "type" "ishift")
12412    (set_attr "length_immediate" "0")
12413    (set_attr "mode" "DI")])
12414
12415 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12416   [(set (reg FLAGS_REG)
12417         (compare
12418           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12419                        (match_operand:QI 2 "const1_operand" ""))
12420           (const_int 0)))
12421    (clobber (match_scratch:DI 0 "=r"))]
12422   "TARGET_64BIT
12423    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12424    && ix86_match_ccmode (insn, CCGOCmode)
12425    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12426   "shr{q}\t%0"
12427   [(set_attr "type" "ishift")
12428    (set_attr "length_immediate" "0")
12429    (set_attr "mode" "DI")])
12430
12431 ;; This pattern can't accept a variable shift count, since shifts by
12432 ;; zero don't affect the flags.  We assume that shifts by constant
12433 ;; zero are optimized away.
12434 (define_insn "*lshrdi3_cmp_rex64"
12435   [(set (reg FLAGS_REG)
12436         (compare
12437           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12438                        (match_operand:QI 2 "const_1_to_63_operand" "J"))
12439           (const_int 0)))
12440    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12441         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12442   "TARGET_64BIT
12443    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12444    && ix86_match_ccmode (insn, CCGOCmode)
12445    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12446   "shr{q}\t{%2, %0|%0, %2}"
12447   [(set_attr "type" "ishift")
12448    (set_attr "mode" "DI")])
12449
12450 (define_insn "*lshrdi3_cconly_rex64"
12451   [(set (reg FLAGS_REG)
12452         (compare
12453           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12454                        (match_operand:QI 2 "const_1_to_63_operand" "J"))
12455           (const_int 0)))
12456    (clobber (match_scratch:DI 0 "=r"))]
12457   "TARGET_64BIT
12458    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12459    && ix86_match_ccmode (insn, CCGOCmode)
12460    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12461   "shr{q}\t{%2, %0|%0, %2}"
12462   [(set_attr "type" "ishift")
12463    (set_attr "mode" "DI")])
12464
12465 (define_insn "*lshrdi3_1"
12466   [(set (match_operand:DI 0 "register_operand" "=r")
12467         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12468                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
12469    (clobber (reg:CC FLAGS_REG))]
12470   "!TARGET_64BIT"
12471   "#"
12472   [(set_attr "type" "multi")])
12473
12474 ;; By default we don't ask for a scratch register, because when DImode
12475 ;; values are manipulated, registers are already at a premium.  But if
12476 ;; we have one handy, we won't turn it away.
12477 (define_peephole2
12478   [(match_scratch:SI 3 "r")
12479    (parallel [(set (match_operand:DI 0 "register_operand" "")
12480                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12481                                 (match_operand:QI 2 "nonmemory_operand" "")))
12482               (clobber (reg:CC FLAGS_REG))])
12483    (match_dup 3)]
12484   "!TARGET_64BIT && TARGET_CMOVE"
12485   [(const_int 0)]
12486   "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12487
12488 (define_split
12489   [(set (match_operand:DI 0 "register_operand" "")
12490         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12491                      (match_operand:QI 2 "nonmemory_operand" "")))
12492    (clobber (reg:CC FLAGS_REG))]
12493   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12494                      ? epilogue_completed : reload_completed)"
12495   [(const_int 0)]
12496   "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12497
12498 (define_expand "lshrsi3"
12499   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12500         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12501                      (match_operand:QI 2 "nonmemory_operand" "")))]
12502   ""
12503   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12504
12505 (define_insn "*lshrsi3_1_one_bit"
12506   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12507         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12508                      (match_operand:QI 2 "const1_operand" "")))
12509    (clobber (reg:CC FLAGS_REG))]
12510   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12511    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12512   "shr{l}\t%0"
12513   [(set_attr "type" "ishift")
12514    (set_attr "length_immediate" "0")
12515    (set_attr "mode" "SI")])
12516
12517 (define_insn "*lshrsi3_1_one_bit_zext"
12518   [(set (match_operand:DI 0 "register_operand" "=r")
12519         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12520                      (match_operand:QI 2 "const1_operand" "")))
12521    (clobber (reg:CC FLAGS_REG))]
12522   "TARGET_64BIT
12523    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12524    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12525   "shr{l}\t%k0"
12526   [(set_attr "type" "ishift")
12527    (set_attr "length_immediate" "0")
12528    (set_attr "mode" "SI")])
12529
12530 (define_insn "*lshrsi3_1"
12531   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12532         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12533                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12534    (clobber (reg:CC FLAGS_REG))]
12535   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12536   "@
12537    shr{l}\t{%2, %0|%0, %2}
12538    shr{l}\t{%b2, %0|%0, %b2}"
12539   [(set_attr "type" "ishift")
12540    (set_attr "mode" "SI")])
12541
12542 (define_insn "*lshrsi3_1_zext"
12543   [(set (match_operand:DI 0 "register_operand" "=r,r")
12544         (zero_extend:DI
12545           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12546                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12547    (clobber (reg:CC FLAGS_REG))]
12548   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12549   "@
12550    shr{l}\t{%2, %k0|%k0, %2}
12551    shr{l}\t{%b2, %k0|%k0, %b2}"
12552   [(set_attr "type" "ishift")
12553    (set_attr "mode" "SI")])
12554
12555 ;; This pattern can't accept a variable shift count, since shifts by
12556 ;; zero don't affect the flags.  We assume that shifts by constant
12557 ;; zero are optimized away.
12558 (define_insn "*lshrsi3_one_bit_cmp"
12559   [(set (reg FLAGS_REG)
12560         (compare
12561           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12562                        (match_operand:QI 2 "const1_operand" ""))
12563           (const_int 0)))
12564    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12565         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12566   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12567    && ix86_match_ccmode (insn, CCGOCmode)
12568    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12569   "shr{l}\t%0"
12570   [(set_attr "type" "ishift")
12571    (set_attr "length_immediate" "0")
12572    (set_attr "mode" "SI")])
12573
12574 (define_insn "*lshrsi3_one_bit_cconly"
12575   [(set (reg FLAGS_REG)
12576         (compare
12577           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12578                        (match_operand:QI 2 "const1_operand" ""))
12579           (const_int 0)))
12580    (clobber (match_scratch:SI 0 "=r"))]
12581   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12582    && ix86_match_ccmode (insn, CCGOCmode)
12583    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12584   "shr{l}\t%0"
12585   [(set_attr "type" "ishift")
12586    (set_attr "length_immediate" "0")
12587    (set_attr "mode" "SI")])
12588
12589 (define_insn "*lshrsi3_cmp_one_bit_zext"
12590   [(set (reg FLAGS_REG)
12591         (compare
12592           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12593                        (match_operand:QI 2 "const1_operand" ""))
12594           (const_int 0)))
12595    (set (match_operand:DI 0 "register_operand" "=r")
12596         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12597   "TARGET_64BIT
12598    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12599    && ix86_match_ccmode (insn, CCGOCmode)
12600    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12601   "shr{l}\t%k0"
12602   [(set_attr "type" "ishift")
12603    (set_attr "length_immediate" "0")
12604    (set_attr "mode" "SI")])
12605
12606 ;; This pattern can't accept a variable shift count, since shifts by
12607 ;; zero don't affect the flags.  We assume that shifts by constant
12608 ;; zero are optimized away.
12609 (define_insn "*lshrsi3_cmp"
12610   [(set (reg FLAGS_REG)
12611         (compare
12612           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12613                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12614           (const_int 0)))
12615    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12616         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12617   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12618    && ix86_match_ccmode (insn, CCGOCmode)
12619    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12620   "shr{l}\t{%2, %0|%0, %2}"
12621   [(set_attr "type" "ishift")
12622    (set_attr "mode" "SI")])
12623
12624 (define_insn "*lshrsi3_cconly"
12625   [(set (reg FLAGS_REG)
12626       (compare
12627         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12628                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
12629         (const_int 0)))
12630    (clobber (match_scratch:SI 0 "=r"))]
12631   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12632    && ix86_match_ccmode (insn, CCGOCmode)
12633    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12634   "shr{l}\t{%2, %0|%0, %2}"
12635   [(set_attr "type" "ishift")
12636    (set_attr "mode" "SI")])
12637
12638 (define_insn "*lshrsi3_cmp_zext"
12639   [(set (reg FLAGS_REG)
12640         (compare
12641           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12642                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12643           (const_int 0)))
12644    (set (match_operand:DI 0 "register_operand" "=r")
12645         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12646   "TARGET_64BIT
12647    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12648    && ix86_match_ccmode (insn, CCGOCmode)
12649    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12650   "shr{l}\t{%2, %k0|%k0, %2}"
12651   [(set_attr "type" "ishift")
12652    (set_attr "mode" "SI")])
12653
12654 (define_expand "lshrhi3"
12655   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12656         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12657                      (match_operand:QI 2 "nonmemory_operand" "")))]
12658   "TARGET_HIMODE_MATH"
12659   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12660
12661 (define_insn "*lshrhi3_1_one_bit"
12662   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12663         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12664                      (match_operand:QI 2 "const1_operand" "")))
12665    (clobber (reg:CC FLAGS_REG))]
12666   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12667    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12668   "shr{w}\t%0"
12669   [(set_attr "type" "ishift")
12670    (set_attr "length_immediate" "0")
12671    (set_attr "mode" "HI")])
12672
12673 (define_insn "*lshrhi3_1"
12674   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12675         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12676                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12677    (clobber (reg:CC FLAGS_REG))]
12678   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12679   "@
12680    shr{w}\t{%2, %0|%0, %2}
12681    shr{w}\t{%b2, %0|%0, %b2}"
12682   [(set_attr "type" "ishift")
12683    (set_attr "mode" "HI")])
12684
12685 ;; This pattern can't accept a variable shift count, since shifts by
12686 ;; zero don't affect the flags.  We assume that shifts by constant
12687 ;; zero are optimized away.
12688 (define_insn "*lshrhi3_one_bit_cmp"
12689   [(set (reg FLAGS_REG)
12690         (compare
12691           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12692                        (match_operand:QI 2 "const1_operand" ""))
12693           (const_int 0)))
12694    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12695         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12696   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12697    && ix86_match_ccmode (insn, CCGOCmode)
12698    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12699   "shr{w}\t%0"
12700   [(set_attr "type" "ishift")
12701    (set_attr "length_immediate" "0")
12702    (set_attr "mode" "HI")])
12703
12704 (define_insn "*lshrhi3_one_bit_cconly"
12705   [(set (reg FLAGS_REG)
12706         (compare
12707           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12708                        (match_operand:QI 2 "const1_operand" ""))
12709           (const_int 0)))
12710    (clobber (match_scratch:HI 0 "=r"))]
12711   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12712    && ix86_match_ccmode (insn, CCGOCmode)
12713    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12714   "shr{w}\t%0"
12715   [(set_attr "type" "ishift")
12716    (set_attr "length_immediate" "0")
12717    (set_attr "mode" "HI")])
12718
12719 ;; This pattern can't accept a variable shift count, since shifts by
12720 ;; zero don't affect the flags.  We assume that shifts by constant
12721 ;; zero are optimized away.
12722 (define_insn "*lshrhi3_cmp"
12723   [(set (reg FLAGS_REG)
12724         (compare
12725           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12726                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12727           (const_int 0)))
12728    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12729         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12730   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12731    && ix86_match_ccmode (insn, CCGOCmode)
12732    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12733   "shr{w}\t{%2, %0|%0, %2}"
12734   [(set_attr "type" "ishift")
12735    (set_attr "mode" "HI")])
12736
12737 (define_insn "*lshrhi3_cconly"
12738   [(set (reg FLAGS_REG)
12739         (compare
12740           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12741                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12742           (const_int 0)))
12743    (clobber (match_scratch:HI 0 "=r"))]
12744   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12745    && ix86_match_ccmode (insn, CCGOCmode)
12746    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12747   "shr{w}\t{%2, %0|%0, %2}"
12748   [(set_attr "type" "ishift")
12749    (set_attr "mode" "HI")])
12750
12751 (define_expand "lshrqi3"
12752   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12753         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12754                      (match_operand:QI 2 "nonmemory_operand" "")))]
12755   "TARGET_QIMODE_MATH"
12756   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12757
12758 (define_insn "*lshrqi3_1_one_bit"
12759   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12760         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12761                      (match_operand:QI 2 "const1_operand" "")))
12762    (clobber (reg:CC FLAGS_REG))]
12763   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12764    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12765   "shr{b}\t%0"
12766   [(set_attr "type" "ishift")
12767    (set_attr "length_immediate" "0")
12768    (set_attr "mode" "QI")])
12769
12770 (define_insn "*lshrqi3_1_one_bit_slp"
12771   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12772         (lshiftrt:QI (match_dup 0)
12773                      (match_operand:QI 1 "const1_operand" "")))
12774    (clobber (reg:CC FLAGS_REG))]
12775   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12776    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
12777   "shr{b}\t%0"
12778   [(set_attr "type" "ishift1")
12779    (set_attr "length_immediate" "0")
12780    (set_attr "mode" "QI")])
12781
12782 (define_insn "*lshrqi3_1"
12783   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12784         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12785                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12786    (clobber (reg:CC FLAGS_REG))]
12787   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12788   "@
12789    shr{b}\t{%2, %0|%0, %2}
12790    shr{b}\t{%b2, %0|%0, %b2}"
12791   [(set_attr "type" "ishift")
12792    (set_attr "mode" "QI")])
12793
12794 (define_insn "*lshrqi3_1_slp"
12795   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12796         (lshiftrt:QI (match_dup 0)
12797                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12798    (clobber (reg:CC FLAGS_REG))]
12799   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12800    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12801   "@
12802    shr{b}\t{%1, %0|%0, %1}
12803    shr{b}\t{%b1, %0|%0, %b1}"
12804   [(set_attr "type" "ishift1")
12805    (set_attr "mode" "QI")])
12806
12807 ;; This pattern can't accept a variable shift count, since shifts by
12808 ;; zero don't affect the flags.  We assume that shifts by constant
12809 ;; zero are optimized away.
12810 (define_insn "*lshrqi2_one_bit_cmp"
12811   [(set (reg FLAGS_REG)
12812         (compare
12813           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12814                        (match_operand:QI 2 "const1_operand" ""))
12815           (const_int 0)))
12816    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12817         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12818   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12819    && ix86_match_ccmode (insn, CCGOCmode)
12820    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12821   "shr{b}\t%0"
12822   [(set_attr "type" "ishift")
12823    (set_attr "length_immediate" "0")
12824    (set_attr "mode" "QI")])
12825
12826 (define_insn "*lshrqi2_one_bit_cconly"
12827   [(set (reg FLAGS_REG)
12828         (compare
12829           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12830                        (match_operand:QI 2 "const1_operand" ""))
12831           (const_int 0)))
12832    (clobber (match_scratch:QI 0 "=q"))]
12833   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12834    && ix86_match_ccmode (insn, CCGOCmode)
12835    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12836   "shr{b}\t%0"
12837   [(set_attr "type" "ishift")
12838    (set_attr "length_immediate" "0")
12839    (set_attr "mode" "QI")])
12840
12841 ;; This pattern can't accept a variable shift count, since shifts by
12842 ;; zero don't affect the flags.  We assume that shifts by constant
12843 ;; zero are optimized away.
12844 (define_insn "*lshrqi2_cmp"
12845   [(set (reg FLAGS_REG)
12846         (compare
12847           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12848                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12849           (const_int 0)))
12850    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12851         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12852   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12853    && ix86_match_ccmode (insn, CCGOCmode)
12854    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12855   "shr{b}\t{%2, %0|%0, %2}"
12856   [(set_attr "type" "ishift")
12857    (set_attr "mode" "QI")])
12858
12859 (define_insn "*lshrqi2_cconly"
12860   [(set (reg FLAGS_REG)
12861         (compare
12862           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12863                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12864           (const_int 0)))
12865    (clobber (match_scratch:QI 0 "=q"))]
12866   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12867    && ix86_match_ccmode (insn, CCGOCmode)
12868    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12869   "shr{b}\t{%2, %0|%0, %2}"
12870   [(set_attr "type" "ishift")
12871    (set_attr "mode" "QI")])
12872 \f
12873 ;; Rotate instructions
12874
12875 (define_expand "rotldi3"
12876   [(set (match_operand:DI 0 "shiftdi_operand" "")
12877         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12878                    (match_operand:QI 2 "nonmemory_operand" "")))]
12879  ""
12880 {
12881   if (TARGET_64BIT)
12882     {
12883       ix86_expand_binary_operator (ROTATE, DImode, operands);
12884       DONE;
12885     }
12886   if (!const_1_to_31_operand (operands[2], VOIDmode))
12887     FAIL;
12888   emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12889   DONE;
12890 })
12891
12892 ;; Implement rotation using two double-precision shift instructions
12893 ;; and a scratch register.
12894 (define_insn_and_split "ix86_rotldi3"
12895  [(set (match_operand:DI 0 "register_operand" "=r")
12896        (rotate:DI (match_operand:DI 1 "register_operand" "0")
12897                   (match_operand:QI 2 "const_1_to_31_operand" "I")))
12898   (clobber (reg:CC FLAGS_REG))
12899   (clobber (match_scratch:SI 3 "=&r"))]
12900  "!TARGET_64BIT"
12901  ""
12902  "&& reload_completed"
12903  [(set (match_dup 3) (match_dup 4))
12904   (parallel
12905    [(set (match_dup 4)
12906          (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12907                  (lshiftrt:SI (match_dup 5)
12908                               (minus:QI (const_int 32) (match_dup 2)))))
12909     (clobber (reg:CC FLAGS_REG))])
12910   (parallel
12911    [(set (match_dup 5)
12912          (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12913                  (lshiftrt:SI (match_dup 3)
12914                               (minus:QI (const_int 32) (match_dup 2)))))
12915     (clobber (reg:CC FLAGS_REG))])]
12916  "split_di (&operands[0], 1, &operands[4], &operands[5]);")
12917
12918 (define_insn "*rotlsi3_1_one_bit_rex64"
12919   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12920         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12921                    (match_operand:QI 2 "const1_operand" "")))
12922    (clobber (reg:CC FLAGS_REG))]
12923   "TARGET_64BIT
12924    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12925    && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12926   "rol{q}\t%0"
12927   [(set_attr "type" "rotate")
12928    (set_attr "length_immediate" "0")
12929    (set_attr "mode" "DI")])
12930
12931 (define_insn "*rotldi3_1_rex64"
12932   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12933         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12934                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
12935    (clobber (reg:CC FLAGS_REG))]
12936   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12937   "@
12938    rol{q}\t{%2, %0|%0, %2}
12939    rol{q}\t{%b2, %0|%0, %b2}"
12940   [(set_attr "type" "rotate")
12941    (set_attr "mode" "DI")])
12942
12943 (define_expand "rotlsi3"
12944   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12945         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12946                    (match_operand:QI 2 "nonmemory_operand" "")))]
12947   ""
12948   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12949
12950 (define_insn "*rotlsi3_1_one_bit"
12951   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12952         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12953                    (match_operand:QI 2 "const1_operand" "")))
12954    (clobber (reg:CC FLAGS_REG))]
12955   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12956    && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12957   "rol{l}\t%0"
12958   [(set_attr "type" "rotate")
12959    (set_attr "length_immediate" "0")
12960    (set_attr "mode" "SI")])
12961
12962 (define_insn "*rotlsi3_1_one_bit_zext"
12963   [(set (match_operand:DI 0 "register_operand" "=r")
12964         (zero_extend:DI
12965           (rotate:SI (match_operand:SI 1 "register_operand" "0")
12966                      (match_operand:QI 2 "const1_operand" ""))))
12967    (clobber (reg:CC FLAGS_REG))]
12968   "TARGET_64BIT
12969    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12970    && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12971   "rol{l}\t%k0"
12972   [(set_attr "type" "rotate")
12973    (set_attr "length_immediate" "0")
12974    (set_attr "mode" "SI")])
12975
12976 (define_insn "*rotlsi3_1"
12977   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12978         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12979                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12980    (clobber (reg:CC FLAGS_REG))]
12981   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12982   "@
12983    rol{l}\t{%2, %0|%0, %2}
12984    rol{l}\t{%b2, %0|%0, %b2}"
12985   [(set_attr "type" "rotate")
12986    (set_attr "mode" "SI")])
12987
12988 (define_insn "*rotlsi3_1_zext"
12989   [(set (match_operand:DI 0 "register_operand" "=r,r")
12990         (zero_extend:DI
12991           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12992                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12993    (clobber (reg:CC FLAGS_REG))]
12994   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12995   "@
12996    rol{l}\t{%2, %k0|%k0, %2}
12997    rol{l}\t{%b2, %k0|%k0, %b2}"
12998   [(set_attr "type" "rotate")
12999    (set_attr "mode" "SI")])
13000
13001 (define_expand "rotlhi3"
13002   [(set (match_operand:HI 0 "nonimmediate_operand" "")
13003         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
13004                    (match_operand:QI 2 "nonmemory_operand" "")))]
13005   "TARGET_HIMODE_MATH"
13006   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
13007
13008 (define_insn "*rotlhi3_1_one_bit"
13009   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13010         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13011                    (match_operand:QI 2 "const1_operand" "")))
13012    (clobber (reg:CC FLAGS_REG))]
13013   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13014    && ix86_binary_operator_ok (ROTATE, HImode, operands)"
13015   "rol{w}\t%0"
13016   [(set_attr "type" "rotate")
13017    (set_attr "length_immediate" "0")
13018    (set_attr "mode" "HI")])
13019
13020 (define_insn "*rotlhi3_1"
13021   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13022         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13023                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
13024    (clobber (reg:CC FLAGS_REG))]
13025   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
13026   "@
13027    rol{w}\t{%2, %0|%0, %2}
13028    rol{w}\t{%b2, %0|%0, %b2}"
13029   [(set_attr "type" "rotate")
13030    (set_attr "mode" "HI")])
13031
13032 (define_split
13033  [(set (match_operand:HI 0 "register_operand" "")
13034        (rotate:HI (match_dup 0) (const_int 8)))
13035   (clobber (reg:CC FLAGS_REG))]
13036  "reload_completed"
13037  [(parallel [(set (strict_low_part (match_dup 0))
13038                   (bswap:HI (match_dup 0)))
13039              (clobber (reg:CC FLAGS_REG))])]
13040  "")
13041
13042 (define_expand "rotlqi3"
13043   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13044         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
13045                    (match_operand:QI 2 "nonmemory_operand" "")))]
13046   "TARGET_QIMODE_MATH"
13047   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
13048
13049 (define_insn "*rotlqi3_1_one_bit_slp"
13050   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13051         (rotate:QI (match_dup 0)
13052                    (match_operand:QI 1 "const1_operand" "")))
13053    (clobber (reg:CC FLAGS_REG))]
13054   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13055    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
13056   "rol{b}\t%0"
13057   [(set_attr "type" "rotate1")
13058    (set_attr "length_immediate" "0")
13059    (set_attr "mode" "QI")])
13060
13061 (define_insn "*rotlqi3_1_one_bit"
13062   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13063         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13064                    (match_operand:QI 2 "const1_operand" "")))
13065    (clobber (reg:CC FLAGS_REG))]
13066   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13067    && ix86_binary_operator_ok (ROTATE, QImode, operands)"
13068   "rol{b}\t%0"
13069   [(set_attr "type" "rotate")
13070    (set_attr "length_immediate" "0")
13071    (set_attr "mode" "QI")])
13072
13073 (define_insn "*rotlqi3_1_slp"
13074   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13075         (rotate:QI (match_dup 0)
13076                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
13077    (clobber (reg:CC FLAGS_REG))]
13078   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13079    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13080   "@
13081    rol{b}\t{%1, %0|%0, %1}
13082    rol{b}\t{%b1, %0|%0, %b1}"
13083   [(set_attr "type" "rotate1")
13084    (set_attr "mode" "QI")])
13085
13086 (define_insn "*rotlqi3_1"
13087   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13088         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13089                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
13090    (clobber (reg:CC FLAGS_REG))]
13091   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
13092   "@
13093    rol{b}\t{%2, %0|%0, %2}
13094    rol{b}\t{%b2, %0|%0, %b2}"
13095   [(set_attr "type" "rotate")
13096    (set_attr "mode" "QI")])
13097
13098 (define_expand "rotrdi3"
13099   [(set (match_operand:DI 0 "shiftdi_operand" "")
13100         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13101                    (match_operand:QI 2 "nonmemory_operand" "")))]
13102  ""
13103 {
13104   if (TARGET_64BIT)
13105     {
13106       ix86_expand_binary_operator (ROTATERT, DImode, operands);
13107       DONE;
13108     }
13109   if (!const_1_to_31_operand (operands[2], VOIDmode))
13110     FAIL;
13111   emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
13112   DONE;
13113 })
13114
13115 ;; Implement rotation using two double-precision shift instructions
13116 ;; and a scratch register.
13117 (define_insn_and_split "ix86_rotrdi3"
13118  [(set (match_operand:DI 0 "register_operand" "=r")
13119        (rotatert:DI (match_operand:DI 1 "register_operand" "0")
13120                     (match_operand:QI 2 "const_1_to_31_operand" "I")))
13121   (clobber (reg:CC FLAGS_REG))
13122   (clobber (match_scratch:SI 3 "=&r"))]
13123  "!TARGET_64BIT"
13124  ""
13125  "&& reload_completed"
13126  [(set (match_dup 3) (match_dup 4))
13127   (parallel
13128    [(set (match_dup 4)
13129          (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
13130                  (ashift:SI (match_dup 5)
13131                             (minus:QI (const_int 32) (match_dup 2)))))
13132     (clobber (reg:CC FLAGS_REG))])
13133   (parallel
13134    [(set (match_dup 5)
13135          (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
13136                  (ashift:SI (match_dup 3)
13137                             (minus:QI (const_int 32) (match_dup 2)))))
13138     (clobber (reg:CC FLAGS_REG))])]
13139  "split_di (&operands[0], 1, &operands[4], &operands[5]);")
13140
13141 (define_insn "*rotrdi3_1_one_bit_rex64"
13142   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13143         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13144                      (match_operand:QI 2 "const1_operand" "")))
13145    (clobber (reg:CC FLAGS_REG))]
13146   "TARGET_64BIT
13147    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13148    && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13149   "ror{q}\t%0"
13150   [(set_attr "type" "rotate")
13151    (set_attr "length_immediate" "0")
13152    (set_attr "mode" "DI")])
13153
13154 (define_insn "*rotrdi3_1_rex64"
13155   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13156         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13157                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
13158    (clobber (reg:CC FLAGS_REG))]
13159   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13160   "@
13161    ror{q}\t{%2, %0|%0, %2}
13162    ror{q}\t{%b2, %0|%0, %b2}"
13163   [(set_attr "type" "rotate")
13164    (set_attr "mode" "DI")])
13165
13166 (define_expand "rotrsi3"
13167   [(set (match_operand:SI 0 "nonimmediate_operand" "")
13168         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
13169                      (match_operand:QI 2 "nonmemory_operand" "")))]
13170   ""
13171   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
13172
13173 (define_insn "*rotrsi3_1_one_bit"
13174   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13175         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13176                      (match_operand:QI 2 "const1_operand" "")))
13177    (clobber (reg:CC FLAGS_REG))]
13178   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13179    && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13180   "ror{l}\t%0"
13181   [(set_attr "type" "rotate")
13182    (set_attr "length_immediate" "0")
13183    (set_attr "mode" "SI")])
13184
13185 (define_insn "*rotrsi3_1_one_bit_zext"
13186   [(set (match_operand:DI 0 "register_operand" "=r")
13187         (zero_extend:DI
13188           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
13189                        (match_operand:QI 2 "const1_operand" ""))))
13190    (clobber (reg:CC FLAGS_REG))]
13191   "TARGET_64BIT
13192    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13193    && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13194   "ror{l}\t%k0"
13195   [(set_attr "type" "rotate")
13196    (set_attr "length_immediate" "0")
13197    (set_attr "mode" "SI")])
13198
13199 (define_insn "*rotrsi3_1"
13200   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13201         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13202                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13203    (clobber (reg:CC FLAGS_REG))]
13204   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13205   "@
13206    ror{l}\t{%2, %0|%0, %2}
13207    ror{l}\t{%b2, %0|%0, %b2}"
13208   [(set_attr "type" "rotate")
13209    (set_attr "mode" "SI")])
13210
13211 (define_insn "*rotrsi3_1_zext"
13212   [(set (match_operand:DI 0 "register_operand" "=r,r")
13213         (zero_extend:DI
13214           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
13215                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13216    (clobber (reg:CC FLAGS_REG))]
13217   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13218   "@
13219    ror{l}\t{%2, %k0|%k0, %2}
13220    ror{l}\t{%b2, %k0|%k0, %b2}"
13221   [(set_attr "type" "rotate")
13222    (set_attr "mode" "SI")])
13223
13224 (define_expand "rotrhi3"
13225   [(set (match_operand:HI 0 "nonimmediate_operand" "")
13226         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
13227                      (match_operand:QI 2 "nonmemory_operand" "")))]
13228   "TARGET_HIMODE_MATH"
13229   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
13230
13231 (define_insn "*rotrhi3_one_bit"
13232   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13233         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13234                      (match_operand:QI 2 "const1_operand" "")))
13235    (clobber (reg:CC FLAGS_REG))]
13236   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13237    && ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13238   "ror{w}\t%0"
13239   [(set_attr "type" "rotate")
13240    (set_attr "length_immediate" "0")
13241    (set_attr "mode" "HI")])
13242
13243 (define_insn "*rotrhi3_1"
13244   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13245         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13246                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13247    (clobber (reg:CC FLAGS_REG))]
13248   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13249   "@
13250    ror{w}\t{%2, %0|%0, %2}
13251    ror{w}\t{%b2, %0|%0, %b2}"
13252   [(set_attr "type" "rotate")
13253    (set_attr "mode" "HI")])
13254
13255 (define_split
13256  [(set (match_operand:HI 0 "register_operand" "")
13257        (rotatert:HI (match_dup 0) (const_int 8)))
13258   (clobber (reg:CC FLAGS_REG))]
13259  "reload_completed"
13260  [(parallel [(set (strict_low_part (match_dup 0))
13261                   (bswap:HI (match_dup 0)))
13262              (clobber (reg:CC FLAGS_REG))])]
13263  "")
13264
13265 (define_expand "rotrqi3"
13266   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13267         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
13268                      (match_operand:QI 2 "nonmemory_operand" "")))]
13269   "TARGET_QIMODE_MATH"
13270   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
13271
13272 (define_insn "*rotrqi3_1_one_bit"
13273   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13274         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13275                      (match_operand:QI 2 "const1_operand" "")))
13276    (clobber (reg:CC FLAGS_REG))]
13277   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13278    && ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13279   "ror{b}\t%0"
13280   [(set_attr "type" "rotate")
13281    (set_attr "length_immediate" "0")
13282    (set_attr "mode" "QI")])
13283
13284 (define_insn "*rotrqi3_1_one_bit_slp"
13285   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13286         (rotatert:QI (match_dup 0)
13287                      (match_operand:QI 1 "const1_operand" "")))
13288    (clobber (reg:CC FLAGS_REG))]
13289   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13290    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
13291   "ror{b}\t%0"
13292   [(set_attr "type" "rotate1")
13293    (set_attr "length_immediate" "0")
13294    (set_attr "mode" "QI")])
13295
13296 (define_insn "*rotrqi3_1"
13297   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13298         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13299                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13300    (clobber (reg:CC FLAGS_REG))]
13301   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13302   "@
13303    ror{b}\t{%2, %0|%0, %2}
13304    ror{b}\t{%b2, %0|%0, %b2}"
13305   [(set_attr "type" "rotate")
13306    (set_attr "mode" "QI")])
13307
13308 (define_insn "*rotrqi3_1_slp"
13309   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13310         (rotatert:QI (match_dup 0)
13311                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
13312    (clobber (reg:CC FLAGS_REG))]
13313   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13314    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13315   "@
13316    ror{b}\t{%1, %0|%0, %1}
13317    ror{b}\t{%b1, %0|%0, %b1}"
13318   [(set_attr "type" "rotate1")
13319    (set_attr "mode" "QI")])
13320 \f
13321 ;; Bit set / bit test instructions
13322
13323 (define_expand "extv"
13324   [(set (match_operand:SI 0 "register_operand" "")
13325         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13326                          (match_operand:SI 2 "const8_operand" "")
13327                          (match_operand:SI 3 "const8_operand" "")))]
13328   ""
13329 {
13330   /* Handle extractions from %ah et al.  */
13331   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13332     FAIL;
13333
13334   /* From mips.md: extract_bit_field doesn't verify that our source
13335      matches the predicate, so check it again here.  */
13336   if (! ext_register_operand (operands[1], VOIDmode))
13337     FAIL;
13338 })
13339
13340 (define_expand "extzv"
13341   [(set (match_operand:SI 0 "register_operand" "")
13342         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13343                          (match_operand:SI 2 "const8_operand" "")
13344                          (match_operand:SI 3 "const8_operand" "")))]
13345   ""
13346 {
13347   /* Handle extractions from %ah et al.  */
13348   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13349     FAIL;
13350
13351   /* From mips.md: extract_bit_field doesn't verify that our source
13352      matches the predicate, so check it again here.  */
13353   if (! ext_register_operand (operands[1], VOIDmode))
13354     FAIL;
13355 })
13356
13357 (define_expand "insv"
13358   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13359                       (match_operand 1 "const8_operand" "")
13360                       (match_operand 2 "const8_operand" ""))
13361         (match_operand 3 "register_operand" ""))]
13362   ""
13363 {
13364   /* Handle insertions to %ah et al.  */
13365   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13366     FAIL;
13367
13368   /* From mips.md: insert_bit_field doesn't verify that our source
13369      matches the predicate, so check it again here.  */
13370   if (! ext_register_operand (operands[0], VOIDmode))
13371     FAIL;
13372
13373   if (TARGET_64BIT)
13374     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13375   else
13376     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13377
13378   DONE;
13379 })
13380
13381 ;; %%% bts, btr, btc, bt.
13382 ;; In general these instructions are *slow* when applied to memory,
13383 ;; since they enforce atomic operation.  When applied to registers,
13384 ;; it depends on the cpu implementation.  They're never faster than
13385 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13386 ;; no point.  But in 64-bit, we can't hold the relevant immediates
13387 ;; within the instruction itself, so operating on bits in the high
13388 ;; 32-bits of a register becomes easier.
13389 ;;
13390 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
13391 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13392 ;; negdf respectively, so they can never be disabled entirely.
13393
13394 (define_insn "*btsq"
13395   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13396                          (const_int 1)
13397                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13398         (const_int 1))
13399    (clobber (reg:CC FLAGS_REG))]
13400   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13401   "bts{q}\t{%1, %0|%0, %1}"
13402   [(set_attr "type" "alu1")
13403    (set_attr "prefix_0f" "1")
13404    (set_attr "mode" "DI")])
13405
13406 (define_insn "*btrq"
13407   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13408                          (const_int 1)
13409                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13410         (const_int 0))
13411    (clobber (reg:CC FLAGS_REG))]
13412   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13413   "btr{q}\t{%1, %0|%0, %1}"
13414   [(set_attr "type" "alu1")
13415    (set_attr "prefix_0f" "1")
13416    (set_attr "mode" "DI")])
13417
13418 (define_insn "*btcq"
13419   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13420                          (const_int 1)
13421                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13422         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13423    (clobber (reg:CC FLAGS_REG))]
13424   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13425   "btc{q}\t{%1, %0|%0, %1}"
13426   [(set_attr "type" "alu1")
13427    (set_attr "prefix_0f" "1")
13428    (set_attr "mode" "DI")])
13429
13430 ;; Allow Nocona to avoid these instructions if a register is available.
13431
13432 (define_peephole2
13433   [(match_scratch:DI 2 "r")
13434    (parallel [(set (zero_extract:DI
13435                      (match_operand:DI 0 "register_operand" "")
13436                      (const_int 1)
13437                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13438                    (const_int 1))
13439               (clobber (reg:CC FLAGS_REG))])]
13440   "TARGET_64BIT && !TARGET_USE_BT"
13441   [(const_int 0)]
13442 {
13443   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13444   rtx op1;
13445
13446   if (HOST_BITS_PER_WIDE_INT >= 64)
13447     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13448   else if (i < HOST_BITS_PER_WIDE_INT)
13449     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13450   else
13451     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13452
13453   op1 = immed_double_const (lo, hi, DImode);
13454   if (i >= 31)
13455     {
13456       emit_move_insn (operands[2], op1);
13457       op1 = operands[2];
13458     }
13459
13460   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13461   DONE;
13462 })
13463
13464 (define_peephole2
13465   [(match_scratch:DI 2 "r")
13466    (parallel [(set (zero_extract:DI
13467                      (match_operand:DI 0 "register_operand" "")
13468                      (const_int 1)
13469                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13470                    (const_int 0))
13471               (clobber (reg:CC FLAGS_REG))])]
13472   "TARGET_64BIT && !TARGET_USE_BT"
13473   [(const_int 0)]
13474 {
13475   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13476   rtx op1;
13477
13478   if (HOST_BITS_PER_WIDE_INT >= 64)
13479     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13480   else if (i < HOST_BITS_PER_WIDE_INT)
13481     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13482   else
13483     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13484
13485   op1 = immed_double_const (~lo, ~hi, DImode);
13486   if (i >= 32)
13487     {
13488       emit_move_insn (operands[2], op1);
13489       op1 = operands[2];
13490     }
13491
13492   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13493   DONE;
13494 })
13495
13496 (define_peephole2
13497   [(match_scratch:DI 2 "r")
13498    (parallel [(set (zero_extract:DI
13499                      (match_operand:DI 0 "register_operand" "")
13500                      (const_int 1)
13501                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13502               (not:DI (zero_extract:DI
13503                         (match_dup 0) (const_int 1) (match_dup 1))))
13504               (clobber (reg:CC FLAGS_REG))])]
13505   "TARGET_64BIT && !TARGET_USE_BT"
13506   [(const_int 0)]
13507 {
13508   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13509   rtx op1;
13510
13511   if (HOST_BITS_PER_WIDE_INT >= 64)
13512     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13513   else if (i < HOST_BITS_PER_WIDE_INT)
13514     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13515   else
13516     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13517
13518   op1 = immed_double_const (lo, hi, DImode);
13519   if (i >= 31)
13520     {
13521       emit_move_insn (operands[2], op1);
13522       op1 = operands[2];
13523     }
13524
13525   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13526   DONE;
13527 })
13528
13529 (define_insn "*btdi_rex64"
13530   [(set (reg:CCC FLAGS_REG)
13531         (compare:CCC
13532           (zero_extract:DI
13533             (match_operand:DI 0 "register_operand" "r")
13534             (const_int 1)
13535             (match_operand:DI 1 "nonmemory_operand" "rN"))
13536           (const_int 0)))]
13537   "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
13538   "bt{q}\t{%1, %0|%0, %1}"
13539   [(set_attr "type" "alu1")
13540    (set_attr "prefix_0f" "1")
13541    (set_attr "mode" "DI")])
13542
13543 (define_insn "*btsi"
13544   [(set (reg:CCC FLAGS_REG)
13545         (compare:CCC
13546           (zero_extract:SI
13547             (match_operand:SI 0 "register_operand" "r")
13548             (const_int 1)
13549             (match_operand:SI 1 "nonmemory_operand" "rN"))
13550           (const_int 0)))]
13551   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
13552   "bt{l}\t{%1, %0|%0, %1}"
13553   [(set_attr "type" "alu1")
13554    (set_attr "prefix_0f" "1")
13555    (set_attr "mode" "SI")])
13556 \f
13557 ;; Store-flag instructions.
13558
13559 ;; For all sCOND expanders, also expand the compare or test insn that
13560 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
13561
13562 (define_insn_and_split "*setcc_di_1"
13563   [(set (match_operand:DI 0 "register_operand" "=q")
13564         (match_operator:DI 1 "ix86_comparison_operator"
13565           [(reg FLAGS_REG) (const_int 0)]))]
13566   "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
13567   "#"
13568   "&& reload_completed"
13569   [(set (match_dup 2) (match_dup 1))
13570    (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
13571 {
13572   PUT_MODE (operands[1], QImode);
13573   operands[2] = gen_lowpart (QImode, operands[0]);
13574 })
13575
13576 (define_insn_and_split "*setcc_si_1_and"
13577   [(set (match_operand:SI 0 "register_operand" "=q")
13578         (match_operator:SI 1 "ix86_comparison_operator"
13579           [(reg FLAGS_REG) (const_int 0)]))
13580    (clobber (reg:CC FLAGS_REG))]
13581   "!TARGET_PARTIAL_REG_STALL
13582    && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
13583   "#"
13584   "&& reload_completed"
13585   [(set (match_dup 2) (match_dup 1))
13586    (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
13587               (clobber (reg:CC FLAGS_REG))])]
13588 {
13589   PUT_MODE (operands[1], QImode);
13590   operands[2] = gen_lowpart (QImode, operands[0]);
13591 })
13592
13593 (define_insn_and_split "*setcc_si_1_movzbl"
13594   [(set (match_operand:SI 0 "register_operand" "=q")
13595         (match_operator:SI 1 "ix86_comparison_operator"
13596           [(reg FLAGS_REG) (const_int 0)]))]
13597   "!TARGET_PARTIAL_REG_STALL
13598    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
13599   "#"
13600   "&& reload_completed"
13601   [(set (match_dup 2) (match_dup 1))
13602    (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
13603 {
13604   PUT_MODE (operands[1], QImode);
13605   operands[2] = gen_lowpart (QImode, operands[0]);
13606 })
13607
13608 (define_insn "*setcc_qi"
13609   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13610         (match_operator:QI 1 "ix86_comparison_operator"
13611           [(reg FLAGS_REG) (const_int 0)]))]
13612   ""
13613   "set%C1\t%0"
13614   [(set_attr "type" "setcc")
13615    (set_attr "mode" "QI")])
13616
13617 (define_insn "*setcc_qi_slp"
13618   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13619         (match_operator:QI 1 "ix86_comparison_operator"
13620           [(reg FLAGS_REG) (const_int 0)]))]
13621   ""
13622   "set%C1\t%0"
13623   [(set_attr "type" "setcc")
13624    (set_attr "mode" "QI")])
13625
13626 ;; In general it is not safe to assume too much about CCmode registers,
13627 ;; so simplify-rtx stops when it sees a second one.  Under certain
13628 ;; conditions this is safe on x86, so help combine not create
13629 ;;
13630 ;;      seta    %al
13631 ;;      testb   %al, %al
13632 ;;      sete    %al
13633
13634 (define_split
13635   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13636         (ne:QI (match_operator 1 "ix86_comparison_operator"
13637                  [(reg FLAGS_REG) (const_int 0)])
13638             (const_int 0)))]
13639   ""
13640   [(set (match_dup 0) (match_dup 1))]
13641 {
13642   PUT_MODE (operands[1], QImode);
13643 })
13644
13645 (define_split
13646   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13647         (ne:QI (match_operator 1 "ix86_comparison_operator"
13648                  [(reg FLAGS_REG) (const_int 0)])
13649             (const_int 0)))]
13650   ""
13651   [(set (match_dup 0) (match_dup 1))]
13652 {
13653   PUT_MODE (operands[1], QImode);
13654 })
13655
13656 (define_split
13657   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13658         (eq:QI (match_operator 1 "ix86_comparison_operator"
13659                  [(reg FLAGS_REG) (const_int 0)])
13660             (const_int 0)))]
13661   ""
13662   [(set (match_dup 0) (match_dup 1))]
13663 {
13664   rtx new_op1 = copy_rtx (operands[1]);
13665   operands[1] = new_op1;
13666   PUT_MODE (new_op1, QImode);
13667   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13668                                              GET_MODE (XEXP (new_op1, 0))));
13669
13670   /* Make sure that (a) the CCmode we have for the flags is strong
13671      enough for the reversed compare or (b) we have a valid FP compare.  */
13672   if (! ix86_comparison_operator (new_op1, VOIDmode))
13673     FAIL;
13674 })
13675
13676 (define_split
13677   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13678         (eq:QI (match_operator 1 "ix86_comparison_operator"
13679                  [(reg FLAGS_REG) (const_int 0)])
13680             (const_int 0)))]
13681   ""
13682   [(set (match_dup 0) (match_dup 1))]
13683 {
13684   rtx new_op1 = copy_rtx (operands[1]);
13685   operands[1] = new_op1;
13686   PUT_MODE (new_op1, QImode);
13687   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13688                                              GET_MODE (XEXP (new_op1, 0))));
13689
13690   /* Make sure that (a) the CCmode we have for the flags is strong
13691      enough for the reversed compare or (b) we have a valid FP compare.  */
13692   if (! ix86_comparison_operator (new_op1, VOIDmode))
13693     FAIL;
13694 })
13695
13696 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13697 ;; subsequent logical operations are used to imitate conditional moves.
13698 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13699 ;; it directly.
13700
13701 (define_insn "*avx_setcc<mode>"
13702   [(set (match_operand:MODEF 0 "register_operand" "=x")
13703         (match_operator:MODEF 1 "avx_comparison_float_operator"
13704           [(match_operand:MODEF 2 "register_operand" "x")
13705            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
13706   "TARGET_AVX"
13707   "vcmp%D1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
13708   [(set_attr "type" "ssecmp")
13709    (set_attr "prefix" "vex")
13710    (set_attr "length_immediate" "1")
13711    (set_attr "mode" "<MODE>")])
13712
13713 (define_insn "*sse_setcc<mode>"
13714   [(set (match_operand:MODEF 0 "register_operand" "=x")
13715         (match_operator:MODEF 1 "sse_comparison_operator"
13716           [(match_operand:MODEF 2 "register_operand" "0")
13717            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
13718   "SSE_FLOAT_MODE_P (<MODE>mode)"
13719   "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
13720   [(set_attr "type" "ssecmp")
13721    (set_attr "length_immediate" "1")
13722    (set_attr "mode" "<MODE>")])
13723 \f
13724 ;; Basic conditional jump instructions.
13725 ;; We ignore the overflow flag for signed branch instructions.
13726
13727 (define_insn "*jcc_1"
13728   [(set (pc)
13729         (if_then_else (match_operator 1 "ix86_comparison_operator"
13730                                       [(reg FLAGS_REG) (const_int 0)])
13731                       (label_ref (match_operand 0 "" ""))
13732                       (pc)))]
13733   ""
13734   "%+j%C1\t%l0"
13735   [(set_attr "type" "ibr")
13736    (set_attr "modrm" "0")
13737    (set (attr "length")
13738            (if_then_else (and (ge (minus (match_dup 0) (pc))
13739                                   (const_int -126))
13740                               (lt (minus (match_dup 0) (pc))
13741                                   (const_int 128)))
13742              (const_int 2)
13743              (const_int 6)))])
13744
13745 (define_insn "*jcc_2"
13746   [(set (pc)
13747         (if_then_else (match_operator 1 "ix86_comparison_operator"
13748                                       [(reg FLAGS_REG) (const_int 0)])
13749                       (pc)
13750                       (label_ref (match_operand 0 "" ""))))]
13751   ""
13752   "%+j%c1\t%l0"
13753   [(set_attr "type" "ibr")
13754    (set_attr "modrm" "0")
13755    (set (attr "length")
13756            (if_then_else (and (ge (minus (match_dup 0) (pc))
13757                                   (const_int -126))
13758                               (lt (minus (match_dup 0) (pc))
13759                                   (const_int 128)))
13760              (const_int 2)
13761              (const_int 6)))])
13762
13763 ;; In general it is not safe to assume too much about CCmode registers,
13764 ;; so simplify-rtx stops when it sees a second one.  Under certain
13765 ;; conditions this is safe on x86, so help combine not create
13766 ;;
13767 ;;      seta    %al
13768 ;;      testb   %al, %al
13769 ;;      je      Lfoo
13770
13771 (define_split
13772   [(set (pc)
13773         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13774                                       [(reg FLAGS_REG) (const_int 0)])
13775                           (const_int 0))
13776                       (label_ref (match_operand 1 "" ""))
13777                       (pc)))]
13778   ""
13779   [(set (pc)
13780         (if_then_else (match_dup 0)
13781                       (label_ref (match_dup 1))
13782                       (pc)))]
13783 {
13784   PUT_MODE (operands[0], VOIDmode);
13785 })
13786
13787 (define_split
13788   [(set (pc)
13789         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13790                                       [(reg FLAGS_REG) (const_int 0)])
13791                           (const_int 0))
13792                       (label_ref (match_operand 1 "" ""))
13793                       (pc)))]
13794   ""
13795   [(set (pc)
13796         (if_then_else (match_dup 0)
13797                       (label_ref (match_dup 1))
13798                       (pc)))]
13799 {
13800   rtx new_op0 = copy_rtx (operands[0]);
13801   operands[0] = new_op0;
13802   PUT_MODE (new_op0, VOIDmode);
13803   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13804                                              GET_MODE (XEXP (new_op0, 0))));
13805
13806   /* Make sure that (a) the CCmode we have for the flags is strong
13807      enough for the reversed compare or (b) we have a valid FP compare.  */
13808   if (! ix86_comparison_operator (new_op0, VOIDmode))
13809     FAIL;
13810 })
13811
13812 ;; zero_extend in SImode is correct, since this is what combine pass
13813 ;; generates from shift insn with QImode operand.  Actually, the mode of
13814 ;; operand 2 (bit offset operand) doesn't matter since bt insn takes
13815 ;; appropriate modulo of the bit offset value.
13816
13817 (define_insn_and_split "*jcc_btdi_rex64"
13818   [(set (pc)
13819         (if_then_else (match_operator 0 "bt_comparison_operator"
13820                         [(zero_extract:DI
13821                            (match_operand:DI 1 "register_operand" "r")
13822                            (const_int 1)
13823                            (zero_extend:SI
13824                              (match_operand:QI 2 "register_operand" "r")))
13825                          (const_int 0)])
13826                       (label_ref (match_operand 3 "" ""))
13827                       (pc)))
13828    (clobber (reg:CC FLAGS_REG))]
13829   "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
13830   "#"
13831   "&& 1"
13832   [(set (reg:CCC FLAGS_REG)
13833         (compare:CCC
13834           (zero_extract:DI
13835             (match_dup 1)
13836             (const_int 1)
13837             (match_dup 2))
13838           (const_int 0)))
13839    (set (pc)
13840         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
13841                       (label_ref (match_dup 3))
13842                       (pc)))]
13843 {
13844   operands[2] = simplify_gen_subreg (DImode, operands[2], QImode, 0);
13845
13846   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
13847 })
13848
13849 ;; avoid useless masking of bit offset operand
13850 (define_insn_and_split "*jcc_btdi_mask_rex64"
13851   [(set (pc)
13852         (if_then_else (match_operator 0 "bt_comparison_operator"
13853                         [(zero_extract:DI
13854                            (match_operand:DI 1 "register_operand" "r")
13855                            (const_int 1)
13856                            (and:SI
13857                              (match_operand:SI 2 "register_operand" "r")
13858                              (match_operand:SI 3 "const_int_operand" "n")))])
13859                       (label_ref (match_operand 4 "" ""))
13860                       (pc)))
13861    (clobber (reg:CC FLAGS_REG))]
13862   "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))
13863    && (INTVAL (operands[3]) & 0x3f) == 0x3f"
13864   "#"
13865   "&& 1"
13866   [(set (reg:CCC FLAGS_REG)
13867         (compare:CCC
13868           (zero_extract:DI
13869             (match_dup 1)
13870             (const_int 1)
13871             (match_dup 2))
13872           (const_int 0)))
13873    (set (pc)
13874         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
13875                       (label_ref (match_dup 4))
13876                       (pc)))]
13877 {
13878   operands[2] = simplify_gen_subreg (DImode, operands[2], SImode, 0);
13879
13880   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
13881 })
13882
13883 (define_insn_and_split "*jcc_btsi"
13884   [(set (pc)
13885         (if_then_else (match_operator 0 "bt_comparison_operator"
13886                         [(zero_extract:SI
13887                            (match_operand:SI 1 "register_operand" "r")
13888                            (const_int 1)
13889                            (zero_extend:SI
13890                              (match_operand:QI 2 "register_operand" "r")))
13891                          (const_int 0)])
13892                       (label_ref (match_operand 3 "" ""))
13893                       (pc)))
13894    (clobber (reg:CC FLAGS_REG))]
13895   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
13896   "#"
13897   "&& 1"
13898   [(set (reg:CCC FLAGS_REG)
13899         (compare:CCC
13900           (zero_extract:SI
13901             (match_dup 1)
13902             (const_int 1)
13903             (match_dup 2))
13904           (const_int 0)))
13905    (set (pc)
13906         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
13907                       (label_ref (match_dup 3))
13908                       (pc)))]
13909 {
13910   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
13911
13912   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
13913 })
13914
13915 ;; avoid useless masking of bit offset operand
13916 (define_insn_and_split "*jcc_btsi_mask"
13917   [(set (pc)
13918         (if_then_else (match_operator 0 "bt_comparison_operator"
13919                         [(zero_extract:SI
13920                            (match_operand:SI 1 "register_operand" "r")
13921                            (const_int 1)
13922                            (and:SI
13923                              (match_operand:SI 2 "register_operand" "r")
13924                              (match_operand:SI 3 "const_int_operand" "n")))])
13925                       (label_ref (match_operand 4 "" ""))
13926                       (pc)))
13927    (clobber (reg:CC FLAGS_REG))]
13928   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
13929    && (INTVAL (operands[3]) & 0x1f) == 0x1f"
13930   "#"
13931   "&& 1"
13932   [(set (reg:CCC FLAGS_REG)
13933         (compare:CCC
13934           (zero_extract:SI
13935             (match_dup 1)
13936             (const_int 1)
13937             (match_dup 2))
13938           (const_int 0)))
13939    (set (pc)
13940         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
13941                       (label_ref (match_dup 4))
13942                       (pc)))]
13943   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
13944
13945 (define_insn_and_split "*jcc_btsi_1"
13946   [(set (pc)
13947         (if_then_else (match_operator 0 "bt_comparison_operator"
13948                         [(and:SI
13949                            (lshiftrt:SI
13950                              (match_operand:SI 1 "register_operand" "r")
13951                              (match_operand:QI 2 "register_operand" "r"))
13952                            (const_int 1))
13953                          (const_int 0)])
13954                       (label_ref (match_operand 3 "" ""))
13955                       (pc)))
13956    (clobber (reg:CC FLAGS_REG))]
13957   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
13958   "#"
13959   "&& 1"
13960   [(set (reg:CCC FLAGS_REG)
13961         (compare:CCC
13962           (zero_extract:SI
13963             (match_dup 1)
13964             (const_int 1)
13965             (match_dup 2))
13966           (const_int 0)))
13967    (set (pc)
13968         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
13969                       (label_ref (match_dup 3))
13970                       (pc)))]
13971 {
13972   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
13973
13974   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
13975 })
13976
13977 ;; avoid useless masking of bit offset operand
13978 (define_insn_and_split "*jcc_btsi_mask_1"
13979   [(set (pc)
13980         (if_then_else
13981           (match_operator 0 "bt_comparison_operator"
13982             [(and:SI
13983                (lshiftrt:SI
13984                  (match_operand:SI 1 "register_operand" "r")
13985                  (subreg:QI
13986                    (and:SI
13987                      (match_operand:SI 2 "register_operand" "r")
13988                      (match_operand:SI 3 "const_int_operand" "n")) 0))
13989                (const_int 1))
13990              (const_int 0)])
13991           (label_ref (match_operand 4 "" ""))
13992           (pc)))
13993    (clobber (reg:CC FLAGS_REG))]
13994   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
13995    && (INTVAL (operands[3]) & 0x1f) == 0x1f"
13996   "#"
13997   "&& 1"
13998   [(set (reg:CCC FLAGS_REG)
13999         (compare:CCC
14000           (zero_extract:SI
14001             (match_dup 1)
14002             (const_int 1)
14003             (match_dup 2))
14004           (const_int 0)))
14005    (set (pc)
14006         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14007                       (label_ref (match_dup 4))
14008                       (pc)))]
14009   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
14010
14011 ;; Define combination compare-and-branch fp compare instructions to help
14012 ;; combine.
14013
14014 (define_insn "*fp_jcc_3_387"
14015   [(set (pc)
14016         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
14017                         [(match_operand 1 "register_operand" "f")
14018                          (match_operand 2 "nonimmediate_operand" "fm")])
14019           (label_ref (match_operand 3 "" ""))
14020           (pc)))
14021    (clobber (reg:CCFP FPSR_REG))
14022    (clobber (reg:CCFP FLAGS_REG))
14023    (clobber (match_scratch:HI 4 "=a"))]
14024   "TARGET_80387
14025    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14026    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14027    && SELECT_CC_MODE (GET_CODE (operands[0]),
14028                       operands[1], operands[2]) == CCFPmode
14029    && !TARGET_CMOVE"
14030   "#")
14031
14032 (define_insn "*fp_jcc_4_387"
14033   [(set (pc)
14034         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
14035                         [(match_operand 1 "register_operand" "f")
14036                          (match_operand 2 "nonimmediate_operand" "fm")])
14037           (pc)
14038           (label_ref (match_operand 3 "" ""))))
14039    (clobber (reg:CCFP FPSR_REG))
14040    (clobber (reg:CCFP FLAGS_REG))
14041    (clobber (match_scratch:HI 4 "=a"))]
14042   "TARGET_80387
14043    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14044    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14045    && SELECT_CC_MODE (GET_CODE (operands[0]),
14046                       operands[1], operands[2]) == CCFPmode
14047    && !TARGET_CMOVE"
14048   "#")
14049
14050 (define_insn "*fp_jcc_5_387"
14051   [(set (pc)
14052         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
14053                         [(match_operand 1 "register_operand" "f")
14054                          (match_operand 2 "register_operand" "f")])
14055           (label_ref (match_operand 3 "" ""))
14056           (pc)))
14057    (clobber (reg:CCFP FPSR_REG))
14058    (clobber (reg:CCFP FLAGS_REG))
14059    (clobber (match_scratch:HI 4 "=a"))]
14060   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14061    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14062    && !TARGET_CMOVE"
14063   "#")
14064
14065 (define_insn "*fp_jcc_6_387"
14066   [(set (pc)
14067         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
14068                         [(match_operand 1 "register_operand" "f")
14069                          (match_operand 2 "register_operand" "f")])
14070           (pc)
14071           (label_ref (match_operand 3 "" ""))))
14072    (clobber (reg:CCFP FPSR_REG))
14073    (clobber (reg:CCFP FLAGS_REG))
14074    (clobber (match_scratch:HI 4 "=a"))]
14075   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14076    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14077    && !TARGET_CMOVE"
14078   "#")
14079
14080 (define_insn "*fp_jcc_7_387"
14081   [(set (pc)
14082         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
14083                         [(match_operand 1 "register_operand" "f")
14084                          (match_operand 2 "const0_operand" "")])
14085           (label_ref (match_operand 3 "" ""))
14086           (pc)))
14087    (clobber (reg:CCFP FPSR_REG))
14088    (clobber (reg:CCFP FLAGS_REG))
14089    (clobber (match_scratch:HI 4 "=a"))]
14090   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14091    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14092    && SELECT_CC_MODE (GET_CODE (operands[0]),
14093                       operands[1], operands[2]) == CCFPmode
14094    && !TARGET_CMOVE"
14095   "#")
14096
14097 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
14098 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
14099 ;; with a precedence over other operators and is always put in the first
14100 ;; place. Swap condition and operands to match ficom instruction.
14101
14102 (define_insn "*fp_jcc_8<mode>_387"
14103   [(set (pc)
14104         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
14105                         [(match_operator 1 "float_operator"
14106                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
14107                            (match_operand 3 "register_operand" "f,f")])
14108           (label_ref (match_operand 4 "" ""))
14109           (pc)))
14110    (clobber (reg:CCFP FPSR_REG))
14111    (clobber (reg:CCFP FLAGS_REG))
14112    (clobber (match_scratch:HI 5 "=a,a"))]
14113   "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
14114    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
14115    && GET_MODE (operands[1]) == GET_MODE (operands[3])
14116    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
14117    && !TARGET_CMOVE"
14118   "#")
14119
14120 (define_split
14121   [(set (pc)
14122         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
14123                         [(match_operand 1 "register_operand" "")
14124                          (match_operand 2 "nonimmediate_operand" "")])
14125           (match_operand 3 "" "")
14126           (match_operand 4 "" "")))
14127    (clobber (reg:CCFP FPSR_REG))
14128    (clobber (reg:CCFP FLAGS_REG))]
14129   "reload_completed"
14130   [(const_int 0)]
14131 {
14132   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14133                         operands[3], operands[4], NULL_RTX, NULL_RTX);
14134   DONE;
14135 })
14136
14137 (define_split
14138   [(set (pc)
14139         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
14140                         [(match_operand 1 "register_operand" "")
14141                          (match_operand 2 "general_operand" "")])
14142           (match_operand 3 "" "")
14143           (match_operand 4 "" "")))
14144    (clobber (reg:CCFP FPSR_REG))
14145    (clobber (reg:CCFP FLAGS_REG))
14146    (clobber (match_scratch:HI 5 "=a"))]
14147   "reload_completed"
14148   [(const_int 0)]
14149 {
14150   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14151                         operands[3], operands[4], operands[5], NULL_RTX);
14152   DONE;
14153 })
14154
14155 (define_split
14156   [(set (pc)
14157         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
14158                         [(match_operator 1 "float_operator"
14159                            [(match_operand:X87MODEI12 2 "memory_operand" "")])
14160                            (match_operand 3 "register_operand" "")])
14161           (match_operand 4 "" "")
14162           (match_operand 5 "" "")))
14163    (clobber (reg:CCFP FPSR_REG))
14164    (clobber (reg:CCFP FLAGS_REG))
14165    (clobber (match_scratch:HI 6 "=a"))]
14166   "reload_completed"
14167   [(const_int 0)]
14168 {
14169   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
14170   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14171                         operands[3], operands[7],
14172                         operands[4], operands[5], operands[6], NULL_RTX);
14173   DONE;
14174 })
14175
14176 ;; %%% Kill this when reload knows how to do it.
14177 (define_split
14178   [(set (pc)
14179         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
14180                         [(match_operator 1 "float_operator"
14181                            [(match_operand:X87MODEI12 2 "register_operand" "")])
14182                            (match_operand 3 "register_operand" "")])
14183           (match_operand 4 "" "")
14184           (match_operand 5 "" "")))
14185    (clobber (reg:CCFP FPSR_REG))
14186    (clobber (reg:CCFP FLAGS_REG))
14187    (clobber (match_scratch:HI 6 "=a"))]
14188   "reload_completed"
14189   [(const_int 0)]
14190 {
14191   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14192   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
14193   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14194                         operands[3], operands[7],
14195                         operands[4], operands[5], operands[6], operands[2]);
14196   DONE;
14197 })
14198 \f
14199 ;; Unconditional and other jump instructions
14200
14201 (define_insn "jump"
14202   [(set (pc)
14203         (label_ref (match_operand 0 "" "")))]
14204   ""
14205   "jmp\t%l0"
14206   [(set_attr "type" "ibr")
14207    (set (attr "length")
14208            (if_then_else (and (ge (minus (match_dup 0) (pc))
14209                                   (const_int -126))
14210                               (lt (minus (match_dup 0) (pc))
14211                                   (const_int 128)))
14212              (const_int 2)
14213              (const_int 5)))
14214    (set_attr "modrm" "0")])
14215
14216 (define_expand "indirect_jump"
14217   [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
14218   ""
14219   "")
14220
14221 (define_insn "*indirect_jump"
14222   [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
14223   ""
14224   "jmp\t%A0"
14225   [(set_attr "type" "ibr")
14226    (set_attr "length_immediate" "0")])
14227
14228 (define_expand "tablejump"
14229   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
14230               (use (label_ref (match_operand 1 "" "")))])]
14231   ""
14232 {
14233   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
14234      relative.  Convert the relative address to an absolute address.  */
14235   if (flag_pic)
14236     {
14237       rtx op0, op1;
14238       enum rtx_code code;
14239
14240       /* We can't use @GOTOFF for text labels on VxWorks;
14241          see gotoff_operand.  */
14242       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
14243         {
14244           code = PLUS;
14245           op0 = operands[0];
14246           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14247         }
14248       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14249         {
14250           code = PLUS;
14251           op0 = operands[0];
14252           op1 = pic_offset_table_rtx;
14253         }
14254       else
14255         {
14256           code = MINUS;
14257           op0 = pic_offset_table_rtx;
14258           op1 = operands[0];
14259         }
14260
14261       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14262                                          OPTAB_DIRECT);
14263     }
14264 })
14265
14266 (define_insn "*tablejump_1"
14267   [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
14268    (use (label_ref (match_operand 1 "" "")))]
14269   ""
14270   "jmp\t%A0"
14271   [(set_attr "type" "ibr")
14272    (set_attr "length_immediate" "0")])
14273 \f
14274 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14275
14276 (define_peephole2
14277   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14278    (set (match_operand:QI 1 "register_operand" "")
14279         (match_operator:QI 2 "ix86_comparison_operator"
14280           [(reg FLAGS_REG) (const_int 0)]))
14281    (set (match_operand 3 "q_regs_operand" "")
14282         (zero_extend (match_dup 1)))]
14283   "(peep2_reg_dead_p (3, operands[1])
14284     || operands_match_p (operands[1], operands[3]))
14285    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14286   [(set (match_dup 4) (match_dup 0))
14287    (set (strict_low_part (match_dup 5))
14288         (match_dup 2))]
14289 {
14290   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14291   operands[5] = gen_lowpart (QImode, operands[3]);
14292   ix86_expand_clear (operands[3]);
14293 })
14294
14295 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14296
14297 (define_peephole2
14298   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14299    (set (match_operand:QI 1 "register_operand" "")
14300         (match_operator:QI 2 "ix86_comparison_operator"
14301           [(reg FLAGS_REG) (const_int 0)]))
14302    (parallel [(set (match_operand 3 "q_regs_operand" "")
14303                    (zero_extend (match_dup 1)))
14304               (clobber (reg:CC FLAGS_REG))])]
14305   "(peep2_reg_dead_p (3, operands[1])
14306     || operands_match_p (operands[1], operands[3]))
14307    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14308   [(set (match_dup 4) (match_dup 0))
14309    (set (strict_low_part (match_dup 5))
14310         (match_dup 2))]
14311 {
14312   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14313   operands[5] = gen_lowpart (QImode, operands[3]);
14314   ix86_expand_clear (operands[3]);
14315 })
14316 \f
14317 ;; Call instructions.
14318
14319 ;; The predicates normally associated with named expanders are not properly
14320 ;; checked for calls.  This is a bug in the generic code, but it isn't that
14321 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
14322
14323 ;; P6 processors will jump to the address after the decrement when %esp
14324 ;; is used as a call operand, so they will execute return address as a code.
14325 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
14326  
14327 ;; Call subroutine returning no value.
14328
14329 (define_expand "call_pop"
14330   [(parallel [(call (match_operand:QI 0 "" "")
14331                     (match_operand:SI 1 "" ""))
14332               (set (reg:SI SP_REG)
14333                    (plus:SI (reg:SI SP_REG)
14334                             (match_operand:SI 3 "" "")))])]
14335   "!TARGET_64BIT"
14336 {
14337   ix86_expand_call (NULL, operands[0], operands[1],
14338                     operands[2], operands[3], 0);
14339   DONE;
14340 })
14341
14342 (define_insn "*call_pop_0"
14343   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14344          (match_operand:SI 1 "" ""))
14345    (set (reg:SI SP_REG)
14346         (plus:SI (reg:SI SP_REG)
14347                  (match_operand:SI 2 "immediate_operand" "")))]
14348   "!TARGET_64BIT"
14349 {
14350   if (SIBLING_CALL_P (insn))
14351     return "jmp\t%P0";
14352   else
14353     return "call\t%P0";
14354 }
14355   [(set_attr "type" "call")])
14356
14357 (define_insn "*call_pop_1"
14358   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
14359          (match_operand:SI 1 "" ""))
14360    (set (reg:SI SP_REG)
14361         (plus:SI (reg:SI SP_REG)
14362                  (match_operand:SI 2 "immediate_operand" "i")))]
14363   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
14364 {
14365   if (constant_call_address_operand (operands[0], Pmode))
14366     return "call\t%P0";
14367   return "call\t%A0";
14368 }
14369   [(set_attr "type" "call")])
14370
14371 (define_insn "*sibcall_pop_1"
14372   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
14373          (match_operand:SI 1 "" ""))
14374    (set (reg:SI SP_REG)
14375         (plus:SI (reg:SI SP_REG)
14376                  (match_operand:SI 2 "immediate_operand" "i,i")))]
14377   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
14378   "@
14379    jmp\t%P0
14380    jmp\t%A0"
14381   [(set_attr "type" "call")])
14382
14383 (define_expand "call"
14384   [(call (match_operand:QI 0 "" "")
14385          (match_operand 1 "" ""))
14386    (use (match_operand 2 "" ""))]
14387   ""
14388 {
14389   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14390   DONE;
14391 })
14392
14393 (define_expand "sibcall"
14394   [(call (match_operand:QI 0 "" "")
14395          (match_operand 1 "" ""))
14396    (use (match_operand 2 "" ""))]
14397   ""
14398 {
14399   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14400   DONE;
14401 })
14402
14403 (define_insn "*call_0"
14404   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14405          (match_operand 1 "" ""))]
14406   ""
14407 {
14408   if (SIBLING_CALL_P (insn))
14409     return "jmp\t%P0";
14410   else
14411     return "call\t%P0";
14412 }
14413   [(set_attr "type" "call")])
14414
14415 (define_insn "*call_1"
14416   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
14417          (match_operand 1 "" ""))]
14418   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
14419 {
14420   if (constant_call_address_operand (operands[0], Pmode))
14421     return "call\t%P0";
14422   return "call\t%A0";
14423 }
14424   [(set_attr "type" "call")])
14425
14426 (define_insn "*sibcall_1"
14427   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
14428          (match_operand 1 "" ""))]
14429   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
14430   "@
14431    jmp\t%P0
14432    jmp\t%A0"
14433   [(set_attr "type" "call")])
14434
14435 (define_insn "*call_1_rex64"
14436   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14437          (match_operand 1 "" ""))]
14438   "TARGET_64BIT && !SIBLING_CALL_P (insn)
14439    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
14440 {
14441   if (constant_call_address_operand (operands[0], Pmode))
14442     return "call\t%P0";
14443   return "call\t%A0";
14444 }
14445   [(set_attr "type" "call")])
14446
14447 (define_insn "*call_1_rex64_ms_sysv"
14448   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14449          (match_operand 1 "" ""))
14450    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
14451    (clobber (reg:TI XMM6_REG))
14452    (clobber (reg:TI XMM7_REG))
14453    (clobber (reg:TI XMM8_REG))
14454    (clobber (reg:TI XMM9_REG))
14455    (clobber (reg:TI XMM10_REG))
14456    (clobber (reg:TI XMM11_REG))
14457    (clobber (reg:TI XMM12_REG))
14458    (clobber (reg:TI XMM13_REG))
14459    (clobber (reg:TI XMM14_REG))
14460    (clobber (reg:TI XMM15_REG))
14461    (clobber (reg:DI SI_REG))
14462    (clobber (reg:DI DI_REG))]
14463   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
14464 {
14465   if (constant_call_address_operand (operands[0], Pmode))
14466     return "call\t%P0";
14467   return "call\t%A0";
14468 }
14469   [(set_attr "type" "call")])
14470
14471 (define_insn "*call_1_rex64_large"
14472   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
14473          (match_operand 1 "" ""))]
14474   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
14475   "call\t%A0"
14476   [(set_attr "type" "call")])
14477
14478 (define_insn "*sibcall_1_rex64"
14479   [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
14480          (match_operand 1 "" ""))]
14481   "TARGET_64BIT && SIBLING_CALL_P (insn)"
14482   "@
14483    jmp\t%P0
14484    jmp\t%A0"
14485   [(set_attr "type" "call")])
14486
14487 ;; Call subroutine, returning value in operand 0
14488 (define_expand "call_value_pop"
14489   [(parallel [(set (match_operand 0 "" "")
14490                    (call (match_operand:QI 1 "" "")
14491                          (match_operand:SI 2 "" "")))
14492               (set (reg:SI SP_REG)
14493                    (plus:SI (reg:SI SP_REG)
14494                             (match_operand:SI 4 "" "")))])]
14495   "!TARGET_64BIT"
14496 {
14497   ix86_expand_call (operands[0], operands[1], operands[2],
14498                     operands[3], operands[4], 0);
14499   DONE;
14500 })
14501
14502 (define_expand "call_value"
14503   [(set (match_operand 0 "" "")
14504         (call (match_operand:QI 1 "" "")
14505               (match_operand:SI 2 "" "")))
14506    (use (match_operand:SI 3 "" ""))]
14507   ;; Operand 3 is not used on the i386.
14508   ""
14509 {
14510   ix86_expand_call (operands[0], operands[1], operands[2],
14511                     operands[3], NULL, 0);
14512   DONE;
14513 })
14514
14515 (define_expand "sibcall_value"
14516   [(set (match_operand 0 "" "")
14517         (call (match_operand:QI 1 "" "")
14518               (match_operand:SI 2 "" "")))
14519    (use (match_operand:SI 3 "" ""))]
14520   ;; Operand 3 is not used on the i386.
14521   ""
14522 {
14523   ix86_expand_call (operands[0], operands[1], operands[2],
14524                     operands[3], NULL, 1);
14525   DONE;
14526 })
14527
14528 ;; Call subroutine returning any type.
14529
14530 (define_expand "untyped_call"
14531   [(parallel [(call (match_operand 0 "" "")
14532                     (const_int 0))
14533               (match_operand 1 "" "")
14534               (match_operand 2 "" "")])]
14535   ""
14536 {
14537   int i;
14538
14539   /* In order to give reg-stack an easier job in validating two
14540      coprocessor registers as containing a possible return value,
14541      simply pretend the untyped call returns a complex long double
14542      value. 
14543
14544      We can't use SSE_REGPARM_MAX here since callee is unprototyped
14545      and should have the default ABI.  */
14546
14547   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14548                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14549                     operands[0], const0_rtx,
14550                     GEN_INT ((TARGET_64BIT
14551                               ? (ix86_abi == SYSV_ABI
14552                                  ? X86_64_SSE_REGPARM_MAX
14553                                  : X86_64_MS_SSE_REGPARM_MAX)
14554                               : X86_32_SSE_REGPARM_MAX)
14555                              - 1),
14556                     NULL, 0);
14557
14558   for (i = 0; i < XVECLEN (operands[2], 0); i++)
14559     {
14560       rtx set = XVECEXP (operands[2], 0, i);
14561       emit_move_insn (SET_DEST (set), SET_SRC (set));
14562     }
14563
14564   /* The optimizer does not know that the call sets the function value
14565      registers we stored in the result block.  We avoid problems by
14566      claiming that all hard registers are used and clobbered at this
14567      point.  */
14568   emit_insn (gen_blockage ());
14569
14570   DONE;
14571 })
14572 \f
14573 ;; Prologue and epilogue instructions
14574
14575 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14576 ;; all of memory.  This blocks insns from being moved across this point.
14577
14578 (define_insn "blockage"
14579   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
14580   ""
14581   ""
14582   [(set_attr "length" "0")])
14583
14584 ;; Do not schedule instructions accessing memory across this point.
14585
14586 (define_expand "memory_blockage"
14587   [(set (match_dup 0)
14588         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
14589   ""
14590 {
14591   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
14592   MEM_VOLATILE_P (operands[0]) = 1;
14593 })
14594
14595 (define_insn "*memory_blockage"
14596   [(set (match_operand:BLK 0 "" "")
14597         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
14598   ""
14599   ""
14600   [(set_attr "length" "0")])
14601
14602 ;; As USE insns aren't meaningful after reload, this is used instead
14603 ;; to prevent deleting instructions setting registers for PIC code
14604 (define_insn "prologue_use"
14605   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
14606   ""
14607   ""
14608   [(set_attr "length" "0")])
14609
14610 ;; Insn emitted into the body of a function to return from a function.
14611 ;; This is only done if the function's epilogue is known to be simple.
14612 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14613
14614 (define_expand "return"
14615   [(return)]
14616   "ix86_can_use_return_insn_p ()"
14617 {
14618   if (crtl->args.pops_args)
14619     {
14620       rtx popc = GEN_INT (crtl->args.pops_args);
14621       emit_jump_insn (gen_return_pop_internal (popc));
14622       DONE;
14623     }
14624 })
14625
14626 (define_insn "return_internal"
14627   [(return)]
14628   "reload_completed"
14629   "ret"
14630   [(set_attr "length" "1")
14631    (set_attr "atom_unit" "jeu")
14632    (set_attr "length_immediate" "0")
14633    (set_attr "modrm" "0")])
14634
14635 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14636 ;; instruction Athlon and K8 have.
14637
14638 (define_insn "return_internal_long"
14639   [(return)
14640    (unspec [(const_int 0)] UNSPEC_REP)]
14641   "reload_completed"
14642   "rep\;ret"
14643   [(set_attr "length" "2")
14644    (set_attr "atom_unit" "jeu")
14645    (set_attr "length_immediate" "0")
14646    (set_attr "prefix_rep" "1")
14647    (set_attr "modrm" "0")])
14648
14649 (define_insn "return_pop_internal"
14650   [(return)
14651    (use (match_operand:SI 0 "const_int_operand" ""))]
14652   "reload_completed"
14653   "ret\t%0"
14654   [(set_attr "length" "3")
14655    (set_attr "atom_unit" "jeu")
14656    (set_attr "length_immediate" "2")
14657    (set_attr "modrm" "0")])
14658
14659 (define_insn "return_indirect_internal"
14660   [(return)
14661    (use (match_operand:SI 0 "register_operand" "r"))]
14662   "reload_completed"
14663   "jmp\t%A0"
14664   [(set_attr "type" "ibr")
14665    (set_attr "length_immediate" "0")])
14666
14667 (define_insn "nop"
14668   [(const_int 0)]
14669   ""
14670   "nop"
14671   [(set_attr "length" "1")
14672    (set_attr "length_immediate" "0")
14673    (set_attr "modrm" "0")])
14674
14675 (define_insn "vswapmov"
14676   [(set (match_operand:SI 0 "register_operand" "=r")
14677         (match_operand:SI 1 "register_operand" "r"))
14678    (unspec_volatile [(const_int 0)] UNSPECV_VSWAPMOV)]
14679   ""
14680   "movl.s\t{%1, %0|%0, %1}"
14681   [(set_attr "length" "2")
14682    (set_attr "length_immediate" "0")
14683    (set_attr "modrm" "0")])
14684
14685 ;; Pad to 16-byte boundary, max skip in op0.  Used to avoid
14686 ;; branch prediction penalty for the third jump in a 16-byte
14687 ;; block on K8.
14688
14689 (define_insn "pad"
14690   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14691   ""
14692 {
14693 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
14694   ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
14695 #else
14696   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14697      The align insn is used to avoid 3 jump instructions in the row to improve
14698      branch prediction and the benefits hardly outweigh the cost of extra 8
14699      nops on the average inserted by full alignment pseudo operation.  */
14700 #endif
14701   return "";
14702 }
14703   [(set_attr "length" "16")])
14704
14705 (define_expand "prologue"
14706   [(const_int 0)]
14707   ""
14708   "ix86_expand_prologue (); DONE;")
14709
14710 (define_insn "set_got"
14711   [(set (match_operand:SI 0 "register_operand" "=r")
14712         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14713    (clobber (reg:CC FLAGS_REG))]
14714   "!TARGET_64BIT"
14715   { return output_set_got (operands[0], NULL_RTX); }
14716   [(set_attr "type" "multi")
14717    (set_attr "length" "12")])
14718
14719 (define_insn "set_got_labelled"
14720   [(set (match_operand:SI 0 "register_operand" "=r")
14721         (unspec:SI [(label_ref (match_operand 1 "" ""))]
14722          UNSPEC_SET_GOT))
14723    (clobber (reg:CC FLAGS_REG))]
14724   "!TARGET_64BIT"
14725   { return output_set_got (operands[0], operands[1]); }
14726   [(set_attr "type" "multi")
14727    (set_attr "length" "12")])
14728
14729 (define_insn "set_got_rex64"
14730   [(set (match_operand:DI 0 "register_operand" "=r")
14731         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14732   "TARGET_64BIT"
14733   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
14734   [(set_attr "type" "lea")
14735    (set_attr "length_address" "4")
14736    (set_attr "mode" "DI")])
14737
14738 (define_insn "set_rip_rex64"
14739   [(set (match_operand:DI 0 "register_operand" "=r")
14740         (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
14741   "TARGET_64BIT"
14742   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
14743   [(set_attr "type" "lea")
14744    (set_attr "length_address" "4")
14745    (set_attr "mode" "DI")])
14746
14747 (define_insn "set_got_offset_rex64"
14748   [(set (match_operand:DI 0 "register_operand" "=r")
14749         (unspec:DI
14750           [(label_ref (match_operand 1 "" ""))]
14751           UNSPEC_SET_GOT_OFFSET))]
14752   "TARGET_64BIT"
14753   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
14754   [(set_attr "type" "imov")
14755    (set_attr "length_immediate" "0")
14756    (set_attr "length_address" "8")
14757    (set_attr "mode" "DI")])
14758
14759 (define_expand "epilogue"
14760   [(const_int 0)]
14761   ""
14762   "ix86_expand_epilogue (1); DONE;")
14763
14764 (define_expand "sibcall_epilogue"
14765   [(const_int 0)]
14766   ""
14767   "ix86_expand_epilogue (0); DONE;")
14768
14769 (define_expand "eh_return"
14770   [(use (match_operand 0 "register_operand" ""))]
14771   ""
14772 {
14773   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14774
14775   /* Tricky bit: we write the address of the handler to which we will
14776      be returning into someone else's stack frame, one word below the
14777      stack address we wish to restore.  */
14778   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14779   tmp = plus_constant (tmp, -UNITS_PER_WORD);
14780   tmp = gen_rtx_MEM (Pmode, tmp);
14781   emit_move_insn (tmp, ra);
14782
14783   emit_jump_insn (gen_eh_return_internal ());
14784   emit_barrier ();
14785   DONE;
14786 })
14787
14788 (define_insn_and_split "eh_return_internal"
14789   [(eh_return)]
14790   ""
14791   "#"
14792   "epilogue_completed"
14793   [(const_int 0)]
14794   "ix86_expand_epilogue (2); DONE;")
14795
14796 (define_insn "leave"
14797   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
14798    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
14799    (clobber (mem:BLK (scratch)))]
14800   "!TARGET_64BIT"
14801   "leave"
14802   [(set_attr "type" "leave")])
14803
14804 (define_insn "leave_rex64"
14805   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
14806    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
14807    (clobber (mem:BLK (scratch)))]
14808   "TARGET_64BIT"
14809   "leave"
14810   [(set_attr "type" "leave")])
14811 \f
14812 (define_expand "ffssi2"
14813   [(parallel
14814      [(set (match_operand:SI 0 "register_operand" "")
14815            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14816       (clobber (match_scratch:SI 2 ""))
14817       (clobber (reg:CC FLAGS_REG))])]
14818   ""
14819 {
14820   if (TARGET_CMOVE)
14821     {
14822       emit_insn (gen_ffs_cmove (operands[0], operands[1]));
14823       DONE;
14824     }
14825 })
14826
14827 (define_expand "ffs_cmove"
14828   [(set (match_dup 2) (const_int -1))
14829    (parallel [(set (reg:CCZ FLAGS_REG)
14830                    (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "")
14831                                 (const_int 0)))
14832               (set (match_operand:SI 0 "register_operand" "")
14833                    (ctz:SI (match_dup 1)))])
14834    (set (match_dup 0) (if_then_else:SI
14835                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14836                         (match_dup 2)
14837                         (match_dup 0)))
14838    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14839               (clobber (reg:CC FLAGS_REG))])]
14840   "TARGET_CMOVE"
14841   "operands[2] = gen_reg_rtx (SImode);")
14842
14843 (define_insn_and_split "*ffs_no_cmove"
14844   [(set (match_operand:SI 0 "register_operand" "=r")
14845         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14846    (clobber (match_scratch:SI 2 "=&q"))
14847    (clobber (reg:CC FLAGS_REG))]
14848   "!TARGET_CMOVE"
14849   "#"
14850   "&& reload_completed"
14851   [(parallel [(set (reg:CCZ FLAGS_REG)
14852                    (compare:CCZ (match_dup 1) (const_int 0)))
14853               (set (match_dup 0) (ctz:SI (match_dup 1)))])
14854    (set (strict_low_part (match_dup 3))
14855         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14856    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14857               (clobber (reg:CC FLAGS_REG))])
14858    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14859               (clobber (reg:CC FLAGS_REG))])
14860    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14861               (clobber (reg:CC FLAGS_REG))])]
14862 {
14863   operands[3] = gen_lowpart (QImode, operands[2]);
14864   ix86_expand_clear (operands[2]);
14865 })
14866
14867 (define_insn "*ffssi_1"
14868   [(set (reg:CCZ FLAGS_REG)
14869         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14870                      (const_int 0)))
14871    (set (match_operand:SI 0 "register_operand" "=r")
14872         (ctz:SI (match_dup 1)))]
14873   ""
14874   "bsf{l}\t{%1, %0|%0, %1}"
14875   [(set_attr "type" "alu1")
14876    (set_attr "prefix_0f" "1")
14877    (set_attr "mode" "SI")])
14878
14879 (define_expand "ffsdi2"
14880   [(set (match_dup 2) (const_int -1))
14881    (parallel [(set (reg:CCZ FLAGS_REG)
14882                    (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "")
14883                                 (const_int 0)))
14884               (set (match_operand:DI 0 "register_operand" "")
14885                    (ctz:DI (match_dup 1)))])
14886    (set (match_dup 0) (if_then_else:DI
14887                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14888                         (match_dup 2)
14889                         (match_dup 0)))
14890    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14891               (clobber (reg:CC FLAGS_REG))])]
14892   "TARGET_64BIT"
14893   "operands[2] = gen_reg_rtx (DImode);")
14894
14895 (define_insn "*ffsdi_1"
14896   [(set (reg:CCZ FLAGS_REG)
14897         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14898                      (const_int 0)))
14899    (set (match_operand:DI 0 "register_operand" "=r")
14900         (ctz:DI (match_dup 1)))]
14901   "TARGET_64BIT"
14902   "bsf{q}\t{%1, %0|%0, %1}"
14903   [(set_attr "type" "alu1")
14904    (set_attr "prefix_0f" "1")
14905    (set_attr "mode" "DI")])
14906
14907 (define_insn "ctzsi2"
14908   [(set (match_operand:SI 0 "register_operand" "=r")
14909         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14910    (clobber (reg:CC FLAGS_REG))]
14911   ""
14912   "bsf{l}\t{%1, %0|%0, %1}"
14913   [(set_attr "type" "alu1")
14914    (set_attr "prefix_0f" "1")
14915    (set_attr "mode" "SI")])
14916
14917 (define_insn "ctzdi2"
14918   [(set (match_operand:DI 0 "register_operand" "=r")
14919         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14920    (clobber (reg:CC FLAGS_REG))]
14921   "TARGET_64BIT"
14922   "bsf{q}\t{%1, %0|%0, %1}"
14923   [(set_attr "type" "alu1")
14924    (set_attr "prefix_0f" "1")
14925    (set_attr "mode" "DI")])
14926
14927 (define_expand "clzsi2"
14928   [(parallel
14929      [(set (match_operand:SI 0 "register_operand" "")
14930            (minus:SI (const_int 31)
14931                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14932       (clobber (reg:CC FLAGS_REG))])
14933    (parallel
14934      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14935       (clobber (reg:CC FLAGS_REG))])]
14936   ""
14937 {
14938   if (TARGET_ABM)
14939     {
14940       emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
14941       DONE;
14942     }
14943 })
14944
14945 (define_insn "clzsi2_abm"
14946   [(set (match_operand:SI 0 "register_operand" "=r")
14947         (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14948    (clobber (reg:CC FLAGS_REG))]
14949   "TARGET_ABM"
14950   "lzcnt{l}\t{%1, %0|%0, %1}"
14951   [(set_attr "prefix_rep" "1")
14952    (set_attr "type" "bitmanip")
14953    (set_attr "mode" "SI")])
14954
14955 (define_insn "bsr"
14956   [(set (match_operand:SI 0 "register_operand" "=r")
14957         (minus:SI (const_int 31)
14958                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14959    (clobber (reg:CC FLAGS_REG))]
14960   ""
14961   "bsr{l}\t{%1, %0|%0, %1}"
14962   [(set_attr "type" "alu1")
14963    (set_attr "prefix_0f" "1")
14964    (set_attr "mode" "SI")])
14965
14966 (define_insn "popcount<mode>2"
14967   [(set (match_operand:SWI248 0 "register_operand" "=r")
14968         (popcount:SWI248
14969           (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
14970    (clobber (reg:CC FLAGS_REG))]
14971   "TARGET_POPCNT"
14972 {
14973 #if TARGET_MACHO
14974   return "popcnt\t{%1, %0|%0, %1}";
14975 #else
14976   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
14977 #endif
14978 }
14979   [(set_attr "prefix_rep" "1")
14980    (set_attr "type" "bitmanip")
14981    (set_attr "mode" "<MODE>")])
14982
14983 (define_insn "*popcount<mode>2_cmp"
14984   [(set (reg FLAGS_REG)
14985         (compare
14986           (popcount:SWI248
14987             (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
14988           (const_int 0)))
14989    (set (match_operand:SWI248 0 "register_operand" "=r")
14990         (popcount:SWI248 (match_dup 1)))]
14991   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14992 {
14993 #if TARGET_MACHO
14994   return "popcnt\t{%1, %0|%0, %1}";
14995 #else
14996   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
14997 #endif
14998 }
14999   [(set_attr "prefix_rep" "1")
15000    (set_attr "type" "bitmanip")
15001    (set_attr "mode" "<MODE>")])
15002
15003 (define_insn "*popcountsi2_cmp_zext"
15004   [(set (reg FLAGS_REG)
15005         (compare
15006           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15007           (const_int 0)))
15008    (set (match_operand:DI 0 "register_operand" "=r")
15009         (zero_extend:DI(popcount:SI (match_dup 1))))]
15010   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15011 {
15012 #if TARGET_MACHO
15013   return "popcnt\t{%1, %0|%0, %1}";
15014 #else
15015   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
15016 #endif
15017 }
15018   [(set_attr "prefix_rep" "1")
15019    (set_attr "type" "bitmanip")
15020    (set_attr "mode" "SI")])
15021
15022 (define_expand "bswapsi2"
15023   [(set (match_operand:SI 0 "register_operand" "")
15024         (bswap:SI (match_operand:SI 1 "register_operand" "")))]
15025   ""
15026 {
15027   if (!(TARGET_BSWAP || TARGET_MOVBE))
15028     {
15029       rtx x = operands[0];
15030
15031       emit_move_insn (x, operands[1]);
15032       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15033       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
15034       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15035       DONE;
15036     }
15037 })
15038
15039 (define_insn "*bswapsi_movbe"
15040   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,m")
15041         (bswap:SI (match_operand:SI 1 "nonimmediate_operand" "0,m,r")))]
15042   "TARGET_MOVBE && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
15043   "@
15044     bswap\t%0
15045     movbe\t{%1, %0|%0, %1}
15046     movbe\t{%1, %0|%0, %1}"
15047   [(set_attr "type" "*,imov,imov")
15048    (set_attr "modrm" "*,1,1")
15049    (set_attr "prefix_0f" "1")
15050    (set_attr "prefix_extra" "*,1,1")
15051    (set_attr "length" "2,*,*")
15052    (set_attr "mode" "SI")])
15053
15054 (define_insn "*bswapsi_1"
15055   [(set (match_operand:SI 0 "register_operand" "=r")
15056         (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
15057   "TARGET_BSWAP"
15058   "bswap\t%0"
15059   [(set_attr "prefix_0f" "1")
15060    (set_attr "length" "2")])
15061
15062 (define_insn "*bswaphi_lowpart_1"
15063   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
15064         (bswap:HI (match_dup 0)))
15065    (clobber (reg:CC FLAGS_REG))]
15066   "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
15067   "@
15068     xchg{b}\t{%h0, %b0|%b0, %h0}
15069     rol{w}\t{$8, %0|%0, 8}"
15070   [(set_attr "length" "2,4")
15071    (set_attr "mode" "QI,HI")])
15072
15073 (define_insn "bswaphi_lowpart"
15074   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
15075         (bswap:HI (match_dup 0)))
15076    (clobber (reg:CC FLAGS_REG))]
15077   ""
15078   "rol{w}\t{$8, %0|%0, 8}"
15079   [(set_attr "length" "4")
15080    (set_attr "mode" "HI")])
15081
15082 (define_expand "bswapdi2"
15083   [(set (match_operand:DI 0 "register_operand" "")
15084         (bswap:DI (match_operand:DI 1 "register_operand" "")))]
15085   "TARGET_64BIT"
15086   "")
15087
15088 (define_insn "*bswapdi_movbe"
15089   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m")
15090         (bswap:DI (match_operand:DI 1 "nonimmediate_operand" "0,m,r")))]
15091   "TARGET_64BIT && TARGET_MOVBE
15092    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
15093   "@
15094     bswap\t%0
15095     movbe\t{%1, %0|%0, %1}
15096     movbe\t{%1, %0|%0, %1}"
15097   [(set_attr "type" "*,imov,imov")
15098    (set_attr "modrm" "*,1,1")
15099    (set_attr "prefix_0f" "1")
15100    (set_attr "prefix_extra" "*,1,1")
15101    (set_attr "length" "3,*,*")
15102    (set_attr "mode" "DI")])
15103
15104 (define_insn "*bswapdi_1"
15105   [(set (match_operand:DI 0 "register_operand" "=r")
15106         (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
15107   "TARGET_64BIT"
15108   "bswap\t%0"
15109   [(set_attr "prefix_0f" "1")
15110    (set_attr "length" "3")])
15111
15112 (define_expand "clzdi2"
15113   [(parallel
15114      [(set (match_operand:DI 0 "register_operand" "")
15115            (minus:DI (const_int 63)
15116                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
15117       (clobber (reg:CC FLAGS_REG))])
15118    (parallel
15119      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
15120       (clobber (reg:CC FLAGS_REG))])]
15121   "TARGET_64BIT"
15122 {
15123   if (TARGET_ABM)
15124     {
15125       emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
15126       DONE;
15127     }
15128 })
15129
15130 (define_insn "clzdi2_abm"
15131   [(set (match_operand:DI 0 "register_operand" "=r")
15132         (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
15133    (clobber (reg:CC FLAGS_REG))]
15134   "TARGET_64BIT && TARGET_ABM"
15135   "lzcnt{q}\t{%1, %0|%0, %1}"
15136   [(set_attr "prefix_rep" "1")
15137    (set_attr "type" "bitmanip")
15138    (set_attr "mode" "DI")])
15139
15140 (define_insn "bsr_rex64"
15141   [(set (match_operand:DI 0 "register_operand" "=r")
15142         (minus:DI (const_int 63)
15143                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
15144    (clobber (reg:CC FLAGS_REG))]
15145   "TARGET_64BIT"
15146   "bsr{q}\t{%1, %0|%0, %1}"
15147   [(set_attr "type" "alu1")
15148    (set_attr "prefix_0f" "1")
15149    (set_attr "mode" "DI")])
15150
15151 (define_expand "clzhi2"
15152   [(parallel
15153      [(set (match_operand:HI 0 "register_operand" "")
15154            (minus:HI (const_int 15)
15155                      (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
15156       (clobber (reg:CC FLAGS_REG))])
15157    (parallel
15158      [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
15159       (clobber (reg:CC FLAGS_REG))])]
15160   ""
15161 {
15162   if (TARGET_ABM)
15163     {
15164       emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
15165       DONE;
15166     }
15167 })
15168
15169 (define_insn "clzhi2_abm"
15170   [(set (match_operand:HI 0 "register_operand" "=r")
15171         (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm")))
15172    (clobber (reg:CC FLAGS_REG))]
15173   "TARGET_ABM"
15174   "lzcnt{w}\t{%1, %0|%0, %1}"
15175   [(set_attr "prefix_rep" "1")
15176    (set_attr "type" "bitmanip")
15177    (set_attr "mode" "HI")])
15178
15179 (define_insn "*bsrhi"
15180   [(set (match_operand:HI 0 "register_operand" "=r")
15181         (minus:HI (const_int 15)
15182                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
15183    (clobber (reg:CC FLAGS_REG))]
15184   ""
15185   "bsr{w}\t{%1, %0|%0, %1}"
15186   [(set_attr "type" "alu1")
15187    (set_attr "prefix_0f" "1")
15188    (set_attr "mode" "HI")])
15189
15190 (define_expand "paritydi2"
15191   [(set (match_operand:DI 0 "register_operand" "")
15192         (parity:DI (match_operand:DI 1 "register_operand" "")))]
15193   "! TARGET_POPCNT"
15194 {
15195   rtx scratch = gen_reg_rtx (QImode);
15196   rtx cond;
15197
15198   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
15199                                 NULL_RTX, operands[1]));
15200
15201   cond = gen_rtx_fmt_ee (ORDERED, QImode,
15202                          gen_rtx_REG (CCmode, FLAGS_REG),
15203                          const0_rtx);
15204   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15205
15206   if (TARGET_64BIT)
15207     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
15208   else
15209     {
15210       rtx tmp = gen_reg_rtx (SImode);
15211
15212       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
15213       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
15214     }
15215   DONE;
15216 })
15217
15218 (define_insn_and_split "paritydi2_cmp"
15219   [(set (reg:CC FLAGS_REG)
15220         (parity:CC (match_operand:DI 3 "register_operand" "0")))
15221    (clobber (match_scratch:DI 0 "=r"))
15222    (clobber (match_scratch:SI 1 "=&r"))
15223    (clobber (match_scratch:HI 2 "=Q"))]
15224   "! TARGET_POPCNT"
15225   "#"
15226   "&& reload_completed"
15227   [(parallel
15228      [(set (match_dup 1)
15229            (xor:SI (match_dup 1) (match_dup 4)))
15230       (clobber (reg:CC FLAGS_REG))])
15231    (parallel
15232      [(set (reg:CC FLAGS_REG)
15233            (parity:CC (match_dup 1)))
15234       (clobber (match_dup 1))
15235       (clobber (match_dup 2))])]
15236 {
15237   operands[4] = gen_lowpart (SImode, operands[3]);
15238
15239   if (TARGET_64BIT)
15240     {
15241       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
15242       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
15243     }
15244   else
15245     operands[1] = gen_highpart (SImode, operands[3]);
15246 })
15247
15248 (define_expand "paritysi2"
15249   [(set (match_operand:SI 0 "register_operand" "")
15250         (parity:SI (match_operand:SI 1 "register_operand" "")))]
15251   "! TARGET_POPCNT"
15252 {
15253   rtx scratch = gen_reg_rtx (QImode);
15254   rtx cond;
15255
15256   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
15257
15258   cond = gen_rtx_fmt_ee (ORDERED, QImode,
15259                          gen_rtx_REG (CCmode, FLAGS_REG),
15260                          const0_rtx);
15261   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15262
15263   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
15264   DONE;
15265 })
15266
15267 (define_insn_and_split "paritysi2_cmp"
15268   [(set (reg:CC FLAGS_REG)
15269         (parity:CC (match_operand:SI 2 "register_operand" "0")))
15270    (clobber (match_scratch:SI 0 "=r"))
15271    (clobber (match_scratch:HI 1 "=&Q"))]
15272   "! TARGET_POPCNT"
15273   "#"
15274   "&& reload_completed"
15275   [(parallel
15276      [(set (match_dup 1)
15277            (xor:HI (match_dup 1) (match_dup 3)))
15278       (clobber (reg:CC FLAGS_REG))])
15279    (parallel
15280      [(set (reg:CC FLAGS_REG)
15281            (parity:CC (match_dup 1)))
15282       (clobber (match_dup 1))])]
15283 {
15284   operands[3] = gen_lowpart (HImode, operands[2]);
15285
15286   emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
15287   emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
15288 })
15289
15290 (define_insn "*parityhi2_cmp"
15291   [(set (reg:CC FLAGS_REG)
15292         (parity:CC (match_operand:HI 1 "register_operand" "0")))
15293    (clobber (match_scratch:HI 0 "=Q"))]
15294   "! TARGET_POPCNT"
15295   "xor{b}\t{%h0, %b0|%b0, %h0}"
15296   [(set_attr "length" "2")
15297    (set_attr "mode" "HI")])
15298
15299 (define_insn "*parityqi2_cmp"
15300   [(set (reg:CC FLAGS_REG)
15301         (parity:CC (match_operand:QI 0 "register_operand" "q")))]
15302   "! TARGET_POPCNT"
15303   "test{b}\t%0, %0"
15304   [(set_attr "length" "2")
15305    (set_attr "mode" "QI")])
15306 \f
15307 ;; Thread-local storage patterns for ELF.
15308 ;;
15309 ;; Note that these code sequences must appear exactly as shown
15310 ;; in order to allow linker relaxation.
15311
15312 (define_insn "*tls_global_dynamic_32_gnu"
15313   [(set (match_operand:SI 0 "register_operand" "=a")
15314         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15315                     (match_operand:SI 2 "tls_symbolic_operand" "")
15316                     (match_operand:SI 3 "call_insn_operand" "")]
15317                     UNSPEC_TLS_GD))
15318    (clobber (match_scratch:SI 4 "=d"))
15319    (clobber (match_scratch:SI 5 "=c"))
15320    (clobber (reg:CC FLAGS_REG))]
15321   "!TARGET_64BIT && TARGET_GNU_TLS"
15322   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
15323   [(set_attr "type" "multi")
15324    (set_attr "length" "12")])
15325
15326 (define_insn "*tls_global_dynamic_32_sun"
15327   [(set (match_operand:SI 0 "register_operand" "=a")
15328         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15329                     (match_operand:SI 2 "tls_symbolic_operand" "")
15330                     (match_operand:SI 3 "call_insn_operand" "")]
15331                     UNSPEC_TLS_GD))
15332    (clobber (match_scratch:SI 4 "=d"))
15333    (clobber (match_scratch:SI 5 "=c"))
15334    (clobber (reg:CC FLAGS_REG))]
15335   "!TARGET_64BIT && TARGET_SUN_TLS"
15336   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
15337         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
15338   [(set_attr "type" "multi")
15339    (set_attr "length" "14")])
15340
15341 (define_expand "tls_global_dynamic_32"
15342   [(parallel [(set (match_operand:SI 0 "register_operand" "")
15343                    (unspec:SI
15344                     [(match_dup 2)
15345                      (match_operand:SI 1 "tls_symbolic_operand" "")
15346                      (match_dup 3)]
15347                     UNSPEC_TLS_GD))
15348               (clobber (match_scratch:SI 4 ""))
15349               (clobber (match_scratch:SI 5 ""))
15350               (clobber (reg:CC FLAGS_REG))])]
15351   ""
15352 {
15353   if (flag_pic)
15354     operands[2] = pic_offset_table_rtx;
15355   else
15356     {
15357       operands[2] = gen_reg_rtx (Pmode);
15358       emit_insn (gen_set_got (operands[2]));
15359     }
15360   if (TARGET_GNU2_TLS)
15361     {
15362        emit_insn (gen_tls_dynamic_gnu2_32
15363                   (operands[0], operands[1], operands[2]));
15364        DONE;
15365     }
15366   operands[3] = ix86_tls_get_addr ();
15367 })
15368
15369 (define_insn "*tls_global_dynamic_64"
15370   [(set (match_operand:DI 0 "register_operand" "=a")
15371         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
15372                  (match_operand:DI 3 "" "")))
15373    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15374               UNSPEC_TLS_GD)]
15375   "TARGET_64BIT"
15376   { 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"; }
15377   [(set_attr "type" "multi")
15378    (set_attr "length" "16")])
15379
15380 (define_expand "tls_global_dynamic_64"
15381   [(parallel [(set (match_operand:DI 0 "register_operand" "")
15382                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
15383               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15384                          UNSPEC_TLS_GD)])]
15385   ""
15386 {
15387   if (TARGET_GNU2_TLS)
15388     {
15389        emit_insn (gen_tls_dynamic_gnu2_64
15390                   (operands[0], operands[1]));
15391        DONE;
15392     }
15393   operands[2] = ix86_tls_get_addr ();
15394 })
15395
15396 (define_insn "*tls_local_dynamic_base_32_gnu"
15397   [(set (match_operand:SI 0 "register_operand" "=a")
15398         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15399                     (match_operand:SI 2 "call_insn_operand" "")]
15400                    UNSPEC_TLS_LD_BASE))
15401    (clobber (match_scratch:SI 3 "=d"))
15402    (clobber (match_scratch:SI 4 "=c"))
15403    (clobber (reg:CC FLAGS_REG))]
15404   "!TARGET_64BIT && TARGET_GNU_TLS"
15405   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
15406   [(set_attr "type" "multi")
15407    (set_attr "length" "11")])
15408
15409 (define_insn "*tls_local_dynamic_base_32_sun"
15410   [(set (match_operand:SI 0 "register_operand" "=a")
15411         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15412                     (match_operand:SI 2 "call_insn_operand" "")]
15413                    UNSPEC_TLS_LD_BASE))
15414    (clobber (match_scratch:SI 3 "=d"))
15415    (clobber (match_scratch:SI 4 "=c"))
15416    (clobber (reg:CC FLAGS_REG))]
15417   "!TARGET_64BIT && TARGET_SUN_TLS"
15418   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
15419         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
15420   [(set_attr "type" "multi")
15421    (set_attr "length" "13")])
15422
15423 (define_expand "tls_local_dynamic_base_32"
15424   [(parallel [(set (match_operand:SI 0 "register_operand" "")
15425                    (unspec:SI [(match_dup 1) (match_dup 2)]
15426                               UNSPEC_TLS_LD_BASE))
15427               (clobber (match_scratch:SI 3 ""))
15428               (clobber (match_scratch:SI 4 ""))
15429               (clobber (reg:CC FLAGS_REG))])]
15430   ""
15431 {
15432   if (flag_pic)
15433     operands[1] = pic_offset_table_rtx;
15434   else
15435     {
15436       operands[1] = gen_reg_rtx (Pmode);
15437       emit_insn (gen_set_got (operands[1]));
15438     }
15439   if (TARGET_GNU2_TLS)
15440     {
15441        emit_insn (gen_tls_dynamic_gnu2_32
15442                   (operands[0], ix86_tls_module_base (), operands[1]));
15443        DONE;
15444     }
15445   operands[2] = ix86_tls_get_addr ();
15446 })
15447
15448 (define_insn "*tls_local_dynamic_base_64"
15449   [(set (match_operand:DI 0 "register_operand" "=a")
15450         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
15451                  (match_operand:DI 2 "" "")))
15452    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
15453   "TARGET_64BIT"
15454   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|rdi, %&@TLSLD[rip]}\;call\t%P1"
15455   [(set_attr "type" "multi")
15456    (set_attr "length" "12")])
15457
15458 (define_expand "tls_local_dynamic_base_64"
15459   [(parallel [(set (match_operand:DI 0 "register_operand" "")
15460                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
15461               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
15462   ""
15463 {
15464   if (TARGET_GNU2_TLS)
15465     {
15466        emit_insn (gen_tls_dynamic_gnu2_64
15467                   (operands[0], ix86_tls_module_base ()));
15468        DONE;
15469     }
15470   operands[1] = ix86_tls_get_addr ();
15471 })
15472
15473 ;; Local dynamic of a single variable is a lose.  Show combine how
15474 ;; to convert that back to global dynamic.
15475
15476 (define_insn_and_split "*tls_local_dynamic_32_once"
15477   [(set (match_operand:SI 0 "register_operand" "=a")
15478         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15479                              (match_operand:SI 2 "call_insn_operand" "")]
15480                             UNSPEC_TLS_LD_BASE)
15481                  (const:SI (unspec:SI
15482                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
15483                             UNSPEC_DTPOFF))))
15484    (clobber (match_scratch:SI 4 "=d"))
15485    (clobber (match_scratch:SI 5 "=c"))
15486    (clobber (reg:CC FLAGS_REG))]
15487   ""
15488   "#"
15489   ""
15490   [(parallel [(set (match_dup 0)
15491                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
15492                               UNSPEC_TLS_GD))
15493               (clobber (match_dup 4))
15494               (clobber (match_dup 5))
15495               (clobber (reg:CC FLAGS_REG))])]
15496   "")
15497
15498 ;; Load and add the thread base pointer from %gs:0.
15499
15500 (define_insn "*load_tp_si"
15501   [(set (match_operand:SI 0 "register_operand" "=r")
15502         (unspec:SI [(const_int 0)] UNSPEC_TP))]
15503   "!TARGET_64BIT"
15504   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
15505   [(set_attr "type" "imov")
15506    (set_attr "modrm" "0")
15507    (set_attr "length" "7")
15508    (set_attr "memory" "load")
15509    (set_attr "imm_disp" "false")])
15510
15511 (define_insn "*add_tp_si"
15512   [(set (match_operand:SI 0 "register_operand" "=r")
15513         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
15514                  (match_operand:SI 1 "register_operand" "0")))
15515    (clobber (reg:CC FLAGS_REG))]
15516   "!TARGET_64BIT"
15517   "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
15518   [(set_attr "type" "alu")
15519    (set_attr "modrm" "0")
15520    (set_attr "length" "7")
15521    (set_attr "memory" "load")
15522    (set_attr "imm_disp" "false")])
15523
15524 (define_insn "*load_tp_di"
15525   [(set (match_operand:DI 0 "register_operand" "=r")
15526         (unspec:DI [(const_int 0)] UNSPEC_TP))]
15527   "TARGET_64BIT"
15528   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
15529   [(set_attr "type" "imov")
15530    (set_attr "modrm" "0")
15531    (set_attr "length" "7")
15532    (set_attr "memory" "load")
15533    (set_attr "imm_disp" "false")])
15534
15535 (define_insn "*add_tp_di"
15536   [(set (match_operand:DI 0 "register_operand" "=r")
15537         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
15538                  (match_operand:DI 1 "register_operand" "0")))
15539    (clobber (reg:CC FLAGS_REG))]
15540   "TARGET_64BIT"
15541   "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
15542   [(set_attr "type" "alu")
15543    (set_attr "modrm" "0")
15544    (set_attr "length" "7")
15545    (set_attr "memory" "load")
15546    (set_attr "imm_disp" "false")])
15547
15548 ;; GNU2 TLS patterns can be split.
15549
15550 (define_expand "tls_dynamic_gnu2_32"
15551   [(set (match_dup 3)
15552         (plus:SI (match_operand:SI 2 "register_operand" "")
15553                  (const:SI
15554                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
15555                              UNSPEC_TLSDESC))))
15556    (parallel
15557     [(set (match_operand:SI 0 "register_operand" "")
15558           (unspec:SI [(match_dup 1) (match_dup 3)
15559                       (match_dup 2) (reg:SI SP_REG)]
15560                       UNSPEC_TLSDESC))
15561      (clobber (reg:CC FLAGS_REG))])]
15562   "!TARGET_64BIT && TARGET_GNU2_TLS"
15563 {
15564   operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
15565   ix86_tls_descriptor_calls_expanded_in_cfun = true;
15566 })
15567
15568 (define_insn "*tls_dynamic_lea_32"
15569   [(set (match_operand:SI 0 "register_operand" "=r")
15570         (plus:SI (match_operand:SI 1 "register_operand" "b")
15571                  (const:SI
15572                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
15573                               UNSPEC_TLSDESC))))]
15574   "!TARGET_64BIT && TARGET_GNU2_TLS"
15575   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
15576   [(set_attr "type" "lea")
15577    (set_attr "mode" "SI")
15578    (set_attr "length" "6")
15579    (set_attr "length_address" "4")])
15580
15581 (define_insn "*tls_dynamic_call_32"
15582   [(set (match_operand:SI 0 "register_operand" "=a")
15583         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
15584                     (match_operand:SI 2 "register_operand" "0")
15585                     ;; we have to make sure %ebx still points to the GOT
15586                     (match_operand:SI 3 "register_operand" "b")
15587                     (reg:SI SP_REG)]
15588                    UNSPEC_TLSDESC))
15589    (clobber (reg:CC FLAGS_REG))]
15590   "!TARGET_64BIT && TARGET_GNU2_TLS"
15591   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
15592   [(set_attr "type" "call")
15593    (set_attr "length" "2")
15594    (set_attr "length_address" "0")])
15595
15596 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
15597   [(set (match_operand:SI 0 "register_operand" "=&a")
15598         (plus:SI
15599          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
15600                      (match_operand:SI 4 "" "")
15601                      (match_operand:SI 2 "register_operand" "b")
15602                      (reg:SI SP_REG)]
15603                     UNSPEC_TLSDESC)
15604          (const:SI (unspec:SI
15605                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
15606                     UNSPEC_DTPOFF))))
15607    (clobber (reg:CC FLAGS_REG))]
15608   "!TARGET_64BIT && TARGET_GNU2_TLS"
15609   "#"
15610   ""
15611   [(set (match_dup 0) (match_dup 5))]
15612 {
15613   operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
15614   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
15615 })
15616
15617 (define_expand "tls_dynamic_gnu2_64"
15618   [(set (match_dup 2)
15619         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15620                    UNSPEC_TLSDESC))
15621    (parallel
15622     [(set (match_operand:DI 0 "register_operand" "")
15623           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
15624                      UNSPEC_TLSDESC))
15625      (clobber (reg:CC FLAGS_REG))])]
15626   "TARGET_64BIT && TARGET_GNU2_TLS"
15627 {
15628   operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
15629   ix86_tls_descriptor_calls_expanded_in_cfun = true;
15630 })
15631
15632 (define_insn "*tls_dynamic_lea_64"
15633   [(set (match_operand:DI 0 "register_operand" "=r")
15634         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15635                    UNSPEC_TLSDESC))]
15636   "TARGET_64BIT && TARGET_GNU2_TLS"
15637   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
15638   [(set_attr "type" "lea")
15639    (set_attr "mode" "DI")
15640    (set_attr "length" "7")
15641    (set_attr "length_address" "4")])
15642
15643 (define_insn "*tls_dynamic_call_64"
15644   [(set (match_operand:DI 0 "register_operand" "=a")
15645         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
15646                     (match_operand:DI 2 "register_operand" "0")
15647                     (reg:DI SP_REG)]
15648                    UNSPEC_TLSDESC))
15649    (clobber (reg:CC FLAGS_REG))]
15650   "TARGET_64BIT && TARGET_GNU2_TLS"
15651   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
15652   [(set_attr "type" "call")
15653    (set_attr "length" "2")
15654    (set_attr "length_address" "0")])
15655
15656 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
15657   [(set (match_operand:DI 0 "register_operand" "=&a")
15658         (plus:DI
15659          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
15660                      (match_operand:DI 3 "" "")
15661                      (reg:DI SP_REG)]
15662                     UNSPEC_TLSDESC)
15663          (const:DI (unspec:DI
15664                     [(match_operand:DI 1 "tls_symbolic_operand" "")]
15665                     UNSPEC_DTPOFF))))
15666    (clobber (reg:CC FLAGS_REG))]
15667   "TARGET_64BIT && TARGET_GNU2_TLS"
15668   "#"
15669   ""
15670   [(set (match_dup 0) (match_dup 4))]
15671 {
15672   operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
15673   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
15674 })
15675
15676 ;;
15677 \f
15678 ;; These patterns match the binary 387 instructions for addM3, subM3,
15679 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
15680 ;; SFmode.  The first is the normal insn, the second the same insn but
15681 ;; with one operand a conversion, and the third the same insn but with
15682 ;; the other operand a conversion.  The conversion may be SFmode or
15683 ;; SImode if the target mode DFmode, but only SImode if the target mode
15684 ;; is SFmode.
15685
15686 ;; Gcc is slightly more smart about handling normal two address instructions
15687 ;; so use special patterns for add and mull.
15688
15689 (define_insn "*fop_<mode>_comm_mixed_avx"
15690   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
15691         (match_operator:MODEF 3 "binary_fp_operator"
15692           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
15693            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
15694   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
15695    && COMMUTATIVE_ARITH_P (operands[3])
15696    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15697   "* return output_387_binary_op (insn, operands);"
15698   [(set (attr "type")
15699         (if_then_else (eq_attr "alternative" "1")
15700            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
15701               (const_string "ssemul")
15702               (const_string "sseadd"))
15703            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
15704               (const_string "fmul")
15705               (const_string "fop"))))
15706    (set_attr "prefix" "orig,maybe_vex")
15707    (set_attr "mode" "<MODE>")])
15708
15709 (define_insn "*fop_<mode>_comm_mixed"
15710   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
15711         (match_operator:MODEF 3 "binary_fp_operator"
15712           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
15713            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
15714   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
15715    && COMMUTATIVE_ARITH_P (operands[3])
15716    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15717   "* return output_387_binary_op (insn, operands);"
15718   [(set (attr "type")
15719         (if_then_else (eq_attr "alternative" "1")
15720            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
15721               (const_string "ssemul")
15722               (const_string "sseadd"))
15723            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
15724               (const_string "fmul")
15725               (const_string "fop"))))
15726    (set_attr "mode" "<MODE>")])
15727
15728 (define_insn "*fop_<mode>_comm_avx"
15729   [(set (match_operand:MODEF 0 "register_operand" "=x")
15730         (match_operator:MODEF 3 "binary_fp_operator"
15731           [(match_operand:MODEF 1 "nonimmediate_operand" "%x")
15732            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
15733   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15734    && COMMUTATIVE_ARITH_P (operands[3])
15735    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15736   "* return output_387_binary_op (insn, operands);"
15737   [(set (attr "type")
15738         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
15739            (const_string "ssemul")
15740            (const_string "sseadd")))
15741    (set_attr "prefix" "vex")
15742    (set_attr "mode" "<MODE>")])
15743
15744 (define_insn "*fop_<mode>_comm_sse"
15745   [(set (match_operand:MODEF 0 "register_operand" "=x")
15746         (match_operator:MODEF 3 "binary_fp_operator"
15747           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
15748            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
15749   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15750    && COMMUTATIVE_ARITH_P (operands[3])
15751    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15752   "* return output_387_binary_op (insn, operands);"
15753   [(set (attr "type")
15754         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
15755            (const_string "ssemul")
15756            (const_string "sseadd")))
15757    (set_attr "mode" "<MODE>")])
15758
15759 (define_insn "*fop_<mode>_comm_i387"
15760   [(set (match_operand:MODEF 0 "register_operand" "=f")
15761         (match_operator:MODEF 3 "binary_fp_operator"
15762           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
15763            (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
15764   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
15765    && COMMUTATIVE_ARITH_P (operands[3])
15766    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15767   "* return output_387_binary_op (insn, operands);"
15768   [(set (attr "type")
15769         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
15770            (const_string "fmul")
15771            (const_string "fop")))
15772    (set_attr "mode" "<MODE>")])
15773
15774 (define_insn "*fop_<mode>_1_mixed_avx"
15775   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
15776         (match_operator:MODEF 3 "binary_fp_operator"
15777           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,x")
15778            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
15779   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
15780    && !COMMUTATIVE_ARITH_P (operands[3])
15781    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15782   "* return output_387_binary_op (insn, operands);"
15783   [(set (attr "type")
15784         (cond [(and (eq_attr "alternative" "2")
15785                     (match_operand:MODEF 3 "mult_operator" ""))
15786                  (const_string "ssemul")
15787                (and (eq_attr "alternative" "2")
15788                     (match_operand:MODEF 3 "div_operator" ""))
15789                  (const_string "ssediv")
15790                (eq_attr "alternative" "2")
15791                  (const_string "sseadd")
15792                (match_operand:MODEF 3 "mult_operator" "")
15793                  (const_string "fmul")
15794                (match_operand:MODEF 3 "div_operator" "")
15795                  (const_string "fdiv")
15796               ]
15797               (const_string "fop")))
15798    (set_attr "prefix" "orig,orig,maybe_vex")
15799    (set_attr "mode" "<MODE>")])
15800
15801 (define_insn "*fop_<mode>_1_mixed"
15802   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
15803         (match_operator:MODEF 3 "binary_fp_operator"
15804           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
15805            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
15806   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
15807    && !COMMUTATIVE_ARITH_P (operands[3])
15808    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15809   "* return output_387_binary_op (insn, operands);"
15810   [(set (attr "type")
15811         (cond [(and (eq_attr "alternative" "2")
15812                     (match_operand:MODEF 3 "mult_operator" ""))
15813                  (const_string "ssemul")
15814                (and (eq_attr "alternative" "2")
15815                     (match_operand:MODEF 3 "div_operator" ""))
15816                  (const_string "ssediv")
15817                (eq_attr "alternative" "2")
15818                  (const_string "sseadd")
15819                (match_operand:MODEF 3 "mult_operator" "")
15820                  (const_string "fmul")
15821                (match_operand:MODEF 3 "div_operator" "")
15822                  (const_string "fdiv")
15823               ]
15824               (const_string "fop")))
15825    (set_attr "mode" "<MODE>")])
15826
15827 (define_insn "*rcpsf2_sse"
15828   [(set (match_operand:SF 0 "register_operand" "=x")
15829         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
15830                    UNSPEC_RCP))]
15831   "TARGET_SSE_MATH"
15832   "%vrcpss\t{%1, %d0|%d0, %1}"
15833   [(set_attr "type" "sse")
15834    (set_attr "atom_sse_attr" "rcp")
15835    (set_attr "prefix" "maybe_vex")
15836    (set_attr "mode" "SF")])
15837
15838 (define_insn "*fop_<mode>_1_avx"
15839   [(set (match_operand:MODEF 0 "register_operand" "=x")
15840         (match_operator:MODEF 3 "binary_fp_operator"
15841           [(match_operand:MODEF 1 "register_operand" "x")
15842            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
15843   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15844    && !COMMUTATIVE_ARITH_P (operands[3])"
15845   "* return output_387_binary_op (insn, operands);"
15846   [(set (attr "type")
15847         (cond [(match_operand:MODEF 3 "mult_operator" "")
15848                  (const_string "ssemul")
15849                (match_operand:MODEF 3 "div_operator" "")
15850                  (const_string "ssediv")
15851               ]
15852               (const_string "sseadd")))
15853    (set_attr "prefix" "vex")
15854    (set_attr "mode" "<MODE>")])
15855
15856 (define_insn "*fop_<mode>_1_sse"
15857   [(set (match_operand:MODEF 0 "register_operand" "=x")
15858         (match_operator:MODEF 3 "binary_fp_operator"
15859           [(match_operand:MODEF 1 "register_operand" "0")
15860            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
15861   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15862    && !COMMUTATIVE_ARITH_P (operands[3])"
15863   "* return output_387_binary_op (insn, operands);"
15864   [(set (attr "type")
15865         (cond [(match_operand:MODEF 3 "mult_operator" "")
15866                  (const_string "ssemul")
15867                (match_operand:MODEF 3 "div_operator" "")
15868                  (const_string "ssediv")
15869               ]
15870               (const_string "sseadd")))
15871    (set_attr "mode" "<MODE>")])
15872
15873 ;; This pattern is not fully shadowed by the pattern above.
15874 (define_insn "*fop_<mode>_1_i387"
15875   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
15876         (match_operator:MODEF 3 "binary_fp_operator"
15877           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
15878            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
15879   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
15880    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15881    && !COMMUTATIVE_ARITH_P (operands[3])
15882    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15883   "* return output_387_binary_op (insn, operands);"
15884   [(set (attr "type")
15885         (cond [(match_operand:MODEF 3 "mult_operator" "")
15886                  (const_string "fmul")
15887                (match_operand:MODEF 3 "div_operator" "")
15888                  (const_string "fdiv")
15889               ]
15890               (const_string "fop")))
15891    (set_attr "mode" "<MODE>")])
15892
15893 ;; ??? Add SSE splitters for these!
15894 (define_insn "*fop_<MODEF:mode>_2_i387"
15895   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
15896         (match_operator:MODEF 3 "binary_fp_operator"
15897           [(float:MODEF
15898              (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15899            (match_operand:MODEF 2 "register_operand" "0,0")]))]
15900   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
15901    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
15902    && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
15903   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15904   [(set (attr "type")
15905         (cond [(match_operand:MODEF 3 "mult_operator" "")
15906                  (const_string "fmul")
15907                (match_operand:MODEF 3 "div_operator" "")
15908                  (const_string "fdiv")
15909               ]
15910               (const_string "fop")))
15911    (set_attr "fp_int_src" "true")
15912    (set_attr "mode" "<X87MODEI12:MODE>")])
15913
15914 (define_insn "*fop_<MODEF:mode>_3_i387"
15915   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
15916         (match_operator:MODEF 3 "binary_fp_operator"
15917           [(match_operand:MODEF 1 "register_operand" "0,0")
15918            (float:MODEF
15919              (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15920   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
15921    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
15922    && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
15923   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15924   [(set (attr "type")
15925         (cond [(match_operand:MODEF 3 "mult_operator" "")
15926                  (const_string "fmul")
15927                (match_operand:MODEF 3 "div_operator" "")
15928                  (const_string "fdiv")
15929               ]
15930               (const_string "fop")))
15931    (set_attr "fp_int_src" "true")
15932    (set_attr "mode" "<MODE>")])
15933
15934 (define_insn "*fop_df_4_i387"
15935   [(set (match_operand:DF 0 "register_operand" "=f,f")
15936         (match_operator:DF 3 "binary_fp_operator"
15937            [(float_extend:DF
15938              (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
15939             (match_operand:DF 2 "register_operand" "0,f")]))]
15940   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
15941    && !(TARGET_SSE2 && TARGET_SSE_MATH)
15942    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15943   "* return output_387_binary_op (insn, operands);"
15944   [(set (attr "type")
15945         (cond [(match_operand:DF 3 "mult_operator" "")
15946                  (const_string "fmul")
15947                (match_operand:DF 3 "div_operator" "")
15948                  (const_string "fdiv")
15949               ]
15950               (const_string "fop")))
15951    (set_attr "mode" "SF")])
15952
15953 (define_insn "*fop_df_5_i387"
15954   [(set (match_operand:DF 0 "register_operand" "=f,f")
15955         (match_operator:DF 3 "binary_fp_operator"
15956           [(match_operand:DF 1 "register_operand" "0,f")
15957            (float_extend:DF
15958             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15959   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
15960    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15961   "* return output_387_binary_op (insn, operands);"
15962   [(set (attr "type")
15963         (cond [(match_operand:DF 3 "mult_operator" "")
15964                  (const_string "fmul")
15965                (match_operand:DF 3 "div_operator" "")
15966                  (const_string "fdiv")
15967               ]
15968               (const_string "fop")))
15969    (set_attr "mode" "SF")])
15970
15971 (define_insn "*fop_df_6_i387"
15972   [(set (match_operand:DF 0 "register_operand" "=f,f")
15973         (match_operator:DF 3 "binary_fp_operator"
15974           [(float_extend:DF
15975             (match_operand:SF 1 "register_operand" "0,f"))
15976            (float_extend:DF
15977             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15978   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
15979    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15980   "* return output_387_binary_op (insn, operands);"
15981   [(set (attr "type")
15982         (cond [(match_operand:DF 3 "mult_operator" "")
15983                  (const_string "fmul")
15984                (match_operand:DF 3 "div_operator" "")
15985                  (const_string "fdiv")
15986               ]
15987               (const_string "fop")))
15988    (set_attr "mode" "SF")])
15989
15990 (define_insn "*fop_xf_comm_i387"
15991   [(set (match_operand:XF 0 "register_operand" "=f")
15992         (match_operator:XF 3 "binary_fp_operator"
15993                         [(match_operand:XF 1 "register_operand" "%0")
15994                          (match_operand:XF 2 "register_operand" "f")]))]
15995   "TARGET_80387
15996    && COMMUTATIVE_ARITH_P (operands[3])"
15997   "* return output_387_binary_op (insn, operands);"
15998   [(set (attr "type")
15999         (if_then_else (match_operand:XF 3 "mult_operator" "")
16000            (const_string "fmul")
16001            (const_string "fop")))
16002    (set_attr "mode" "XF")])
16003
16004 (define_insn "*fop_xf_1_i387"
16005   [(set (match_operand:XF 0 "register_operand" "=f,f")
16006         (match_operator:XF 3 "binary_fp_operator"
16007                         [(match_operand:XF 1 "register_operand" "0,f")
16008                          (match_operand:XF 2 "register_operand" "f,0")]))]
16009   "TARGET_80387
16010    && !COMMUTATIVE_ARITH_P (operands[3])"
16011   "* return output_387_binary_op (insn, operands);"
16012   [(set (attr "type")
16013         (cond [(match_operand:XF 3 "mult_operator" "")
16014                  (const_string "fmul")
16015                (match_operand:XF 3 "div_operator" "")
16016                  (const_string "fdiv")
16017               ]
16018               (const_string "fop")))
16019    (set_attr "mode" "XF")])
16020
16021 (define_insn "*fop_xf_2_i387"
16022   [(set (match_operand:XF 0 "register_operand" "=f,f")
16023         (match_operator:XF 3 "binary_fp_operator"
16024           [(float:XF
16025              (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16026            (match_operand:XF 2 "register_operand" "0,0")]))]
16027   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16028   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16029   [(set (attr "type")
16030         (cond [(match_operand:XF 3 "mult_operator" "")
16031                  (const_string "fmul")
16032                (match_operand:XF 3 "div_operator" "")
16033                  (const_string "fdiv")
16034               ]
16035               (const_string "fop")))
16036    (set_attr "fp_int_src" "true")
16037    (set_attr "mode" "<MODE>")])
16038
16039 (define_insn "*fop_xf_3_i387"
16040   [(set (match_operand:XF 0 "register_operand" "=f,f")
16041         (match_operator:XF 3 "binary_fp_operator"
16042           [(match_operand:XF 1 "register_operand" "0,0")
16043            (float:XF
16044              (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16045   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16046   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16047   [(set (attr "type")
16048         (cond [(match_operand:XF 3 "mult_operator" "")
16049                  (const_string "fmul")
16050                (match_operand:XF 3 "div_operator" "")
16051                  (const_string "fdiv")
16052               ]
16053               (const_string "fop")))
16054    (set_attr "fp_int_src" "true")
16055    (set_attr "mode" "<MODE>")])
16056
16057 (define_insn "*fop_xf_4_i387"
16058   [(set (match_operand:XF 0 "register_operand" "=f,f")
16059         (match_operator:XF 3 "binary_fp_operator"
16060            [(float_extend:XF
16061               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
16062             (match_operand:XF 2 "register_operand" "0,f")]))]
16063   "TARGET_80387"
16064   "* return output_387_binary_op (insn, operands);"
16065   [(set (attr "type")
16066         (cond [(match_operand:XF 3 "mult_operator" "")
16067                  (const_string "fmul")
16068                (match_operand:XF 3 "div_operator" "")
16069                  (const_string "fdiv")
16070               ]
16071               (const_string "fop")))
16072    (set_attr "mode" "<MODE>")])
16073
16074 (define_insn "*fop_xf_5_i387"
16075   [(set (match_operand:XF 0 "register_operand" "=f,f")
16076         (match_operator:XF 3 "binary_fp_operator"
16077           [(match_operand:XF 1 "register_operand" "0,f")
16078            (float_extend:XF
16079              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16080   "TARGET_80387"
16081   "* return output_387_binary_op (insn, operands);"
16082   [(set (attr "type")
16083         (cond [(match_operand:XF 3 "mult_operator" "")
16084                  (const_string "fmul")
16085                (match_operand:XF 3 "div_operator" "")
16086                  (const_string "fdiv")
16087               ]
16088               (const_string "fop")))
16089    (set_attr "mode" "<MODE>")])
16090
16091 (define_insn "*fop_xf_6_i387"
16092   [(set (match_operand:XF 0 "register_operand" "=f,f")
16093         (match_operator:XF 3 "binary_fp_operator"
16094           [(float_extend:XF
16095              (match_operand:MODEF 1 "register_operand" "0,f"))
16096            (float_extend:XF
16097              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16098   "TARGET_80387"
16099   "* return output_387_binary_op (insn, operands);"
16100   [(set (attr "type")
16101         (cond [(match_operand:XF 3 "mult_operator" "")
16102                  (const_string "fmul")
16103                (match_operand:XF 3 "div_operator" "")
16104                  (const_string "fdiv")
16105               ]
16106               (const_string "fop")))
16107    (set_attr "mode" "<MODE>")])
16108
16109 (define_split
16110   [(set (match_operand 0 "register_operand" "")
16111         (match_operator 3 "binary_fp_operator"
16112            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
16113             (match_operand 2 "register_operand" "")]))]
16114   "reload_completed
16115    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
16116    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
16117   [(const_int 0)]
16118 {
16119   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
16120   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16121   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16122                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
16123                                           GET_MODE (operands[3]),
16124                                           operands[4],
16125                                           operands[2])));
16126   ix86_free_from_memory (GET_MODE (operands[1]));
16127   DONE;
16128 })
16129
16130 (define_split
16131   [(set (match_operand 0 "register_operand" "")
16132         (match_operator 3 "binary_fp_operator"
16133            [(match_operand 1 "register_operand" "")
16134             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
16135   "reload_completed
16136    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
16137    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
16138   [(const_int 0)]
16139 {
16140   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
16141   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16142   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16143                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
16144                                           GET_MODE (operands[3]),
16145                                           operands[1],
16146                                           operands[4])));
16147   ix86_free_from_memory (GET_MODE (operands[2]));
16148   DONE;
16149 })
16150 \f
16151 ;; FPU special functions.
16152
16153 ;; This pattern implements a no-op XFmode truncation for
16154 ;; all fancy i386 XFmode math functions.
16155
16156 (define_insn "truncxf<mode>2_i387_noop_unspec"
16157   [(set (match_operand:MODEF 0 "register_operand" "=f")
16158         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
16159         UNSPEC_TRUNC_NOOP))]
16160   "TARGET_USE_FANCY_MATH_387"
16161   "* return output_387_reg_move (insn, operands);"
16162   [(set_attr "type" "fmov")
16163    (set_attr "mode" "<MODE>")])
16164
16165 (define_insn "sqrtxf2"
16166   [(set (match_operand:XF 0 "register_operand" "=f")
16167         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
16168   "TARGET_USE_FANCY_MATH_387"
16169   "fsqrt"
16170   [(set_attr "type" "fpspc")
16171    (set_attr "mode" "XF")
16172    (set_attr "athlon_decode" "direct")
16173    (set_attr "amdfam10_decode" "direct")])
16174
16175 (define_insn "sqrt_extend<mode>xf2_i387"
16176   [(set (match_operand:XF 0 "register_operand" "=f")
16177         (sqrt:XF
16178           (float_extend:XF
16179             (match_operand:MODEF 1 "register_operand" "0"))))]
16180   "TARGET_USE_FANCY_MATH_387"
16181   "fsqrt"
16182   [(set_attr "type" "fpspc")
16183    (set_attr "mode" "XF")
16184    (set_attr "athlon_decode" "direct")
16185    (set_attr "amdfam10_decode" "direct")])
16186
16187 (define_insn "*rsqrtsf2_sse"
16188   [(set (match_operand:SF 0 "register_operand" "=x")
16189         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16190                    UNSPEC_RSQRT))]
16191   "TARGET_SSE_MATH"
16192   "%vrsqrtss\t{%1, %d0|%d0, %1}"
16193   [(set_attr "type" "sse")
16194    (set_attr "atom_sse_attr" "rcp")
16195    (set_attr "prefix" "maybe_vex")
16196    (set_attr "mode" "SF")])
16197
16198 (define_expand "rsqrtsf2"
16199   [(set (match_operand:SF 0 "register_operand" "")
16200         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
16201                    UNSPEC_RSQRT))]
16202   "TARGET_SSE_MATH"
16203 {
16204   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
16205   DONE;
16206 })
16207
16208 (define_insn "*sqrt<mode>2_sse"
16209   [(set (match_operand:MODEF 0 "register_operand" "=x")
16210         (sqrt:MODEF
16211           (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
16212   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16213   "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}"
16214   [(set_attr "type" "sse")
16215    (set_attr "atom_sse_attr" "sqrt")
16216    (set_attr "prefix" "maybe_vex")
16217    (set_attr "mode" "<MODE>")
16218    (set_attr "athlon_decode" "*")
16219    (set_attr "amdfam10_decode" "*")])
16220
16221 (define_expand "sqrt<mode>2"
16222   [(set (match_operand:MODEF 0 "register_operand" "")
16223         (sqrt:MODEF
16224           (match_operand:MODEF 1 "nonimmediate_operand" "")))]
16225   "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
16226    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16227 {
16228   if (<MODE>mode == SFmode
16229       && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
16230       && flag_finite_math_only && !flag_trapping_math
16231       && flag_unsafe_math_optimizations)
16232     {
16233       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
16234       DONE;
16235     }
16236
16237   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
16238     {
16239       rtx op0 = gen_reg_rtx (XFmode);
16240       rtx op1 = force_reg (<MODE>mode, operands[1]);
16241
16242       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
16243       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16244       DONE;
16245    }
16246 })
16247
16248 (define_insn "fpremxf4_i387"
16249   [(set (match_operand:XF 0 "register_operand" "=f")
16250         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16251                     (match_operand:XF 3 "register_operand" "1")]
16252                    UNSPEC_FPREM_F))
16253    (set (match_operand:XF 1 "register_operand" "=u")
16254         (unspec:XF [(match_dup 2) (match_dup 3)]
16255                    UNSPEC_FPREM_U))
16256    (set (reg:CCFP FPSR_REG)
16257         (unspec:CCFP [(match_dup 2) (match_dup 3)]
16258                      UNSPEC_C2_FLAG))]
16259   "TARGET_USE_FANCY_MATH_387"
16260   "fprem"
16261   [(set_attr "type" "fpspc")
16262    (set_attr "mode" "XF")])
16263
16264 (define_expand "fmodxf3"
16265   [(use (match_operand:XF 0 "register_operand" ""))
16266    (use (match_operand:XF 1 "general_operand" ""))
16267    (use (match_operand:XF 2 "general_operand" ""))]
16268   "TARGET_USE_FANCY_MATH_387"
16269 {
16270   rtx label = gen_label_rtx ();
16271
16272   rtx op1 = gen_reg_rtx (XFmode);
16273   rtx op2 = gen_reg_rtx (XFmode);
16274
16275   emit_move_insn (op2, operands[2]);
16276   emit_move_insn (op1, operands[1]);
16277
16278   emit_label (label);
16279   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16280   ix86_emit_fp_unordered_jump (label);
16281   LABEL_NUSES (label) = 1;
16282
16283   emit_move_insn (operands[0], op1);
16284   DONE;
16285 })
16286
16287 (define_expand "fmod<mode>3"
16288   [(use (match_operand:MODEF 0 "register_operand" ""))
16289    (use (match_operand:MODEF 1 "general_operand" ""))
16290    (use (match_operand:MODEF 2 "general_operand" ""))]
16291   "TARGET_USE_FANCY_MATH_387"
16292 {
16293   rtx label = gen_label_rtx ();
16294
16295   rtx op1 = gen_reg_rtx (XFmode);
16296   rtx op2 = gen_reg_rtx (XFmode);
16297
16298   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16299   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16300
16301   emit_label (label);
16302   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16303   ix86_emit_fp_unordered_jump (label);
16304   LABEL_NUSES (label) = 1;
16305
16306   /* Truncate the result properly for strict SSE math.  */
16307   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16308       && !TARGET_MIX_SSE_I387)
16309     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16310   else
16311     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16312
16313   DONE;
16314 })
16315
16316 (define_insn "fprem1xf4_i387"
16317   [(set (match_operand:XF 0 "register_operand" "=f")
16318         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16319                     (match_operand:XF 3 "register_operand" "1")]
16320                    UNSPEC_FPREM1_F))
16321    (set (match_operand:XF 1 "register_operand" "=u")
16322         (unspec:XF [(match_dup 2) (match_dup 3)]
16323                    UNSPEC_FPREM1_U))
16324    (set (reg:CCFP FPSR_REG)
16325         (unspec:CCFP [(match_dup 2) (match_dup 3)]
16326                      UNSPEC_C2_FLAG))]
16327   "TARGET_USE_FANCY_MATH_387"
16328   "fprem1"
16329   [(set_attr "type" "fpspc")
16330    (set_attr "mode" "XF")])
16331
16332 (define_expand "remainderxf3"
16333   [(use (match_operand:XF 0 "register_operand" ""))
16334    (use (match_operand:XF 1 "general_operand" ""))
16335    (use (match_operand:XF 2 "general_operand" ""))]
16336   "TARGET_USE_FANCY_MATH_387"
16337 {
16338   rtx label = gen_label_rtx ();
16339
16340   rtx op1 = gen_reg_rtx (XFmode);
16341   rtx op2 = gen_reg_rtx (XFmode);
16342
16343   emit_move_insn (op2, operands[2]);
16344   emit_move_insn (op1, operands[1]);
16345
16346   emit_label (label);
16347   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16348   ix86_emit_fp_unordered_jump (label);
16349   LABEL_NUSES (label) = 1;
16350
16351   emit_move_insn (operands[0], op1);
16352   DONE;
16353 })
16354
16355 (define_expand "remainder<mode>3"
16356   [(use (match_operand:MODEF 0 "register_operand" ""))
16357    (use (match_operand:MODEF 1 "general_operand" ""))
16358    (use (match_operand:MODEF 2 "general_operand" ""))]
16359   "TARGET_USE_FANCY_MATH_387"
16360 {
16361   rtx label = gen_label_rtx ();
16362
16363   rtx op1 = gen_reg_rtx (XFmode);
16364   rtx op2 = gen_reg_rtx (XFmode);
16365
16366   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16367   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16368
16369   emit_label (label);
16370
16371   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16372   ix86_emit_fp_unordered_jump (label);
16373   LABEL_NUSES (label) = 1;
16374
16375   /* Truncate the result properly for strict SSE math.  */
16376   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16377       && !TARGET_MIX_SSE_I387)
16378     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16379   else
16380     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16381
16382   DONE;
16383 })
16384
16385 (define_insn "*sinxf2_i387"
16386   [(set (match_operand:XF 0 "register_operand" "=f")
16387         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
16388   "TARGET_USE_FANCY_MATH_387
16389    && flag_unsafe_math_optimizations"
16390   "fsin"
16391   [(set_attr "type" "fpspc")
16392    (set_attr "mode" "XF")])
16393
16394 (define_insn "*sin_extend<mode>xf2_i387"
16395   [(set (match_operand:XF 0 "register_operand" "=f")
16396         (unspec:XF [(float_extend:XF
16397                       (match_operand:MODEF 1 "register_operand" "0"))]
16398                    UNSPEC_SIN))]
16399   "TARGET_USE_FANCY_MATH_387
16400    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16401        || TARGET_MIX_SSE_I387)
16402    && flag_unsafe_math_optimizations"
16403   "fsin"
16404   [(set_attr "type" "fpspc")
16405    (set_attr "mode" "XF")])
16406
16407 (define_insn "*cosxf2_i387"
16408   [(set (match_operand:XF 0 "register_operand" "=f")
16409         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
16410   "TARGET_USE_FANCY_MATH_387
16411    && flag_unsafe_math_optimizations"
16412   "fcos"
16413   [(set_attr "type" "fpspc")
16414    (set_attr "mode" "XF")])
16415
16416 (define_insn "*cos_extend<mode>xf2_i387"
16417   [(set (match_operand:XF 0 "register_operand" "=f")
16418         (unspec:XF [(float_extend:XF
16419                       (match_operand:MODEF 1 "register_operand" "0"))]
16420                    UNSPEC_COS))]
16421   "TARGET_USE_FANCY_MATH_387
16422    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16423        || TARGET_MIX_SSE_I387)
16424    && flag_unsafe_math_optimizations"
16425   "fcos"
16426   [(set_attr "type" "fpspc")
16427    (set_attr "mode" "XF")])
16428
16429 ;; When sincos pattern is defined, sin and cos builtin functions will be
16430 ;; expanded to sincos pattern with one of its outputs left unused.
16431 ;; CSE pass will figure out if two sincos patterns can be combined,
16432 ;; otherwise sincos pattern will be split back to sin or cos pattern,
16433 ;; depending on the unused output.
16434
16435 (define_insn "sincosxf3"
16436   [(set (match_operand:XF 0 "register_operand" "=f")
16437         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16438                    UNSPEC_SINCOS_COS))
16439    (set (match_operand:XF 1 "register_operand" "=u")
16440         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16441   "TARGET_USE_FANCY_MATH_387
16442    && flag_unsafe_math_optimizations"
16443   "fsincos"
16444   [(set_attr "type" "fpspc")
16445    (set_attr "mode" "XF")])
16446
16447 (define_split
16448   [(set (match_operand:XF 0 "register_operand" "")
16449         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16450                    UNSPEC_SINCOS_COS))
16451    (set (match_operand:XF 1 "register_operand" "")
16452         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16453   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16454    && !(reload_completed || reload_in_progress)"
16455   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
16456   "")
16457
16458 (define_split
16459   [(set (match_operand:XF 0 "register_operand" "")
16460         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16461                    UNSPEC_SINCOS_COS))
16462    (set (match_operand:XF 1 "register_operand" "")
16463         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16464   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16465    && !(reload_completed || reload_in_progress)"
16466   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
16467   "")
16468
16469 (define_insn "sincos_extend<mode>xf3_i387"
16470   [(set (match_operand:XF 0 "register_operand" "=f")
16471         (unspec:XF [(float_extend:XF
16472                       (match_operand:MODEF 2 "register_operand" "0"))]
16473                    UNSPEC_SINCOS_COS))
16474    (set (match_operand:XF 1 "register_operand" "=u")
16475         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16476   "TARGET_USE_FANCY_MATH_387
16477    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16478        || TARGET_MIX_SSE_I387)
16479    && flag_unsafe_math_optimizations"
16480   "fsincos"
16481   [(set_attr "type" "fpspc")
16482    (set_attr "mode" "XF")])
16483
16484 (define_split
16485   [(set (match_operand:XF 0 "register_operand" "")
16486         (unspec:XF [(float_extend:XF
16487                       (match_operand:MODEF 2 "register_operand" ""))]
16488                    UNSPEC_SINCOS_COS))
16489    (set (match_operand:XF 1 "register_operand" "")
16490         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16491   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16492    && !(reload_completed || reload_in_progress)"
16493   [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
16494   "")
16495
16496 (define_split
16497   [(set (match_operand:XF 0 "register_operand" "")
16498         (unspec:XF [(float_extend:XF
16499                       (match_operand:MODEF 2 "register_operand" ""))]
16500                    UNSPEC_SINCOS_COS))
16501    (set (match_operand:XF 1 "register_operand" "")
16502         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16503   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16504    && !(reload_completed || reload_in_progress)"
16505   [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
16506   "")
16507
16508 (define_expand "sincos<mode>3"
16509   [(use (match_operand:MODEF 0 "register_operand" ""))
16510    (use (match_operand:MODEF 1 "register_operand" ""))
16511    (use (match_operand:MODEF 2 "register_operand" ""))]
16512   "TARGET_USE_FANCY_MATH_387
16513    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16514        || TARGET_MIX_SSE_I387)
16515    && flag_unsafe_math_optimizations"
16516 {
16517   rtx op0 = gen_reg_rtx (XFmode);
16518   rtx op1 = gen_reg_rtx (XFmode);
16519
16520   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
16521   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16522   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
16523   DONE;
16524 })
16525
16526 (define_insn "fptanxf4_i387"
16527   [(set (match_operand:XF 0 "register_operand" "=f")
16528         (match_operand:XF 3 "const_double_operand" "F"))
16529    (set (match_operand:XF 1 "register_operand" "=u")
16530         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16531                    UNSPEC_TAN))]
16532   "TARGET_USE_FANCY_MATH_387
16533    && flag_unsafe_math_optimizations
16534    && standard_80387_constant_p (operands[3]) == 2"
16535   "fptan"
16536   [(set_attr "type" "fpspc")
16537    (set_attr "mode" "XF")])
16538
16539 (define_insn "fptan_extend<mode>xf4_i387"
16540   [(set (match_operand:MODEF 0 "register_operand" "=f")
16541         (match_operand:MODEF 3 "const_double_operand" "F"))
16542    (set (match_operand:XF 1 "register_operand" "=u")
16543         (unspec:XF [(float_extend:XF
16544                       (match_operand:MODEF 2 "register_operand" "0"))]
16545                    UNSPEC_TAN))]
16546   "TARGET_USE_FANCY_MATH_387
16547    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16548        || TARGET_MIX_SSE_I387)
16549    && flag_unsafe_math_optimizations
16550    && standard_80387_constant_p (operands[3]) == 2"
16551   "fptan"
16552   [(set_attr "type" "fpspc")
16553    (set_attr "mode" "XF")])
16554
16555 (define_expand "tanxf2"
16556   [(use (match_operand:XF 0 "register_operand" ""))
16557    (use (match_operand:XF 1 "register_operand" ""))]
16558   "TARGET_USE_FANCY_MATH_387
16559    && flag_unsafe_math_optimizations"
16560 {
16561   rtx one = gen_reg_rtx (XFmode);
16562   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
16563
16564   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
16565   DONE;
16566 })
16567
16568 (define_expand "tan<mode>2"
16569   [(use (match_operand:MODEF 0 "register_operand" ""))
16570    (use (match_operand:MODEF 1 "register_operand" ""))]
16571   "TARGET_USE_FANCY_MATH_387
16572    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16573        || TARGET_MIX_SSE_I387)
16574    && flag_unsafe_math_optimizations"
16575 {
16576   rtx op0 = gen_reg_rtx (XFmode);
16577
16578   rtx one = gen_reg_rtx (<MODE>mode);
16579   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
16580
16581   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
16582                                              operands[1], op2));
16583   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16584   DONE;
16585 })
16586
16587 (define_insn "*fpatanxf3_i387"
16588   [(set (match_operand:XF 0 "register_operand" "=f")
16589         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16590                     (match_operand:XF 2 "register_operand" "u")]
16591                    UNSPEC_FPATAN))
16592    (clobber (match_scratch:XF 3 "=2"))]
16593   "TARGET_USE_FANCY_MATH_387
16594    && flag_unsafe_math_optimizations"
16595   "fpatan"
16596   [(set_attr "type" "fpspc")
16597    (set_attr "mode" "XF")])
16598
16599 (define_insn "fpatan_extend<mode>xf3_i387"
16600   [(set (match_operand:XF 0 "register_operand" "=f")
16601         (unspec:XF [(float_extend:XF
16602                       (match_operand:MODEF 1 "register_operand" "0"))
16603                     (float_extend:XF
16604                       (match_operand:MODEF 2 "register_operand" "u"))]
16605                    UNSPEC_FPATAN))
16606    (clobber (match_scratch:XF 3 "=2"))]
16607   "TARGET_USE_FANCY_MATH_387
16608    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16609        || TARGET_MIX_SSE_I387)
16610    && flag_unsafe_math_optimizations"
16611   "fpatan"
16612   [(set_attr "type" "fpspc")
16613    (set_attr "mode" "XF")])
16614
16615 (define_expand "atan2xf3"
16616   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16617                    (unspec:XF [(match_operand:XF 2 "register_operand" "")
16618                                (match_operand:XF 1 "register_operand" "")]
16619                               UNSPEC_FPATAN))
16620               (clobber (match_scratch:XF 3 ""))])]
16621   "TARGET_USE_FANCY_MATH_387
16622    && flag_unsafe_math_optimizations"
16623   "")
16624
16625 (define_expand "atan2<mode>3"
16626   [(use (match_operand:MODEF 0 "register_operand" ""))
16627    (use (match_operand:MODEF 1 "register_operand" ""))
16628    (use (match_operand:MODEF 2 "register_operand" ""))]
16629   "TARGET_USE_FANCY_MATH_387
16630    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16631        || TARGET_MIX_SSE_I387)
16632    && flag_unsafe_math_optimizations"
16633 {
16634   rtx op0 = gen_reg_rtx (XFmode);
16635
16636   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
16637   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16638   DONE;
16639 })
16640
16641 (define_expand "atanxf2"
16642   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16643                    (unspec:XF [(match_dup 2)
16644                                (match_operand:XF 1 "register_operand" "")]
16645                               UNSPEC_FPATAN))
16646               (clobber (match_scratch:XF 3 ""))])]
16647   "TARGET_USE_FANCY_MATH_387
16648    && flag_unsafe_math_optimizations"
16649 {
16650   operands[2] = gen_reg_rtx (XFmode);
16651   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
16652 })
16653
16654 (define_expand "atan<mode>2"
16655   [(use (match_operand:MODEF 0 "register_operand" ""))
16656    (use (match_operand:MODEF 1 "register_operand" ""))]
16657   "TARGET_USE_FANCY_MATH_387
16658    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16659        || TARGET_MIX_SSE_I387)
16660    && flag_unsafe_math_optimizations"
16661 {
16662   rtx op0 = gen_reg_rtx (XFmode);
16663
16664   rtx op2 = gen_reg_rtx (<MODE>mode);
16665   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
16666
16667   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
16668   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16669   DONE;
16670 })
16671
16672 (define_expand "asinxf2"
16673   [(set (match_dup 2)
16674         (mult:XF (match_operand:XF 1 "register_operand" "")
16675                  (match_dup 1)))
16676    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16677    (set (match_dup 5) (sqrt:XF (match_dup 4)))
16678    (parallel [(set (match_operand:XF 0 "register_operand" "")
16679                    (unspec:XF [(match_dup 5) (match_dup 1)]
16680                               UNSPEC_FPATAN))
16681               (clobber (match_scratch:XF 6 ""))])]
16682   "TARGET_USE_FANCY_MATH_387
16683    && flag_unsafe_math_optimizations"
16684 {
16685   int i;
16686
16687   if (optimize_insn_for_size_p ())
16688     FAIL;
16689
16690   for (i = 2; i < 6; i++)
16691     operands[i] = gen_reg_rtx (XFmode);
16692
16693   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16694 })
16695
16696 (define_expand "asin<mode>2"
16697   [(use (match_operand:MODEF 0 "register_operand" ""))
16698    (use (match_operand:MODEF 1 "general_operand" ""))]
16699  "TARGET_USE_FANCY_MATH_387
16700    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16701        || TARGET_MIX_SSE_I387)
16702    && flag_unsafe_math_optimizations"
16703 {
16704   rtx op0 = gen_reg_rtx (XFmode);
16705   rtx op1 = gen_reg_rtx (XFmode);
16706
16707   if (optimize_insn_for_size_p ())
16708     FAIL;
16709
16710   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16711   emit_insn (gen_asinxf2 (op0, op1));
16712   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16713   DONE;
16714 })
16715
16716 (define_expand "acosxf2"
16717   [(set (match_dup 2)
16718         (mult:XF (match_operand:XF 1 "register_operand" "")
16719                  (match_dup 1)))
16720    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16721    (set (match_dup 5) (sqrt:XF (match_dup 4)))
16722    (parallel [(set (match_operand:XF 0 "register_operand" "")
16723                    (unspec:XF [(match_dup 1) (match_dup 5)]
16724                               UNSPEC_FPATAN))
16725               (clobber (match_scratch:XF 6 ""))])]
16726   "TARGET_USE_FANCY_MATH_387
16727    && flag_unsafe_math_optimizations"
16728 {
16729   int i;
16730
16731   if (optimize_insn_for_size_p ())
16732     FAIL;
16733
16734   for (i = 2; i < 6; i++)
16735     operands[i] = gen_reg_rtx (XFmode);
16736
16737   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16738 })
16739
16740 (define_expand "acos<mode>2"
16741   [(use (match_operand:MODEF 0 "register_operand" ""))
16742    (use (match_operand:MODEF 1 "general_operand" ""))]
16743  "TARGET_USE_FANCY_MATH_387
16744    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16745        || TARGET_MIX_SSE_I387)
16746    && flag_unsafe_math_optimizations"
16747 {
16748   rtx op0 = gen_reg_rtx (XFmode);
16749   rtx op1 = gen_reg_rtx (XFmode);
16750
16751   if (optimize_insn_for_size_p ())
16752     FAIL;
16753
16754   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16755   emit_insn (gen_acosxf2 (op0, op1));
16756   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16757   DONE;
16758 })
16759
16760 (define_insn "fyl2xxf3_i387"
16761   [(set (match_operand:XF 0 "register_operand" "=f")
16762         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16763                     (match_operand:XF 2 "register_operand" "u")]
16764                    UNSPEC_FYL2X))
16765    (clobber (match_scratch:XF 3 "=2"))]
16766   "TARGET_USE_FANCY_MATH_387
16767    && flag_unsafe_math_optimizations"
16768   "fyl2x"
16769   [(set_attr "type" "fpspc")
16770    (set_attr "mode" "XF")])
16771
16772 (define_insn "fyl2x_extend<mode>xf3_i387"
16773   [(set (match_operand:XF 0 "register_operand" "=f")
16774         (unspec:XF [(float_extend:XF
16775                       (match_operand:MODEF 1 "register_operand" "0"))
16776                     (match_operand:XF 2 "register_operand" "u")]
16777                    UNSPEC_FYL2X))
16778    (clobber (match_scratch:XF 3 "=2"))]
16779   "TARGET_USE_FANCY_MATH_387
16780    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16781        || TARGET_MIX_SSE_I387)
16782    && flag_unsafe_math_optimizations"
16783   "fyl2x"
16784   [(set_attr "type" "fpspc")
16785    (set_attr "mode" "XF")])
16786
16787 (define_expand "logxf2"
16788   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16789                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16790                                (match_dup 2)] UNSPEC_FYL2X))
16791               (clobber (match_scratch:XF 3 ""))])]
16792   "TARGET_USE_FANCY_MATH_387
16793    && flag_unsafe_math_optimizations"
16794 {
16795   operands[2] = gen_reg_rtx (XFmode);
16796   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
16797 })
16798
16799 (define_expand "log<mode>2"
16800   [(use (match_operand:MODEF 0 "register_operand" ""))
16801    (use (match_operand:MODEF 1 "register_operand" ""))]
16802   "TARGET_USE_FANCY_MATH_387
16803    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16804        || TARGET_MIX_SSE_I387)
16805    && flag_unsafe_math_optimizations"
16806 {
16807   rtx op0 = gen_reg_rtx (XFmode);
16808
16809   rtx op2 = gen_reg_rtx (XFmode);
16810   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
16811
16812   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16813   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16814   DONE;
16815 })
16816
16817 (define_expand "log10xf2"
16818   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16819                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16820                                (match_dup 2)] UNSPEC_FYL2X))
16821               (clobber (match_scratch:XF 3 ""))])]
16822   "TARGET_USE_FANCY_MATH_387
16823    && flag_unsafe_math_optimizations"
16824 {
16825   operands[2] = gen_reg_rtx (XFmode);
16826   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
16827 })
16828
16829 (define_expand "log10<mode>2"
16830   [(use (match_operand:MODEF 0 "register_operand" ""))
16831    (use (match_operand:MODEF 1 "register_operand" ""))]
16832   "TARGET_USE_FANCY_MATH_387
16833    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16834        || TARGET_MIX_SSE_I387)
16835    && flag_unsafe_math_optimizations"
16836 {
16837   rtx op0 = gen_reg_rtx (XFmode);
16838
16839   rtx op2 = gen_reg_rtx (XFmode);
16840   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
16841
16842   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16843   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16844   DONE;
16845 })
16846
16847 (define_expand "log2xf2"
16848   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16849                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16850                                (match_dup 2)] UNSPEC_FYL2X))
16851               (clobber (match_scratch:XF 3 ""))])]
16852   "TARGET_USE_FANCY_MATH_387
16853    && flag_unsafe_math_optimizations"
16854 {
16855   operands[2] = gen_reg_rtx (XFmode);
16856   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16857 })
16858
16859 (define_expand "log2<mode>2"
16860   [(use (match_operand:MODEF 0 "register_operand" ""))
16861    (use (match_operand:MODEF 1 "register_operand" ""))]
16862   "TARGET_USE_FANCY_MATH_387
16863    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16864        || TARGET_MIX_SSE_I387)
16865    && flag_unsafe_math_optimizations"
16866 {
16867   rtx op0 = gen_reg_rtx (XFmode);
16868
16869   rtx op2 = gen_reg_rtx (XFmode);
16870   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
16871
16872   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16873   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16874   DONE;
16875 })
16876
16877 (define_insn "fyl2xp1xf3_i387"
16878   [(set (match_operand:XF 0 "register_operand" "=f")
16879         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16880                     (match_operand:XF 2 "register_operand" "u")]
16881                    UNSPEC_FYL2XP1))
16882    (clobber (match_scratch:XF 3 "=2"))]
16883   "TARGET_USE_FANCY_MATH_387
16884    && flag_unsafe_math_optimizations"
16885   "fyl2xp1"
16886   [(set_attr "type" "fpspc")
16887    (set_attr "mode" "XF")])
16888
16889 (define_insn "fyl2xp1_extend<mode>xf3_i387"
16890   [(set (match_operand:XF 0 "register_operand" "=f")
16891         (unspec:XF [(float_extend:XF
16892                       (match_operand:MODEF 1 "register_operand" "0"))
16893                     (match_operand:XF 2 "register_operand" "u")]
16894                    UNSPEC_FYL2XP1))
16895    (clobber (match_scratch:XF 3 "=2"))]
16896   "TARGET_USE_FANCY_MATH_387
16897    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16898        || TARGET_MIX_SSE_I387)
16899    && flag_unsafe_math_optimizations"
16900   "fyl2xp1"
16901   [(set_attr "type" "fpspc")
16902    (set_attr "mode" "XF")])
16903
16904 (define_expand "log1pxf2"
16905   [(use (match_operand:XF 0 "register_operand" ""))
16906    (use (match_operand:XF 1 "register_operand" ""))]
16907   "TARGET_USE_FANCY_MATH_387
16908    && flag_unsafe_math_optimizations"
16909 {
16910   if (optimize_insn_for_size_p ())
16911     FAIL;
16912
16913   ix86_emit_i387_log1p (operands[0], operands[1]);
16914   DONE;
16915 })
16916
16917 (define_expand "log1p<mode>2"
16918   [(use (match_operand:MODEF 0 "register_operand" ""))
16919    (use (match_operand:MODEF 1 "register_operand" ""))]
16920   "TARGET_USE_FANCY_MATH_387
16921    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16922        || TARGET_MIX_SSE_I387)
16923    && flag_unsafe_math_optimizations"
16924 {
16925   rtx op0;
16926
16927   if (optimize_insn_for_size_p ())
16928     FAIL;
16929
16930   op0 = gen_reg_rtx (XFmode);
16931
16932   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
16933
16934   ix86_emit_i387_log1p (op0, operands[1]);
16935   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16936   DONE;
16937 })
16938
16939 (define_insn "fxtractxf3_i387"
16940   [(set (match_operand:XF 0 "register_operand" "=f")
16941         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16942                    UNSPEC_XTRACT_FRACT))
16943    (set (match_operand:XF 1 "register_operand" "=u")
16944         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16945   "TARGET_USE_FANCY_MATH_387
16946    && flag_unsafe_math_optimizations"
16947   "fxtract"
16948   [(set_attr "type" "fpspc")
16949    (set_attr "mode" "XF")])
16950
16951 (define_insn "fxtract_extend<mode>xf3_i387"
16952   [(set (match_operand:XF 0 "register_operand" "=f")
16953         (unspec:XF [(float_extend:XF
16954                       (match_operand:MODEF 2 "register_operand" "0"))]
16955                    UNSPEC_XTRACT_FRACT))
16956    (set (match_operand:XF 1 "register_operand" "=u")
16957         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
16958   "TARGET_USE_FANCY_MATH_387
16959    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16960        || TARGET_MIX_SSE_I387)
16961    && flag_unsafe_math_optimizations"
16962   "fxtract"
16963   [(set_attr "type" "fpspc")
16964    (set_attr "mode" "XF")])
16965
16966 (define_expand "logbxf2"
16967   [(parallel [(set (match_dup 2)
16968                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16969                               UNSPEC_XTRACT_FRACT))
16970               (set (match_operand:XF 0 "register_operand" "")
16971                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16972   "TARGET_USE_FANCY_MATH_387
16973    && flag_unsafe_math_optimizations"
16974 {
16975   operands[2] = gen_reg_rtx (XFmode);
16976 })
16977
16978 (define_expand "logb<mode>2"
16979   [(use (match_operand:MODEF 0 "register_operand" ""))
16980    (use (match_operand:MODEF 1 "register_operand" ""))]
16981   "TARGET_USE_FANCY_MATH_387
16982    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16983        || TARGET_MIX_SSE_I387)
16984    && flag_unsafe_math_optimizations"
16985 {
16986   rtx op0 = gen_reg_rtx (XFmode);
16987   rtx op1 = gen_reg_rtx (XFmode);
16988
16989   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16990   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
16991   DONE;
16992 })
16993
16994 (define_expand "ilogbxf2"
16995   [(use (match_operand:SI 0 "register_operand" ""))
16996    (use (match_operand:XF 1 "register_operand" ""))]
16997   "TARGET_USE_FANCY_MATH_387
16998    && flag_unsafe_math_optimizations"
16999 {
17000   rtx op0, op1;
17001
17002   if (optimize_insn_for_size_p ())
17003     FAIL;
17004
17005   op0 = gen_reg_rtx (XFmode);
17006   op1 = gen_reg_rtx (XFmode);
17007
17008   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
17009   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17010   DONE;
17011 })
17012
17013 (define_expand "ilogb<mode>2"
17014   [(use (match_operand:SI 0 "register_operand" ""))
17015    (use (match_operand:MODEF 1 "register_operand" ""))]
17016   "TARGET_USE_FANCY_MATH_387
17017    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17018        || TARGET_MIX_SSE_I387)
17019    && flag_unsafe_math_optimizations"
17020 {
17021   rtx op0, op1;
17022
17023   if (optimize_insn_for_size_p ())
17024     FAIL;
17025
17026   op0 = gen_reg_rtx (XFmode);
17027   op1 = gen_reg_rtx (XFmode);
17028
17029   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17030   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17031   DONE;
17032 })
17033
17034 (define_insn "*f2xm1xf2_i387"
17035   [(set (match_operand:XF 0 "register_operand" "=f")
17036         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17037                    UNSPEC_F2XM1))]
17038   "TARGET_USE_FANCY_MATH_387
17039    && flag_unsafe_math_optimizations"
17040   "f2xm1"
17041   [(set_attr "type" "fpspc")
17042    (set_attr "mode" "XF")])
17043
17044 (define_insn "*fscalexf4_i387"
17045   [(set (match_operand:XF 0 "register_operand" "=f")
17046         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
17047                     (match_operand:XF 3 "register_operand" "1")]
17048                    UNSPEC_FSCALE_FRACT))
17049    (set (match_operand:XF 1 "register_operand" "=u")
17050         (unspec:XF [(match_dup 2) (match_dup 3)]
17051                    UNSPEC_FSCALE_EXP))]
17052   "TARGET_USE_FANCY_MATH_387
17053    && flag_unsafe_math_optimizations"
17054   "fscale"
17055   [(set_attr "type" "fpspc")
17056    (set_attr "mode" "XF")])
17057
17058 (define_expand "expNcorexf3"
17059   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17060                                (match_operand:XF 2 "register_operand" "")))
17061    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17062    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17063    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17064    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
17065    (parallel [(set (match_operand:XF 0 "register_operand" "")
17066                    (unspec:XF [(match_dup 8) (match_dup 4)]
17067                               UNSPEC_FSCALE_FRACT))
17068               (set (match_dup 9)
17069                    (unspec:XF [(match_dup 8) (match_dup 4)]
17070                               UNSPEC_FSCALE_EXP))])]
17071   "TARGET_USE_FANCY_MATH_387
17072    && flag_unsafe_math_optimizations"
17073 {
17074   int i;
17075
17076   if (optimize_insn_for_size_p ())
17077     FAIL;
17078
17079   for (i = 3; i < 10; i++)
17080     operands[i] = gen_reg_rtx (XFmode);
17081
17082   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
17083 })
17084
17085 (define_expand "expxf2"
17086   [(use (match_operand:XF 0 "register_operand" ""))
17087    (use (match_operand:XF 1 "register_operand" ""))]
17088   "TARGET_USE_FANCY_MATH_387
17089    && flag_unsafe_math_optimizations"
17090 {
17091   rtx op2;
17092
17093   if (optimize_insn_for_size_p ())
17094     FAIL;
17095
17096   op2 = gen_reg_rtx (XFmode);
17097   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
17098
17099   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17100   DONE;
17101 })
17102
17103 (define_expand "exp<mode>2"
17104   [(use (match_operand:MODEF 0 "register_operand" ""))
17105    (use (match_operand:MODEF 1 "general_operand" ""))]
17106  "TARGET_USE_FANCY_MATH_387
17107    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17108        || TARGET_MIX_SSE_I387)
17109    && flag_unsafe_math_optimizations"
17110 {
17111   rtx op0, op1;
17112
17113   if (optimize_insn_for_size_p ())
17114     FAIL;
17115
17116   op0 = gen_reg_rtx (XFmode);
17117   op1 = gen_reg_rtx (XFmode);
17118
17119   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17120   emit_insn (gen_expxf2 (op0, op1));
17121   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17122   DONE;
17123 })
17124
17125 (define_expand "exp10xf2"
17126   [(use (match_operand:XF 0 "register_operand" ""))
17127    (use (match_operand:XF 1 "register_operand" ""))]
17128   "TARGET_USE_FANCY_MATH_387
17129    && flag_unsafe_math_optimizations"
17130 {
17131   rtx op2;
17132
17133   if (optimize_insn_for_size_p ())
17134     FAIL;
17135
17136   op2 = gen_reg_rtx (XFmode);
17137   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
17138
17139   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17140   DONE;
17141 })
17142
17143 (define_expand "exp10<mode>2"
17144   [(use (match_operand:MODEF 0 "register_operand" ""))
17145    (use (match_operand:MODEF 1 "general_operand" ""))]
17146  "TARGET_USE_FANCY_MATH_387
17147    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17148        || TARGET_MIX_SSE_I387)
17149    && flag_unsafe_math_optimizations"
17150 {
17151   rtx op0, op1;
17152
17153   if (optimize_insn_for_size_p ())
17154     FAIL;
17155
17156   op0 = gen_reg_rtx (XFmode);
17157   op1 = gen_reg_rtx (XFmode);
17158
17159   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17160   emit_insn (gen_exp10xf2 (op0, op1));
17161   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17162   DONE;
17163 })
17164
17165 (define_expand "exp2xf2"
17166   [(use (match_operand:XF 0 "register_operand" ""))
17167    (use (match_operand:XF 1 "register_operand" ""))]
17168   "TARGET_USE_FANCY_MATH_387
17169    && flag_unsafe_math_optimizations"
17170 {
17171   rtx op2;
17172
17173   if (optimize_insn_for_size_p ())
17174     FAIL;
17175
17176   op2 = gen_reg_rtx (XFmode);
17177   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
17178
17179   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17180   DONE;
17181 })
17182
17183 (define_expand "exp2<mode>2"
17184   [(use (match_operand:MODEF 0 "register_operand" ""))
17185    (use (match_operand:MODEF 1 "general_operand" ""))]
17186  "TARGET_USE_FANCY_MATH_387
17187    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17188        || TARGET_MIX_SSE_I387)
17189    && flag_unsafe_math_optimizations"
17190 {
17191   rtx op0, op1;
17192
17193   if (optimize_insn_for_size_p ())
17194     FAIL;
17195
17196   op0 = gen_reg_rtx (XFmode);
17197   op1 = gen_reg_rtx (XFmode);
17198
17199   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17200   emit_insn (gen_exp2xf2 (op0, op1));
17201   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17202   DONE;
17203 })
17204
17205 (define_expand "expm1xf2"
17206   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17207                                (match_dup 2)))
17208    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17209    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17210    (set (match_dup 9) (float_extend:XF (match_dup 13)))
17211    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17212    (parallel [(set (match_dup 7)
17213                    (unspec:XF [(match_dup 6) (match_dup 4)]
17214                               UNSPEC_FSCALE_FRACT))
17215               (set (match_dup 8)
17216                    (unspec:XF [(match_dup 6) (match_dup 4)]
17217                               UNSPEC_FSCALE_EXP))])
17218    (parallel [(set (match_dup 10)
17219                    (unspec:XF [(match_dup 9) (match_dup 8)]
17220                               UNSPEC_FSCALE_FRACT))
17221               (set (match_dup 11)
17222                    (unspec:XF [(match_dup 9) (match_dup 8)]
17223                               UNSPEC_FSCALE_EXP))])
17224    (set (match_dup 12) (minus:XF (match_dup 10)
17225                                  (float_extend:XF (match_dup 13))))
17226    (set (match_operand:XF 0 "register_operand" "")
17227         (plus:XF (match_dup 12) (match_dup 7)))]
17228   "TARGET_USE_FANCY_MATH_387
17229    && flag_unsafe_math_optimizations"
17230 {
17231   int i;
17232
17233   if (optimize_insn_for_size_p ())
17234     FAIL;
17235
17236   for (i = 2; i < 13; i++)
17237     operands[i] = gen_reg_rtx (XFmode);
17238
17239   operands[13]
17240     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
17241
17242   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
17243 })
17244
17245 (define_expand "expm1<mode>2"
17246   [(use (match_operand:MODEF 0 "register_operand" ""))
17247    (use (match_operand:MODEF 1 "general_operand" ""))]
17248  "TARGET_USE_FANCY_MATH_387
17249    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17250        || TARGET_MIX_SSE_I387)
17251    && flag_unsafe_math_optimizations"
17252 {
17253   rtx op0, op1;
17254
17255   if (optimize_insn_for_size_p ())
17256     FAIL;
17257
17258   op0 = gen_reg_rtx (XFmode);
17259   op1 = gen_reg_rtx (XFmode);
17260
17261   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17262   emit_insn (gen_expm1xf2 (op0, op1));
17263   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17264   DONE;
17265 })
17266
17267 (define_expand "ldexpxf3"
17268   [(set (match_dup 3)
17269         (float:XF (match_operand:SI 2 "register_operand" "")))
17270    (parallel [(set (match_operand:XF 0 " register_operand" "")
17271                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17272                                (match_dup 3)]
17273                               UNSPEC_FSCALE_FRACT))
17274               (set (match_dup 4)
17275                    (unspec:XF [(match_dup 1) (match_dup 3)]
17276                               UNSPEC_FSCALE_EXP))])]
17277   "TARGET_USE_FANCY_MATH_387
17278    && flag_unsafe_math_optimizations"
17279 {
17280   if (optimize_insn_for_size_p ())
17281     FAIL;
17282
17283   operands[3] = gen_reg_rtx (XFmode);
17284   operands[4] = gen_reg_rtx (XFmode);
17285 })
17286
17287 (define_expand "ldexp<mode>3"
17288   [(use (match_operand:MODEF 0 "register_operand" ""))
17289    (use (match_operand:MODEF 1 "general_operand" ""))
17290    (use (match_operand:SI 2 "register_operand" ""))]
17291  "TARGET_USE_FANCY_MATH_387
17292    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17293        || TARGET_MIX_SSE_I387)
17294    && flag_unsafe_math_optimizations"
17295 {
17296   rtx op0, op1;
17297
17298   if (optimize_insn_for_size_p ())
17299     FAIL;
17300
17301   op0 = gen_reg_rtx (XFmode);
17302   op1 = gen_reg_rtx (XFmode);
17303
17304   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17305   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
17306   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17307   DONE;
17308 })
17309
17310 (define_expand "scalbxf3"
17311   [(parallel [(set (match_operand:XF 0 " register_operand" "")
17312                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17313                                (match_operand:XF 2 "register_operand" "")]
17314                               UNSPEC_FSCALE_FRACT))
17315               (set (match_dup 3)
17316                    (unspec:XF [(match_dup 1) (match_dup 2)]
17317                               UNSPEC_FSCALE_EXP))])]
17318   "TARGET_USE_FANCY_MATH_387
17319    && flag_unsafe_math_optimizations"
17320 {
17321   if (optimize_insn_for_size_p ())
17322     FAIL;
17323
17324   operands[3] = gen_reg_rtx (XFmode);
17325 })
17326
17327 (define_expand "scalb<mode>3"
17328   [(use (match_operand:MODEF 0 "register_operand" ""))
17329    (use (match_operand:MODEF 1 "general_operand" ""))
17330    (use (match_operand:MODEF 2 "general_operand" ""))]
17331  "TARGET_USE_FANCY_MATH_387
17332    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17333        || TARGET_MIX_SSE_I387)
17334    && flag_unsafe_math_optimizations"
17335 {
17336   rtx op0, op1, op2;
17337
17338   if (optimize_insn_for_size_p ())
17339     FAIL;
17340
17341   op0 = gen_reg_rtx (XFmode);
17342   op1 = gen_reg_rtx (XFmode);
17343   op2 = gen_reg_rtx (XFmode);
17344
17345   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17346   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
17347   emit_insn (gen_scalbxf3 (op0, op1, op2));
17348   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17349   DONE;
17350 })
17351
17352 (define_expand "significandxf2"
17353   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17354                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17355                               UNSPEC_XTRACT_FRACT))
17356               (set (match_dup 2)
17357                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
17358   "TARGET_USE_FANCY_MATH_387
17359    && flag_unsafe_math_optimizations"
17360 {
17361   operands[2] = gen_reg_rtx (XFmode);
17362 })
17363
17364 (define_expand "significand<mode>2"
17365   [(use (match_operand:MODEF 0 "register_operand" ""))
17366    (use (match_operand:MODEF 1 "register_operand" ""))]
17367   "TARGET_USE_FANCY_MATH_387
17368    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17369        || TARGET_MIX_SSE_I387)
17370    && flag_unsafe_math_optimizations"
17371 {
17372   rtx op0 = gen_reg_rtx (XFmode);
17373   rtx op1 = gen_reg_rtx (XFmode);
17374
17375   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17376   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17377   DONE;
17378 })
17379 \f
17380
17381 (define_insn "sse4_1_round<mode>2"
17382   [(set (match_operand:MODEF 0 "register_operand" "=x")
17383         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
17384                        (match_operand:SI 2 "const_0_to_15_operand" "n")]
17385                       UNSPEC_ROUND))]
17386   "TARGET_ROUND"
17387   "%vrounds<ssemodefsuffix>\t{%2, %1, %d0|%d0, %1, %2}"
17388   [(set_attr "type" "ssecvt")
17389    (set_attr "prefix_extra" "1")
17390    (set_attr "prefix" "maybe_vex")
17391    (set_attr "mode" "<MODE>")])
17392
17393 (define_insn "rintxf2"
17394   [(set (match_operand:XF 0 "register_operand" "=f")
17395         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17396                    UNSPEC_FRNDINT))]
17397   "TARGET_USE_FANCY_MATH_387
17398    && flag_unsafe_math_optimizations"
17399   "frndint"
17400   [(set_attr "type" "fpspc")
17401    (set_attr "mode" "XF")])
17402
17403 (define_expand "rint<mode>2"
17404   [(use (match_operand:MODEF 0 "register_operand" ""))
17405    (use (match_operand:MODEF 1 "register_operand" ""))]
17406   "(TARGET_USE_FANCY_MATH_387
17407     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17408         || TARGET_MIX_SSE_I387)
17409     && flag_unsafe_math_optimizations)
17410    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17411        && !flag_trapping_math)"
17412 {
17413   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17414       && !flag_trapping_math)
17415     {
17416       if (!TARGET_ROUND && optimize_insn_for_size_p ())
17417         FAIL;
17418       if (TARGET_ROUND)
17419         emit_insn (gen_sse4_1_round<mode>2
17420                    (operands[0], operands[1], GEN_INT (0x04)));
17421       else
17422         ix86_expand_rint (operand0, operand1);
17423     }
17424   else
17425     {
17426       rtx op0 = gen_reg_rtx (XFmode);
17427       rtx op1 = gen_reg_rtx (XFmode);
17428
17429       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17430       emit_insn (gen_rintxf2 (op0, op1));
17431
17432       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17433     }
17434   DONE;
17435 })
17436
17437 (define_expand "round<mode>2"
17438   [(match_operand:MODEF 0 "register_operand" "")
17439    (match_operand:MODEF 1 "nonimmediate_operand" "")]
17440   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17441    && !flag_trapping_math && !flag_rounding_math"
17442 {
17443   if (optimize_insn_for_size_p ())
17444     FAIL;
17445   if (TARGET_64BIT || (<MODE>mode != DFmode))
17446     ix86_expand_round (operand0, operand1);
17447   else
17448     ix86_expand_rounddf_32 (operand0, operand1);
17449   DONE;
17450 })
17451
17452 (define_insn_and_split "*fistdi2_1"
17453   [(set (match_operand:DI 0 "nonimmediate_operand" "")
17454         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17455                    UNSPEC_FIST))]
17456   "TARGET_USE_FANCY_MATH_387
17457    && can_create_pseudo_p ()"
17458   "#"
17459   "&& 1"
17460   [(const_int 0)]
17461 {
17462   if (memory_operand (operands[0], VOIDmode))
17463     emit_insn (gen_fistdi2 (operands[0], operands[1]));
17464   else
17465     {
17466       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17467       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17468                                          operands[2]));
17469     }
17470   DONE;
17471 }
17472   [(set_attr "type" "fpspc")
17473    (set_attr "mode" "DI")])
17474
17475 (define_insn "fistdi2"
17476   [(set (match_operand:DI 0 "memory_operand" "=m")
17477         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17478                    UNSPEC_FIST))
17479    (clobber (match_scratch:XF 2 "=&1f"))]
17480   "TARGET_USE_FANCY_MATH_387"
17481   "* return output_fix_trunc (insn, operands, 0);"
17482   [(set_attr "type" "fpspc")
17483    (set_attr "mode" "DI")])
17484
17485 (define_insn "fistdi2_with_temp"
17486   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17487         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17488                    UNSPEC_FIST))
17489    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
17490    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17491   "TARGET_USE_FANCY_MATH_387"
17492   "#"
17493   [(set_attr "type" "fpspc")
17494    (set_attr "mode" "DI")])
17495
17496 (define_split
17497   [(set (match_operand:DI 0 "register_operand" "")
17498         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17499                    UNSPEC_FIST))
17500    (clobber (match_operand:DI 2 "memory_operand" ""))
17501    (clobber (match_scratch 3 ""))]
17502   "reload_completed"
17503   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17504               (clobber (match_dup 3))])
17505    (set (match_dup 0) (match_dup 2))]
17506   "")
17507
17508 (define_split
17509   [(set (match_operand:DI 0 "memory_operand" "")
17510         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17511                    UNSPEC_FIST))
17512    (clobber (match_operand:DI 2 "memory_operand" ""))
17513    (clobber (match_scratch 3 ""))]
17514   "reload_completed"
17515   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17516               (clobber (match_dup 3))])]
17517   "")
17518
17519 (define_insn_and_split "*fist<mode>2_1"
17520   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17521         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17522                            UNSPEC_FIST))]
17523   "TARGET_USE_FANCY_MATH_387
17524    && can_create_pseudo_p ()"
17525   "#"
17526   "&& 1"
17527   [(const_int 0)]
17528 {
17529   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17530   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17531                                         operands[2]));
17532   DONE;
17533 }
17534   [(set_attr "type" "fpspc")
17535    (set_attr "mode" "<MODE>")])
17536
17537 (define_insn "fist<mode>2"
17538   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17539         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17540                            UNSPEC_FIST))]
17541   "TARGET_USE_FANCY_MATH_387"
17542   "* return output_fix_trunc (insn, operands, 0);"
17543   [(set_attr "type" "fpspc")
17544    (set_attr "mode" "<MODE>")])
17545
17546 (define_insn "fist<mode>2_with_temp"
17547   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17548         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17549                            UNSPEC_FIST))
17550    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17551   "TARGET_USE_FANCY_MATH_387"
17552   "#"
17553   [(set_attr "type" "fpspc")
17554    (set_attr "mode" "<MODE>")])
17555
17556 (define_split
17557   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17558         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17559                            UNSPEC_FIST))
17560    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17561   "reload_completed"
17562   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
17563    (set (match_dup 0) (match_dup 2))]
17564   "")
17565
17566 (define_split
17567   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17568         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17569                            UNSPEC_FIST))
17570    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17571   "reload_completed"
17572   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
17573   "")
17574
17575 (define_expand "lrintxf<mode>2"
17576   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17577      (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17578                       UNSPEC_FIST))]
17579   "TARGET_USE_FANCY_MATH_387"
17580   "")
17581
17582 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
17583   [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17584      (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
17585                         UNSPEC_FIX_NOTRUNC))]
17586   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17587    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
17588   "")
17589
17590 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
17591   [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17592    (match_operand:MODEF 1 "register_operand" "")]
17593   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17594    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
17595    && !flag_trapping_math && !flag_rounding_math"
17596 {
17597   if (optimize_insn_for_size_p ())
17598     FAIL;
17599   ix86_expand_lround (operand0, operand1);
17600   DONE;
17601 })
17602
17603 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17604 (define_insn_and_split "frndintxf2_floor"
17605   [(set (match_operand:XF 0 "register_operand" "")
17606         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17607          UNSPEC_FRNDINT_FLOOR))
17608    (clobber (reg:CC FLAGS_REG))]
17609   "TARGET_USE_FANCY_MATH_387
17610    && flag_unsafe_math_optimizations
17611    && can_create_pseudo_p ()"
17612   "#"
17613   "&& 1"
17614   [(const_int 0)]
17615 {
17616   ix86_optimize_mode_switching[I387_FLOOR] = 1;
17617
17618   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17619   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17620
17621   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17622                                         operands[2], operands[3]));
17623   DONE;
17624 }
17625   [(set_attr "type" "frndint")
17626    (set_attr "i387_cw" "floor")
17627    (set_attr "mode" "XF")])
17628
17629 (define_insn "frndintxf2_floor_i387"
17630   [(set (match_operand:XF 0 "register_operand" "=f")
17631         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17632          UNSPEC_FRNDINT_FLOOR))
17633    (use (match_operand:HI 2 "memory_operand" "m"))
17634    (use (match_operand:HI 3 "memory_operand" "m"))]
17635   "TARGET_USE_FANCY_MATH_387
17636    && flag_unsafe_math_optimizations"
17637   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17638   [(set_attr "type" "frndint")
17639    (set_attr "i387_cw" "floor")
17640    (set_attr "mode" "XF")])
17641
17642 (define_expand "floorxf2"
17643   [(use (match_operand:XF 0 "register_operand" ""))
17644    (use (match_operand:XF 1 "register_operand" ""))]
17645   "TARGET_USE_FANCY_MATH_387
17646    && flag_unsafe_math_optimizations"
17647 {
17648   if (optimize_insn_for_size_p ())
17649     FAIL;
17650   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17651   DONE;
17652 })
17653
17654 (define_expand "floor<mode>2"
17655   [(use (match_operand:MODEF 0 "register_operand" ""))
17656    (use (match_operand:MODEF 1 "register_operand" ""))]
17657   "(TARGET_USE_FANCY_MATH_387
17658     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17659         || TARGET_MIX_SSE_I387)
17660     && flag_unsafe_math_optimizations)
17661    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17662        && !flag_trapping_math)"
17663 {
17664   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17665       && !flag_trapping_math
17666       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
17667     {
17668       if (!TARGET_ROUND && optimize_insn_for_size_p ())
17669         FAIL;
17670       if (TARGET_ROUND)
17671         emit_insn (gen_sse4_1_round<mode>2
17672                    (operands[0], operands[1], GEN_INT (0x01)));
17673       else if (TARGET_64BIT || (<MODE>mode != DFmode))
17674         ix86_expand_floorceil (operand0, operand1, true);
17675       else
17676         ix86_expand_floorceildf_32 (operand0, operand1, true);
17677     }
17678   else
17679     {
17680       rtx op0, op1;
17681
17682       if (optimize_insn_for_size_p ())
17683         FAIL;
17684
17685       op0 = gen_reg_rtx (XFmode);
17686       op1 = gen_reg_rtx (XFmode);
17687       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17688       emit_insn (gen_frndintxf2_floor (op0, op1));
17689
17690       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17691     }
17692   DONE;
17693 })
17694
17695 (define_insn_and_split "*fist<mode>2_floor_1"
17696   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17697         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17698          UNSPEC_FIST_FLOOR))
17699    (clobber (reg:CC FLAGS_REG))]
17700   "TARGET_USE_FANCY_MATH_387
17701    && flag_unsafe_math_optimizations
17702    && can_create_pseudo_p ()"
17703   "#"
17704   "&& 1"
17705   [(const_int 0)]
17706 {
17707   ix86_optimize_mode_switching[I387_FLOOR] = 1;
17708
17709   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17710   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17711   if (memory_operand (operands[0], VOIDmode))
17712     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17713                                       operands[2], operands[3]));
17714   else
17715     {
17716       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17717       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17718                                                   operands[2], operands[3],
17719                                                   operands[4]));
17720     }
17721   DONE;
17722 }
17723   [(set_attr "type" "fistp")
17724    (set_attr "i387_cw" "floor")
17725    (set_attr "mode" "<MODE>")])
17726
17727 (define_insn "fistdi2_floor"
17728   [(set (match_operand:DI 0 "memory_operand" "=m")
17729         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17730          UNSPEC_FIST_FLOOR))
17731    (use (match_operand:HI 2 "memory_operand" "m"))
17732    (use (match_operand:HI 3 "memory_operand" "m"))
17733    (clobber (match_scratch:XF 4 "=&1f"))]
17734   "TARGET_USE_FANCY_MATH_387
17735    && flag_unsafe_math_optimizations"
17736   "* return output_fix_trunc (insn, operands, 0);"
17737   [(set_attr "type" "fistp")
17738    (set_attr "i387_cw" "floor")
17739    (set_attr "mode" "DI")])
17740
17741 (define_insn "fistdi2_floor_with_temp"
17742   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17743         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17744          UNSPEC_FIST_FLOOR))
17745    (use (match_operand:HI 2 "memory_operand" "m,m"))
17746    (use (match_operand:HI 3 "memory_operand" "m,m"))
17747    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
17748    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17749   "TARGET_USE_FANCY_MATH_387
17750    && flag_unsafe_math_optimizations"
17751   "#"
17752   [(set_attr "type" "fistp")
17753    (set_attr "i387_cw" "floor")
17754    (set_attr "mode" "DI")])
17755
17756 (define_split
17757   [(set (match_operand:DI 0 "register_operand" "")
17758         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17759          UNSPEC_FIST_FLOOR))
17760    (use (match_operand:HI 2 "memory_operand" ""))
17761    (use (match_operand:HI 3 "memory_operand" ""))
17762    (clobber (match_operand:DI 4 "memory_operand" ""))
17763    (clobber (match_scratch 5 ""))]
17764   "reload_completed"
17765   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17766               (use (match_dup 2))
17767               (use (match_dup 3))
17768               (clobber (match_dup 5))])
17769    (set (match_dup 0) (match_dup 4))]
17770   "")
17771
17772 (define_split
17773   [(set (match_operand:DI 0 "memory_operand" "")
17774         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17775          UNSPEC_FIST_FLOOR))
17776    (use (match_operand:HI 2 "memory_operand" ""))
17777    (use (match_operand:HI 3 "memory_operand" ""))
17778    (clobber (match_operand:DI 4 "memory_operand" ""))
17779    (clobber (match_scratch 5 ""))]
17780   "reload_completed"
17781   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17782               (use (match_dup 2))
17783               (use (match_dup 3))
17784               (clobber (match_dup 5))])]
17785   "")
17786
17787 (define_insn "fist<mode>2_floor"
17788   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17789         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17790          UNSPEC_FIST_FLOOR))
17791    (use (match_operand:HI 2 "memory_operand" "m"))
17792    (use (match_operand:HI 3 "memory_operand" "m"))]
17793   "TARGET_USE_FANCY_MATH_387
17794    && flag_unsafe_math_optimizations"
17795   "* return output_fix_trunc (insn, operands, 0);"
17796   [(set_attr "type" "fistp")
17797    (set_attr "i387_cw" "floor")
17798    (set_attr "mode" "<MODE>")])
17799
17800 (define_insn "fist<mode>2_floor_with_temp"
17801   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17802         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17803          UNSPEC_FIST_FLOOR))
17804    (use (match_operand:HI 2 "memory_operand" "m,m"))
17805    (use (match_operand:HI 3 "memory_operand" "m,m"))
17806    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
17807   "TARGET_USE_FANCY_MATH_387
17808    && flag_unsafe_math_optimizations"
17809   "#"
17810   [(set_attr "type" "fistp")
17811    (set_attr "i387_cw" "floor")
17812    (set_attr "mode" "<MODE>")])
17813
17814 (define_split
17815   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17816         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17817          UNSPEC_FIST_FLOOR))
17818    (use (match_operand:HI 2 "memory_operand" ""))
17819    (use (match_operand:HI 3 "memory_operand" ""))
17820    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17821   "reload_completed"
17822   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17823                                   UNSPEC_FIST_FLOOR))
17824               (use (match_dup 2))
17825               (use (match_dup 3))])
17826    (set (match_dup 0) (match_dup 4))]
17827   "")
17828
17829 (define_split
17830   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17831         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17832          UNSPEC_FIST_FLOOR))
17833    (use (match_operand:HI 2 "memory_operand" ""))
17834    (use (match_operand:HI 3 "memory_operand" ""))
17835    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17836   "reload_completed"
17837   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17838                                   UNSPEC_FIST_FLOOR))
17839               (use (match_dup 2))
17840               (use (match_dup 3))])]
17841   "")
17842
17843 (define_expand "lfloorxf<mode>2"
17844   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17845                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17846                     UNSPEC_FIST_FLOOR))
17847               (clobber (reg:CC FLAGS_REG))])]
17848   "TARGET_USE_FANCY_MATH_387
17849    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17850    && flag_unsafe_math_optimizations"
17851   "")
17852
17853 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
17854   [(match_operand:SWI48 0 "nonimmediate_operand" "")
17855    (match_operand:MODEF 1 "register_operand" "")]
17856   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17857    && !flag_trapping_math"
17858 {
17859   if (TARGET_64BIT && optimize_insn_for_size_p ())
17860     FAIL;
17861   ix86_expand_lfloorceil (operand0, operand1, true);
17862   DONE;
17863 })
17864
17865 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17866 (define_insn_and_split "frndintxf2_ceil"
17867   [(set (match_operand:XF 0 "register_operand" "")
17868         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17869          UNSPEC_FRNDINT_CEIL))
17870    (clobber (reg:CC FLAGS_REG))]
17871   "TARGET_USE_FANCY_MATH_387
17872    && flag_unsafe_math_optimizations
17873    && can_create_pseudo_p ()"
17874   "#"
17875   "&& 1"
17876   [(const_int 0)]
17877 {
17878   ix86_optimize_mode_switching[I387_CEIL] = 1;
17879
17880   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17881   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17882
17883   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17884                                        operands[2], operands[3]));
17885   DONE;
17886 }
17887   [(set_attr "type" "frndint")
17888    (set_attr "i387_cw" "ceil")
17889    (set_attr "mode" "XF")])
17890
17891 (define_insn "frndintxf2_ceil_i387"
17892   [(set (match_operand:XF 0 "register_operand" "=f")
17893         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17894          UNSPEC_FRNDINT_CEIL))
17895    (use (match_operand:HI 2 "memory_operand" "m"))
17896    (use (match_operand:HI 3 "memory_operand" "m"))]
17897   "TARGET_USE_FANCY_MATH_387
17898    && flag_unsafe_math_optimizations"
17899   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17900   [(set_attr "type" "frndint")
17901    (set_attr "i387_cw" "ceil")
17902    (set_attr "mode" "XF")])
17903
17904 (define_expand "ceilxf2"
17905   [(use (match_operand:XF 0 "register_operand" ""))
17906    (use (match_operand:XF 1 "register_operand" ""))]
17907   "TARGET_USE_FANCY_MATH_387
17908    && flag_unsafe_math_optimizations"
17909 {
17910   if (optimize_insn_for_size_p ())
17911     FAIL;
17912   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17913   DONE;
17914 })
17915
17916 (define_expand "ceil<mode>2"
17917   [(use (match_operand:MODEF 0 "register_operand" ""))
17918    (use (match_operand:MODEF 1 "register_operand" ""))]
17919   "(TARGET_USE_FANCY_MATH_387
17920     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17921         || TARGET_MIX_SSE_I387)
17922     && flag_unsafe_math_optimizations)
17923    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17924        && !flag_trapping_math)"
17925 {
17926   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17927       && !flag_trapping_math
17928       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
17929     {
17930       if (TARGET_ROUND)
17931         emit_insn (gen_sse4_1_round<mode>2
17932                    (operands[0], operands[1], GEN_INT (0x02)));
17933       else if (optimize_insn_for_size_p ())
17934         FAIL;
17935       else if (TARGET_64BIT || (<MODE>mode != DFmode))
17936         ix86_expand_floorceil (operand0, operand1, false);
17937       else
17938         ix86_expand_floorceildf_32 (operand0, operand1, false);
17939     }
17940   else
17941     {
17942       rtx op0, op1;
17943
17944       if (optimize_insn_for_size_p ())
17945         FAIL;
17946
17947       op0 = gen_reg_rtx (XFmode);
17948       op1 = gen_reg_rtx (XFmode);
17949       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17950       emit_insn (gen_frndintxf2_ceil (op0, op1));
17951
17952       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17953     }
17954   DONE;
17955 })
17956
17957 (define_insn_and_split "*fist<mode>2_ceil_1"
17958   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17959         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17960          UNSPEC_FIST_CEIL))
17961    (clobber (reg:CC FLAGS_REG))]
17962   "TARGET_USE_FANCY_MATH_387
17963    && flag_unsafe_math_optimizations
17964    && can_create_pseudo_p ()"
17965   "#"
17966   "&& 1"
17967   [(const_int 0)]
17968 {
17969   ix86_optimize_mode_switching[I387_CEIL] = 1;
17970
17971   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17972   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17973   if (memory_operand (operands[0], VOIDmode))
17974     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17975                                      operands[2], operands[3]));
17976   else
17977     {
17978       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17979       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17980                                                  operands[2], operands[3],
17981                                                  operands[4]));
17982     }
17983   DONE;
17984 }
17985   [(set_attr "type" "fistp")
17986    (set_attr "i387_cw" "ceil")
17987    (set_attr "mode" "<MODE>")])
17988
17989 (define_insn "fistdi2_ceil"
17990   [(set (match_operand:DI 0 "memory_operand" "=m")
17991         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17992          UNSPEC_FIST_CEIL))
17993    (use (match_operand:HI 2 "memory_operand" "m"))
17994    (use (match_operand:HI 3 "memory_operand" "m"))
17995    (clobber (match_scratch:XF 4 "=&1f"))]
17996   "TARGET_USE_FANCY_MATH_387
17997    && flag_unsafe_math_optimizations"
17998   "* return output_fix_trunc (insn, operands, 0);"
17999   [(set_attr "type" "fistp")
18000    (set_attr "i387_cw" "ceil")
18001    (set_attr "mode" "DI")])
18002
18003 (define_insn "fistdi2_ceil_with_temp"
18004   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18005         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18006          UNSPEC_FIST_CEIL))
18007    (use (match_operand:HI 2 "memory_operand" "m,m"))
18008    (use (match_operand:HI 3 "memory_operand" "m,m"))
18009    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
18010    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18011   "TARGET_USE_FANCY_MATH_387
18012    && flag_unsafe_math_optimizations"
18013   "#"
18014   [(set_attr "type" "fistp")
18015    (set_attr "i387_cw" "ceil")
18016    (set_attr "mode" "DI")])
18017
18018 (define_split
18019   [(set (match_operand:DI 0 "register_operand" "")
18020         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18021          UNSPEC_FIST_CEIL))
18022    (use (match_operand:HI 2 "memory_operand" ""))
18023    (use (match_operand:HI 3 "memory_operand" ""))
18024    (clobber (match_operand:DI 4 "memory_operand" ""))
18025    (clobber (match_scratch 5 ""))]
18026   "reload_completed"
18027   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18028               (use (match_dup 2))
18029               (use (match_dup 3))
18030               (clobber (match_dup 5))])
18031    (set (match_dup 0) (match_dup 4))]
18032   "")
18033
18034 (define_split
18035   [(set (match_operand:DI 0 "memory_operand" "")
18036         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18037          UNSPEC_FIST_CEIL))
18038    (use (match_operand:HI 2 "memory_operand" ""))
18039    (use (match_operand:HI 3 "memory_operand" ""))
18040    (clobber (match_operand:DI 4 "memory_operand" ""))
18041    (clobber (match_scratch 5 ""))]
18042   "reload_completed"
18043   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18044               (use (match_dup 2))
18045               (use (match_dup 3))
18046               (clobber (match_dup 5))])]
18047   "")
18048
18049 (define_insn "fist<mode>2_ceil"
18050   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18051         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18052          UNSPEC_FIST_CEIL))
18053    (use (match_operand:HI 2 "memory_operand" "m"))
18054    (use (match_operand:HI 3 "memory_operand" "m"))]
18055   "TARGET_USE_FANCY_MATH_387
18056    && flag_unsafe_math_optimizations"
18057   "* return output_fix_trunc (insn, operands, 0);"
18058   [(set_attr "type" "fistp")
18059    (set_attr "i387_cw" "ceil")
18060    (set_attr "mode" "<MODE>")])
18061
18062 (define_insn "fist<mode>2_ceil_with_temp"
18063   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18064         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18065          UNSPEC_FIST_CEIL))
18066    (use (match_operand:HI 2 "memory_operand" "m,m"))
18067    (use (match_operand:HI 3 "memory_operand" "m,m"))
18068    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
18069   "TARGET_USE_FANCY_MATH_387
18070    && flag_unsafe_math_optimizations"
18071   "#"
18072   [(set_attr "type" "fistp")
18073    (set_attr "i387_cw" "ceil")
18074    (set_attr "mode" "<MODE>")])
18075
18076 (define_split
18077   [(set (match_operand:X87MODEI12 0 "register_operand" "")
18078         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18079          UNSPEC_FIST_CEIL))
18080    (use (match_operand:HI 2 "memory_operand" ""))
18081    (use (match_operand:HI 3 "memory_operand" ""))
18082    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18083   "reload_completed"
18084   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18085                                   UNSPEC_FIST_CEIL))
18086               (use (match_dup 2))
18087               (use (match_dup 3))])
18088    (set (match_dup 0) (match_dup 4))]
18089   "")
18090
18091 (define_split
18092   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18093         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18094          UNSPEC_FIST_CEIL))
18095    (use (match_operand:HI 2 "memory_operand" ""))
18096    (use (match_operand:HI 3 "memory_operand" ""))
18097    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18098   "reload_completed"
18099   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18100                                   UNSPEC_FIST_CEIL))
18101               (use (match_dup 2))
18102               (use (match_dup 3))])]
18103   "")
18104
18105 (define_expand "lceilxf<mode>2"
18106   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18107                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18108                     UNSPEC_FIST_CEIL))
18109               (clobber (reg:CC FLAGS_REG))])]
18110   "TARGET_USE_FANCY_MATH_387
18111    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18112    && flag_unsafe_math_optimizations"
18113   "")
18114
18115 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
18116   [(match_operand:SWI48 0 "nonimmediate_operand" "")
18117    (match_operand:MODEF 1 "register_operand" "")]
18118   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
18119    && !flag_trapping_math"
18120 {
18121   ix86_expand_lfloorceil (operand0, operand1, false);
18122   DONE;
18123 })
18124
18125 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18126 (define_insn_and_split "frndintxf2_trunc"
18127   [(set (match_operand:XF 0 "register_operand" "")
18128         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18129          UNSPEC_FRNDINT_TRUNC))
18130    (clobber (reg:CC FLAGS_REG))]
18131   "TARGET_USE_FANCY_MATH_387
18132    && flag_unsafe_math_optimizations
18133    && can_create_pseudo_p ()"
18134   "#"
18135   "&& 1"
18136   [(const_int 0)]
18137 {
18138   ix86_optimize_mode_switching[I387_TRUNC] = 1;
18139
18140   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18141   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
18142
18143   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
18144                                         operands[2], operands[3]));
18145   DONE;
18146 }
18147   [(set_attr "type" "frndint")
18148    (set_attr "i387_cw" "trunc")
18149    (set_attr "mode" "XF")])
18150
18151 (define_insn "frndintxf2_trunc_i387"
18152   [(set (match_operand:XF 0 "register_operand" "=f")
18153         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18154          UNSPEC_FRNDINT_TRUNC))
18155    (use (match_operand:HI 2 "memory_operand" "m"))
18156    (use (match_operand:HI 3 "memory_operand" "m"))]
18157   "TARGET_USE_FANCY_MATH_387
18158    && flag_unsafe_math_optimizations"
18159   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18160   [(set_attr "type" "frndint")
18161    (set_attr "i387_cw" "trunc")
18162    (set_attr "mode" "XF")])
18163
18164 (define_expand "btruncxf2"
18165   [(use (match_operand:XF 0 "register_operand" ""))
18166    (use (match_operand:XF 1 "register_operand" ""))]
18167   "TARGET_USE_FANCY_MATH_387
18168    && flag_unsafe_math_optimizations"
18169 {
18170   if (optimize_insn_for_size_p ())
18171     FAIL;
18172   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
18173   DONE;
18174 })
18175
18176 (define_expand "btrunc<mode>2"
18177   [(use (match_operand:MODEF 0 "register_operand" ""))
18178    (use (match_operand:MODEF 1 "register_operand" ""))]
18179   "(TARGET_USE_FANCY_MATH_387
18180     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18181         || TARGET_MIX_SSE_I387)
18182     && flag_unsafe_math_optimizations)
18183    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18184        && !flag_trapping_math)"
18185 {
18186   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18187       && !flag_trapping_math
18188       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
18189     {
18190       if (TARGET_ROUND)
18191         emit_insn (gen_sse4_1_round<mode>2
18192                    (operands[0], operands[1], GEN_INT (0x03)));
18193       else if (optimize_insn_for_size_p ())
18194         FAIL;
18195       else if (TARGET_64BIT || (<MODE>mode != DFmode))
18196         ix86_expand_trunc (operand0, operand1);
18197       else
18198         ix86_expand_truncdf_32 (operand0, operand1);
18199     }
18200   else
18201     {
18202       rtx op0, op1;
18203
18204       if (optimize_insn_for_size_p ())
18205         FAIL;
18206
18207       op0 = gen_reg_rtx (XFmode);
18208       op1 = gen_reg_rtx (XFmode);
18209       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18210       emit_insn (gen_frndintxf2_trunc (op0, op1));
18211
18212       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18213     }
18214   DONE;
18215 })
18216
18217 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18218 (define_insn_and_split "frndintxf2_mask_pm"
18219   [(set (match_operand:XF 0 "register_operand" "")
18220         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18221          UNSPEC_FRNDINT_MASK_PM))
18222    (clobber (reg:CC FLAGS_REG))]
18223   "TARGET_USE_FANCY_MATH_387
18224    && flag_unsafe_math_optimizations
18225    && can_create_pseudo_p ()"
18226   "#"
18227   "&& 1"
18228   [(const_int 0)]
18229 {
18230   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
18231
18232   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18233   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18234
18235   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18236                                           operands[2], operands[3]));
18237   DONE;
18238 }
18239   [(set_attr "type" "frndint")
18240    (set_attr "i387_cw" "mask_pm")
18241    (set_attr "mode" "XF")])
18242
18243 (define_insn "frndintxf2_mask_pm_i387"
18244   [(set (match_operand:XF 0 "register_operand" "=f")
18245         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18246          UNSPEC_FRNDINT_MASK_PM))
18247    (use (match_operand:HI 2 "memory_operand" "m"))
18248    (use (match_operand:HI 3 "memory_operand" "m"))]
18249   "TARGET_USE_FANCY_MATH_387
18250    && flag_unsafe_math_optimizations"
18251   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18252   [(set_attr "type" "frndint")
18253    (set_attr "i387_cw" "mask_pm")
18254    (set_attr "mode" "XF")])
18255
18256 (define_expand "nearbyintxf2"
18257   [(use (match_operand:XF 0 "register_operand" ""))
18258    (use (match_operand:XF 1 "register_operand" ""))]
18259   "TARGET_USE_FANCY_MATH_387
18260    && flag_unsafe_math_optimizations"
18261 {
18262   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18263
18264   DONE;
18265 })
18266
18267 (define_expand "nearbyint<mode>2"
18268   [(use (match_operand:MODEF 0 "register_operand" ""))
18269    (use (match_operand:MODEF 1 "register_operand" ""))]
18270   "TARGET_USE_FANCY_MATH_387
18271    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18272        || TARGET_MIX_SSE_I387)
18273    && flag_unsafe_math_optimizations"
18274 {
18275   rtx op0 = gen_reg_rtx (XFmode);
18276   rtx op1 = gen_reg_rtx (XFmode);
18277
18278   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18279   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18280
18281   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18282   DONE;
18283 })
18284
18285 (define_insn "fxam<mode>2_i387"
18286   [(set (match_operand:HI 0 "register_operand" "=a")
18287         (unspec:HI
18288           [(match_operand:X87MODEF 1 "register_operand" "f")]
18289           UNSPEC_FXAM))]
18290   "TARGET_USE_FANCY_MATH_387"
18291   "fxam\n\tfnstsw\t%0"
18292   [(set_attr "type" "multi")
18293    (set_attr "length" "4")
18294    (set_attr "unit" "i387")
18295    (set_attr "mode" "<MODE>")])
18296
18297 (define_insn_and_split "fxam<mode>2_i387_with_temp"
18298   [(set (match_operand:HI 0 "register_operand" "")
18299         (unspec:HI
18300           [(match_operand:MODEF 1 "memory_operand" "")]
18301           UNSPEC_FXAM_MEM))]
18302   "TARGET_USE_FANCY_MATH_387
18303    && can_create_pseudo_p ()"
18304   "#"
18305   "&& 1"
18306   [(set (match_dup 2)(match_dup 1))
18307    (set (match_dup 0)
18308         (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
18309 {
18310   operands[2] = gen_reg_rtx (<MODE>mode);
18311
18312   MEM_VOLATILE_P (operands[1]) = 1;
18313 }
18314   [(set_attr "type" "multi")
18315    (set_attr "unit" "i387")
18316    (set_attr "mode" "<MODE>")])
18317
18318 (define_expand "isinfxf2"
18319   [(use (match_operand:SI 0 "register_operand" ""))
18320    (use (match_operand:XF 1 "register_operand" ""))]
18321   "TARGET_USE_FANCY_MATH_387
18322    && TARGET_C99_FUNCTIONS"
18323 {
18324   rtx mask = GEN_INT (0x45);
18325   rtx val = GEN_INT (0x05);
18326
18327   rtx cond;
18328
18329   rtx scratch = gen_reg_rtx (HImode);
18330   rtx res = gen_reg_rtx (QImode);
18331
18332   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
18333
18334   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18335   emit_insn (gen_cmpqi_ext_3 (scratch, val));
18336   cond = gen_rtx_fmt_ee (EQ, QImode,
18337                          gen_rtx_REG (CCmode, FLAGS_REG),
18338                          const0_rtx);
18339   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18340   emit_insn (gen_zero_extendqisi2 (operands[0], res));
18341   DONE;
18342 })
18343
18344 (define_expand "isinf<mode>2"
18345   [(use (match_operand:SI 0 "register_operand" ""))
18346    (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
18347   "TARGET_USE_FANCY_MATH_387
18348    && TARGET_C99_FUNCTIONS
18349    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18350 {
18351   rtx mask = GEN_INT (0x45);
18352   rtx val = GEN_INT (0x05);
18353
18354   rtx cond;
18355
18356   rtx scratch = gen_reg_rtx (HImode);
18357   rtx res = gen_reg_rtx (QImode);
18358
18359   /* Remove excess precision by forcing value through memory. */
18360   if (memory_operand (operands[1], VOIDmode))
18361     emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
18362   else
18363     {
18364       enum ix86_stack_slot slot = (virtuals_instantiated
18365                                    ? SLOT_TEMP
18366                                    : SLOT_VIRTUAL);
18367       rtx temp = assign_386_stack_local (<MODE>mode, slot);
18368
18369       emit_move_insn (temp, operands[1]);
18370       emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
18371     }
18372
18373   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18374   emit_insn (gen_cmpqi_ext_3 (scratch, val));
18375   cond = gen_rtx_fmt_ee (EQ, QImode,
18376                          gen_rtx_REG (CCmode, FLAGS_REG),
18377                          const0_rtx);
18378   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18379   emit_insn (gen_zero_extendqisi2 (operands[0], res));
18380   DONE;
18381 })
18382
18383 (define_expand "signbit<mode>2"
18384   [(use (match_operand:SI 0 "register_operand" ""))
18385    (use (match_operand:X87MODEF 1 "register_operand" ""))]
18386   "TARGET_USE_FANCY_MATH_387
18387    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18388 {
18389   rtx mask = GEN_INT (0x0200);
18390
18391   rtx scratch = gen_reg_rtx (HImode);
18392
18393   emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18394   emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
18395   DONE;
18396 })
18397 \f
18398 ;; Block operation instructions
18399
18400 (define_insn "cld"
18401   [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
18402   ""
18403   "cld"
18404   [(set_attr "length" "1")
18405    (set_attr "length_immediate" "0")
18406    (set_attr "modrm" "0")])
18407
18408 (define_expand "movmemsi"
18409   [(use (match_operand:BLK 0 "memory_operand" ""))
18410    (use (match_operand:BLK 1 "memory_operand" ""))
18411    (use (match_operand:SI 2 "nonmemory_operand" ""))
18412    (use (match_operand:SI 3 "const_int_operand" ""))
18413    (use (match_operand:SI 4 "const_int_operand" ""))
18414    (use (match_operand:SI 5 "const_int_operand" ""))]
18415   ""
18416 {
18417  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18418                          operands[4], operands[5]))
18419    DONE;
18420  else
18421    FAIL;
18422 })
18423
18424 (define_expand "movmemdi"
18425   [(use (match_operand:BLK 0 "memory_operand" ""))
18426    (use (match_operand:BLK 1 "memory_operand" ""))
18427    (use (match_operand:DI 2 "nonmemory_operand" ""))
18428    (use (match_operand:DI 3 "const_int_operand" ""))
18429    (use (match_operand:SI 4 "const_int_operand" ""))
18430    (use (match_operand:SI 5 "const_int_operand" ""))]
18431   "TARGET_64BIT"
18432 {
18433  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18434                          operands[4], operands[5]))
18435    DONE;
18436  else
18437    FAIL;
18438 })
18439
18440 ;; Most CPUs don't like single string operations
18441 ;; Handle this case here to simplify previous expander.
18442
18443 (define_expand "strmov"
18444   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18445    (set (match_operand 1 "memory_operand" "") (match_dup 4))
18446    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18447               (clobber (reg:CC FLAGS_REG))])
18448    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18449               (clobber (reg:CC FLAGS_REG))])]
18450   ""
18451 {
18452   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18453
18454   /* If .md ever supports :P for Pmode, these can be directly
18455      in the pattern above.  */
18456   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18457   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18458
18459   /* Can't use this if the user has appropriated esi or edi.  */
18460   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
18461       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
18462     {
18463       emit_insn (gen_strmov_singleop (operands[0], operands[1],
18464                                       operands[2], operands[3],
18465                                       operands[5], operands[6]));
18466       DONE;
18467     }
18468
18469   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18470 })
18471
18472 (define_expand "strmov_singleop"
18473   [(parallel [(set (match_operand 1 "memory_operand" "")
18474                    (match_operand 3 "memory_operand" ""))
18475               (set (match_operand 0 "register_operand" "")
18476                    (match_operand 4 "" ""))
18477               (set (match_operand 2 "register_operand" "")
18478                    (match_operand 5 "" ""))])]
18479   ""
18480   "ix86_current_function_needs_cld = 1;")
18481
18482 (define_insn "*strmovdi_rex_1"
18483   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18484         (mem:DI (match_operand:DI 3 "register_operand" "1")))
18485    (set (match_operand:DI 0 "register_operand" "=D")
18486         (plus:DI (match_dup 2)
18487                  (const_int 8)))
18488    (set (match_operand:DI 1 "register_operand" "=S")
18489         (plus:DI (match_dup 3)
18490                  (const_int 8)))]
18491   "TARGET_64BIT"
18492   "movsq"
18493   [(set_attr "type" "str")
18494    (set_attr "mode" "DI")
18495    (set_attr "memory" "both")])
18496
18497 (define_insn "*strmovsi_1"
18498   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18499         (mem:SI (match_operand:SI 3 "register_operand" "1")))
18500    (set (match_operand:SI 0 "register_operand" "=D")
18501         (plus:SI (match_dup 2)
18502                  (const_int 4)))
18503    (set (match_operand:SI 1 "register_operand" "=S")
18504         (plus:SI (match_dup 3)
18505                  (const_int 4)))]
18506   "!TARGET_64BIT"
18507   "movs{l|d}"
18508   [(set_attr "type" "str")
18509    (set_attr "mode" "SI")
18510    (set_attr "memory" "both")])
18511
18512 (define_insn "*strmovsi_rex_1"
18513   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18514         (mem:SI (match_operand:DI 3 "register_operand" "1")))
18515    (set (match_operand:DI 0 "register_operand" "=D")
18516         (plus:DI (match_dup 2)
18517                  (const_int 4)))
18518    (set (match_operand:DI 1 "register_operand" "=S")
18519         (plus:DI (match_dup 3)
18520                  (const_int 4)))]
18521   "TARGET_64BIT"
18522   "movs{l|d}"
18523   [(set_attr "type" "str")
18524    (set_attr "mode" "SI")
18525    (set_attr "memory" "both")])
18526
18527 (define_insn "*strmovhi_1"
18528   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18529         (mem:HI (match_operand:SI 3 "register_operand" "1")))
18530    (set (match_operand:SI 0 "register_operand" "=D")
18531         (plus:SI (match_dup 2)
18532                  (const_int 2)))
18533    (set (match_operand:SI 1 "register_operand" "=S")
18534         (plus:SI (match_dup 3)
18535                  (const_int 2)))]
18536   "!TARGET_64BIT"
18537   "movsw"
18538   [(set_attr "type" "str")
18539    (set_attr "memory" "both")
18540    (set_attr "mode" "HI")])
18541
18542 (define_insn "*strmovhi_rex_1"
18543   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18544         (mem:HI (match_operand:DI 3 "register_operand" "1")))
18545    (set (match_operand:DI 0 "register_operand" "=D")
18546         (plus:DI (match_dup 2)
18547                  (const_int 2)))
18548    (set (match_operand:DI 1 "register_operand" "=S")
18549         (plus:DI (match_dup 3)
18550                  (const_int 2)))]
18551   "TARGET_64BIT"
18552   "movsw"
18553   [(set_attr "type" "str")
18554    (set_attr "memory" "both")
18555    (set_attr "mode" "HI")])
18556
18557 (define_insn "*strmovqi_1"
18558   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18559         (mem:QI (match_operand:SI 3 "register_operand" "1")))
18560    (set (match_operand:SI 0 "register_operand" "=D")
18561         (plus:SI (match_dup 2)
18562                  (const_int 1)))
18563    (set (match_operand:SI 1 "register_operand" "=S")
18564         (plus:SI (match_dup 3)
18565                  (const_int 1)))]
18566   "!TARGET_64BIT"
18567   "movsb"
18568   [(set_attr "type" "str")
18569    (set_attr "memory" "both")
18570    (set_attr "mode" "QI")])
18571
18572 (define_insn "*strmovqi_rex_1"
18573   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18574         (mem:QI (match_operand:DI 3 "register_operand" "1")))
18575    (set (match_operand:DI 0 "register_operand" "=D")
18576         (plus:DI (match_dup 2)
18577                  (const_int 1)))
18578    (set (match_operand:DI 1 "register_operand" "=S")
18579         (plus:DI (match_dup 3)
18580                  (const_int 1)))]
18581   "TARGET_64BIT"
18582   "movsb"
18583   [(set_attr "type" "str")
18584    (set_attr "memory" "both")
18585    (set_attr "prefix_rex" "0")
18586    (set_attr "mode" "QI")])
18587
18588 (define_expand "rep_mov"
18589   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18590               (set (match_operand 0 "register_operand" "")
18591                    (match_operand 5 "" ""))
18592               (set (match_operand 2 "register_operand" "")
18593                    (match_operand 6 "" ""))
18594               (set (match_operand 1 "memory_operand" "")
18595                    (match_operand 3 "memory_operand" ""))
18596               (use (match_dup 4))])]
18597   ""
18598   "ix86_current_function_needs_cld = 1;")
18599
18600 (define_insn "*rep_movdi_rex64"
18601   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18602    (set (match_operand:DI 0 "register_operand" "=D")
18603         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18604                             (const_int 3))
18605                  (match_operand:DI 3 "register_operand" "0")))
18606    (set (match_operand:DI 1 "register_operand" "=S")
18607         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18608                  (match_operand:DI 4 "register_operand" "1")))
18609    (set (mem:BLK (match_dup 3))
18610         (mem:BLK (match_dup 4)))
18611    (use (match_dup 5))]
18612   "TARGET_64BIT"
18613   "rep movsq"
18614   [(set_attr "type" "str")
18615    (set_attr "prefix_rep" "1")
18616    (set_attr "memory" "both")
18617    (set_attr "mode" "DI")])
18618
18619 (define_insn "*rep_movsi"
18620   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18621    (set (match_operand:SI 0 "register_operand" "=D")
18622         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18623                             (const_int 2))
18624                  (match_operand:SI 3 "register_operand" "0")))
18625    (set (match_operand:SI 1 "register_operand" "=S")
18626         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18627                  (match_operand:SI 4 "register_operand" "1")))
18628    (set (mem:BLK (match_dup 3))
18629         (mem:BLK (match_dup 4)))
18630    (use (match_dup 5))]
18631   "!TARGET_64BIT"
18632   "rep movs{l|d}"
18633   [(set_attr "type" "str")
18634    (set_attr "prefix_rep" "1")
18635    (set_attr "memory" "both")
18636    (set_attr "mode" "SI")])
18637
18638 (define_insn "*rep_movsi_rex64"
18639   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18640    (set (match_operand:DI 0 "register_operand" "=D")
18641         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18642                             (const_int 2))
18643                  (match_operand:DI 3 "register_operand" "0")))
18644    (set (match_operand:DI 1 "register_operand" "=S")
18645         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18646                  (match_operand:DI 4 "register_operand" "1")))
18647    (set (mem:BLK (match_dup 3))
18648         (mem:BLK (match_dup 4)))
18649    (use (match_dup 5))]
18650   "TARGET_64BIT"
18651   "rep movs{l|d}"
18652   [(set_attr "type" "str")
18653    (set_attr "prefix_rep" "1")
18654    (set_attr "memory" "both")
18655    (set_attr "mode" "SI")])
18656
18657 (define_insn "*rep_movqi"
18658   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18659    (set (match_operand:SI 0 "register_operand" "=D")
18660         (plus:SI (match_operand:SI 3 "register_operand" "0")
18661                  (match_operand:SI 5 "register_operand" "2")))
18662    (set (match_operand:SI 1 "register_operand" "=S")
18663         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18664    (set (mem:BLK (match_dup 3))
18665         (mem:BLK (match_dup 4)))
18666    (use (match_dup 5))]
18667   "!TARGET_64BIT"
18668   "rep movsb"
18669   [(set_attr "type" "str")
18670    (set_attr "prefix_rep" "1")
18671    (set_attr "memory" "both")
18672    (set_attr "mode" "SI")])
18673
18674 (define_insn "*rep_movqi_rex64"
18675   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18676    (set (match_operand:DI 0 "register_operand" "=D")
18677         (plus:DI (match_operand:DI 3 "register_operand" "0")
18678                  (match_operand:DI 5 "register_operand" "2")))
18679    (set (match_operand:DI 1 "register_operand" "=S")
18680         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18681    (set (mem:BLK (match_dup 3))
18682         (mem:BLK (match_dup 4)))
18683    (use (match_dup 5))]
18684   "TARGET_64BIT"
18685   "rep movsb"
18686   [(set_attr "type" "str")
18687    (set_attr "prefix_rep" "1")
18688    (set_attr "memory" "both")
18689    (set_attr "mode" "SI")])
18690
18691 (define_expand "setmemsi"
18692    [(use (match_operand:BLK 0 "memory_operand" ""))
18693     (use (match_operand:SI 1 "nonmemory_operand" ""))
18694     (use (match_operand 2 "const_int_operand" ""))
18695     (use (match_operand 3 "const_int_operand" ""))
18696     (use (match_operand:SI 4 "const_int_operand" ""))
18697     (use (match_operand:SI 5 "const_int_operand" ""))]
18698   ""
18699 {
18700  if (ix86_expand_setmem (operands[0], operands[1],
18701                          operands[2], operands[3],
18702                          operands[4], operands[5]))
18703    DONE;
18704  else
18705    FAIL;
18706 })
18707
18708 (define_expand "setmemdi"
18709    [(use (match_operand:BLK 0 "memory_operand" ""))
18710     (use (match_operand:DI 1 "nonmemory_operand" ""))
18711     (use (match_operand 2 "const_int_operand" ""))
18712     (use (match_operand 3 "const_int_operand" ""))
18713     (use (match_operand 4 "const_int_operand" ""))
18714     (use (match_operand 5 "const_int_operand" ""))]
18715   "TARGET_64BIT"
18716 {
18717  if (ix86_expand_setmem (operands[0], operands[1],
18718                          operands[2], operands[3],
18719                          operands[4], operands[5]))
18720    DONE;
18721  else
18722    FAIL;
18723 })
18724
18725 ;; Most CPUs don't like single string operations
18726 ;; Handle this case here to simplify previous expander.
18727
18728 (define_expand "strset"
18729   [(set (match_operand 1 "memory_operand" "")
18730         (match_operand 2 "register_operand" ""))
18731    (parallel [(set (match_operand 0 "register_operand" "")
18732                    (match_dup 3))
18733               (clobber (reg:CC FLAGS_REG))])]
18734   ""
18735 {
18736   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18737     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18738
18739   /* If .md ever supports :P for Pmode, this can be directly
18740      in the pattern above.  */
18741   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18742                               GEN_INT (GET_MODE_SIZE (GET_MODE
18743                                                       (operands[2]))));
18744   if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
18745     {
18746       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18747                                       operands[3]));
18748       DONE;
18749     }
18750 })
18751
18752 (define_expand "strset_singleop"
18753   [(parallel [(set (match_operand 1 "memory_operand" "")
18754                    (match_operand 2 "register_operand" ""))
18755               (set (match_operand 0 "register_operand" "")
18756                    (match_operand 3 "" ""))])]
18757   ""
18758   "ix86_current_function_needs_cld = 1;")
18759
18760 (define_insn "*strsetdi_rex_1"
18761   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18762         (match_operand:DI 2 "register_operand" "a"))
18763    (set (match_operand:DI 0 "register_operand" "=D")
18764         (plus:DI (match_dup 1)
18765                  (const_int 8)))]
18766   "TARGET_64BIT"
18767   "stosq"
18768   [(set_attr "type" "str")
18769    (set_attr "memory" "store")
18770    (set_attr "mode" "DI")])
18771
18772 (define_insn "*strsetsi_1"
18773   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18774         (match_operand:SI 2 "register_operand" "a"))
18775    (set (match_operand:SI 0 "register_operand" "=D")
18776         (plus:SI (match_dup 1)
18777                  (const_int 4)))]
18778   "!TARGET_64BIT"
18779   "stos{l|d}"
18780   [(set_attr "type" "str")
18781    (set_attr "memory" "store")
18782    (set_attr "mode" "SI")])
18783
18784 (define_insn "*strsetsi_rex_1"
18785   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18786         (match_operand:SI 2 "register_operand" "a"))
18787    (set (match_operand:DI 0 "register_operand" "=D")
18788         (plus:DI (match_dup 1)
18789                  (const_int 4)))]
18790   "TARGET_64BIT"
18791   "stos{l|d}"
18792   [(set_attr "type" "str")
18793    (set_attr "memory" "store")
18794    (set_attr "mode" "SI")])
18795
18796 (define_insn "*strsethi_1"
18797   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18798         (match_operand:HI 2 "register_operand" "a"))
18799    (set (match_operand:SI 0 "register_operand" "=D")
18800         (plus:SI (match_dup 1)
18801                  (const_int 2)))]
18802   "!TARGET_64BIT"
18803   "stosw"
18804   [(set_attr "type" "str")
18805    (set_attr "memory" "store")
18806    (set_attr "mode" "HI")])
18807
18808 (define_insn "*strsethi_rex_1"
18809   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18810         (match_operand:HI 2 "register_operand" "a"))
18811    (set (match_operand:DI 0 "register_operand" "=D")
18812         (plus:DI (match_dup 1)
18813                  (const_int 2)))]
18814   "TARGET_64BIT"
18815   "stosw"
18816   [(set_attr "type" "str")
18817    (set_attr "memory" "store")
18818    (set_attr "mode" "HI")])
18819
18820 (define_insn "*strsetqi_1"
18821   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18822         (match_operand:QI 2 "register_operand" "a"))
18823    (set (match_operand:SI 0 "register_operand" "=D")
18824         (plus:SI (match_dup 1)
18825                  (const_int 1)))]
18826   "!TARGET_64BIT"
18827   "stosb"
18828   [(set_attr "type" "str")
18829    (set_attr "memory" "store")
18830    (set_attr "mode" "QI")])
18831
18832 (define_insn "*strsetqi_rex_1"
18833   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18834         (match_operand:QI 2 "register_operand" "a"))
18835    (set (match_operand:DI 0 "register_operand" "=D")
18836         (plus:DI (match_dup 1)
18837                  (const_int 1)))]
18838   "TARGET_64BIT"
18839   "stosb"
18840   [(set_attr "type" "str")
18841    (set_attr "memory" "store")
18842    (set_attr "prefix_rex" "0")
18843    (set_attr "mode" "QI")])
18844
18845 (define_expand "rep_stos"
18846   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18847               (set (match_operand 0 "register_operand" "")
18848                    (match_operand 4 "" ""))
18849               (set (match_operand 2 "memory_operand" "") (const_int 0))
18850               (use (match_operand 3 "register_operand" ""))
18851               (use (match_dup 1))])]
18852   ""
18853   "ix86_current_function_needs_cld = 1;")
18854
18855 (define_insn "*rep_stosdi_rex64"
18856   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18857    (set (match_operand:DI 0 "register_operand" "=D")
18858         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18859                             (const_int 3))
18860                  (match_operand:DI 3 "register_operand" "0")))
18861    (set (mem:BLK (match_dup 3))
18862         (const_int 0))
18863    (use (match_operand:DI 2 "register_operand" "a"))
18864    (use (match_dup 4))]
18865   "TARGET_64BIT"
18866   "rep stosq"
18867   [(set_attr "type" "str")
18868    (set_attr "prefix_rep" "1")
18869    (set_attr "memory" "store")
18870    (set_attr "mode" "DI")])
18871
18872 (define_insn "*rep_stossi"
18873   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18874    (set (match_operand:SI 0 "register_operand" "=D")
18875         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18876                             (const_int 2))
18877                  (match_operand:SI 3 "register_operand" "0")))
18878    (set (mem:BLK (match_dup 3))
18879         (const_int 0))
18880    (use (match_operand:SI 2 "register_operand" "a"))
18881    (use (match_dup 4))]
18882   "!TARGET_64BIT"
18883   "rep stos{l|d}"
18884   [(set_attr "type" "str")
18885    (set_attr "prefix_rep" "1")
18886    (set_attr "memory" "store")
18887    (set_attr "mode" "SI")])
18888
18889 (define_insn "*rep_stossi_rex64"
18890   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18891    (set (match_operand:DI 0 "register_operand" "=D")
18892         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18893                             (const_int 2))
18894                  (match_operand:DI 3 "register_operand" "0")))
18895    (set (mem:BLK (match_dup 3))
18896         (const_int 0))
18897    (use (match_operand:SI 2 "register_operand" "a"))
18898    (use (match_dup 4))]
18899   "TARGET_64BIT"
18900   "rep stos{l|d}"
18901   [(set_attr "type" "str")
18902    (set_attr "prefix_rep" "1")
18903    (set_attr "memory" "store")
18904    (set_attr "mode" "SI")])
18905
18906 (define_insn "*rep_stosqi"
18907   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18908    (set (match_operand:SI 0 "register_operand" "=D")
18909         (plus:SI (match_operand:SI 3 "register_operand" "0")
18910                  (match_operand:SI 4 "register_operand" "1")))
18911    (set (mem:BLK (match_dup 3))
18912         (const_int 0))
18913    (use (match_operand:QI 2 "register_operand" "a"))
18914    (use (match_dup 4))]
18915   "!TARGET_64BIT"
18916   "rep stosb"
18917   [(set_attr "type" "str")
18918    (set_attr "prefix_rep" "1")
18919    (set_attr "memory" "store")
18920    (set_attr "mode" "QI")])
18921
18922 (define_insn "*rep_stosqi_rex64"
18923   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18924    (set (match_operand:DI 0 "register_operand" "=D")
18925         (plus:DI (match_operand:DI 3 "register_operand" "0")
18926                  (match_operand:DI 4 "register_operand" "1")))
18927    (set (mem:BLK (match_dup 3))
18928         (const_int 0))
18929    (use (match_operand:QI 2 "register_operand" "a"))
18930    (use (match_dup 4))]
18931   "TARGET_64BIT"
18932   "rep stosb"
18933   [(set_attr "type" "str")
18934    (set_attr "prefix_rep" "1")
18935    (set_attr "memory" "store")
18936    (set_attr "prefix_rex" "0")
18937    (set_attr "mode" "QI")])
18938
18939 (define_expand "cmpstrnsi"
18940   [(set (match_operand:SI 0 "register_operand" "")
18941         (compare:SI (match_operand:BLK 1 "general_operand" "")
18942                     (match_operand:BLK 2 "general_operand" "")))
18943    (use (match_operand 3 "general_operand" ""))
18944    (use (match_operand 4 "immediate_operand" ""))]
18945   ""
18946 {
18947   rtx addr1, addr2, out, outlow, count, countreg, align;
18948
18949   if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
18950     FAIL;
18951
18952   /* Can't use this if the user has appropriated esi or edi.  */
18953   if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
18954     FAIL;
18955
18956   out = operands[0];
18957   if (!REG_P (out))
18958     out = gen_reg_rtx (SImode);
18959
18960   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18961   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18962   if (addr1 != XEXP (operands[1], 0))
18963     operands[1] = replace_equiv_address_nv (operands[1], addr1);
18964   if (addr2 != XEXP (operands[2], 0))
18965     operands[2] = replace_equiv_address_nv (operands[2], addr2);
18966
18967   count = operands[3];
18968   countreg = ix86_zero_extend_to_Pmode (count);
18969
18970   /* %%% Iff we are testing strict equality, we can use known alignment
18971      to good advantage.  This may be possible with combine, particularly
18972      once cc0 is dead.  */
18973   align = operands[4];
18974
18975   if (CONST_INT_P (count))
18976     {
18977       if (INTVAL (count) == 0)
18978         {
18979           emit_move_insn (operands[0], const0_rtx);
18980           DONE;
18981         }
18982       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18983                                      operands[1], operands[2]));
18984     }
18985   else
18986     {
18987       rtx (*cmp_insn)(rtx, rtx);
18988
18989       if (TARGET_64BIT)
18990         cmp_insn = gen_cmpdi_1;
18991       else
18992         cmp_insn = gen_cmpsi_1;
18993       emit_insn (cmp_insn (countreg, countreg));
18994       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18995                                   operands[1], operands[2]));
18996     }
18997
18998   outlow = gen_lowpart (QImode, out);
18999   emit_insn (gen_cmpintqi (outlow));
19000   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
19001
19002   if (operands[0] != out)
19003     emit_move_insn (operands[0], out);
19004
19005   DONE;
19006 })
19007
19008 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
19009
19010 (define_expand "cmpintqi"
19011   [(set (match_dup 1)
19012         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19013    (set (match_dup 2)
19014         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19015    (parallel [(set (match_operand:QI 0 "register_operand" "")
19016                    (minus:QI (match_dup 1)
19017                              (match_dup 2)))
19018               (clobber (reg:CC FLAGS_REG))])]
19019   ""
19020   "operands[1] = gen_reg_rtx (QImode);
19021    operands[2] = gen_reg_rtx (QImode);")
19022
19023 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
19024 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
19025
19026 (define_expand "cmpstrnqi_nz_1"
19027   [(parallel [(set (reg:CC FLAGS_REG)
19028                    (compare:CC (match_operand 4 "memory_operand" "")
19029                                (match_operand 5 "memory_operand" "")))
19030               (use (match_operand 2 "register_operand" ""))
19031               (use (match_operand:SI 3 "immediate_operand" ""))
19032               (clobber (match_operand 0 "register_operand" ""))
19033               (clobber (match_operand 1 "register_operand" ""))
19034               (clobber (match_dup 2))])]
19035   ""
19036   "ix86_current_function_needs_cld = 1;")
19037
19038 (define_insn "*cmpstrnqi_nz_1"
19039   [(set (reg:CC FLAGS_REG)
19040         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19041                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
19042    (use (match_operand:SI 6 "register_operand" "2"))
19043    (use (match_operand:SI 3 "immediate_operand" "i"))
19044    (clobber (match_operand:SI 0 "register_operand" "=S"))
19045    (clobber (match_operand:SI 1 "register_operand" "=D"))
19046    (clobber (match_operand:SI 2 "register_operand" "=c"))]
19047   "!TARGET_64BIT"
19048   "repz cmpsb"
19049   [(set_attr "type" "str")
19050    (set_attr "mode" "QI")
19051    (set_attr "prefix_rep" "1")])
19052
19053 (define_insn "*cmpstrnqi_nz_rex_1"
19054   [(set (reg:CC FLAGS_REG)
19055         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19056                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
19057    (use (match_operand:DI 6 "register_operand" "2"))
19058    (use (match_operand:SI 3 "immediate_operand" "i"))
19059    (clobber (match_operand:DI 0 "register_operand" "=S"))
19060    (clobber (match_operand:DI 1 "register_operand" "=D"))
19061    (clobber (match_operand:DI 2 "register_operand" "=c"))]
19062   "TARGET_64BIT"
19063   "repz cmpsb"
19064   [(set_attr "type" "str")
19065    (set_attr "mode" "QI")
19066    (set_attr "prefix_rex" "0")
19067    (set_attr "prefix_rep" "1")])
19068
19069 ;; The same, but the count is not known to not be zero.
19070
19071 (define_expand "cmpstrnqi_1"
19072   [(parallel [(set (reg:CC FLAGS_REG)
19073                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
19074                                      (const_int 0))
19075                   (compare:CC (match_operand 4 "memory_operand" "")
19076                               (match_operand 5 "memory_operand" ""))
19077                   (const_int 0)))
19078               (use (match_operand:SI 3 "immediate_operand" ""))
19079               (use (reg:CC FLAGS_REG))
19080               (clobber (match_operand 0 "register_operand" ""))
19081               (clobber (match_operand 1 "register_operand" ""))
19082               (clobber (match_dup 2))])]
19083   ""
19084   "ix86_current_function_needs_cld = 1;")
19085
19086 (define_insn "*cmpstrnqi_1"
19087   [(set (reg:CC FLAGS_REG)
19088         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
19089                              (const_int 0))
19090           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19091                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
19092           (const_int 0)))
19093    (use (match_operand:SI 3 "immediate_operand" "i"))
19094    (use (reg:CC FLAGS_REG))
19095    (clobber (match_operand:SI 0 "register_operand" "=S"))
19096    (clobber (match_operand:SI 1 "register_operand" "=D"))
19097    (clobber (match_operand:SI 2 "register_operand" "=c"))]
19098   "!TARGET_64BIT"
19099   "repz cmpsb"
19100   [(set_attr "type" "str")
19101    (set_attr "mode" "QI")
19102    (set_attr "prefix_rep" "1")])
19103
19104 (define_insn "*cmpstrnqi_rex_1"
19105   [(set (reg:CC FLAGS_REG)
19106         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
19107                              (const_int 0))
19108           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19109                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
19110           (const_int 0)))
19111    (use (match_operand:SI 3 "immediate_operand" "i"))
19112    (use (reg:CC FLAGS_REG))
19113    (clobber (match_operand:DI 0 "register_operand" "=S"))
19114    (clobber (match_operand:DI 1 "register_operand" "=D"))
19115    (clobber (match_operand:DI 2 "register_operand" "=c"))]
19116   "TARGET_64BIT"
19117   "repz cmpsb"
19118   [(set_attr "type" "str")
19119    (set_attr "mode" "QI")
19120    (set_attr "prefix_rex" "0")
19121    (set_attr "prefix_rep" "1")])
19122
19123 (define_expand "strlensi"
19124   [(set (match_operand:SI 0 "register_operand" "")
19125         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
19126                     (match_operand:QI 2 "immediate_operand" "")
19127                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19128   ""
19129 {
19130  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19131    DONE;
19132  else
19133    FAIL;
19134 })
19135
19136 (define_expand "strlendi"
19137   [(set (match_operand:DI 0 "register_operand" "")
19138         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
19139                     (match_operand:QI 2 "immediate_operand" "")
19140                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19141   ""
19142 {
19143  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19144    DONE;
19145  else
19146    FAIL;
19147 })
19148
19149 (define_expand "strlenqi_1"
19150   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
19151               (clobber (match_operand 1 "register_operand" ""))
19152               (clobber (reg:CC FLAGS_REG))])]
19153   ""
19154   "ix86_current_function_needs_cld = 1;")
19155
19156 (define_insn "*strlenqi_1"
19157   [(set (match_operand:SI 0 "register_operand" "=&c")
19158         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
19159                     (match_operand:QI 2 "register_operand" "a")
19160                     (match_operand:SI 3 "immediate_operand" "i")
19161                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
19162    (clobber (match_operand:SI 1 "register_operand" "=D"))
19163    (clobber (reg:CC FLAGS_REG))]
19164   "!TARGET_64BIT"
19165   "repnz scasb"
19166   [(set_attr "type" "str")
19167    (set_attr "mode" "QI")
19168    (set_attr "prefix_rep" "1")])
19169
19170 (define_insn "*strlenqi_rex_1"
19171   [(set (match_operand:DI 0 "register_operand" "=&c")
19172         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
19173                     (match_operand:QI 2 "register_operand" "a")
19174                     (match_operand:DI 3 "immediate_operand" "i")
19175                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
19176    (clobber (match_operand:DI 1 "register_operand" "=D"))
19177    (clobber (reg:CC FLAGS_REG))]
19178   "TARGET_64BIT"
19179   "repnz scasb"
19180   [(set_attr "type" "str")
19181    (set_attr "mode" "QI")
19182    (set_attr "prefix_rex" "0")
19183    (set_attr "prefix_rep" "1")])
19184
19185 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
19186 ;; handled in combine, but it is not currently up to the task.
19187 ;; When used for their truth value, the cmpstrn* expanders generate
19188 ;; code like this:
19189 ;;
19190 ;;   repz cmpsb
19191 ;;   seta       %al
19192 ;;   setb       %dl
19193 ;;   cmpb       %al, %dl
19194 ;;   jcc        label
19195 ;;
19196 ;; The intermediate three instructions are unnecessary.
19197
19198 ;; This one handles cmpstrn*_nz_1...
19199 (define_peephole2
19200   [(parallel[
19201      (set (reg:CC FLAGS_REG)
19202           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19203                       (mem:BLK (match_operand 5 "register_operand" ""))))
19204      (use (match_operand 6 "register_operand" ""))
19205      (use (match_operand:SI 3 "immediate_operand" ""))
19206      (clobber (match_operand 0 "register_operand" ""))
19207      (clobber (match_operand 1 "register_operand" ""))
19208      (clobber (match_operand 2 "register_operand" ""))])
19209    (set (match_operand:QI 7 "register_operand" "")
19210         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19211    (set (match_operand:QI 8 "register_operand" "")
19212         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19213    (set (reg FLAGS_REG)
19214         (compare (match_dup 7) (match_dup 8)))
19215   ]
19216   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19217   [(parallel[
19218      (set (reg:CC FLAGS_REG)
19219           (compare:CC (mem:BLK (match_dup 4))
19220                       (mem:BLK (match_dup 5))))
19221      (use (match_dup 6))
19222      (use (match_dup 3))
19223      (clobber (match_dup 0))
19224      (clobber (match_dup 1))
19225      (clobber (match_dup 2))])]
19226   "")
19227
19228 ;; ...and this one handles cmpstrn*_1.
19229 (define_peephole2
19230   [(parallel[
19231      (set (reg:CC FLAGS_REG)
19232           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
19233                                (const_int 0))
19234             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19235                         (mem:BLK (match_operand 5 "register_operand" "")))
19236             (const_int 0)))
19237      (use (match_operand:SI 3 "immediate_operand" ""))
19238      (use (reg:CC FLAGS_REG))
19239      (clobber (match_operand 0 "register_operand" ""))
19240      (clobber (match_operand 1 "register_operand" ""))
19241      (clobber (match_operand 2 "register_operand" ""))])
19242    (set (match_operand:QI 7 "register_operand" "")
19243         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19244    (set (match_operand:QI 8 "register_operand" "")
19245         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19246    (set (reg FLAGS_REG)
19247         (compare (match_dup 7) (match_dup 8)))
19248   ]
19249   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19250   [(parallel[
19251      (set (reg:CC FLAGS_REG)
19252           (if_then_else:CC (ne (match_dup 6)
19253                                (const_int 0))
19254             (compare:CC (mem:BLK (match_dup 4))
19255                         (mem:BLK (match_dup 5)))
19256             (const_int 0)))
19257      (use (match_dup 3))
19258      (use (reg:CC FLAGS_REG))
19259      (clobber (match_dup 0))
19260      (clobber (match_dup 1))
19261      (clobber (match_dup 2))])]
19262   "")
19263
19264
19265 \f
19266 ;; Conditional move instructions.
19267
19268 (define_expand "mov<mode>cc"
19269   [(set (match_operand:SWIM 0 "register_operand" "")
19270         (if_then_else:SWIM (match_operand 1 "comparison_operator" "")
19271                            (match_operand:SWIM 2 "general_operand" "")
19272                            (match_operand:SWIM 3 "general_operand" "")))]
19273   ""
19274   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19275
19276 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19277 ;; the register first winds up with `sbbl $0,reg', which is also weird.
19278 ;; So just document what we're doing explicitly.
19279
19280 (define_insn "x86_mov<mode>cc_0_m1"
19281   [(set (match_operand:SWI48 0 "register_operand" "=r")
19282         (if_then_else:SWI48 (match_operand 1 "ix86_carry_flag_operator" "")
19283           (const_int -1)
19284           (const_int 0)))
19285    (clobber (reg:CC FLAGS_REG))]
19286   ""
19287   "sbb{<imodesuffix>}\t%0, %0"
19288   ; Since we don't have the proper number of operands for an alu insn,
19289   ; fill in all the blanks.
19290   [(set_attr "type" "alu")
19291    (set_attr "use_carry" "1")
19292    (set_attr "pent_pair" "pu")
19293    (set_attr "memory" "none")
19294    (set_attr "imm_disp" "false")
19295    (set_attr "mode" "<MODE>")
19296    (set_attr "length_immediate" "0")])
19297
19298 (define_insn "*x86_mov<mode>cc_0_m1_se"
19299   [(set (match_operand:SWI48 0 "register_operand" "=r")
19300         (sign_extract:SWI48 (match_operand 1 "ix86_carry_flag_operator" "")
19301                             (const_int 1)
19302                             (const_int 0)))
19303    (clobber (reg:CC FLAGS_REG))]
19304   ""
19305   "sbb{<imodesuffix>}\t%0, %0"
19306   [(set_attr "type" "alu")
19307    (set_attr "use_carry" "1")
19308    (set_attr "pent_pair" "pu")
19309    (set_attr "memory" "none")
19310    (set_attr "imm_disp" "false")
19311    (set_attr "mode" "<MODE>")
19312    (set_attr "length_immediate" "0")])
19313
19314 (define_insn "*x86_mov<mode>cc_0_m1_neg"
19315   [(set (match_operand:SWI48 0 "register_operand" "=r")
19316         (neg:SWI48 (match_operand 1 "ix86_carry_flag_operator" "")))]
19317   ""
19318   "sbb{<imodesuffix>}\t%0, %0"
19319   [(set_attr "type" "alu")
19320    (set_attr "use_carry" "1")
19321    (set_attr "pent_pair" "pu")
19322    (set_attr "memory" "none")
19323    (set_attr "imm_disp" "false")
19324    (set_attr "mode" "<MODE>")
19325    (set_attr "length_immediate" "0")])
19326
19327 (define_insn "*mov<mode>cc_noc"
19328   [(set (match_operand:SWI248 0 "register_operand" "=r,r")
19329         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
19330                                [(reg FLAGS_REG) (const_int 0)])
19331           (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
19332           (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
19333   "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19334   "@
19335    cmov%O2%C1\t{%2, %0|%0, %2}
19336    cmov%O2%c1\t{%3, %0|%0, %3}"
19337   [(set_attr "type" "icmov")
19338    (set_attr "mode" "<MODE>")])
19339
19340 (define_insn_and_split "*movqicc_noc"
19341   [(set (match_operand:QI 0 "register_operand" "=r,r")
19342         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
19343                            [(match_operand 4 "flags_reg_operand" "")
19344                             (const_int 0)])
19345                       (match_operand:QI 2 "register_operand" "r,0")
19346                       (match_operand:QI 3 "register_operand" "0,r")))]
19347   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19348   "#"
19349   "&& reload_completed"
19350   [(set (match_dup 0)
19351         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19352                       (match_dup 2)
19353                       (match_dup 3)))]
19354   "operands[0] = gen_lowpart (SImode, operands[0]);
19355    operands[2] = gen_lowpart (SImode, operands[2]);
19356    operands[3] = gen_lowpart (SImode, operands[3]);"
19357   [(set_attr "type" "icmov")
19358    (set_attr "mode" "SI")])
19359
19360 (define_expand "mov<mode>cc"
19361   [(set (match_operand:X87MODEF 0 "register_operand" "")
19362         (if_then_else:X87MODEF
19363           (match_operand 1 "ix86_fp_comparison_operator" "")
19364           (match_operand:X87MODEF 2 "register_operand" "")
19365           (match_operand:X87MODEF 3 "register_operand" "")))]
19366   "(TARGET_80387 && TARGET_CMOVE)
19367    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
19368   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
19369
19370 (define_insn "*movsfcc_1_387"
19371   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19372         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19373                                 [(reg FLAGS_REG) (const_int 0)])
19374                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19375                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19376   "TARGET_80387 && TARGET_CMOVE
19377    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19378   "@
19379    fcmov%F1\t{%2, %0|%0, %2}
19380    fcmov%f1\t{%3, %0|%0, %3}
19381    cmov%O2%C1\t{%2, %0|%0, %2}
19382    cmov%O2%c1\t{%3, %0|%0, %3}"
19383   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19384    (set_attr "mode" "SF,SF,SI,SI")])
19385
19386 (define_insn "*movdfcc_1"
19387   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19388         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19389                                 [(reg FLAGS_REG) (const_int 0)])
19390                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19391                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19392   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19393    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19394   "@
19395    fcmov%F1\t{%2, %0|%0, %2}
19396    fcmov%f1\t{%3, %0|%0, %3}
19397    #
19398    #"
19399   [(set_attr "type" "fcmov,fcmov,multi,multi")
19400    (set_attr "mode" "DF")])
19401
19402 (define_insn "*movdfcc_1_rex64"
19403   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19404         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19405                                 [(reg FLAGS_REG) (const_int 0)])
19406                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19407                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19408   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19409    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19410   "@
19411    fcmov%F1\t{%2, %0|%0, %2}
19412    fcmov%f1\t{%3, %0|%0, %3}
19413    cmov%O2%C1\t{%2, %0|%0, %2}
19414    cmov%O2%c1\t{%3, %0|%0, %3}"
19415   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19416    (set_attr "mode" "DF")])
19417
19418 (define_split
19419   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19420         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19421                                 [(match_operand 4 "flags_reg_operand" "")
19422                                  (const_int 0)])
19423                       (match_operand:DF 2 "nonimmediate_operand" "")
19424                       (match_operand:DF 3 "nonimmediate_operand" "")))]
19425   "!TARGET_64BIT && reload_completed"
19426   [(set (match_dup 2)
19427         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19428                       (match_dup 5)
19429                       (match_dup 6)))
19430    (set (match_dup 3)
19431         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19432                       (match_dup 7)
19433                       (match_dup 8)))]
19434   "split_di (&operands[2], 2, &operands[5], &operands[7]);
19435    split_di (&operands[0], 1, &operands[2], &operands[3]);")
19436
19437 (define_insn "*movxfcc_1"
19438   [(set (match_operand:XF 0 "register_operand" "=f,f")
19439         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19440                                 [(reg FLAGS_REG) (const_int 0)])
19441                       (match_operand:XF 2 "register_operand" "f,0")
19442                       (match_operand:XF 3 "register_operand" "0,f")))]
19443   "TARGET_80387 && TARGET_CMOVE"
19444   "@
19445    fcmov%F1\t{%2, %0|%0, %2}
19446    fcmov%f1\t{%3, %0|%0, %3}"
19447   [(set_attr "type" "fcmov")
19448    (set_attr "mode" "XF")])
19449
19450 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
19451 ;; the scalar versions to have only XMM registers as operands.
19452
19453 ;; XOP conditional move
19454 (define_insn "*xop_pcmov_<mode>"
19455   [(set (match_operand:MODEF 0 "register_operand" "=x")
19456         (if_then_else:MODEF
19457           (match_operand:MODEF 1 "register_operand" "x")
19458           (match_operand:MODEF 2 "register_operand" "x")
19459           (match_operand:MODEF 3 "register_operand" "x")))]
19460   "TARGET_XOP && ix86_fma4_valid_op_p (operands, insn, 4, true, 1, false)"
19461   "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
19462   [(set_attr "type" "sse4arg")])
19463
19464 ;; These versions of the min/max patterns are intentionally ignorant of
19465 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19466 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19467 ;; are undefined in this condition, we're certain this is correct.
19468
19469 (define_insn "*avx_<code><mode>3"
19470   [(set (match_operand:MODEF 0 "register_operand" "=x")
19471         (smaxmin:MODEF
19472           (match_operand:MODEF 1 "nonimmediate_operand" "%x")
19473           (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
19474   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19475   "v<maxminfprefix>s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
19476   [(set_attr "type" "sseadd")
19477    (set_attr "prefix" "vex")
19478    (set_attr "mode" "<MODE>")])
19479
19480 (define_insn "<code><mode>3"
19481   [(set (match_operand:MODEF 0 "register_operand" "=x")
19482         (smaxmin:MODEF
19483           (match_operand:MODEF 1 "nonimmediate_operand" "%0")
19484           (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
19485   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19486   "<maxminfprefix>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
19487   [(set_attr "type" "sseadd")
19488    (set_attr "mode" "<MODE>")])
19489
19490 ;; These versions of the min/max patterns implement exactly the operations
19491 ;;   min = (op1 < op2 ? op1 : op2)
19492 ;;   max = (!(op1 < op2) ? op1 : op2)
19493 ;; Their operands are not commutative, and thus they may be used in the
19494 ;; presence of -0.0 and NaN.
19495
19496 (define_insn "*avx_ieee_smin<mode>3"
19497   [(set (match_operand:MODEF 0 "register_operand" "=x")
19498         (unspec:MODEF
19499           [(match_operand:MODEF 1 "register_operand" "x")
19500            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
19501          UNSPEC_IEEE_MIN))]
19502   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19503   "vmins<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
19504   [(set_attr "type" "sseadd")
19505    (set_attr "prefix" "vex")
19506    (set_attr "mode" "<MODE>")])
19507
19508 (define_insn "*ieee_smin<mode>3"
19509   [(set (match_operand:MODEF 0 "register_operand" "=x")
19510         (unspec:MODEF
19511           [(match_operand:MODEF 1 "register_operand" "0")
19512            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
19513          UNSPEC_IEEE_MIN))]
19514   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19515   "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
19516   [(set_attr "type" "sseadd")
19517    (set_attr "mode" "<MODE>")])
19518
19519 (define_insn "*avx_ieee_smax<mode>3"
19520   [(set (match_operand:MODEF 0 "register_operand" "=x")
19521         (unspec:MODEF
19522           [(match_operand:MODEF 1 "register_operand" "0")
19523            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
19524          UNSPEC_IEEE_MAX))]
19525   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19526   "vmaxs<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
19527   [(set_attr "type" "sseadd")
19528    (set_attr "prefix" "vex")
19529    (set_attr "mode" "<MODE>")])
19530
19531 (define_insn "*ieee_smax<mode>3"
19532   [(set (match_operand:MODEF 0 "register_operand" "=x")
19533         (unspec:MODEF
19534           [(match_operand:MODEF 1 "register_operand" "0")
19535            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
19536          UNSPEC_IEEE_MAX))]
19537   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19538   "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
19539   [(set_attr "type" "sseadd")
19540    (set_attr "mode" "<MODE>")])
19541
19542 ;; Make two stack loads independent:
19543 ;;   fld aa              fld aa
19544 ;;   fld %st(0)     ->   fld bb
19545 ;;   fmul bb             fmul %st(1), %st
19546 ;;
19547 ;; Actually we only match the last two instructions for simplicity.
19548 (define_peephole2
19549   [(set (match_operand 0 "fp_register_operand" "")
19550         (match_operand 1 "fp_register_operand" ""))
19551    (set (match_dup 0)
19552         (match_operator 2 "binary_fp_operator"
19553            [(match_dup 0)
19554             (match_operand 3 "memory_operand" "")]))]
19555   "REGNO (operands[0]) != REGNO (operands[1])"
19556   [(set (match_dup 0) (match_dup 3))
19557    (set (match_dup 0) (match_dup 4))]
19558
19559   ;; The % modifier is not operational anymore in peephole2's, so we have to
19560   ;; swap the operands manually in the case of addition and multiplication.
19561   "if (COMMUTATIVE_ARITH_P (operands[2]))
19562      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19563                                  operands[0], operands[1]);
19564    else
19565      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19566                                  operands[1], operands[0]);")
19567
19568 ;; Conditional addition patterns
19569 (define_expand "add<mode>cc"
19570   [(match_operand:SWI 0 "register_operand" "")
19571    (match_operand 1 "comparison_operator" "")
19572    (match_operand:SWI 2 "register_operand" "")
19573    (match_operand:SWI 3 "const_int_operand" "")]
19574   ""
19575   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
19576
19577 \f
19578 ;; Misc patterns (?)
19579
19580 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19581 ;; Otherwise there will be nothing to keep
19582 ;;
19583 ;; [(set (reg ebp) (reg esp))]
19584 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19585 ;;  (clobber (eflags)]
19586 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19587 ;;
19588 ;; in proper program order.
19589 (define_insn "pro_epilogue_adjust_stack_1"
19590   [(set (match_operand:SI 0 "register_operand" "=r,r")
19591         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19592                  (match_operand:SI 2 "immediate_operand" "i,i")))
19593    (clobber (reg:CC FLAGS_REG))
19594    (clobber (mem:BLK (scratch)))]
19595   "!TARGET_64BIT"
19596 {
19597   switch (get_attr_type (insn))
19598     {
19599     case TYPE_IMOV:
19600       return "mov{l}\t{%1, %0|%0, %1}";
19601
19602     case TYPE_ALU:
19603       if (CONST_INT_P (operands[2])
19604           && (INTVAL (operands[2]) == 128
19605               || (INTVAL (operands[2]) < 0
19606                   && INTVAL (operands[2]) != -128)))
19607         {
19608           operands[2] = GEN_INT (-INTVAL (operands[2]));
19609           return "sub{l}\t{%2, %0|%0, %2}";
19610         }
19611       return "add{l}\t{%2, %0|%0, %2}";
19612
19613     case TYPE_LEA:
19614       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19615       return "lea{l}\t{%a2, %0|%0, %a2}";
19616
19617     default:
19618       gcc_unreachable ();
19619     }
19620 }
19621   [(set (attr "type")
19622         (cond [(and (eq_attr "alternative" "0") 
19623                     (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
19624                  (const_string "alu")
19625                (match_operand:SI 2 "const0_operand" "")
19626                  (const_string "imov")
19627               ]
19628               (const_string "lea")))
19629    (set (attr "length_immediate")
19630         (cond [(eq_attr "type" "imov")
19631                  (const_string "0")
19632                (and (eq_attr "type" "alu")
19633                     (match_operand 2 "const128_operand" ""))
19634                  (const_string "1")
19635               ]
19636               (const_string "*")))
19637    (set_attr "mode" "SI")])
19638
19639 (define_insn "pro_epilogue_adjust_stack_rex64"
19640   [(set (match_operand:DI 0 "register_operand" "=r,r")
19641         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19642                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19643    (clobber (reg:CC FLAGS_REG))
19644    (clobber (mem:BLK (scratch)))]
19645   "TARGET_64BIT"
19646 {
19647   switch (get_attr_type (insn))
19648     {
19649     case TYPE_IMOV:
19650       return "mov{q}\t{%1, %0|%0, %1}";
19651
19652     case TYPE_ALU:
19653       if (CONST_INT_P (operands[2])
19654           /* Avoid overflows.  */
19655           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19656           && (INTVAL (operands[2]) == 128
19657               || (INTVAL (operands[2]) < 0
19658                   && INTVAL (operands[2]) != -128)))
19659         {
19660           operands[2] = GEN_INT (-INTVAL (operands[2]));
19661           return "sub{q}\t{%2, %0|%0, %2}";
19662         }
19663       return "add{q}\t{%2, %0|%0, %2}";
19664
19665     case TYPE_LEA:
19666       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19667       return "lea{q}\t{%a2, %0|%0, %a2}";
19668
19669     default:
19670       gcc_unreachable ();
19671     }
19672 }
19673   [(set (attr "type")
19674         (cond [(and (eq_attr "alternative" "0")
19675                     (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
19676                  (const_string "alu")
19677                (match_operand:DI 2 "const0_operand" "")
19678                  (const_string "imov")
19679               ]
19680               (const_string "lea")))
19681    (set (attr "length_immediate")
19682         (cond [(eq_attr "type" "imov")
19683                  (const_string "0")
19684                (and (eq_attr "type" "alu")
19685                     (match_operand 2 "const128_operand" ""))
19686                  (const_string "1")
19687               ]
19688               (const_string "*")))
19689    (set_attr "mode" "DI")])
19690
19691 (define_insn "pro_epilogue_adjust_stack_rex64_2"
19692   [(set (match_operand:DI 0 "register_operand" "=r,r")
19693         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19694                  (match_operand:DI 3 "immediate_operand" "i,i")))
19695    (use (match_operand:DI 2 "register_operand" "r,r"))
19696    (clobber (reg:CC FLAGS_REG))
19697    (clobber (mem:BLK (scratch)))]
19698   "TARGET_64BIT"
19699 {
19700   switch (get_attr_type (insn))
19701     {
19702     case TYPE_ALU:
19703       return "add{q}\t{%2, %0|%0, %2}";
19704
19705     case TYPE_LEA:
19706       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19707       return "lea{q}\t{%a2, %0|%0, %a2}";
19708
19709     default:
19710       gcc_unreachable ();
19711     }
19712 }
19713   [(set_attr "type" "alu,lea")
19714    (set_attr "mode" "DI")])
19715
19716 (define_insn "allocate_stack_worker_32"
19717   [(set (match_operand:SI 0 "register_operand" "=a")
19718         (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")]
19719                             UNSPECV_STACK_PROBE))
19720    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 1)))
19721    (clobber (reg:CC FLAGS_REG))]
19722   "!TARGET_64BIT && TARGET_STACK_PROBE"
19723   "call\t___chkstk"
19724   [(set_attr "type" "multi")
19725    (set_attr "length" "5")])
19726
19727 (define_insn "allocate_stack_worker_64"
19728   [(set (match_operand:DI 0 "register_operand" "=a")
19729         (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "0")]
19730                             UNSPECV_STACK_PROBE))
19731    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 1)))
19732    (clobber (reg:DI R10_REG))
19733    (clobber (reg:DI R11_REG))
19734    (clobber (reg:CC FLAGS_REG))]
19735   "TARGET_64BIT && TARGET_STACK_PROBE"
19736   "call\t___chkstk"
19737   [(set_attr "type" "multi")
19738    (set_attr "length" "5")])
19739
19740 (define_expand "allocate_stack"
19741   [(match_operand 0 "register_operand" "")
19742    (match_operand 1 "general_operand" "")]
19743   "TARGET_STACK_PROBE"
19744 {
19745   rtx x;
19746
19747 #ifndef CHECK_STACK_LIMIT
19748 #define CHECK_STACK_LIMIT 0
19749 #endif
19750
19751   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
19752       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19753     {
19754       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
19755                                stack_pointer_rtx, 0, OPTAB_DIRECT);
19756       if (x != stack_pointer_rtx)
19757         emit_move_insn (stack_pointer_rtx, x);
19758     }
19759   else
19760     {
19761       x = copy_to_mode_reg (Pmode, operands[1]);
19762       if (TARGET_64BIT)
19763         x = gen_allocate_stack_worker_64 (x, x);
19764       else
19765         x = gen_allocate_stack_worker_32 (x, x);
19766       emit_insn (x);
19767     }
19768
19769   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19770   DONE;
19771 })
19772
19773 ;; Use IOR for stack probes, this is shorter.
19774 (define_expand "probe_stack"
19775   [(match_operand 0 "memory_operand" "")]
19776   ""
19777 {
19778   if (GET_MODE (operands[0]) == DImode)
19779     emit_insn (gen_iordi3 (operands[0], operands[0], const0_rtx));
19780   else
19781     emit_insn (gen_iorsi3 (operands[0], operands[0], const0_rtx));
19782   DONE;
19783 })
19784
19785 (define_expand "builtin_setjmp_receiver"
19786   [(label_ref (match_operand 0 "" ""))]
19787   "!TARGET_64BIT && flag_pic"
19788 {
19789 #if TARGET_MACHO
19790   if (TARGET_MACHO)
19791     {
19792       rtx xops[3];
19793       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19794       rtx label_rtx = gen_label_rtx ();
19795       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19796       xops[0] = xops[1] = picreg;
19797       xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
19798       ix86_expand_binary_operator (MINUS, SImode, xops);
19799     }
19800   else
19801 #endif
19802     emit_insn (gen_set_got (pic_offset_table_rtx));
19803   DONE;
19804 })
19805 \f
19806 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19807
19808 (define_split
19809   [(set (match_operand 0 "register_operand" "")
19810         (match_operator 3 "promotable_binary_operator"
19811            [(match_operand 1 "register_operand" "")
19812             (match_operand 2 "aligned_operand" "")]))
19813    (clobber (reg:CC FLAGS_REG))]
19814   "! TARGET_PARTIAL_REG_STALL && reload_completed
19815    && ((GET_MODE (operands[0]) == HImode
19816         && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
19817             /* ??? next two lines just !satisfies_constraint_K (...) */
19818             || !CONST_INT_P (operands[2])
19819             || satisfies_constraint_K (operands[2])))
19820        || (GET_MODE (operands[0]) == QImode
19821            && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
19822   [(parallel [(set (match_dup 0)
19823                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19824               (clobber (reg:CC FLAGS_REG))])]
19825   "operands[0] = gen_lowpart (SImode, operands[0]);
19826    operands[1] = gen_lowpart (SImode, operands[1]);
19827    if (GET_CODE (operands[3]) != ASHIFT)
19828      operands[2] = gen_lowpart (SImode, operands[2]);
19829    PUT_MODE (operands[3], SImode);")
19830
19831 ; Promote the QImode tests, as i386 has encoding of the AND
19832 ; instruction with 32-bit sign-extended immediate and thus the
19833 ; instruction size is unchanged, except in the %eax case for
19834 ; which it is increased by one byte, hence the ! optimize_size.
19835 (define_split
19836   [(set (match_operand 0 "flags_reg_operand" "")
19837         (match_operator 2 "compare_operator"
19838           [(and (match_operand 3 "aligned_operand" "")
19839                 (match_operand 4 "const_int_operand" ""))
19840            (const_int 0)]))
19841    (set (match_operand 1 "register_operand" "")
19842         (and (match_dup 3) (match_dup 4)))]
19843   "! TARGET_PARTIAL_REG_STALL && reload_completed
19844    && optimize_insn_for_speed_p ()
19845    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19846        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
19847    /* Ensure that the operand will remain sign-extended immediate.  */
19848    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
19849   [(parallel [(set (match_dup 0)
19850                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19851                                     (const_int 0)]))
19852               (set (match_dup 1)
19853                    (and:SI (match_dup 3) (match_dup 4)))])]
19854 {
19855   operands[4]
19856     = gen_int_mode (INTVAL (operands[4])
19857                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19858   operands[1] = gen_lowpart (SImode, operands[1]);
19859   operands[3] = gen_lowpart (SImode, operands[3]);
19860 })
19861
19862 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19863 ; the TEST instruction with 32-bit sign-extended immediate and thus
19864 ; the instruction size would at least double, which is not what we
19865 ; want even with ! optimize_size.
19866 (define_split
19867   [(set (match_operand 0 "flags_reg_operand" "")
19868         (match_operator 1 "compare_operator"
19869           [(and (match_operand:HI 2 "aligned_operand" "")
19870                 (match_operand:HI 3 "const_int_operand" ""))
19871            (const_int 0)]))]
19872   "! TARGET_PARTIAL_REG_STALL && reload_completed
19873    && ! TARGET_FAST_PREFIX
19874    && optimize_insn_for_speed_p ()
19875    /* Ensure that the operand will remain sign-extended immediate.  */
19876    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
19877   [(set (match_dup 0)
19878         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19879                          (const_int 0)]))]
19880 {
19881   operands[3]
19882     = gen_int_mode (INTVAL (operands[3])
19883                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19884   operands[2] = gen_lowpart (SImode, operands[2]);
19885 })
19886
19887 (define_split
19888   [(set (match_operand 0 "register_operand" "")
19889         (neg (match_operand 1 "register_operand" "")))
19890    (clobber (reg:CC FLAGS_REG))]
19891   "! TARGET_PARTIAL_REG_STALL && reload_completed
19892    && (GET_MODE (operands[0]) == HImode
19893        || (GET_MODE (operands[0]) == QImode
19894            && (TARGET_PROMOTE_QImode
19895                || optimize_insn_for_size_p ())))"
19896   [(parallel [(set (match_dup 0)
19897                    (neg:SI (match_dup 1)))
19898               (clobber (reg:CC FLAGS_REG))])]
19899   "operands[0] = gen_lowpart (SImode, operands[0]);
19900    operands[1] = gen_lowpart (SImode, operands[1]);")
19901
19902 (define_split
19903   [(set (match_operand 0 "register_operand" "")
19904         (not (match_operand 1 "register_operand" "")))]
19905   "! TARGET_PARTIAL_REG_STALL && reload_completed
19906    && (GET_MODE (operands[0]) == HImode
19907        || (GET_MODE (operands[0]) == QImode
19908            && (TARGET_PROMOTE_QImode
19909                || optimize_insn_for_size_p ())))"
19910   [(set (match_dup 0)
19911         (not:SI (match_dup 1)))]
19912   "operands[0] = gen_lowpart (SImode, operands[0]);
19913    operands[1] = gen_lowpart (SImode, operands[1]);")
19914
19915 (define_split
19916   [(set (match_operand 0 "register_operand" "")
19917         (if_then_else (match_operator 1 "comparison_operator"
19918                                 [(reg FLAGS_REG) (const_int 0)])
19919                       (match_operand 2 "register_operand" "")
19920                       (match_operand 3 "register_operand" "")))]
19921   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19922    && (GET_MODE (operands[0]) == HImode
19923        || (GET_MODE (operands[0]) == QImode
19924            && (TARGET_PROMOTE_QImode
19925                || optimize_insn_for_size_p ())))"
19926   [(set (match_dup 0)
19927         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19928   "operands[0] = gen_lowpart (SImode, operands[0]);
19929    operands[2] = gen_lowpart (SImode, operands[2]);
19930    operands[3] = gen_lowpart (SImode, operands[3]);")
19931
19932 \f
19933 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
19934 ;; transform a complex memory operation into two memory to register operations.
19935
19936 ;; Don't push memory operands
19937 (define_peephole2
19938   [(set (match_operand:SI 0 "push_operand" "")
19939         (match_operand:SI 1 "memory_operand" ""))
19940    (match_scratch:SI 2 "r")]
19941   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
19942    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19943   [(set (match_dup 2) (match_dup 1))
19944    (set (match_dup 0) (match_dup 2))]
19945   "")
19946
19947 (define_peephole2
19948   [(set (match_operand:DI 0 "push_operand" "")
19949         (match_operand:DI 1 "memory_operand" ""))
19950    (match_scratch:DI 2 "r")]
19951   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
19952    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19953   [(set (match_dup 2) (match_dup 1))
19954    (set (match_dup 0) (match_dup 2))]
19955   "")
19956
19957 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19958 ;; SImode pushes.
19959 (define_peephole2
19960   [(set (match_operand:SF 0 "push_operand" "")
19961         (match_operand:SF 1 "memory_operand" ""))
19962    (match_scratch:SF 2 "r")]
19963   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
19964    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19965   [(set (match_dup 2) (match_dup 1))
19966    (set (match_dup 0) (match_dup 2))]
19967   "")
19968
19969 (define_peephole2
19970   [(set (match_operand:HI 0 "push_operand" "")
19971         (match_operand:HI 1 "memory_operand" ""))
19972    (match_scratch:HI 2 "r")]
19973   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
19974    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19975   [(set (match_dup 2) (match_dup 1))
19976    (set (match_dup 0) (match_dup 2))]
19977   "")
19978
19979 (define_peephole2
19980   [(set (match_operand:QI 0 "push_operand" "")
19981         (match_operand:QI 1 "memory_operand" ""))
19982    (match_scratch:QI 2 "q")]
19983   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
19984    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19985   [(set (match_dup 2) (match_dup 1))
19986    (set (match_dup 0) (match_dup 2))]
19987   "")
19988
19989 ;; Don't move an immediate directly to memory when the instruction
19990 ;; gets too big.
19991 (define_peephole2
19992   [(match_scratch:SI 1 "r")
19993    (set (match_operand:SI 0 "memory_operand" "")
19994         (const_int 0))]
19995   "optimize_insn_for_speed_p ()
19996    && ! TARGET_USE_MOV0
19997    && TARGET_SPLIT_LONG_MOVES
19998    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
19999    && peep2_regno_dead_p (0, FLAGS_REG)"
20000   [(parallel [(set (match_dup 1) (const_int 0))
20001               (clobber (reg:CC FLAGS_REG))])
20002    (set (match_dup 0) (match_dup 1))]
20003   "")
20004
20005 (define_peephole2
20006   [(match_scratch:HI 1 "r")
20007    (set (match_operand:HI 0 "memory_operand" "")
20008         (const_int 0))]
20009   "optimize_insn_for_speed_p ()
20010    && ! TARGET_USE_MOV0
20011    && TARGET_SPLIT_LONG_MOVES
20012    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
20013    && peep2_regno_dead_p (0, FLAGS_REG)"
20014   [(parallel [(set (match_dup 2) (const_int 0))
20015               (clobber (reg:CC FLAGS_REG))])
20016    (set (match_dup 0) (match_dup 1))]
20017   "operands[2] = gen_lowpart (SImode, operands[1]);")
20018
20019 (define_peephole2
20020   [(match_scratch:QI 1 "q")
20021    (set (match_operand:QI 0 "memory_operand" "")
20022         (const_int 0))]
20023   "optimize_insn_for_speed_p ()
20024    && ! TARGET_USE_MOV0
20025    && TARGET_SPLIT_LONG_MOVES
20026    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
20027    && peep2_regno_dead_p (0, FLAGS_REG)"
20028   [(parallel [(set (match_dup 2) (const_int 0))
20029               (clobber (reg:CC FLAGS_REG))])
20030    (set (match_dup 0) (match_dup 1))]
20031   "operands[2] = gen_lowpart (SImode, operands[1]);")
20032
20033 (define_peephole2
20034   [(match_scratch:SI 2 "r")
20035    (set (match_operand:SI 0 "memory_operand" "")
20036         (match_operand:SI 1 "immediate_operand" ""))]
20037   "optimize_insn_for_speed_p ()
20038    && TARGET_SPLIT_LONG_MOVES
20039    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
20040   [(set (match_dup 2) (match_dup 1))
20041    (set (match_dup 0) (match_dup 2))]
20042   "")
20043
20044 (define_peephole2
20045   [(match_scratch:HI 2 "r")
20046    (set (match_operand:HI 0 "memory_operand" "")
20047         (match_operand:HI 1 "immediate_operand" ""))]
20048   "optimize_insn_for_speed_p ()
20049    && TARGET_SPLIT_LONG_MOVES
20050    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
20051   [(set (match_dup 2) (match_dup 1))
20052    (set (match_dup 0) (match_dup 2))]
20053   "")
20054
20055 (define_peephole2
20056   [(match_scratch:QI 2 "q")
20057    (set (match_operand:QI 0 "memory_operand" "")
20058         (match_operand:QI 1 "immediate_operand" ""))]
20059   "optimize_insn_for_speed_p ()
20060    && TARGET_SPLIT_LONG_MOVES
20061    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
20062   [(set (match_dup 2) (match_dup 1))
20063    (set (match_dup 0) (match_dup 2))]
20064   "")
20065
20066 ;; Don't compare memory with zero, load and use a test instead.
20067 (define_peephole2
20068   [(set (match_operand 0 "flags_reg_operand" "")
20069         (match_operator 1 "compare_operator"
20070           [(match_operand:SI 2 "memory_operand" "")
20071            (const_int 0)]))
20072    (match_scratch:SI 3 "r")]
20073   "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
20074   [(set (match_dup 3) (match_dup 2))
20075    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
20076   "")
20077
20078 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
20079 ;; Don't split NOTs with a displacement operand, because resulting XOR
20080 ;; will not be pairable anyway.
20081 ;;
20082 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
20083 ;; represented using a modRM byte.  The XOR replacement is long decoded,
20084 ;; so this split helps here as well.
20085 ;;
20086 ;; Note: Can't do this as a regular split because we can't get proper
20087 ;; lifetime information then.
20088
20089 (define_peephole2
20090   [(set (match_operand:SI 0 "nonimmediate_operand" "")
20091         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
20092   "optimize_insn_for_speed_p ()
20093    && ((TARGET_NOT_UNPAIRABLE
20094         && (!MEM_P (operands[0])
20095             || !memory_displacement_operand (operands[0], SImode)))
20096        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
20097    && peep2_regno_dead_p (0, FLAGS_REG)"
20098   [(parallel [(set (match_dup 0)
20099                    (xor:SI (match_dup 1) (const_int -1)))
20100               (clobber (reg:CC FLAGS_REG))])]
20101   "")
20102
20103 (define_peephole2
20104   [(set (match_operand:HI 0 "nonimmediate_operand" "")
20105         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
20106   "optimize_insn_for_speed_p ()
20107    && ((TARGET_NOT_UNPAIRABLE
20108         && (!MEM_P (operands[0])
20109             || !memory_displacement_operand (operands[0], HImode)))
20110        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
20111    && peep2_regno_dead_p (0, FLAGS_REG)"
20112   [(parallel [(set (match_dup 0)
20113                    (xor:HI (match_dup 1) (const_int -1)))
20114               (clobber (reg:CC FLAGS_REG))])]
20115   "")
20116
20117 (define_peephole2
20118   [(set (match_operand:QI 0 "nonimmediate_operand" "")
20119         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
20120   "optimize_insn_for_speed_p ()
20121    && ((TARGET_NOT_UNPAIRABLE
20122         && (!MEM_P (operands[0])
20123             || !memory_displacement_operand (operands[0], QImode)))
20124        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
20125    && peep2_regno_dead_p (0, FLAGS_REG)"
20126   [(parallel [(set (match_dup 0)
20127                    (xor:QI (match_dup 1) (const_int -1)))
20128               (clobber (reg:CC FLAGS_REG))])]
20129   "")
20130
20131 ;; Non pairable "test imm, reg" instructions can be translated to
20132 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
20133 ;; byte opcode instead of two, have a short form for byte operands),
20134 ;; so do it for other CPUs as well.  Given that the value was dead,
20135 ;; this should not create any new dependencies.  Pass on the sub-word
20136 ;; versions if we're concerned about partial register stalls.
20137
20138 (define_peephole2
20139   [(set (match_operand 0 "flags_reg_operand" "")
20140         (match_operator 1 "compare_operator"
20141           [(and:SI (match_operand:SI 2 "register_operand" "")
20142                    (match_operand:SI 3 "immediate_operand" ""))
20143            (const_int 0)]))]
20144   "ix86_match_ccmode (insn, CCNOmode)
20145    && (true_regnum (operands[2]) != AX_REG
20146        || satisfies_constraint_K (operands[3]))
20147    && peep2_reg_dead_p (1, operands[2])"
20148   [(parallel
20149      [(set (match_dup 0)
20150            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20151                             (const_int 0)]))
20152       (set (match_dup 2)
20153            (and:SI (match_dup 2) (match_dup 3)))])]
20154   "")
20155
20156 ;; We don't need to handle HImode case, because it will be promoted to SImode
20157 ;; on ! TARGET_PARTIAL_REG_STALL
20158
20159 (define_peephole2
20160   [(set (match_operand 0 "flags_reg_operand" "")
20161         (match_operator 1 "compare_operator"
20162           [(and:QI (match_operand:QI 2 "register_operand" "")
20163                    (match_operand:QI 3 "immediate_operand" ""))
20164            (const_int 0)]))]
20165   "! TARGET_PARTIAL_REG_STALL
20166    && ix86_match_ccmode (insn, CCNOmode)
20167    && true_regnum (operands[2]) != AX_REG
20168    && peep2_reg_dead_p (1, operands[2])"
20169   [(parallel
20170      [(set (match_dup 0)
20171            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
20172                             (const_int 0)]))
20173       (set (match_dup 2)
20174            (and:QI (match_dup 2) (match_dup 3)))])]
20175   "")
20176
20177 (define_peephole2
20178   [(set (match_operand 0 "flags_reg_operand" "")
20179         (match_operator 1 "compare_operator"
20180           [(and:SI
20181              (zero_extract:SI
20182                (match_operand 2 "ext_register_operand" "")
20183                (const_int 8)
20184                (const_int 8))
20185              (match_operand 3 "const_int_operand" ""))
20186            (const_int 0)]))]
20187   "! TARGET_PARTIAL_REG_STALL
20188    && ix86_match_ccmode (insn, CCNOmode)
20189    && true_regnum (operands[2]) != AX_REG
20190    && peep2_reg_dead_p (1, operands[2])"
20191   [(parallel [(set (match_dup 0)
20192                    (match_op_dup 1
20193                      [(and:SI
20194                         (zero_extract:SI
20195                           (match_dup 2)
20196                           (const_int 8)
20197                           (const_int 8))
20198                         (match_dup 3))
20199                       (const_int 0)]))
20200               (set (zero_extract:SI (match_dup 2)
20201                                     (const_int 8)
20202                                     (const_int 8))
20203                    (and:SI
20204                      (zero_extract:SI
20205                        (match_dup 2)
20206                        (const_int 8)
20207                        (const_int 8))
20208                      (match_dup 3)))])]
20209   "")
20210
20211 ;; Don't do logical operations with memory inputs.
20212 (define_peephole2
20213   [(match_scratch:SI 2 "r")
20214    (parallel [(set (match_operand:SI 0 "register_operand" "")
20215                    (match_operator:SI 3 "arith_or_logical_operator"
20216                      [(match_dup 0)
20217                       (match_operand:SI 1 "memory_operand" "")]))
20218               (clobber (reg:CC FLAGS_REG))])]
20219   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
20220   [(set (match_dup 2) (match_dup 1))
20221    (parallel [(set (match_dup 0)
20222                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
20223               (clobber (reg:CC FLAGS_REG))])]
20224   "")
20225
20226 (define_peephole2
20227   [(match_scratch:SI 2 "r")
20228    (parallel [(set (match_operand:SI 0 "register_operand" "")
20229                    (match_operator:SI 3 "arith_or_logical_operator"
20230                      [(match_operand:SI 1 "memory_operand" "")
20231                       (match_dup 0)]))
20232               (clobber (reg:CC FLAGS_REG))])]
20233   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
20234   [(set (match_dup 2) (match_dup 1))
20235    (parallel [(set (match_dup 0)
20236                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
20237               (clobber (reg:CC FLAGS_REG))])]
20238   "")
20239
20240 ;; Prefer Load+RegOp to Mov+MemOp.  Watch out for cases when the memory address
20241 ;; refers to the destination of the load!
20242
20243 (define_peephole2
20244   [(set (match_operand:SI 0 "register_operand" "")
20245         (match_operand:SI 1 "register_operand" ""))
20246    (parallel [(set (match_dup 0)
20247                    (match_operator:SI 3 "commutative_operator"
20248                      [(match_dup 0)
20249                       (match_operand:SI 2 "memory_operand" "")]))
20250               (clobber (reg:CC FLAGS_REG))])]
20251   "REGNO (operands[0]) != REGNO (operands[1])
20252    && GENERAL_REGNO_P (REGNO (operands[0]))
20253    && GENERAL_REGNO_P (REGNO (operands[1]))"
20254   [(set (match_dup 0) (match_dup 4))
20255    (parallel [(set (match_dup 0)
20256                    (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
20257               (clobber (reg:CC FLAGS_REG))])]
20258   "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
20259
20260 (define_peephole2
20261   [(set (match_operand 0 "register_operand" "")
20262         (match_operand 1 "register_operand" ""))
20263    (set (match_dup 0)
20264                    (match_operator 3 "commutative_operator"
20265                      [(match_dup 0)
20266                       (match_operand 2 "memory_operand" "")]))]
20267   "REGNO (operands[0]) != REGNO (operands[1])
20268    && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1])) 
20269        || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
20270   [(set (match_dup 0) (match_dup 2))
20271    (set (match_dup 0)
20272         (match_op_dup 3 [(match_dup 0) (match_dup 1)]))]
20273   "")
20274
20275 ; Don't do logical operations with memory outputs
20276 ;
20277 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
20278 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
20279 ; the same decoder scheduling characteristics as the original.
20280
20281 (define_peephole2
20282   [(match_scratch:SI 2 "r")
20283    (parallel [(set (match_operand:SI 0 "memory_operand" "")
20284                    (match_operator:SI 3 "arith_or_logical_operator"
20285                      [(match_dup 0)
20286                       (match_operand:SI 1 "nonmemory_operand" "")]))
20287               (clobber (reg:CC FLAGS_REG))])]
20288   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
20289    /* Do not split stack checking probes.  */
20290    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
20291   [(set (match_dup 2) (match_dup 0))
20292    (parallel [(set (match_dup 2)
20293                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20294               (clobber (reg:CC FLAGS_REG))])
20295    (set (match_dup 0) (match_dup 2))]
20296   "")
20297
20298 (define_peephole2
20299   [(match_scratch:SI 2 "r")
20300    (parallel [(set (match_operand:SI 0 "memory_operand" "")
20301                    (match_operator:SI 3 "arith_or_logical_operator"
20302                      [(match_operand:SI 1 "nonmemory_operand" "")
20303                       (match_dup 0)]))
20304               (clobber (reg:CC FLAGS_REG))])]
20305   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
20306    /* Do not split stack checking probes.  */
20307    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
20308   [(set (match_dup 2) (match_dup 0))
20309    (parallel [(set (match_dup 2)
20310                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20311               (clobber (reg:CC FLAGS_REG))])
20312    (set (match_dup 0) (match_dup 2))]
20313   "")
20314
20315 ;; Attempt to always use XOR for zeroing registers.
20316 (define_peephole2
20317   [(set (match_operand 0 "register_operand" "")
20318         (match_operand 1 "const0_operand" ""))]
20319   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20320    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
20321    && GENERAL_REG_P (operands[0])
20322    && peep2_regno_dead_p (0, FLAGS_REG)"
20323   [(parallel [(set (match_dup 0) (const_int 0))
20324               (clobber (reg:CC FLAGS_REG))])]
20325 {
20326   operands[0] = gen_lowpart (word_mode, operands[0]);
20327 })
20328
20329 (define_peephole2
20330   [(set (strict_low_part (match_operand 0 "register_operand" ""))
20331         (const_int 0))]
20332   "(GET_MODE (operands[0]) == QImode
20333     || GET_MODE (operands[0]) == HImode)
20334    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
20335    && peep2_regno_dead_p (0, FLAGS_REG)"
20336   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20337               (clobber (reg:CC FLAGS_REG))])])
20338
20339 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20340 (define_peephole2
20341   [(set (match_operand 0 "register_operand" "")
20342         (const_int -1))]
20343   "(GET_MODE (operands[0]) == HImode
20344     || GET_MODE (operands[0]) == SImode
20345     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20346    && (optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
20347    && peep2_regno_dead_p (0, FLAGS_REG)"
20348   [(parallel [(set (match_dup 0) (const_int -1))
20349               (clobber (reg:CC FLAGS_REG))])]
20350   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20351                               operands[0]);")
20352
20353 ;; Attempt to convert simple leas to adds. These can be created by
20354 ;; move expanders.
20355 (define_peephole2
20356   [(set (match_operand:SI 0 "register_operand" "")
20357         (plus:SI (match_dup 0)
20358                  (match_operand:SI 1 "nonmemory_operand" "")))]
20359   "peep2_regno_dead_p (0, FLAGS_REG)"
20360   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20361               (clobber (reg:CC FLAGS_REG))])]
20362   "")
20363
20364 (define_peephole2
20365   [(set (match_operand:SI 0 "register_operand" "")
20366         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20367                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20368   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20369   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20370               (clobber (reg:CC FLAGS_REG))])]
20371   "operands[2] = gen_lowpart (SImode, operands[2]);")
20372
20373 (define_peephole2
20374   [(set (match_operand:DI 0 "register_operand" "")
20375         (plus:DI (match_dup 0)
20376                  (match_operand:DI 1 "x86_64_general_operand" "")))]
20377   "peep2_regno_dead_p (0, FLAGS_REG)"
20378   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20379               (clobber (reg:CC FLAGS_REG))])]
20380   "")
20381
20382 (define_peephole2
20383   [(set (match_operand:SI 0 "register_operand" "")
20384         (mult:SI (match_dup 0)
20385                  (match_operand:SI 1 "const_int_operand" "")))]
20386   "exact_log2 (INTVAL (operands[1])) >= 0
20387    && peep2_regno_dead_p (0, FLAGS_REG)"
20388   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20389               (clobber (reg:CC FLAGS_REG))])]
20390   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20391
20392 (define_peephole2
20393   [(set (match_operand:DI 0 "register_operand" "")
20394         (mult:DI (match_dup 0)
20395                  (match_operand:DI 1 "const_int_operand" "")))]
20396   "exact_log2 (INTVAL (operands[1])) >= 0
20397    && peep2_regno_dead_p (0, FLAGS_REG)"
20398   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20399               (clobber (reg:CC FLAGS_REG))])]
20400   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20401
20402 (define_peephole2
20403   [(set (match_operand:SI 0 "register_operand" "")
20404         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20405                    (match_operand:DI 2 "const_int_operand" "")) 0))]
20406   "exact_log2 (INTVAL (operands[2])) >= 0
20407    && REGNO (operands[0]) == REGNO (operands[1])
20408    && peep2_regno_dead_p (0, FLAGS_REG)"
20409   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20410               (clobber (reg:CC FLAGS_REG))])]
20411   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20412
20413 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
20414 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
20415 ;; many CPUs it is also faster, since special hardware to avoid esp
20416 ;; dependencies is present.
20417
20418 ;; While some of these conversions may be done using splitters, we use peepholes
20419 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20420
20421 ;; Convert prologue esp subtractions to push.
20422 ;; We need register to push.  In order to keep verify_flow_info happy we have
20423 ;; two choices
20424 ;; - use scratch and clobber it in order to avoid dependencies
20425 ;; - use already live register
20426 ;; We can't use the second way right now, since there is no reliable way how to
20427 ;; verify that given register is live.  First choice will also most likely in
20428 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
20429 ;; call clobbered registers are dead.  We may want to use base pointer as an
20430 ;; alternative when no register is available later.
20431
20432 (define_peephole2
20433   [(match_scratch:SI 0 "r")
20434    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20435               (clobber (reg:CC FLAGS_REG))
20436               (clobber (mem:BLK (scratch)))])]
20437   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
20438   [(clobber (match_dup 0))
20439    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20440               (clobber (mem:BLK (scratch)))])])
20441
20442 (define_peephole2
20443   [(match_scratch:SI 0 "r")
20444    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20445               (clobber (reg:CC FLAGS_REG))
20446               (clobber (mem:BLK (scratch)))])]
20447   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
20448   [(clobber (match_dup 0))
20449    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20450    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20451               (clobber (mem:BLK (scratch)))])])
20452
20453 ;; Convert esp subtractions to push.
20454 (define_peephole2
20455   [(match_scratch:SI 0 "r")
20456    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20457               (clobber (reg:CC FLAGS_REG))])]
20458   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
20459   [(clobber (match_dup 0))
20460    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20461
20462 (define_peephole2
20463   [(match_scratch:SI 0 "r")
20464    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20465               (clobber (reg:CC FLAGS_REG))])]
20466   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
20467   [(clobber (match_dup 0))
20468    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20469    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20470
20471 ;; Convert epilogue deallocator to pop.
20472 (define_peephole2
20473   [(match_scratch:SI 0 "r")
20474    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20475               (clobber (reg:CC FLAGS_REG))
20476               (clobber (mem:BLK (scratch)))])]
20477   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
20478   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20479               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20480               (clobber (mem:BLK (scratch)))])]
20481   "")
20482
20483 ;; Two pops case is tricky, since pop causes dependency on destination register.
20484 ;; We use two registers if available.
20485 (define_peephole2
20486   [(match_scratch:SI 0 "r")
20487    (match_scratch:SI 1 "r")
20488    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20489               (clobber (reg:CC FLAGS_REG))
20490               (clobber (mem:BLK (scratch)))])]
20491   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
20492   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20493               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20494               (clobber (mem:BLK (scratch)))])
20495    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20496               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20497   "")
20498
20499 (define_peephole2
20500   [(match_scratch:SI 0 "r")
20501    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20502               (clobber (reg:CC FLAGS_REG))
20503               (clobber (mem:BLK (scratch)))])]
20504   "optimize_insn_for_size_p ()"
20505   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20506               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20507               (clobber (mem:BLK (scratch)))])
20508    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20509               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20510   "")
20511
20512 ;; Convert esp additions to pop.
20513 (define_peephole2
20514   [(match_scratch:SI 0 "r")
20515    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20516               (clobber (reg:CC FLAGS_REG))])]
20517   ""
20518   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20519               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20520   "")
20521
20522 ;; Two pops case is tricky, since pop causes dependency on destination register.
20523 ;; We use two registers if available.
20524 (define_peephole2
20525   [(match_scratch:SI 0 "r")
20526    (match_scratch:SI 1 "r")
20527    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20528               (clobber (reg:CC FLAGS_REG))])]
20529   ""
20530   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20531               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20532    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20533               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20534   "")
20535
20536 (define_peephole2
20537   [(match_scratch:SI 0 "r")
20538    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20539               (clobber (reg:CC FLAGS_REG))])]
20540   "optimize_insn_for_size_p ()"
20541   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20542               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20543    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20544               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20545   "")
20546 \f
20547 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20548 ;; required and register dies.  Similarly for 128 to -128.
20549 (define_peephole2
20550   [(set (match_operand 0 "flags_reg_operand" "")
20551         (match_operator 1 "compare_operator"
20552           [(match_operand 2 "register_operand" "")
20553            (match_operand 3 "const_int_operand" "")]))]
20554   "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
20555      && incdec_operand (operands[3], GET_MODE (operands[3])))
20556     || (!TARGET_FUSE_CMP_AND_BRANCH
20557         && INTVAL (operands[3]) == 128))
20558    && ix86_match_ccmode (insn, CCGCmode)
20559    && peep2_reg_dead_p (1, operands[2])"
20560   [(parallel [(set (match_dup 0)
20561                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20562               (clobber (match_dup 2))])]
20563   "")
20564 \f
20565 (define_peephole2
20566   [(match_scratch:DI 0 "r")
20567    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20568               (clobber (reg:CC FLAGS_REG))
20569               (clobber (mem:BLK (scratch)))])]
20570   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
20571   [(clobber (match_dup 0))
20572    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20573               (clobber (mem:BLK (scratch)))])])
20574
20575 (define_peephole2
20576   [(match_scratch:DI 0 "r")
20577    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20578               (clobber (reg:CC FLAGS_REG))
20579               (clobber (mem:BLK (scratch)))])]
20580   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
20581   [(clobber (match_dup 0))
20582    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20583    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20584               (clobber (mem:BLK (scratch)))])])
20585
20586 ;; Convert esp subtractions to push.
20587 (define_peephole2
20588   [(match_scratch:DI 0 "r")
20589    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20590               (clobber (reg:CC FLAGS_REG))])]
20591   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
20592   [(clobber (match_dup 0))
20593    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20594
20595 (define_peephole2
20596   [(match_scratch:DI 0 "r")
20597    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20598               (clobber (reg:CC FLAGS_REG))])]
20599   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
20600   [(clobber (match_dup 0))
20601    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20602    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20603
20604 ;; Convert epilogue deallocator to pop.
20605 (define_peephole2
20606   [(match_scratch:DI 0 "r")
20607    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20608               (clobber (reg:CC FLAGS_REG))
20609               (clobber (mem:BLK (scratch)))])]
20610   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
20611   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20612               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20613               (clobber (mem:BLK (scratch)))])]
20614   "")
20615
20616 ;; Two pops case is tricky, since pop causes dependency on destination register.
20617 ;; We use two registers if available.
20618 (define_peephole2
20619   [(match_scratch:DI 0 "r")
20620    (match_scratch:DI 1 "r")
20621    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20622               (clobber (reg:CC FLAGS_REG))
20623               (clobber (mem:BLK (scratch)))])]
20624   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
20625   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20626               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20627               (clobber (mem:BLK (scratch)))])
20628    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20629               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20630   "")
20631
20632 (define_peephole2
20633   [(match_scratch:DI 0 "r")
20634    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20635               (clobber (reg:CC FLAGS_REG))
20636               (clobber (mem:BLK (scratch)))])]
20637   "optimize_insn_for_size_p ()"
20638   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20639               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20640               (clobber (mem:BLK (scratch)))])
20641    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20642               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20643   "")
20644
20645 ;; Convert esp additions to pop.
20646 (define_peephole2
20647   [(match_scratch:DI 0 "r")
20648    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20649               (clobber (reg:CC FLAGS_REG))])]
20650   ""
20651   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20652               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20653   "")
20654
20655 ;; Two pops case is tricky, since pop causes dependency on destination register.
20656 ;; We use two registers if available.
20657 (define_peephole2
20658   [(match_scratch:DI 0 "r")
20659    (match_scratch:DI 1 "r")
20660    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20661               (clobber (reg:CC FLAGS_REG))])]
20662   ""
20663   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20664               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20665    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20666               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20667   "")
20668
20669 (define_peephole2
20670   [(match_scratch:DI 0 "r")
20671    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20672               (clobber (reg:CC FLAGS_REG))])]
20673   "optimize_insn_for_size_p ()"
20674   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20675               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20676    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20677               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20678   "")
20679 \f
20680 ;; Convert imul by three, five and nine into lea
20681 (define_peephole2
20682   [(parallel
20683     [(set (match_operand:SI 0 "register_operand" "")
20684           (mult:SI (match_operand:SI 1 "register_operand" "")
20685                    (match_operand:SI 2 "const_int_operand" "")))
20686      (clobber (reg:CC FLAGS_REG))])]
20687   "INTVAL (operands[2]) == 3
20688    || INTVAL (operands[2]) == 5
20689    || INTVAL (operands[2]) == 9"
20690   [(set (match_dup 0)
20691         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20692                  (match_dup 1)))]
20693   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20694
20695 (define_peephole2
20696   [(parallel
20697     [(set (match_operand:SI 0 "register_operand" "")
20698           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20699                    (match_operand:SI 2 "const_int_operand" "")))
20700      (clobber (reg:CC FLAGS_REG))])]
20701   "optimize_insn_for_speed_p ()
20702    && (INTVAL (operands[2]) == 3
20703        || INTVAL (operands[2]) == 5
20704        || INTVAL (operands[2]) == 9)"
20705   [(set (match_dup 0) (match_dup 1))
20706    (set (match_dup 0)
20707         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20708                  (match_dup 0)))]
20709   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20710
20711 (define_peephole2
20712   [(parallel
20713     [(set (match_operand:DI 0 "register_operand" "")
20714           (mult:DI (match_operand:DI 1 "register_operand" "")
20715                    (match_operand:DI 2 "const_int_operand" "")))
20716      (clobber (reg:CC FLAGS_REG))])]
20717   "TARGET_64BIT
20718    && (INTVAL (operands[2]) == 3
20719        || INTVAL (operands[2]) == 5
20720        || INTVAL (operands[2]) == 9)"
20721   [(set (match_dup 0)
20722         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20723                  (match_dup 1)))]
20724   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20725
20726 (define_peephole2
20727   [(parallel
20728     [(set (match_operand:DI 0 "register_operand" "")
20729           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20730                    (match_operand:DI 2 "const_int_operand" "")))
20731      (clobber (reg:CC FLAGS_REG))])]
20732   "TARGET_64BIT
20733    && optimize_insn_for_speed_p ()
20734    && (INTVAL (operands[2]) == 3
20735        || INTVAL (operands[2]) == 5
20736        || INTVAL (operands[2]) == 9)"
20737   [(set (match_dup 0) (match_dup 1))
20738    (set (match_dup 0)
20739         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20740                  (match_dup 0)))]
20741   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20742
20743 ;; Imul $32bit_imm, mem, reg is vector decoded, while
20744 ;; imul $32bit_imm, reg, reg is direct decoded.
20745 (define_peephole2
20746   [(match_scratch:DI 3 "r")
20747    (parallel [(set (match_operand:DI 0 "register_operand" "")
20748                    (mult:DI (match_operand:DI 1 "memory_operand" "")
20749                             (match_operand:DI 2 "immediate_operand" "")))
20750               (clobber (reg:CC FLAGS_REG))])]
20751   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
20752    && !satisfies_constraint_K (operands[2])"
20753   [(set (match_dup 3) (match_dup 1))
20754    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20755               (clobber (reg:CC FLAGS_REG))])]
20756 "")
20757
20758 (define_peephole2
20759   [(match_scratch:SI 3 "r")
20760    (parallel [(set (match_operand:SI 0 "register_operand" "")
20761                    (mult:SI (match_operand:SI 1 "memory_operand" "")
20762                             (match_operand:SI 2 "immediate_operand" "")))
20763               (clobber (reg:CC FLAGS_REG))])]
20764   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
20765    && !satisfies_constraint_K (operands[2])"
20766   [(set (match_dup 3) (match_dup 1))
20767    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20768               (clobber (reg:CC FLAGS_REG))])]
20769 "")
20770
20771 (define_peephole2
20772   [(match_scratch:SI 3 "r")
20773    (parallel [(set (match_operand:DI 0 "register_operand" "")
20774                    (zero_extend:DI
20775                      (mult:SI (match_operand:SI 1 "memory_operand" "")
20776                               (match_operand:SI 2 "immediate_operand" ""))))
20777               (clobber (reg:CC FLAGS_REG))])]
20778   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
20779    && !satisfies_constraint_K (operands[2])"
20780   [(set (match_dup 3) (match_dup 1))
20781    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20782               (clobber (reg:CC FLAGS_REG))])]
20783 "")
20784
20785 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20786 ;; Convert it into imul reg, reg
20787 ;; It would be better to force assembler to encode instruction using long
20788 ;; immediate, but there is apparently no way to do so.
20789 (define_peephole2
20790   [(parallel [(set (match_operand:DI 0 "register_operand" "")
20791                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20792                             (match_operand:DI 2 "const_int_operand" "")))
20793               (clobber (reg:CC FLAGS_REG))])
20794    (match_scratch:DI 3 "r")]
20795   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
20796    && satisfies_constraint_K (operands[2])"
20797   [(set (match_dup 3) (match_dup 2))
20798    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20799               (clobber (reg:CC FLAGS_REG))])]
20800 {
20801   if (!rtx_equal_p (operands[0], operands[1]))
20802     emit_move_insn (operands[0], operands[1]);
20803 })
20804
20805 (define_peephole2
20806   [(parallel [(set (match_operand:SI 0 "register_operand" "")
20807                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20808                             (match_operand:SI 2 "const_int_operand" "")))
20809               (clobber (reg:CC FLAGS_REG))])
20810    (match_scratch:SI 3 "r")]
20811   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
20812    && satisfies_constraint_K (operands[2])"
20813   [(set (match_dup 3) (match_dup 2))
20814    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20815               (clobber (reg:CC FLAGS_REG))])]
20816 {
20817   if (!rtx_equal_p (operands[0], operands[1]))
20818     emit_move_insn (operands[0], operands[1]);
20819 })
20820
20821 (define_peephole2
20822   [(parallel [(set (match_operand:HI 0 "register_operand" "")
20823                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20824                             (match_operand:HI 2 "immediate_operand" "")))
20825               (clobber (reg:CC FLAGS_REG))])
20826    (match_scratch:HI 3 "r")]
20827   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()"
20828   [(set (match_dup 3) (match_dup 2))
20829    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20830               (clobber (reg:CC FLAGS_REG))])]
20831 {
20832   if (!rtx_equal_p (operands[0], operands[1]))
20833     emit_move_insn (operands[0], operands[1]);
20834 })
20835
20836 ;; After splitting up read-modify operations, array accesses with memory
20837 ;; operands might end up in form:
20838 ;;  sall    $2, %eax
20839 ;;  movl    4(%esp), %edx
20840 ;;  addl    %edx, %eax
20841 ;; instead of pre-splitting:
20842 ;;  sall    $2, %eax
20843 ;;  addl    4(%esp), %eax
20844 ;; Turn it into:
20845 ;;  movl    4(%esp), %edx
20846 ;;  leal    (%edx,%eax,4), %eax
20847
20848 (define_peephole2
20849   [(parallel [(set (match_operand 0 "register_operand" "")
20850                    (ashift (match_operand 1 "register_operand" "")
20851                            (match_operand 2 "const_int_operand" "")))
20852                (clobber (reg:CC FLAGS_REG))])
20853    (set (match_operand 3 "register_operand")
20854         (match_operand 4 "x86_64_general_operand" ""))
20855    (parallel [(set (match_operand 5 "register_operand" "")
20856                    (plus (match_operand 6 "register_operand" "")
20857                          (match_operand 7 "register_operand" "")))
20858                    (clobber (reg:CC FLAGS_REG))])]
20859   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20860    /* Validate MODE for lea.  */
20861    && ((!TARGET_PARTIAL_REG_STALL
20862         && (GET_MODE (operands[0]) == QImode
20863             || GET_MODE (operands[0]) == HImode))
20864        || GET_MODE (operands[0]) == SImode
20865        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20866    /* We reorder load and the shift.  */
20867    && !rtx_equal_p (operands[1], operands[3])
20868    && !reg_overlap_mentioned_p (operands[0], operands[4])
20869    /* Last PLUS must consist of operand 0 and 3.  */
20870    && !rtx_equal_p (operands[0], operands[3])
20871    && (rtx_equal_p (operands[3], operands[6])
20872        || rtx_equal_p (operands[3], operands[7]))
20873    && (rtx_equal_p (operands[0], operands[6])
20874        || rtx_equal_p (operands[0], operands[7]))
20875    /* The intermediate operand 0 must die or be same as output.  */
20876    && (rtx_equal_p (operands[0], operands[5])
20877        || peep2_reg_dead_p (3, operands[0]))"
20878   [(set (match_dup 3) (match_dup 4))
20879    (set (match_dup 0) (match_dup 1))]
20880 {
20881   enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20882   int scale = 1 << INTVAL (operands[2]);
20883   rtx index = gen_lowpart (Pmode, operands[1]);
20884   rtx base = gen_lowpart (Pmode, operands[3]);
20885   rtx dest = gen_lowpart (mode, operands[5]);
20886
20887   operands[1] = gen_rtx_PLUS (Pmode, base,
20888                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20889   if (mode != Pmode)
20890     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20891   operands[0] = dest;
20892 })
20893 \f
20894 ;; Call-value patterns last so that the wildcard operand does not
20895 ;; disrupt insn-recog's switch tables.
20896
20897 (define_insn "*call_value_pop_0"
20898   [(set (match_operand 0 "" "")
20899         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20900               (match_operand:SI 2 "" "")))
20901    (set (reg:SI SP_REG)
20902         (plus:SI (reg:SI SP_REG)
20903                  (match_operand:SI 3 "immediate_operand" "")))]
20904   "!TARGET_64BIT"
20905 {
20906   if (SIBLING_CALL_P (insn))
20907     return "jmp\t%P1";
20908   else
20909     return "call\t%P1";
20910 }
20911   [(set_attr "type" "callv")])
20912
20913 (define_insn "*call_value_pop_1"
20914   [(set (match_operand 0 "" "")
20915         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
20916               (match_operand:SI 2 "" "")))
20917    (set (reg:SI SP_REG)
20918         (plus:SI (reg:SI SP_REG)
20919                  (match_operand:SI 3 "immediate_operand" "i")))]
20920   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
20921 {
20922   if (constant_call_address_operand (operands[1], Pmode))
20923     return "call\t%P1";
20924   return "call\t%A1";
20925 }
20926   [(set_attr "type" "callv")])
20927
20928 (define_insn "*sibcall_value_pop_1"
20929   [(set (match_operand 0 "" "")
20930         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
20931               (match_operand:SI 2 "" "")))
20932    (set (reg:SI SP_REG)
20933         (plus:SI (reg:SI SP_REG)
20934                  (match_operand:SI 3 "immediate_operand" "i,i")))]
20935   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
20936   "@
20937    jmp\t%P1
20938    jmp\t%A1"
20939   [(set_attr "type" "callv")])
20940
20941 (define_insn "*call_value_0"
20942   [(set (match_operand 0 "" "")
20943         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20944               (match_operand:SI 2 "" "")))]
20945   "!TARGET_64BIT"
20946 {
20947   if (SIBLING_CALL_P (insn))
20948     return "jmp\t%P1";
20949   else
20950     return "call\t%P1";
20951 }
20952   [(set_attr "type" "callv")])
20953
20954 (define_insn "*call_value_0_rex64"
20955   [(set (match_operand 0 "" "")
20956         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20957               (match_operand:DI 2 "const_int_operand" "")))]
20958   "TARGET_64BIT"
20959 {
20960   if (SIBLING_CALL_P (insn))
20961     return "jmp\t%P1";
20962   else
20963     return "call\t%P1";
20964 }
20965   [(set_attr "type" "callv")])
20966
20967 (define_insn "*call_value_0_rex64_ms_sysv"
20968   [(set (match_operand 0 "" "")
20969         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20970               (match_operand:DI 2 "const_int_operand" "")))
20971    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
20972    (clobber (reg:TI XMM6_REG))
20973    (clobber (reg:TI XMM7_REG))
20974    (clobber (reg:TI XMM8_REG))
20975    (clobber (reg:TI XMM9_REG))
20976    (clobber (reg:TI XMM10_REG))
20977    (clobber (reg:TI XMM11_REG))
20978    (clobber (reg:TI XMM12_REG))
20979    (clobber (reg:TI XMM13_REG))
20980    (clobber (reg:TI XMM14_REG))
20981    (clobber (reg:TI XMM15_REG))
20982    (clobber (reg:DI SI_REG))
20983    (clobber (reg:DI DI_REG))]
20984   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
20985 {
20986   if (SIBLING_CALL_P (insn))
20987     return "jmp\t%P1";
20988   else
20989     return "call\t%P1";
20990 }
20991   [(set_attr "type" "callv")])
20992
20993 (define_insn "*call_value_1"
20994   [(set (match_operand 0 "" "")
20995         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
20996               (match_operand:SI 2 "" "")))]
20997   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
20998 {
20999   if (constant_call_address_operand (operands[1], Pmode))
21000     return "call\t%P1";
21001   return "call\t%A1";
21002 }
21003   [(set_attr "type" "callv")])
21004
21005 (define_insn "*sibcall_value_1"
21006   [(set (match_operand 0 "" "")
21007         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
21008               (match_operand:SI 2 "" "")))]
21009   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
21010   "@
21011    jmp\t%P1
21012    jmp\t%A1"
21013   [(set_attr "type" "callv")])
21014
21015 (define_insn "*call_value_1_rex64"
21016   [(set (match_operand 0 "" "")
21017         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
21018               (match_operand:DI 2 "" "")))]
21019   "TARGET_64BIT && !SIBLING_CALL_P (insn)
21020    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
21021 {
21022   if (constant_call_address_operand (operands[1], Pmode))
21023     return "call\t%P1";
21024   return "call\t%A1";
21025 }
21026   [(set_attr "type" "callv")])
21027
21028 (define_insn "*call_value_1_rex64_ms_sysv"
21029   [(set (match_operand 0 "" "")
21030         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
21031               (match_operand:DI 2 "" "")))
21032    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
21033    (clobber (reg:TI XMM6_REG))
21034    (clobber (reg:TI XMM7_REG))
21035    (clobber (reg:TI XMM8_REG))
21036    (clobber (reg:TI XMM9_REG))
21037    (clobber (reg:TI XMM10_REG))
21038    (clobber (reg:TI XMM11_REG))
21039    (clobber (reg:TI XMM12_REG))
21040    (clobber (reg:TI XMM13_REG))
21041    (clobber (reg:TI XMM14_REG))
21042    (clobber (reg:TI XMM15_REG))
21043    (clobber (reg:DI SI_REG))
21044    (clobber (reg:DI DI_REG))]
21045   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
21046 {
21047   if (constant_call_address_operand (operands[1], Pmode))
21048     return "call\t%P1";
21049   return "call\t%A1";
21050 }
21051   [(set_attr "type" "callv")])
21052
21053 (define_insn "*call_value_1_rex64_large"
21054   [(set (match_operand 0 "" "")
21055         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
21056               (match_operand:DI 2 "" "")))]
21057   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
21058   "call\t%A1"
21059   [(set_attr "type" "callv")])
21060
21061 (define_insn "*sibcall_value_1_rex64"
21062   [(set (match_operand 0 "" "")
21063         (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
21064               (match_operand:DI 2 "" "")))]
21065   "TARGET_64BIT && SIBLING_CALL_P (insn)"
21066   "@
21067    jmp\t%P1
21068    jmp\t%A1"
21069   [(set_attr "type" "callv")])
21070 \f
21071 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
21072 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
21073 ;; caught for use by garbage collectors and the like.  Using an insn that
21074 ;; maps to SIGILL makes it more likely the program will rightfully die.
21075 ;; Keeping with tradition, "6" is in honor of #UD.
21076 (define_insn "trap"
21077   [(trap_if (const_int 1) (const_int 6))]
21078   ""
21079   { return ASM_SHORT "0x0b0f"; }
21080   [(set_attr "length" "2")])
21081
21082 (define_expand "sse_prologue_save"
21083   [(parallel [(set (match_operand:BLK 0 "" "")
21084                    (unspec:BLK [(reg:DI XMM0_REG)
21085                                 (reg:DI XMM1_REG)
21086                                 (reg:DI XMM2_REG)
21087                                 (reg:DI XMM3_REG)
21088                                 (reg:DI XMM4_REG)
21089                                 (reg:DI XMM5_REG)
21090                                 (reg:DI XMM6_REG)
21091                                 (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE))
21092               (use (match_operand:DI 1 "register_operand" ""))
21093               (use (match_operand:DI 2 "immediate_operand" ""))
21094               (use (label_ref:DI (match_operand 3 "" "")))])]
21095   "TARGET_64BIT"
21096   "")
21097
21098 (define_insn "*sse_prologue_save_insn"
21099   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
21100                           (match_operand:DI 4 "const_int_operand" "n")))
21101         (unspec:BLK [(reg:DI XMM0_REG)
21102                      (reg:DI XMM1_REG)
21103                      (reg:DI XMM2_REG)
21104                      (reg:DI XMM3_REG)
21105                      (reg:DI XMM4_REG)
21106                      (reg:DI XMM5_REG)
21107                      (reg:DI XMM6_REG)
21108                      (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE))
21109    (use (match_operand:DI 1 "register_operand" "r"))
21110    (use (match_operand:DI 2 "const_int_operand" "i"))
21111    (use (label_ref:DI (match_operand 3 "" "X")))]
21112   "TARGET_64BIT
21113    && INTVAL (operands[4]) + X86_64_SSE_REGPARM_MAX * 16 - 16 < 128
21114    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
21115 {
21116   int i;
21117   operands[0] = gen_rtx_MEM (Pmode,
21118                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
21119   /* VEX instruction with a REX prefix will #UD.  */
21120   if (TARGET_AVX && GET_CODE (XEXP (operands[0], 0)) != PLUS)
21121     gcc_unreachable ();
21122
21123   output_asm_insn ("jmp\t%A1", operands);
21124   for (i = X86_64_SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
21125     {
21126       operands[4] = adjust_address (operands[0], DImode, i*16);
21127       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
21128       PUT_MODE (operands[4], TImode);
21129       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
21130         output_asm_insn ("rex", operands);
21131       output_asm_insn ("%vmovaps\t{%5, %4|%4, %5}", operands);
21132     }
21133   (*targetm.asm_out.internal_label) (asm_out_file, "L",
21134                                      CODE_LABEL_NUMBER (operands[3]));
21135   return "";
21136 }
21137   [(set_attr "type" "other")
21138    (set_attr "length_immediate" "0")
21139    (set_attr "length_address" "0")
21140    (set (attr "length")
21141      (if_then_else
21142        (eq (symbol_ref "TARGET_AVX") (const_int 0))
21143        (const_string "34")
21144        (const_string "42")))
21145    (set_attr "memory" "store")
21146    (set_attr "modrm" "0")
21147    (set_attr "prefix" "maybe_vex")
21148    (set_attr "mode" "DI")])
21149
21150 (define_expand "prefetch"
21151   [(prefetch (match_operand 0 "address_operand" "")
21152              (match_operand:SI 1 "const_int_operand" "")
21153              (match_operand:SI 2 "const_int_operand" ""))]
21154   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
21155 {
21156   int rw = INTVAL (operands[1]);
21157   int locality = INTVAL (operands[2]);
21158
21159   gcc_assert (rw == 0 || rw == 1);
21160   gcc_assert (locality >= 0 && locality <= 3);
21161   gcc_assert (GET_MODE (operands[0]) == Pmode
21162               || GET_MODE (operands[0]) == VOIDmode);
21163
21164   /* Use 3dNOW prefetch in case we are asking for write prefetch not
21165      supported by SSE counterpart or the SSE prefetch is not available
21166      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
21167      of locality.  */
21168   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
21169     operands[2] = GEN_INT (3);
21170   else
21171     operands[1] = const0_rtx;
21172 })
21173
21174 (define_insn "*prefetch_sse"
21175   [(prefetch (match_operand:SI 0 "address_operand" "p")
21176              (const_int 0)
21177              (match_operand:SI 1 "const_int_operand" ""))]
21178   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
21179 {
21180   static const char * const patterns[4] = {
21181    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21182   };
21183
21184   int locality = INTVAL (operands[1]);
21185   gcc_assert (locality >= 0 && locality <= 3);
21186
21187   return patterns[locality];
21188 }
21189   [(set_attr "type" "sse")
21190    (set_attr "atom_sse_attr" "prefetch")
21191    (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
21192    (set_attr "memory" "none")])
21193
21194 (define_insn "*prefetch_sse_rex"
21195   [(prefetch (match_operand:DI 0 "address_operand" "p")
21196              (const_int 0)
21197              (match_operand:SI 1 "const_int_operand" ""))]
21198   "TARGET_PREFETCH_SSE && TARGET_64BIT"
21199 {
21200   static const char * const patterns[4] = {
21201    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21202   };
21203
21204   int locality = INTVAL (operands[1]);
21205   gcc_assert (locality >= 0 && locality <= 3);
21206
21207   return patterns[locality];
21208 }
21209   [(set_attr "type" "sse")
21210    (set_attr "atom_sse_attr" "prefetch")
21211    (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
21212    (set_attr "memory" "none")])
21213
21214 (define_insn "*prefetch_3dnow"
21215   [(prefetch (match_operand:SI 0 "address_operand" "p")
21216              (match_operand:SI 1 "const_int_operand" "n")
21217              (const_int 3))]
21218   "TARGET_3DNOW && !TARGET_64BIT"
21219 {
21220   if (INTVAL (operands[1]) == 0)
21221     return "prefetch\t%a0";
21222   else
21223     return "prefetchw\t%a0";
21224 }
21225   [(set_attr "type" "mmx")
21226    (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
21227    (set_attr "memory" "none")])
21228
21229 (define_insn "*prefetch_3dnow_rex"
21230   [(prefetch (match_operand:DI 0 "address_operand" "p")
21231              (match_operand:SI 1 "const_int_operand" "n")
21232              (const_int 3))]
21233   "TARGET_3DNOW && TARGET_64BIT"
21234 {
21235   if (INTVAL (operands[1]) == 0)
21236     return "prefetch\t%a0";
21237   else
21238     return "prefetchw\t%a0";
21239 }
21240   [(set_attr "type" "mmx")
21241    (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
21242    (set_attr "memory" "none")])
21243
21244 (define_expand "stack_protect_set"
21245   [(match_operand 0 "memory_operand" "")
21246    (match_operand 1 "memory_operand" "")]
21247   ""
21248 {
21249 #ifdef TARGET_THREAD_SSP_OFFSET
21250   if (TARGET_64BIT)
21251     emit_insn (gen_stack_tls_protect_set_di (operands[0],
21252                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21253   else
21254     emit_insn (gen_stack_tls_protect_set_si (operands[0],
21255                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21256 #else
21257   if (TARGET_64BIT)
21258     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
21259   else
21260     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
21261 #endif
21262   DONE;
21263 })
21264
21265 (define_insn "stack_protect_set_si"
21266   [(set (match_operand:SI 0 "memory_operand" "=m")
21267         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21268    (set (match_scratch:SI 2 "=&r") (const_int 0))
21269    (clobber (reg:CC FLAGS_REG))]
21270   ""
21271   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21272   [(set_attr "type" "multi")])
21273
21274 (define_insn "stack_protect_set_di"
21275   [(set (match_operand:DI 0 "memory_operand" "=m")
21276         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21277    (set (match_scratch:DI 2 "=&r") (const_int 0))
21278    (clobber (reg:CC FLAGS_REG))]
21279   "TARGET_64BIT"
21280   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
21281   [(set_attr "type" "multi")])
21282
21283 (define_insn "stack_tls_protect_set_si"
21284   [(set (match_operand:SI 0 "memory_operand" "=m")
21285         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21286    (set (match_scratch:SI 2 "=&r") (const_int 0))
21287    (clobber (reg:CC FLAGS_REG))]
21288   ""
21289   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21290   [(set_attr "type" "multi")])
21291
21292 (define_insn "stack_tls_protect_set_di"
21293   [(set (match_operand:DI 0 "memory_operand" "=m")
21294         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21295    (set (match_scratch:DI 2 "=&r") (const_int 0))
21296    (clobber (reg:CC FLAGS_REG))]
21297   "TARGET_64BIT"
21298   {
21299      /* The kernel uses a different segment register for performance reasons; a
21300         system call would not have to trash the userspace segment register,
21301         which would be expensive */
21302      if (ix86_cmodel != CM_KERNEL)
21303         return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21304      else
21305         return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21306   }
21307   [(set_attr "type" "multi")])
21308
21309 (define_expand "stack_protect_test"
21310   [(match_operand 0 "memory_operand" "")
21311    (match_operand 1 "memory_operand" "")
21312    (match_operand 2 "" "")]
21313   ""
21314 {
21315   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
21316
21317 #ifdef TARGET_THREAD_SSP_OFFSET
21318   if (TARGET_64BIT)
21319     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
21320                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21321   else
21322     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
21323                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21324 #else
21325   if (TARGET_64BIT)
21326     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
21327   else
21328     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
21329 #endif
21330
21331   emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
21332                                   flags, const0_rtx, operands[2]));
21333   DONE;
21334 })
21335
21336 (define_insn "stack_protect_test_si"
21337   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21338         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21339                      (match_operand:SI 2 "memory_operand" "m")]
21340                     UNSPEC_SP_TEST))
21341    (clobber (match_scratch:SI 3 "=&r"))]
21342   ""
21343   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
21344   [(set_attr "type" "multi")])
21345
21346 (define_insn "stack_protect_test_di"
21347   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21348         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21349                      (match_operand:DI 2 "memory_operand" "m")]
21350                     UNSPEC_SP_TEST))
21351    (clobber (match_scratch:DI 3 "=&r"))]
21352   "TARGET_64BIT"
21353   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
21354   [(set_attr "type" "multi")])
21355
21356 (define_insn "stack_tls_protect_test_si"
21357   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21358         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21359                      (match_operand:SI 2 "const_int_operand" "i")]
21360                     UNSPEC_SP_TLS_TEST))
21361    (clobber (match_scratch:SI 3 "=r"))]
21362   ""
21363   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
21364   [(set_attr "type" "multi")])
21365
21366 (define_insn "stack_tls_protect_test_di"
21367   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21368         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21369                      (match_operand:DI 2 "const_int_operand" "i")]
21370                     UNSPEC_SP_TLS_TEST))
21371    (clobber (match_scratch:DI 3 "=r"))]
21372   "TARGET_64BIT"
21373   {
21374      /* The kernel uses a different segment register for performance reasons; a
21375         system call would not have to trash the userspace segment register,
21376         which would be expensive */
21377      if (ix86_cmodel != CM_KERNEL)
21378         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
21379      else
21380         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
21381   }
21382   [(set_attr "type" "multi")])
21383
21384 (define_mode_iterator CRC32MODE [QI HI SI])
21385 (define_mode_attr crc32modesuffix [(QI "b") (HI "w") (SI "l")])
21386 (define_mode_attr crc32modeconstraint [(QI "qm") (HI "rm") (SI "rm")])
21387
21388 (define_insn "sse4_2_crc32<mode>"
21389   [(set (match_operand:SI 0 "register_operand" "=r")
21390         (unspec:SI
21391           [(match_operand:SI 1 "register_operand" "0")
21392            (match_operand:CRC32MODE 2 "nonimmediate_operand" "<crc32modeconstraint>")]
21393           UNSPEC_CRC32))]
21394   "TARGET_SSE4_2 || TARGET_CRC32"
21395   "crc32<crc32modesuffix>\t{%2, %0|%0, %2}"
21396   [(set_attr "type" "sselog1")
21397    (set_attr "prefix_rep" "1")
21398    (set_attr "prefix_extra" "1")
21399    (set (attr "prefix_data16")
21400      (if_then_else (match_operand:HI 2 "" "")
21401        (const_string "1")
21402        (const_string "*")))
21403    (set (attr "prefix_rex")
21404      (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
21405        (const_string "1")
21406        (const_string "*")))
21407    (set_attr "mode" "SI")])
21408
21409 (define_insn "sse4_2_crc32di"
21410   [(set (match_operand:DI 0 "register_operand" "=r")
21411         (unspec:DI
21412           [(match_operand:DI 1 "register_operand" "0")
21413            (match_operand:DI 2 "nonimmediate_operand" "rm")]
21414           UNSPEC_CRC32))]
21415   "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
21416   "crc32q\t{%2, %0|%0, %2}"
21417   [(set_attr "type" "sselog1")
21418    (set_attr "prefix_rep" "1")
21419    (set_attr "prefix_extra" "1")
21420    (set_attr "mode" "DI")])
21421
21422 (define_expand "rdpmc"
21423   [(match_operand:DI 0 "register_operand" "")
21424    (match_operand:SI 1 "register_operand" "")]
21425   ""
21426 {
21427   rtx reg = gen_reg_rtx (DImode);
21428   rtx si;
21429
21430   /* Force operand 1 into ECX.  */
21431   rtx ecx = gen_rtx_REG (SImode, CX_REG);
21432   emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
21433   si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
21434                                 UNSPECV_RDPMC);
21435
21436   if (TARGET_64BIT)
21437     {
21438       rtvec vec = rtvec_alloc (2);
21439       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
21440       rtx upper = gen_reg_rtx (DImode);
21441       rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
21442                                         gen_rtvec (1, const0_rtx),
21443                                         UNSPECV_RDPMC);
21444       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
21445       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
21446       emit_insn (load);
21447       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
21448                                    NULL, 1, OPTAB_DIRECT);
21449       reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
21450                                  OPTAB_DIRECT);
21451     }
21452   else
21453     emit_insn (gen_rtx_SET (VOIDmode, reg, si));
21454   emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
21455   DONE;
21456 })
21457
21458 (define_insn "*rdpmc"
21459   [(set (match_operand:DI 0 "register_operand" "=A")
21460         (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
21461                             UNSPECV_RDPMC))]
21462   "!TARGET_64BIT"
21463   "rdpmc"
21464   [(set_attr "type" "other")
21465    (set_attr "length" "2")])
21466
21467 (define_insn "*rdpmc_rex64"
21468   [(set (match_operand:DI 0 "register_operand" "=a")
21469         (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
21470                             UNSPECV_RDPMC))
21471   (set (match_operand:DI 1 "register_operand" "=d")
21472        (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
21473   "TARGET_64BIT"
21474   "rdpmc"
21475   [(set_attr "type" "other")
21476    (set_attr "length" "2")])
21477
21478 (define_expand "rdtsc"
21479   [(set (match_operand:DI 0 "register_operand" "")
21480         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
21481   ""
21482 {
21483   if (TARGET_64BIT)
21484     {
21485       rtvec vec = rtvec_alloc (2);
21486       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
21487       rtx upper = gen_reg_rtx (DImode);
21488       rtx lower = gen_reg_rtx (DImode);
21489       rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
21490                                          gen_rtvec (1, const0_rtx),
21491                                          UNSPECV_RDTSC);
21492       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
21493       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
21494       emit_insn (load);
21495       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
21496                                    NULL, 1, OPTAB_DIRECT);
21497       lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
21498                                    OPTAB_DIRECT);
21499       emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
21500       DONE;
21501     }
21502 })
21503
21504 (define_insn "*rdtsc"
21505   [(set (match_operand:DI 0 "register_operand" "=A")
21506         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
21507   "!TARGET_64BIT"
21508   "rdtsc"
21509   [(set_attr "type" "other")
21510    (set_attr "length" "2")])
21511
21512 (define_insn "*rdtsc_rex64"
21513   [(set (match_operand:DI 0 "register_operand" "=a")
21514         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
21515    (set (match_operand:DI 1 "register_operand" "=d")
21516         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
21517   "TARGET_64BIT"
21518   "rdtsc"
21519   [(set_attr "type" "other")
21520    (set_attr "length" "2")])
21521
21522 (define_expand "rdtscp"
21523   [(match_operand:DI 0 "register_operand" "")
21524    (match_operand:SI 1 "memory_operand" "")]
21525   ""
21526 {
21527   rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
21528                                     gen_rtvec (1, const0_rtx),
21529                                     UNSPECV_RDTSCP);
21530   rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
21531                                     gen_rtvec (1, const0_rtx),
21532                                     UNSPECV_RDTSCP);
21533   rtx reg = gen_reg_rtx (DImode);
21534   rtx tmp = gen_reg_rtx (SImode);
21535
21536   if (TARGET_64BIT)
21537     {
21538       rtvec vec = rtvec_alloc (3);
21539       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
21540       rtx upper = gen_reg_rtx (DImode);
21541       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
21542       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
21543       RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
21544       emit_insn (load);
21545       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
21546                                    NULL, 1, OPTAB_DIRECT);
21547       reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
21548                                  OPTAB_DIRECT);
21549     }
21550   else
21551     {
21552       rtvec vec = rtvec_alloc (2);
21553       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
21554       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
21555       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
21556       emit_insn (load);
21557     }
21558   emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
21559   emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
21560   DONE;
21561 })
21562
21563 (define_insn "*rdtscp"
21564   [(set (match_operand:DI 0 "register_operand" "=A")
21565         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
21566    (set (match_operand:SI 1 "register_operand" "=c")
21567         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
21568   "!TARGET_64BIT"
21569   "rdtscp"
21570   [(set_attr "type" "other")
21571    (set_attr "length" "3")])
21572
21573 (define_insn "*rdtscp_rex64"
21574   [(set (match_operand:DI 0 "register_operand" "=a")
21575         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
21576    (set (match_operand:DI 1 "register_operand" "=d")
21577         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
21578    (set (match_operand:SI 2 "register_operand" "=c")
21579         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
21580   "TARGET_64BIT"
21581   "rdtscp"
21582   [(set_attr "type" "other")
21583    (set_attr "length" "3")])
21584
21585 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
21586 ;;
21587 ;; LWP instructions
21588 ;;
21589 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
21590
21591 (define_insn "lwp_llwpcbhi1"
21592   [(unspec [(match_operand:HI 0 "register_operand" "r")]
21593            UNSPEC_LLWP_INTRINSIC)]
21594   "TARGET_LWP"
21595   "llwpcb\t%0"
21596   [(set_attr "type" "lwp")
21597    (set_attr "mode" "HI")])
21598
21599 (define_insn "lwp_llwpcbsi1"
21600   [(unspec [(match_operand:SI 0 "register_operand" "r")]
21601            UNSPEC_LLWP_INTRINSIC)]
21602   "TARGET_LWP"
21603   "llwpcb\t%0"
21604   [(set_attr "type" "lwp")
21605    (set_attr "mode" "SI")])
21606
21607 (define_insn "lwp_llwpcbdi1"
21608   [(unspec [(match_operand:DI 0 "register_operand" "r")]
21609            UNSPEC_LLWP_INTRINSIC)]
21610   "TARGET_LWP"
21611   "llwpcb\t%0"
21612   [(set_attr "type" "lwp")
21613    (set_attr "mode" "DI")])
21614
21615 (define_insn "lwp_slwpcbhi1"
21616   [(unspec [(match_operand:HI 0 "register_operand" "r")]
21617            UNSPEC_SLWP_INTRINSIC)]
21618   "TARGET_LWP"
21619   "slwpcb\t%0"
21620   [(set_attr "type" "lwp")
21621    (set_attr "mode" "HI")])
21622
21623 (define_insn "lwp_slwpcbsi1"
21624   [(unspec [(match_operand:SI 0 "register_operand" "r")]
21625            UNSPEC_SLWP_INTRINSIC)]
21626   "TARGET_LWP"
21627   "slwpcb\t%0"
21628   [(set_attr "type" "lwp")
21629    (set_attr "mode" "SI")])
21630
21631 (define_insn "lwp_slwpcbdi1"
21632   [(unspec [(match_operand:DI 0 "register_operand" "r")]
21633            UNSPEC_SLWP_INTRINSIC)]
21634   "TARGET_LWP"
21635   "slwpcb\t%0"
21636   [(set_attr "type" "lwp")
21637    (set_attr "mode" "DI")])
21638
21639 (define_insn "lwp_lwpvalhi3"
21640   [(unspec_volatile [(match_operand:HI 0 "register_operand" "r")
21641                      (match_operand:SI 1 "nonimmediate_operand" "rm")
21642                      (match_operand:HI 2 "const_int_operand" "")]
21643                     UNSPECV_LWPVAL_INTRINSIC)]
21644   "TARGET_LWP"
21645   "lwpval\t{%2, %1, %0|%0, %1, %2}"
21646   [(set_attr "type" "lwp")
21647    (set_attr "mode" "HI")])
21648
21649 (define_insn "lwp_lwpvalsi3"
21650   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
21651                      (match_operand:SI 1 "nonimmediate_operand" "rm")
21652                      (match_operand:SI 2 "const_int_operand" "")]
21653                     UNSPECV_LWPVAL_INTRINSIC)]
21654   "TARGET_LWP"
21655   "lwpval\t{%2, %1, %0|%0, %1, %2}"
21656   [(set_attr "type" "lwp")
21657    (set_attr "mode" "SI")])
21658
21659 (define_insn "lwp_lwpvaldi3"
21660   [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")
21661                      (match_operand:SI 1 "nonimmediate_operand" "rm")
21662                      (match_operand:SI 2 "const_int_operand" "")]
21663                     UNSPECV_LWPVAL_INTRINSIC)]
21664   "TARGET_LWP"
21665   "lwpval\t{%2, %1, %0|%0, %1, %2}"
21666   [(set_attr "type" "lwp")
21667    (set_attr "mode" "DI")])
21668
21669 (define_insn "lwp_lwpinshi3"
21670   [(unspec_volatile [(match_operand:HI 0 "register_operand" "r")
21671                      (match_operand:SI 1 "nonimmediate_operand" "rm")
21672                      (match_operand:HI 2 "const_int_operand" "")]
21673                     UNSPECV_LWPINS_INTRINSIC)]
21674   "TARGET_LWP"
21675   "lwpins\t{%2, %1, %0|%0, %1, %2}"
21676   [(set_attr "type" "lwp")
21677    (set_attr "mode" "HI")])
21678
21679 (define_insn "lwp_lwpinssi3"
21680   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
21681                      (match_operand:SI 1 "nonimmediate_operand" "rm")
21682                      (match_operand:SI 2 "const_int_operand" "")]
21683                     UNSPECV_LWPINS_INTRINSIC)]
21684   "TARGET_LWP"
21685   "lwpins\t{%2, %1, %0|%0, %1, %2}"
21686   [(set_attr "type" "lwp")
21687    (set_attr "mode" "SI")])
21688
21689 (define_insn "lwp_lwpinsdi3"
21690   [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")
21691                      (match_operand:SI 1 "nonimmediate_operand" "rm")
21692                      (match_operand:SI 2 "const_int_operand" "")]
21693                     UNSPECV_LWPINS_INTRINSIC)]
21694   "TARGET_LWP"
21695   "lwpins\t{%2, %1, %0|%0, %1, %2}"
21696   [(set_attr "type" "lwp")
21697    (set_attr "mode" "DI")])
21698
21699 (include "mmx.md")
21700 (include "sse.md")
21701 (include "sync.md")