OSDN Git Service

8bd8e0f133abc11885a7e14f60819c9ee49549be
[pf3gnuchains/gcc-fork.git] / gcc / config / i386 / i386.md
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
7 ;;
8 ;; This file is part of GCC.
9 ;;
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 3, or (at your option)
13 ;; any later version.
14 ;;
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 ;; GNU General Public License for more details.
19 ;;
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING3.  If not see
22 ;; <http://www.gnu.org/licenses/>.  */
23 ;;
24 ;; The original PO technology requires these to be ordered by speed,
25 ;; so that assigner will pick the fastest.
26 ;;
27 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
28 ;;
29 ;; The special asm out single letter directives following a '%' are:
30 ;; L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
31 ;; C -- print opcode suffix for set/cmov insn.
32 ;; c -- like C, but print reversed condition
33 ;; F,f -- likewise, but for floating-point.
34 ;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
35 ;;      otherwise nothing
36 ;; R -- print the prefix for register names.
37 ;; z -- print the opcode suffix for the size of the current operand.
38 ;; Z -- likewise, with special suffixes for x87 instructions.
39 ;; * -- print a star (in certain assembler syntax)
40 ;; A -- print an absolute memory reference.
41 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
42 ;; s -- print a shift double count, followed by the assemblers argument
43 ;;      delimiter.
44 ;; b -- print the QImode name of the register for the indicated operand.
45 ;;      %b0 would print %al if operands[0] is reg 0.
46 ;; w --  likewise, print the HImode name of the register.
47 ;; k --  likewise, print the SImode name of the register.
48 ;; q --  likewise, print the DImode name of the register.
49 ;; x --  likewise, print the V4SFmode name of the register.
50 ;; t --  likewise, print the V8SFmode name of the register.
51 ;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
52 ;; y -- print "st(0)" instead of "st" as a register.
53 ;; d -- print duplicated register operand for AVX instruction.
54 ;; D -- print condition for SSE cmp instruction.
55 ;; P -- if PIC, print an @PLT suffix.
56 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
57 ;; & -- print some in-use local-dynamic symbol name.
58 ;; H -- print a memory address offset by 8; used for sse high-parts
59 ;; Y -- print condition for XOP pcom* instruction.
60 ;; + -- print a branch hint as 'cs' or 'ds' prefix
61 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
62
63 ;; UNSPEC usage:
64
65 (define_constants
66   [; Relocation specifiers
67    (UNSPEC_GOT                  0)
68    (UNSPEC_GOTOFF               1)
69    (UNSPEC_GOTPCREL             2)
70    (UNSPEC_GOTTPOFF             3)
71    (UNSPEC_TPOFF                4)
72    (UNSPEC_NTPOFF               5)
73    (UNSPEC_DTPOFF               6)
74    (UNSPEC_GOTNTPOFF            7)
75    (UNSPEC_INDNTPOFF            8)
76    (UNSPEC_PLTOFF               9)
77    (UNSPEC_MACHOPIC_OFFSET      10)
78
79    ; Prologue support
80    (UNSPEC_STACK_ALLOC          11)
81    (UNSPEC_SET_GOT              12)
82    (UNSPEC_SSE_PROLOGUE_SAVE    13)
83    (UNSPEC_REG_SAVE             14)
84    (UNSPEC_DEF_CFA              15)
85    (UNSPEC_SET_RIP              16)
86    (UNSPEC_SET_GOT_OFFSET       17)
87    (UNSPEC_MEMORY_BLOCKAGE      18)
88
89    ; TLS support
90    (UNSPEC_TP                   20)
91    (UNSPEC_TLS_GD               21)
92    (UNSPEC_TLS_LD_BASE          22)
93    (UNSPEC_TLSDESC              23)
94
95    ; Other random patterns
96    (UNSPEC_SCAS                 30)
97    (UNSPEC_FNSTSW               31)
98    (UNSPEC_SAHF                 32)
99    (UNSPEC_FSTCW                33)
100    (UNSPEC_ADD_CARRY            34)
101    (UNSPEC_FLDCW                35)
102    (UNSPEC_REP                  36)
103    (UNSPEC_LD_MPIC              38)     ; load_macho_picbase
104    (UNSPEC_TRUNC_NOOP           39)
105
106    ; For SSE/MMX support:
107    (UNSPEC_FIX_NOTRUNC          40)
108    (UNSPEC_MASKMOV              41)
109    (UNSPEC_MOVMSK               42)
110    (UNSPEC_MOVNT                43)
111    (UNSPEC_MOVU                 44)
112    (UNSPEC_RCP                  45)
113    (UNSPEC_RSQRT                46)
114    (UNSPEC_SFENCE               47)
115    (UNSPEC_PFRCP                49)
116    (UNSPEC_PFRCPIT1             40)
117    (UNSPEC_PFRCPIT2             41)
118    (UNSPEC_PFRSQRT              42)
119    (UNSPEC_PFRSQIT1             43)
120    (UNSPEC_MFENCE               44)
121    (UNSPEC_LFENCE               45)
122    (UNSPEC_PSADBW               46)
123    (UNSPEC_LDDQU                47)
124    (UNSPEC_MS_TO_SYSV_CALL      48)
125
126    ; Generic math support
127    (UNSPEC_COPYSIGN             50)
128    (UNSPEC_IEEE_MIN             51)     ; not commutative
129    (UNSPEC_IEEE_MAX             52)     ; not commutative
130
131    ; x87 Floating point
132    (UNSPEC_SIN                  60)
133    (UNSPEC_COS                  61)
134    (UNSPEC_FPATAN               62)
135    (UNSPEC_FYL2X                63)
136    (UNSPEC_FYL2XP1              64)
137    (UNSPEC_FRNDINT              65)
138    (UNSPEC_FIST                 66)
139    (UNSPEC_F2XM1                67)
140    (UNSPEC_TAN                  68)
141    (UNSPEC_FXAM                 69)
142
143    ; x87 Rounding
144    (UNSPEC_FRNDINT_FLOOR        70)
145    (UNSPEC_FRNDINT_CEIL         71)
146    (UNSPEC_FRNDINT_TRUNC        72)
147    (UNSPEC_FRNDINT_MASK_PM      73)
148    (UNSPEC_FIST_FLOOR           74)
149    (UNSPEC_FIST_CEIL            75)
150
151    ; x87 Double output FP
152    (UNSPEC_SINCOS_COS           80)
153    (UNSPEC_SINCOS_SIN           81)
154    (UNSPEC_XTRACT_FRACT         84)
155    (UNSPEC_XTRACT_EXP           85)
156    (UNSPEC_FSCALE_FRACT         86)
157    (UNSPEC_FSCALE_EXP           87)
158    (UNSPEC_FPREM_F              88)
159    (UNSPEC_FPREM_U              89)
160    (UNSPEC_FPREM1_F             90)
161    (UNSPEC_FPREM1_U             91)
162
163    (UNSPEC_C2_FLAG              95)
164    (UNSPEC_FXAM_MEM             96)
165
166    ; SSP patterns
167    (UNSPEC_SP_SET               100)
168    (UNSPEC_SP_TEST              101)
169    (UNSPEC_SP_TLS_SET           102)
170    (UNSPEC_SP_TLS_TEST          103)
171
172    ; SSSE3
173    (UNSPEC_PSHUFB               120)
174    (UNSPEC_PSIGN                121)
175    (UNSPEC_PALIGNR              122)
176
177    ; For SSE4A support
178    (UNSPEC_EXTRQI               130)
179    (UNSPEC_EXTRQ                131)
180    (UNSPEC_INSERTQI             132)
181    (UNSPEC_INSERTQ              133)
182
183    ; For SSE4.1 support
184    (UNSPEC_BLENDV               134)
185    (UNSPEC_INSERTPS             135)
186    (UNSPEC_DP                   136)
187    (UNSPEC_MOVNTDQA             137)
188    (UNSPEC_MPSADBW              138)
189    (UNSPEC_PHMINPOSUW           139)
190    (UNSPEC_PTEST                140)
191    (UNSPEC_ROUND                141)
192
193    ; For SSE4.2 support
194    (UNSPEC_CRC32                143)
195    (UNSPEC_PCMPESTR             144)
196    (UNSPEC_PCMPISTR             145)
197
198    ; For FMA4 support
199    (UNSPEC_FMA4_INTRINSIC       150)
200    (UNSPEC_FMA4_FMADDSUB        151)
201    (UNSPEC_FMA4_FMSUBADD        152)
202    (UNSPEC_XOP_UNSIGNED_CMP     151)
203    (UNSPEC_XOP_TRUEFALSE        152)
204    (UNSPEC_XOP_PERMUTE          153)
205    (UNSPEC_FRCZ                 154)
206
207    ; For AES support
208    (UNSPEC_AESENC               159)
209    (UNSPEC_AESENCLAST           160)
210    (UNSPEC_AESDEC               161)
211    (UNSPEC_AESDECLAST           162)
212    (UNSPEC_AESIMC               163)
213    (UNSPEC_AESKEYGENASSIST      164)
214
215    ; For PCLMUL support
216    (UNSPEC_PCLMUL               165)
217
218    ; For AVX support
219    (UNSPEC_PCMP                 166)
220    (UNSPEC_VPERMIL              167)
221    (UNSPEC_VPERMIL2             168)
222    (UNSPEC_VPERMIL2F128         169)
223    (UNSPEC_MASKLOAD             170)
224    (UNSPEC_MASKSTORE            171)
225    (UNSPEC_CAST                 172)
226    (UNSPEC_VTESTP               173)
227   ])
228
229 (define_constants
230   [(UNSPECV_BLOCKAGE            0)
231    (UNSPECV_STACK_PROBE         1)
232    (UNSPECV_EMMS                2)
233    (UNSPECV_LDMXCSR             3)
234    (UNSPECV_STMXCSR             4)
235    (UNSPECV_FEMMS               5)
236    (UNSPECV_CLFLUSH             6)
237    (UNSPECV_ALIGN               7)
238    (UNSPECV_MONITOR             8)
239    (UNSPECV_MWAIT               9)
240    (UNSPECV_CMPXCHG             10)
241    (UNSPECV_XCHG                12)
242    (UNSPECV_LOCK                13)
243    (UNSPECV_PROLOGUE_USE        14)
244    (UNSPECV_CLD                 15)
245    (UNSPECV_VZEROALL            16)
246    (UNSPECV_VZEROUPPER          17)
247    (UNSPECV_RDTSC               18)
248    (UNSPECV_RDTSCP              19)
249    (UNSPECV_RDPMC               20)
250    (UNSPECV_VSWAPMOV            21)
251    (UNSPECV_LLWP_INTRINSIC      22)
252    (UNSPECV_SLWP_INTRINSIC      23)
253    (UNSPECV_LWPVAL_INTRINSIC    24)
254    (UNSPECV_LWPINS_INTRINSIC    25)
255   ])
256
257 ;; Constants to represent pcomtrue/pcomfalse variants
258 (define_constants
259   [(PCOM_FALSE                  0)
260    (PCOM_TRUE                   1)
261    (COM_FALSE_S                 2)
262    (COM_FALSE_P                 3)
263    (COM_TRUE_S                  4)
264    (COM_TRUE_P                  5)
265   ])
266
267 ;; Constants used in the XOP pperm instruction
268 (define_constants
269   [(PPERM_SRC                   0x00)   /* copy source */
270    (PPERM_INVERT                0x20)   /* invert source */
271    (PPERM_REVERSE               0x40)   /* bit reverse source */
272    (PPERM_REV_INV               0x60)   /* bit reverse & invert src */
273    (PPERM_ZERO                  0x80)   /* all 0's */
274    (PPERM_ONES                  0xa0)   /* all 1's */
275    (PPERM_SIGN                  0xc0)   /* propagate sign bit */
276    (PPERM_INV_SIGN              0xe0)   /* invert & propagate sign */
277    (PPERM_SRC1                  0x00)   /* use first source byte */
278    (PPERM_SRC2                  0x10)   /* use second source byte */
279    ])
280
281 ;; Registers by name.
282 (define_constants
283   [(AX_REG                       0)
284    (DX_REG                       1)
285    (CX_REG                       2)
286    (BX_REG                       3)
287    (SI_REG                       4)
288    (DI_REG                       5)
289    (BP_REG                       6)
290    (SP_REG                       7)
291    (ST0_REG                      8)
292    (ST1_REG                      9)
293    (ST2_REG                     10)
294    (ST3_REG                     11)
295    (ST4_REG                     12)
296    (ST5_REG                     13)
297    (ST6_REG                     14)
298    (ST7_REG                     15)
299    (FLAGS_REG                   17)
300    (FPSR_REG                    18)
301    (FPCR_REG                    19)
302    (XMM0_REG                    21)
303    (XMM1_REG                    22)
304    (XMM2_REG                    23)
305    (XMM3_REG                    24)
306    (XMM4_REG                    25)
307    (XMM5_REG                    26)
308    (XMM6_REG                    27)
309    (XMM7_REG                    28)
310    (MM0_REG                     29)
311    (MM1_REG                     30)
312    (MM2_REG                     31)
313    (MM3_REG                     32)
314    (MM4_REG                     33)
315    (MM5_REG                     34)
316    (MM6_REG                     35)
317    (MM7_REG                     36)
318    (R8_REG                      37)
319    (R9_REG                      38)
320    (R10_REG                     39)
321    (R11_REG                     40)
322    (R12_REG                     41)
323    (R13_REG                     42)
324    (XMM8_REG                    45)
325    (XMM9_REG                    46)
326    (XMM10_REG                   47)
327    (XMM11_REG                   48)
328    (XMM12_REG                   49)
329    (XMM13_REG                   50)
330    (XMM14_REG                   51)
331    (XMM15_REG                   52)
332   ])
333
334 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
335 ;; from i386.c.
336
337 ;; In C guard expressions, put expressions which may be compile-time
338 ;; constants first.  This allows for better optimization.  For
339 ;; example, write "TARGET_64BIT && reload_completed", not
340 ;; "reload_completed && TARGET_64BIT".
341
342 \f
343 ;; Processor type.
344 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,atom,
345                     generic64,amdfam10"
346   (const (symbol_ref "ix86_schedule")))
347
348 ;; A basic instruction type.  Refinements due to arguments to be
349 ;; provided in other attributes.
350 (define_attr "type"
351   "other,multi,
352    alu,alu1,negnot,imov,imovx,lea,
353    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
354    icmp,test,ibr,setcc,icmov,
355    push,pop,call,callv,leave,
356    str,bitmanip,
357    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
358    sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
359    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
360    ssemuladd,sse4arg,lwp,
361    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
362   (const_string "other"))
363
364 ;; Main data type used by the insn
365 (define_attr "mode"
366   "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
367   (const_string "unknown"))
368
369 ;; The CPU unit operations uses.
370 (define_attr "unit" "integer,i387,sse,mmx,unknown"
371   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
372            (const_string "i387")
373          (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
374                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
375                           ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
376            (const_string "sse")
377          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
378            (const_string "mmx")
379          (eq_attr "type" "other")
380            (const_string "unknown")]
381          (const_string "integer")))
382
383 ;; The (bounding maximum) length of an instruction immediate.
384 (define_attr "length_immediate" ""
385   (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
386                           bitmanip")
387            (const_int 0)
388          (eq_attr "unit" "i387,sse,mmx")
389            (const_int 0)
390          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
391                           imul,icmp,push,pop")
392            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
393          (eq_attr "type" "imov,test")
394            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
395          (eq_attr "type" "call")
396            (if_then_else (match_operand 0 "constant_call_address_operand" "")
397              (const_int 4)
398              (const_int 0))
399          (eq_attr "type" "callv")
400            (if_then_else (match_operand 1 "constant_call_address_operand" "")
401              (const_int 4)
402              (const_int 0))
403          ;; We don't know the size before shorten_branches.  Expect
404          ;; the instruction to fit for better scheduling.
405          (eq_attr "type" "ibr")
406            (const_int 1)
407          ]
408          (symbol_ref "/* Update immediate_length and other attributes! */
409                       gcc_unreachable (),1")))
410
411 ;; The (bounding maximum) length of an instruction address.
412 (define_attr "length_address" ""
413   (cond [(eq_attr "type" "str,other,multi,fxch")
414            (const_int 0)
415          (and (eq_attr "type" "call")
416               (match_operand 0 "constant_call_address_operand" ""))
417              (const_int 0)
418          (and (eq_attr "type" "callv")
419               (match_operand 1 "constant_call_address_operand" ""))
420              (const_int 0)
421          ]
422          (symbol_ref "ix86_attr_length_address_default (insn)")))
423
424 ;; Set when length prefix is used.
425 (define_attr "prefix_data16" ""
426   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
427            (const_int 0)
428          (eq_attr "mode" "HI")
429            (const_int 1)
430          (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
431            (const_int 1)
432         ]
433         (const_int 0)))
434
435 ;; Set when string REP prefix is used.
436 (define_attr "prefix_rep" ""
437   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
438            (const_int 0)
439          (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
440            (const_int 1)
441         ]
442         (const_int 0)))
443
444 ;; Set when 0f opcode prefix is used.
445 (define_attr "prefix_0f" ""
446   (if_then_else
447     (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
448          (eq_attr "unit" "sse,mmx"))
449     (const_int 1)
450     (const_int 0)))
451
452 ;; Set when REX opcode prefix is used.
453 (define_attr "prefix_rex" ""
454   (cond [(ne (symbol_ref "!TARGET_64BIT") (const_int 0))
455            (const_int 0)
456          (and (eq_attr "mode" "DI")
457               (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
458                    (eq_attr "unit" "!mmx")))
459            (const_int 1)
460          (and (eq_attr "mode" "QI")
461               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
462                   (const_int 0)))
463            (const_int 1)
464          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
465              (const_int 0))
466            (const_int 1)
467          (and (eq_attr "type" "imovx")
468               (match_operand:QI 1 "ext_QIreg_operand" ""))
469            (const_int 1)
470         ]
471         (const_int 0)))
472
473 ;; There are also additional prefixes in 3DNOW, SSSE3.
474 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
475 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
476 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
477 (define_attr "prefix_extra" ""
478   (cond [(eq_attr "type" "ssemuladd,sse4arg")
479            (const_int 2)
480          (eq_attr "type" "sseiadd1,ssecvt1")
481            (const_int 1)
482         ]
483         (const_int 0)))
484
485 ;; Prefix used: original, VEX or maybe VEX.
486 (define_attr "prefix" "orig,vex,maybe_vex"
487   (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
488     (const_string "vex")
489     (const_string "orig")))
490
491 ;; VEX W bit is used.
492 (define_attr "prefix_vex_w" "" (const_int 0))
493
494 ;; The length of VEX prefix
495 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
496 ;; 0f38/0f3a prefixes can't.  In i386.md 0f3[8a] is
497 ;; still prefix_0f 1, with prefix_extra 1.
498 (define_attr "length_vex" ""
499   (if_then_else (and (eq_attr "prefix_0f" "1")
500                      (eq_attr "prefix_extra" "0"))
501     (if_then_else (eq_attr "prefix_vex_w" "1")
502       (symbol_ref "ix86_attr_length_vex_default (insn, 1, 1)")
503       (symbol_ref "ix86_attr_length_vex_default (insn, 1, 0)"))
504     (if_then_else (eq_attr "prefix_vex_w" "1")
505       (symbol_ref "ix86_attr_length_vex_default (insn, 0, 1)")
506       (symbol_ref "ix86_attr_length_vex_default (insn, 0, 0)"))))
507
508 ;; Set when modrm byte is used.
509 (define_attr "modrm" ""
510   (cond [(eq_attr "type" "str,leave")
511            (const_int 0)
512          (eq_attr "unit" "i387")
513            (const_int 0)
514          (and (eq_attr "type" "incdec")
515               (and (eq (symbol_ref "TARGET_64BIT") (const_int 0))
516                    (ior (match_operand:SI 1 "register_operand" "")
517                         (match_operand:HI 1 "register_operand" ""))))
518            (const_int 0)
519          (and (eq_attr "type" "push")
520               (not (match_operand 1 "memory_operand" "")))
521            (const_int 0)
522          (and (eq_attr "type" "pop")
523               (not (match_operand 0 "memory_operand" "")))
524            (const_int 0)
525          (and (eq_attr "type" "imov")
526               (and (not (eq_attr "mode" "DI"))
527                    (ior (and (match_operand 0 "register_operand" "")
528                              (match_operand 1 "immediate_operand" ""))
529                         (ior (and (match_operand 0 "ax_reg_operand" "")
530                                   (match_operand 1 "memory_displacement_only_operand" ""))
531                              (and (match_operand 0 "memory_displacement_only_operand" "")
532                                   (match_operand 1 "ax_reg_operand" ""))))))
533            (const_int 0)
534          (and (eq_attr "type" "call")
535               (match_operand 0 "constant_call_address_operand" ""))
536              (const_int 0)
537          (and (eq_attr "type" "callv")
538               (match_operand 1 "constant_call_address_operand" ""))
539              (const_int 0)
540          (and (eq_attr "type" "alu,alu1,icmp,test")
541               (match_operand 0 "ax_reg_operand" ""))
542              (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
543          ]
544          (const_int 1)))
545
546 ;; The (bounding maximum) length of an instruction in bytes.
547 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
548 ;; Later we may want to split them and compute proper length as for
549 ;; other insns.
550 (define_attr "length" ""
551   (cond [(eq_attr "type" "other,multi,fistp,frndint")
552            (const_int 16)
553          (eq_attr "type" "fcmp")
554            (const_int 4)
555          (eq_attr "unit" "i387")
556            (plus (const_int 2)
557                  (plus (attr "prefix_data16")
558                        (attr "length_address")))
559          (ior (eq_attr "prefix" "vex")
560               (and (eq_attr "prefix" "maybe_vex")
561                     (ne (symbol_ref "TARGET_AVX") (const_int 0))))
562            (plus (attr "length_vex")
563                  (plus (attr "length_immediate")
564                        (plus (attr "modrm")
565                              (attr "length_address"))))]
566          (plus (plus (attr "modrm")
567                      (plus (attr "prefix_0f")
568                            (plus (attr "prefix_rex")
569                                  (plus (attr "prefix_extra")
570                                        (const_int 1)))))
571                (plus (attr "prefix_rep")
572                      (plus (attr "prefix_data16")
573                            (plus (attr "length_immediate")
574                                  (attr "length_address")))))))
575
576 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
577 ;; `store' if there is a simple memory reference therein, or `unknown'
578 ;; if the instruction is complex.
579
580 (define_attr "memory" "none,load,store,both,unknown"
581   (cond [(eq_attr "type" "other,multi,str,lwp")
582            (const_string "unknown")
583          (eq_attr "type" "lea,fcmov,fpspc")
584            (const_string "none")
585          (eq_attr "type" "fistp,leave")
586            (const_string "both")
587          (eq_attr "type" "frndint")
588            (const_string "load")
589          (eq_attr "type" "push")
590            (if_then_else (match_operand 1 "memory_operand" "")
591              (const_string "both")
592              (const_string "store"))
593          (eq_attr "type" "pop")
594            (if_then_else (match_operand 0 "memory_operand" "")
595              (const_string "both")
596              (const_string "load"))
597          (eq_attr "type" "setcc")
598            (if_then_else (match_operand 0 "memory_operand" "")
599              (const_string "store")
600              (const_string "none"))
601          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
602            (if_then_else (ior (match_operand 0 "memory_operand" "")
603                               (match_operand 1 "memory_operand" ""))
604              (const_string "load")
605              (const_string "none"))
606          (eq_attr "type" "ibr")
607            (if_then_else (match_operand 0 "memory_operand" "")
608              (const_string "load")
609              (const_string "none"))
610          (eq_attr "type" "call")
611            (if_then_else (match_operand 0 "constant_call_address_operand" "")
612              (const_string "none")
613              (const_string "load"))
614          (eq_attr "type" "callv")
615            (if_then_else (match_operand 1 "constant_call_address_operand" "")
616              (const_string "none")
617              (const_string "load"))
618          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
619               (match_operand 1 "memory_operand" ""))
620            (const_string "both")
621          (and (match_operand 0 "memory_operand" "")
622               (match_operand 1 "memory_operand" ""))
623            (const_string "both")
624          (match_operand 0 "memory_operand" "")
625            (const_string "store")
626          (match_operand 1 "memory_operand" "")
627            (const_string "load")
628          (and (eq_attr "type"
629                  "!alu1,negnot,ishift1,
630                    imov,imovx,icmp,test,bitmanip,
631                    fmov,fcmp,fsgn,
632                    sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
633                    sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
634               (match_operand 2 "memory_operand" ""))
635            (const_string "load")
636          (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
637               (match_operand 3 "memory_operand" ""))
638            (const_string "load")
639         ]
640         (const_string "none")))
641
642 ;; Indicates if an instruction has both an immediate and a displacement.
643
644 (define_attr "imm_disp" "false,true,unknown"
645   (cond [(eq_attr "type" "other,multi")
646            (const_string "unknown")
647          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
648               (and (match_operand 0 "memory_displacement_operand" "")
649                    (match_operand 1 "immediate_operand" "")))
650            (const_string "true")
651          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
652               (and (match_operand 0 "memory_displacement_operand" "")
653                    (match_operand 2 "immediate_operand" "")))
654            (const_string "true")
655         ]
656         (const_string "false")))
657
658 ;; Indicates if an FP operation has an integer source.
659
660 (define_attr "fp_int_src" "false,true"
661   (const_string "false"))
662
663 ;; Defines rounding mode of an FP operation.
664
665 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
666   (const_string "any"))
667
668 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
669 (define_attr "use_carry" "0,1" (const_string "0"))
670
671 ;; Define attribute to indicate unaligned ssemov insns
672 (define_attr "movu" "0,1" (const_string "0"))
673
674 ;; Describe a user's asm statement.
675 (define_asm_attributes
676   [(set_attr "length" "128")
677    (set_attr "type" "multi")])
678
679 ;; All integer comparison codes.
680 (define_code_iterator int_cond [ne eq ge gt le lt geu gtu leu ltu])
681
682 ;; All floating-point comparison codes.
683 (define_code_iterator fp_cond [unordered ordered
684                                uneq unge ungt unle unlt ltgt])
685
686 (define_code_iterator plusminus [plus minus])
687
688 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
689
690 ;; Base name for define_insn
691 (define_code_attr plusminus_insn
692   [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
693    (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
694
695 ;; Base name for insn mnemonic.
696 (define_code_attr plusminus_mnemonic
697   [(plus "add") (ss_plus "adds") (us_plus "addus")
698    (minus "sub") (ss_minus "subs") (us_minus "subus")])
699 (define_code_attr plusminus_carry_mnemonic
700   [(plus "adc") (minus "sbb")])
701
702 ;; Mark commutative operators as such in constraints.
703 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
704                         (minus "") (ss_minus "") (us_minus "")])
705
706 ;; Mapping of signed max and min
707 (define_code_iterator smaxmin [smax smin])
708
709 ;; Mapping of unsigned max and min
710 (define_code_iterator umaxmin [umax umin])
711
712 ;; Mapping of signed/unsigned max and min
713 (define_code_iterator maxmin [smax smin umax umin])
714
715 ;; Base name for integer and FP insn mnemonic
716 (define_code_attr maxminiprefix [(smax "maxs") (smin "mins")
717                                  (umax "maxu") (umin "minu")])
718 (define_code_attr maxminfprefix [(smax "max") (smin "min")])
719
720 ;; Mapping of logic operators
721 (define_code_iterator any_logic [and ior xor])
722 (define_code_iterator any_or [ior xor])
723
724 ;; Base name for insn mnemonic.
725 (define_code_attr logicprefix [(and "and") (ior "or") (xor "xor")])
726
727 ;; Mapping of abs neg operators
728 (define_code_iterator absneg [abs neg])
729
730 ;; Base name for x87 insn mnemonic.
731 (define_code_attr absnegprefix [(abs "abs") (neg "chs")])
732
733 ;; Used in signed and unsigned widening multiplications.
734 (define_code_iterator any_extend [sign_extend zero_extend])
735
736 ;; Various insn prefixes for signed and unsigned operations.
737 (define_code_attr u [(sign_extend "") (zero_extend "u")
738                      (div "") (udiv "u")])
739 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
740
741 ;; Used in signed and unsigned divisions.
742 (define_code_iterator any_div [div udiv])
743
744 ;; Instruction prefix for signed and unsigned operations.
745 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")
746                              (div "i") (udiv "")])
747
748 ;; All single word integer modes.
749 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
750
751 ;; Single word integer modes without DImode.
752 (define_mode_iterator SWI124 [QI HI SI])
753
754 ;; Single word integer modes without QImode.
755 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
756
757 ;; Single word integer modes without QImode and HImode.
758 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
759
760 ;; All math-dependant single and double word integer modes.
761 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
762                              (HI "TARGET_HIMODE_MATH")
763                              SI DI (TI "TARGET_64BIT")])
764
765 ;; Math-dependant single word integer modes.
766 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
767                             (HI "TARGET_HIMODE_MATH")
768                             SI (DI "TARGET_64BIT")])
769
770 ;; Math-dependant single word integer modes without QImode.
771 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
772                                SI (DI "TARGET_64BIT")])
773
774 ;; Half mode for double word integer modes.
775 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
776                             (DI "TARGET_64BIT")])
777
778 ;; Double word integer modes.
779 (define_mode_attr DWI [(SI "DI") (DI "TI")])
780 (define_mode_attr dwi [(SI "di") (DI "ti")])
781
782 ;; Instruction suffix for integer modes.
783 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
784
785 ;; Register class for integer modes.
786 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
787
788 ;; Immediate operand constraint for integer modes.
789 (define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")])
790
791 ;; General operand constraint for word modes.
792 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "g") (DI "rme")])
793
794 ;; Immediate operand constraint for double integer modes.
795 (define_mode_attr di [(SI "iF") (DI "e")])
796
797 ;; General operand predicate for integer modes.
798 (define_mode_attr general_operand
799         [(QI "general_operand")
800          (HI "general_operand")
801          (SI "general_operand")
802          (DI "x86_64_general_operand")
803          (TI "x86_64_general_operand")])
804
805 ;; General sign/zero extend operand predicate for integer modes.
806 (define_mode_attr general_szext_operand
807         [(QI "general_operand")
808          (HI "general_operand")
809          (SI "general_operand")
810          (DI "x86_64_szext_general_operand")])
811
812 ;; SSE and x87 SFmode and DFmode floating point modes
813 (define_mode_iterator MODEF [SF DF])
814
815 ;; All x87 floating point modes
816 (define_mode_iterator X87MODEF [SF DF XF])
817
818 ;; All integer modes handled by x87 fisttp operator.
819 (define_mode_iterator X87MODEI [HI SI DI])
820
821 ;; All integer modes handled by integer x87 operators.
822 (define_mode_iterator X87MODEI12 [HI SI])
823
824 ;; All integer modes handled by SSE cvtts?2si* operators.
825 (define_mode_iterator SSEMODEI24 [SI DI])
826
827 ;; SSE asm suffix for floating point modes
828 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
829
830 ;; SSE vector mode corresponding to a scalar mode
831 (define_mode_attr ssevecmode
832   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
833
834 ;; Instruction suffix for REX 64bit operators.
835 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
836
837 ;; This mode iterator allows :P to be used for patterns that operate on
838 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
839 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
840 \f
841 ;; Scheduling descriptions
842
843 (include "pentium.md")
844 (include "ppro.md")
845 (include "k6.md")
846 (include "athlon.md")
847 (include "geode.md")
848 (include "atom.md")
849
850 \f
851 ;; Operand and operator predicates and constraints
852
853 (include "predicates.md")
854 (include "constraints.md")
855
856 \f
857 ;; Compare and branch/compare and store instructions.
858
859 (define_expand "cbranch<mode>4"
860   [(set (reg:CC FLAGS_REG)
861         (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
862                     (match_operand:SDWIM 2 "<general_operand>" "")))
863    (set (pc) (if_then_else
864                (match_operator 0 "comparison_operator"
865                 [(reg:CC FLAGS_REG) (const_int 0)])
866                (label_ref (match_operand 3 "" ""))
867                (pc)))]
868   ""
869 {
870   if (MEM_P (operands[1]) && MEM_P (operands[2]))
871     operands[1] = force_reg (<MODE>mode, operands[1]);
872   ix86_compare_op0 = operands[1];
873   ix86_compare_op1 = operands[2];
874   ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
875   DONE;
876 })
877
878 (define_expand "cstore<mode>4"
879   [(set (reg:CC FLAGS_REG)
880         (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
881                     (match_operand:SWIM 3 "<general_operand>" "")))
882    (set (match_operand:QI 0 "register_operand" "")
883         (match_operator 1 "comparison_operator"
884           [(reg:CC FLAGS_REG) (const_int 0)]))]
885   ""
886 {
887   if (MEM_P (operands[2]) && MEM_P (operands[3]))
888     operands[2] = force_reg (<MODE>mode, operands[2]);
889   ix86_compare_op0 = operands[2];
890   ix86_compare_op1 = operands[3];
891   ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
892   DONE;
893 })
894
895 (define_expand "cmp<mode>_1"
896   [(set (reg:CC FLAGS_REG)
897         (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
898                     (match_operand:SWI48 1 "<general_operand>" "")))]
899   ""
900   "")
901
902 (define_insn "*cmp<mode>_ccno_1"
903   [(set (reg FLAGS_REG)
904         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
905                  (match_operand:SWI 1 "const0_operand" "")))]
906   "ix86_match_ccmode (insn, CCNOmode)"
907   "@
908    test{<imodesuffix>}\t%0, %0
909    cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
910   [(set_attr "type" "test,icmp")
911    (set_attr "length_immediate" "0,1")
912    (set_attr "mode" "<MODE>")])
913
914 (define_insn "*cmp<mode>_1"
915   [(set (reg FLAGS_REG)
916         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
917                  (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
918   "ix86_match_ccmode (insn, CCmode)"
919   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
920   [(set_attr "type" "icmp")
921    (set_attr "mode" "<MODE>")])
922
923 (define_insn "*cmp<mode>_minus_1"
924   [(set (reg FLAGS_REG)
925         (compare
926           (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
927                      (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
928           (const_int 0)))]
929   "ix86_match_ccmode (insn, CCGOCmode)"
930   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
931   [(set_attr "type" "icmp")
932    (set_attr "mode" "<MODE>")])
933
934 (define_insn "*cmpqi_ext_1"
935   [(set (reg FLAGS_REG)
936         (compare
937           (match_operand:QI 0 "general_operand" "Qm")
938           (subreg:QI
939             (zero_extract:SI
940               (match_operand 1 "ext_register_operand" "Q")
941               (const_int 8)
942               (const_int 8)) 0)))]
943   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
944   "cmp{b}\t{%h1, %0|%0, %h1}"
945   [(set_attr "type" "icmp")
946    (set_attr "mode" "QI")])
947
948 (define_insn "*cmpqi_ext_1_rex64"
949   [(set (reg FLAGS_REG)
950         (compare
951           (match_operand:QI 0 "register_operand" "Q")
952           (subreg:QI
953             (zero_extract:SI
954               (match_operand 1 "ext_register_operand" "Q")
955               (const_int 8)
956               (const_int 8)) 0)))]
957   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
958   "cmp{b}\t{%h1, %0|%0, %h1}"
959   [(set_attr "type" "icmp")
960    (set_attr "mode" "QI")])
961
962 (define_insn "*cmpqi_ext_2"
963   [(set (reg FLAGS_REG)
964         (compare
965           (subreg:QI
966             (zero_extract:SI
967               (match_operand 0 "ext_register_operand" "Q")
968               (const_int 8)
969               (const_int 8)) 0)
970           (match_operand:QI 1 "const0_operand" "")))]
971   "ix86_match_ccmode (insn, CCNOmode)"
972   "test{b}\t%h0, %h0"
973   [(set_attr "type" "test")
974    (set_attr "length_immediate" "0")
975    (set_attr "mode" "QI")])
976
977 (define_expand "cmpqi_ext_3"
978   [(set (reg:CC FLAGS_REG)
979         (compare:CC
980           (subreg:QI
981             (zero_extract:SI
982               (match_operand 0 "ext_register_operand" "")
983               (const_int 8)
984               (const_int 8)) 0)
985           (match_operand:QI 1 "immediate_operand" "")))]
986   ""
987   "")
988
989 (define_insn "*cmpqi_ext_3_insn"
990   [(set (reg FLAGS_REG)
991         (compare
992           (subreg:QI
993             (zero_extract:SI
994               (match_operand 0 "ext_register_operand" "Q")
995               (const_int 8)
996               (const_int 8)) 0)
997           (match_operand:QI 1 "general_operand" "Qmn")))]
998   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
999   "cmp{b}\t{%1, %h0|%h0, %1}"
1000   [(set_attr "type" "icmp")
1001    (set_attr "modrm" "1")
1002    (set_attr "mode" "QI")])
1003
1004 (define_insn "*cmpqi_ext_3_insn_rex64"
1005   [(set (reg FLAGS_REG)
1006         (compare
1007           (subreg:QI
1008             (zero_extract:SI
1009               (match_operand 0 "ext_register_operand" "Q")
1010               (const_int 8)
1011               (const_int 8)) 0)
1012           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1013   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1014   "cmp{b}\t{%1, %h0|%h0, %1}"
1015   [(set_attr "type" "icmp")
1016    (set_attr "modrm" "1")
1017    (set_attr "mode" "QI")])
1018
1019 (define_insn "*cmpqi_ext_4"
1020   [(set (reg FLAGS_REG)
1021         (compare
1022           (subreg:QI
1023             (zero_extract:SI
1024               (match_operand 0 "ext_register_operand" "Q")
1025               (const_int 8)
1026               (const_int 8)) 0)
1027           (subreg:QI
1028             (zero_extract:SI
1029               (match_operand 1 "ext_register_operand" "Q")
1030               (const_int 8)
1031               (const_int 8)) 0)))]
1032   "ix86_match_ccmode (insn, CCmode)"
1033   "cmp{b}\t{%h1, %h0|%h0, %h1}"
1034   [(set_attr "type" "icmp")
1035    (set_attr "mode" "QI")])
1036
1037 ;; These implement float point compares.
1038 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1039 ;; which would allow mix and match FP modes on the compares.  Which is what
1040 ;; the old patterns did, but with many more of them.
1041
1042 (define_expand "cbranchxf4"
1043   [(set (reg:CC FLAGS_REG)
1044         (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1045                     (match_operand:XF 2 "nonmemory_operand" "")))
1046    (set (pc) (if_then_else
1047               (match_operator 0 "ix86_fp_comparison_operator"
1048                [(reg:CC FLAGS_REG)
1049                 (const_int 0)])
1050               (label_ref (match_operand 3 "" ""))
1051               (pc)))]
1052   "TARGET_80387"
1053 {
1054   ix86_compare_op0 = operands[1];
1055   ix86_compare_op1 = operands[2];
1056   ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1057   DONE;
1058 })
1059
1060 (define_expand "cstorexf4"
1061   [(set (reg:CC FLAGS_REG)
1062         (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1063                     (match_operand:XF 3 "nonmemory_operand" "")))
1064    (set (match_operand:QI 0 "register_operand" "")
1065               (match_operator 1 "ix86_fp_comparison_operator"
1066                [(reg:CC FLAGS_REG)
1067                 (const_int 0)]))]
1068   "TARGET_80387"
1069 {
1070   ix86_compare_op0 = operands[2];
1071   ix86_compare_op1 = operands[3];
1072   ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1073   DONE;
1074 })
1075
1076 (define_expand "cbranch<mode>4"
1077   [(set (reg:CC FLAGS_REG)
1078         (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1079                     (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1080    (set (pc) (if_then_else
1081               (match_operator 0 "ix86_fp_comparison_operator"
1082                [(reg:CC FLAGS_REG)
1083                 (const_int 0)])
1084               (label_ref (match_operand 3 "" ""))
1085               (pc)))]
1086   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1087 {
1088   ix86_compare_op0 = operands[1];
1089   ix86_compare_op1 = operands[2];
1090   ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1091   DONE;
1092 })
1093
1094 (define_expand "cstore<mode>4"
1095   [(set (reg:CC FLAGS_REG)
1096         (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1097                     (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1098    (set (match_operand:QI 0 "register_operand" "")
1099               (match_operator 1 "ix86_fp_comparison_operator"
1100                [(reg:CC FLAGS_REG)
1101                 (const_int 0)]))]
1102   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1103 {
1104   ix86_compare_op0 = operands[2];
1105   ix86_compare_op1 = operands[3];
1106   ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1107   DONE;
1108 })
1109
1110 (define_expand "cbranchcc4"
1111   [(set (pc) (if_then_else
1112               (match_operator 0 "comparison_operator"
1113                [(match_operand 1 "flags_reg_operand" "")
1114                 (match_operand 2 "const0_operand" "")])
1115               (label_ref (match_operand 3 "" ""))
1116               (pc)))]
1117   ""
1118 {
1119   ix86_compare_op0 = operands[1];
1120   ix86_compare_op1 = operands[2];
1121   ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1122   DONE;
1123 })
1124
1125 (define_expand "cstorecc4"
1126   [(set (match_operand:QI 0 "register_operand" "")
1127               (match_operator 1 "comparison_operator"
1128                [(match_operand 2 "flags_reg_operand" "")
1129                 (match_operand 3 "const0_operand" "")]))]
1130   ""
1131 {
1132   ix86_compare_op0 = operands[2];
1133   ix86_compare_op1 = operands[3];
1134   ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1135   DONE;
1136 })
1137
1138
1139 ;; FP compares, step 1:
1140 ;; Set the FP condition codes.
1141 ;;
1142 ;; CCFPmode     compare with exceptions
1143 ;; CCFPUmode    compare with no exceptions
1144
1145 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1146 ;; used to manage the reg stack popping would not be preserved.
1147
1148 (define_insn "*cmpfp_0"
1149   [(set (match_operand:HI 0 "register_operand" "=a")
1150         (unspec:HI
1151           [(compare:CCFP
1152              (match_operand 1 "register_operand" "f")
1153              (match_operand 2 "const0_operand" ""))]
1154         UNSPEC_FNSTSW))]
1155   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1156    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1157   "* return output_fp_compare (insn, operands, 0, 0);"
1158   [(set_attr "type" "multi")
1159    (set_attr "unit" "i387")
1160    (set (attr "mode")
1161      (cond [(match_operand:SF 1 "" "")
1162               (const_string "SF")
1163             (match_operand:DF 1 "" "")
1164               (const_string "DF")
1165            ]
1166            (const_string "XF")))])
1167
1168 (define_insn_and_split "*cmpfp_0_cc"
1169   [(set (reg:CCFP FLAGS_REG)
1170         (compare:CCFP
1171           (match_operand 1 "register_operand" "f")
1172           (match_operand 2 "const0_operand" "")))
1173    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1174   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1175    && TARGET_SAHF && !TARGET_CMOVE
1176    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1177   "#"
1178   "&& reload_completed"
1179   [(set (match_dup 0)
1180         (unspec:HI
1181           [(compare:CCFP (match_dup 1)(match_dup 2))]
1182         UNSPEC_FNSTSW))
1183    (set (reg:CC FLAGS_REG)
1184         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1185   ""
1186   [(set_attr "type" "multi")
1187    (set_attr "unit" "i387")
1188    (set (attr "mode")
1189      (cond [(match_operand:SF 1 "" "")
1190               (const_string "SF")
1191             (match_operand:DF 1 "" "")
1192               (const_string "DF")
1193            ]
1194            (const_string "XF")))])
1195
1196 (define_insn "*cmpfp_xf"
1197   [(set (match_operand:HI 0 "register_operand" "=a")
1198         (unspec:HI
1199           [(compare:CCFP
1200              (match_operand:XF 1 "register_operand" "f")
1201              (match_operand:XF 2 "register_operand" "f"))]
1202           UNSPEC_FNSTSW))]
1203   "TARGET_80387"
1204   "* return output_fp_compare (insn, operands, 0, 0);"
1205   [(set_attr "type" "multi")
1206    (set_attr "unit" "i387")
1207    (set_attr "mode" "XF")])
1208
1209 (define_insn_and_split "*cmpfp_xf_cc"
1210   [(set (reg:CCFP FLAGS_REG)
1211         (compare:CCFP
1212           (match_operand:XF 1 "register_operand" "f")
1213           (match_operand:XF 2 "register_operand" "f")))
1214    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1215   "TARGET_80387
1216    && TARGET_SAHF && !TARGET_CMOVE"
1217   "#"
1218   "&& reload_completed"
1219   [(set (match_dup 0)
1220         (unspec:HI
1221           [(compare:CCFP (match_dup 1)(match_dup 2))]
1222         UNSPEC_FNSTSW))
1223    (set (reg:CC FLAGS_REG)
1224         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1225   ""
1226   [(set_attr "type" "multi")
1227    (set_attr "unit" "i387")
1228    (set_attr "mode" "XF")])
1229
1230 (define_insn "*cmpfp_<mode>"
1231   [(set (match_operand:HI 0 "register_operand" "=a")
1232         (unspec:HI
1233           [(compare:CCFP
1234              (match_operand:MODEF 1 "register_operand" "f")
1235              (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1236           UNSPEC_FNSTSW))]
1237   "TARGET_80387"
1238   "* return output_fp_compare (insn, operands, 0, 0);"
1239   [(set_attr "type" "multi")
1240    (set_attr "unit" "i387")
1241    (set_attr "mode" "<MODE>")])
1242
1243 (define_insn_and_split "*cmpfp_<mode>_cc"
1244   [(set (reg:CCFP FLAGS_REG)
1245         (compare:CCFP
1246           (match_operand:MODEF 1 "register_operand" "f")
1247           (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1248    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1249   "TARGET_80387
1250    && TARGET_SAHF && !TARGET_CMOVE"
1251   "#"
1252   "&& reload_completed"
1253   [(set (match_dup 0)
1254         (unspec:HI
1255           [(compare:CCFP (match_dup 1)(match_dup 2))]
1256         UNSPEC_FNSTSW))
1257    (set (reg:CC FLAGS_REG)
1258         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1259   ""
1260   [(set_attr "type" "multi")
1261    (set_attr "unit" "i387")
1262    (set_attr "mode" "<MODE>")])
1263
1264 (define_insn "*cmpfp_u"
1265   [(set (match_operand:HI 0 "register_operand" "=a")
1266         (unspec:HI
1267           [(compare:CCFPU
1268              (match_operand 1 "register_operand" "f")
1269              (match_operand 2 "register_operand" "f"))]
1270           UNSPEC_FNSTSW))]
1271   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1272    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1273   "* return output_fp_compare (insn, operands, 0, 1);"
1274   [(set_attr "type" "multi")
1275    (set_attr "unit" "i387")
1276    (set (attr "mode")
1277      (cond [(match_operand:SF 1 "" "")
1278               (const_string "SF")
1279             (match_operand:DF 1 "" "")
1280               (const_string "DF")
1281            ]
1282            (const_string "XF")))])
1283
1284 (define_insn_and_split "*cmpfp_u_cc"
1285   [(set (reg:CCFPU FLAGS_REG)
1286         (compare:CCFPU
1287           (match_operand 1 "register_operand" "f")
1288           (match_operand 2 "register_operand" "f")))
1289    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1290   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1291    && TARGET_SAHF && !TARGET_CMOVE
1292    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1293   "#"
1294   "&& reload_completed"
1295   [(set (match_dup 0)
1296         (unspec:HI
1297           [(compare:CCFPU (match_dup 1)(match_dup 2))]
1298         UNSPEC_FNSTSW))
1299    (set (reg:CC FLAGS_REG)
1300         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1301   ""
1302   [(set_attr "type" "multi")
1303    (set_attr "unit" "i387")
1304    (set (attr "mode")
1305      (cond [(match_operand:SF 1 "" "")
1306               (const_string "SF")
1307             (match_operand:DF 1 "" "")
1308               (const_string "DF")
1309            ]
1310            (const_string "XF")))])
1311
1312 (define_insn "*cmpfp_<mode>"
1313   [(set (match_operand:HI 0 "register_operand" "=a")
1314         (unspec:HI
1315           [(compare:CCFP
1316              (match_operand 1 "register_operand" "f")
1317              (match_operator 3 "float_operator"
1318                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1319           UNSPEC_FNSTSW))]
1320   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1321    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1322    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1323   "* return output_fp_compare (insn, operands, 0, 0);"
1324   [(set_attr "type" "multi")
1325    (set_attr "unit" "i387")
1326    (set_attr "fp_int_src" "true")
1327    (set_attr "mode" "<MODE>")])
1328
1329 (define_insn_and_split "*cmpfp_<mode>_cc"
1330   [(set (reg:CCFP FLAGS_REG)
1331         (compare:CCFP
1332           (match_operand 1 "register_operand" "f")
1333           (match_operator 3 "float_operator"
1334             [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1335    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1336   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1337    && TARGET_SAHF && !TARGET_CMOVE
1338    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1339    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1340   "#"
1341   "&& reload_completed"
1342   [(set (match_dup 0)
1343         (unspec:HI
1344           [(compare:CCFP
1345              (match_dup 1)
1346              (match_op_dup 3 [(match_dup 2)]))]
1347         UNSPEC_FNSTSW))
1348    (set (reg:CC FLAGS_REG)
1349         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1350   ""
1351   [(set_attr "type" "multi")
1352    (set_attr "unit" "i387")
1353    (set_attr "fp_int_src" "true")
1354    (set_attr "mode" "<MODE>")])
1355
1356 ;; FP compares, step 2
1357 ;; Move the fpsw to ax.
1358
1359 (define_insn "x86_fnstsw_1"
1360   [(set (match_operand:HI 0 "register_operand" "=a")
1361         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1362   "TARGET_80387"
1363   "fnstsw\t%0"
1364   [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1365    (set_attr "mode" "SI")
1366    (set_attr "unit" "i387")])
1367
1368 ;; FP compares, step 3
1369 ;; Get ax into flags, general case.
1370
1371 (define_insn "x86_sahf_1"
1372   [(set (reg:CC FLAGS_REG)
1373         (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1374                    UNSPEC_SAHF))]
1375   "TARGET_SAHF"
1376 {
1377 #ifdef HAVE_AS_IX86_SAHF
1378   return "sahf";
1379 #else
1380   return ASM_BYTE "0x9e";
1381 #endif
1382 }
1383   [(set_attr "length" "1")
1384    (set_attr "athlon_decode" "vector")
1385    (set_attr "amdfam10_decode" "direct")
1386    (set_attr "mode" "SI")])
1387
1388 ;; Pentium Pro can do steps 1 through 3 in one go.
1389 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1390 (define_insn "*cmpfp_i_mixed"
1391   [(set (reg:CCFP FLAGS_REG)
1392         (compare:CCFP (match_operand 0 "register_operand" "f,x")
1393                       (match_operand 1 "nonimmediate_operand" "f,xm")))]
1394   "TARGET_MIX_SSE_I387
1395    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1396    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1397   "* return output_fp_compare (insn, operands, 1, 0);"
1398   [(set_attr "type" "fcmp,ssecomi")
1399    (set_attr "prefix" "orig,maybe_vex")
1400    (set (attr "mode")
1401      (if_then_else (match_operand:SF 1 "" "")
1402         (const_string "SF")
1403         (const_string "DF")))
1404    (set (attr "prefix_rep")
1405         (if_then_else (eq_attr "type" "ssecomi")
1406                       (const_string "0")
1407                       (const_string "*")))
1408    (set (attr "prefix_data16")
1409         (cond [(eq_attr "type" "fcmp")
1410                  (const_string "*")
1411                (eq_attr "mode" "DF")
1412                  (const_string "1")
1413               ]
1414               (const_string "0")))
1415    (set_attr "athlon_decode" "vector")
1416    (set_attr "amdfam10_decode" "direct")])
1417
1418 (define_insn "*cmpfp_i_sse"
1419   [(set (reg:CCFP FLAGS_REG)
1420         (compare:CCFP (match_operand 0 "register_operand" "x")
1421                       (match_operand 1 "nonimmediate_operand" "xm")))]
1422   "TARGET_SSE_MATH
1423    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1424    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1425   "* return output_fp_compare (insn, operands, 1, 0);"
1426   [(set_attr "type" "ssecomi")
1427    (set_attr "prefix" "maybe_vex")
1428    (set (attr "mode")
1429      (if_then_else (match_operand:SF 1 "" "")
1430         (const_string "SF")
1431         (const_string "DF")))
1432    (set_attr "prefix_rep" "0")
1433    (set (attr "prefix_data16")
1434         (if_then_else (eq_attr "mode" "DF")
1435                       (const_string "1")
1436                       (const_string "0")))
1437    (set_attr "athlon_decode" "vector")
1438    (set_attr "amdfam10_decode" "direct")])
1439
1440 (define_insn "*cmpfp_i_i387"
1441   [(set (reg:CCFP FLAGS_REG)
1442         (compare:CCFP (match_operand 0 "register_operand" "f")
1443                       (match_operand 1 "register_operand" "f")))]
1444   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1445    && TARGET_CMOVE
1446    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1447    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1448   "* return output_fp_compare (insn, operands, 1, 0);"
1449   [(set_attr "type" "fcmp")
1450    (set (attr "mode")
1451      (cond [(match_operand:SF 1 "" "")
1452               (const_string "SF")
1453             (match_operand:DF 1 "" "")
1454               (const_string "DF")
1455            ]
1456            (const_string "XF")))
1457    (set_attr "athlon_decode" "vector")
1458    (set_attr "amdfam10_decode" "direct")])
1459
1460 (define_insn "*cmpfp_iu_mixed"
1461   [(set (reg:CCFPU FLAGS_REG)
1462         (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1463                        (match_operand 1 "nonimmediate_operand" "f,xm")))]
1464   "TARGET_MIX_SSE_I387
1465    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1466    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1467   "* return output_fp_compare (insn, operands, 1, 1);"
1468   [(set_attr "type" "fcmp,ssecomi")
1469    (set_attr "prefix" "orig,maybe_vex")
1470    (set (attr "mode")
1471      (if_then_else (match_operand:SF 1 "" "")
1472         (const_string "SF")
1473         (const_string "DF")))
1474    (set (attr "prefix_rep")
1475         (if_then_else (eq_attr "type" "ssecomi")
1476                       (const_string "0")
1477                       (const_string "*")))
1478    (set (attr "prefix_data16")
1479         (cond [(eq_attr "type" "fcmp")
1480                  (const_string "*")
1481                (eq_attr "mode" "DF")
1482                  (const_string "1")
1483               ]
1484               (const_string "0")))
1485    (set_attr "athlon_decode" "vector")
1486    (set_attr "amdfam10_decode" "direct")])
1487
1488 (define_insn "*cmpfp_iu_sse"
1489   [(set (reg:CCFPU FLAGS_REG)
1490         (compare:CCFPU (match_operand 0 "register_operand" "x")
1491                        (match_operand 1 "nonimmediate_operand" "xm")))]
1492   "TARGET_SSE_MATH
1493    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1494    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1495   "* return output_fp_compare (insn, operands, 1, 1);"
1496   [(set_attr "type" "ssecomi")
1497    (set_attr "prefix" "maybe_vex")
1498    (set (attr "mode")
1499      (if_then_else (match_operand:SF 1 "" "")
1500         (const_string "SF")
1501         (const_string "DF")))
1502    (set_attr "prefix_rep" "0")
1503    (set (attr "prefix_data16")
1504         (if_then_else (eq_attr "mode" "DF")
1505                       (const_string "1")
1506                       (const_string "0")))
1507    (set_attr "athlon_decode" "vector")
1508    (set_attr "amdfam10_decode" "direct")])
1509
1510 (define_insn "*cmpfp_iu_387"
1511   [(set (reg:CCFPU FLAGS_REG)
1512         (compare:CCFPU (match_operand 0 "register_operand" "f")
1513                        (match_operand 1 "register_operand" "f")))]
1514   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1515    && TARGET_CMOVE
1516    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1517    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1518   "* return output_fp_compare (insn, operands, 1, 1);"
1519   [(set_attr "type" "fcmp")
1520    (set (attr "mode")
1521      (cond [(match_operand:SF 1 "" "")
1522               (const_string "SF")
1523             (match_operand:DF 1 "" "")
1524               (const_string "DF")
1525            ]
1526            (const_string "XF")))
1527    (set_attr "athlon_decode" "vector")
1528    (set_attr "amdfam10_decode" "direct")])
1529 \f
1530 ;; Move instructions.
1531
1532 ;; General case of fullword move.
1533
1534 (define_expand "movsi"
1535   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1536         (match_operand:SI 1 "general_operand" ""))]
1537   ""
1538   "ix86_expand_move (SImode, operands); DONE;")
1539
1540 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1541 ;; general_operand.
1542 ;;
1543 ;; %%% We don't use a post-inc memory reference because x86 is not a
1544 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1545 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1546 ;; targets without our curiosities, and it is just as easy to represent
1547 ;; this differently.
1548
1549 (define_insn "*pushsi2"
1550   [(set (match_operand:SI 0 "push_operand" "=<")
1551         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1552   "!TARGET_64BIT"
1553   "push{l}\t%1"
1554   [(set_attr "type" "push")
1555    (set_attr "mode" "SI")])
1556
1557 ;; For 64BIT abi we always round up to 8 bytes.
1558 (define_insn "*pushsi2_rex64"
1559   [(set (match_operand:SI 0 "push_operand" "=X")
1560         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1561   "TARGET_64BIT"
1562   "push{q}\t%q1"
1563   [(set_attr "type" "push")
1564    (set_attr "mode" "SI")])
1565
1566 (define_insn "*pushsi2_prologue"
1567   [(set (match_operand:SI 0 "push_operand" "=<")
1568         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1569    (clobber (mem:BLK (scratch)))]
1570   "!TARGET_64BIT"
1571   "push{l}\t%1"
1572   [(set_attr "type" "push")
1573    (set_attr "mode" "SI")])
1574
1575 (define_insn "*popsi1_epilogue"
1576   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1577         (mem:SI (reg:SI SP_REG)))
1578    (set (reg:SI SP_REG)
1579         (plus:SI (reg:SI SP_REG) (const_int 4)))
1580    (clobber (mem:BLK (scratch)))]
1581   "!TARGET_64BIT"
1582   "pop{l}\t%0"
1583   [(set_attr "type" "pop")
1584    (set_attr "mode" "SI")])
1585
1586 (define_insn "popsi1"
1587   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1588         (mem:SI (reg:SI SP_REG)))
1589    (set (reg:SI SP_REG)
1590         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1591   "!TARGET_64BIT"
1592   "pop{l}\t%0"
1593   [(set_attr "type" "pop")
1594    (set_attr "mode" "SI")])
1595
1596 (define_insn "*movsi_xor"
1597   [(set (match_operand:SI 0 "register_operand" "=r")
1598         (match_operand:SI 1 "const0_operand" ""))
1599    (clobber (reg:CC FLAGS_REG))]
1600   "reload_completed"
1601   "xor{l}\t%0, %0"
1602   [(set_attr "type" "alu1")
1603    (set_attr "mode" "SI")
1604    (set_attr "length_immediate" "0")])
1605
1606 (define_insn "*movsi_or"
1607   [(set (match_operand:SI 0 "register_operand" "=r")
1608         (match_operand:SI 1 "immediate_operand" "i"))
1609    (clobber (reg:CC FLAGS_REG))]
1610   "reload_completed
1611    && operands[1] == constm1_rtx"
1612 {
1613   operands[1] = constm1_rtx;
1614   return "or{l}\t{%1, %0|%0, %1}";
1615 }
1616   [(set_attr "type" "alu1")
1617    (set_attr "mode" "SI")
1618    (set_attr "length_immediate" "1")])
1619
1620 (define_insn "*movsi_1"
1621   [(set (match_operand:SI 0 "nonimmediate_operand"
1622                         "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1623         (match_operand:SI 1 "general_operand"
1624                         "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r   ,m "))]
1625   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1626 {
1627   switch (get_attr_type (insn))
1628     {
1629     case TYPE_SSELOG1:
1630       if (get_attr_mode (insn) == MODE_TI)
1631         return "%vpxor\t%0, %d0";
1632       return "%vxorps\t%0, %d0";
1633
1634     case TYPE_SSEMOV:
1635       switch (get_attr_mode (insn))
1636         {
1637         case MODE_TI:
1638           return "%vmovdqa\t{%1, %0|%0, %1}";
1639         case MODE_V4SF:
1640           return "%vmovaps\t{%1, %0|%0, %1}";
1641         case MODE_SI:
1642           return "%vmovd\t{%1, %0|%0, %1}";
1643         case MODE_SF:
1644           return "%vmovss\t{%1, %0|%0, %1}";
1645         default:
1646           gcc_unreachable ();
1647         }
1648
1649     case TYPE_MMX:
1650       return "pxor\t%0, %0";
1651
1652     case TYPE_MMXMOV:
1653       if (get_attr_mode (insn) == MODE_DI)
1654         return "movq\t{%1, %0|%0, %1}";
1655       return "movd\t{%1, %0|%0, %1}";
1656
1657     case TYPE_LEA:
1658       return "lea{l}\t{%1, %0|%0, %1}";
1659
1660     default:
1661       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1662       return "mov{l}\t{%1, %0|%0, %1}";
1663     }
1664 }
1665   [(set (attr "type")
1666      (cond [(eq_attr "alternative" "2")
1667               (const_string "mmx")
1668             (eq_attr "alternative" "3,4,5")
1669               (const_string "mmxmov")
1670             (eq_attr "alternative" "6")
1671               (const_string "sselog1")
1672             (eq_attr "alternative" "7,8,9,10,11")
1673               (const_string "ssemov")
1674             (match_operand:DI 1 "pic_32bit_operand" "")
1675               (const_string "lea")
1676            ]
1677            (const_string "imov")))
1678    (set (attr "prefix")
1679      (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
1680        (const_string "orig")
1681        (const_string "maybe_vex")))
1682    (set (attr "prefix_data16")
1683      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
1684        (const_string "1")
1685        (const_string "*")))
1686    (set (attr "mode")
1687      (cond [(eq_attr "alternative" "2,3")
1688               (const_string "DI")
1689             (eq_attr "alternative" "6,7")
1690               (if_then_else
1691                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1692                 (const_string "V4SF")
1693                 (const_string "TI"))
1694             (and (eq_attr "alternative" "8,9,10,11")
1695                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1696               (const_string "SF")
1697            ]
1698            (const_string "SI")))])
1699
1700 ;; Stores and loads of ax to arbitrary constant address.
1701 ;; We fake an second form of instruction to force reload to load address
1702 ;; into register when rax is not available
1703 (define_insn "*movabssi_1_rex64"
1704   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1705         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1706   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1707   "@
1708    movabs{l}\t{%1, %P0|%P0, %1}
1709    mov{l}\t{%1, %a0|%a0, %1}"
1710   [(set_attr "type" "imov")
1711    (set_attr "modrm" "0,*")
1712    (set_attr "length_address" "8,0")
1713    (set_attr "length_immediate" "0,*")
1714    (set_attr "memory" "store")
1715    (set_attr "mode" "SI")])
1716
1717 (define_insn "*movabssi_2_rex64"
1718   [(set (match_operand:SI 0 "register_operand" "=a,r")
1719         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1720   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1721   "@
1722    movabs{l}\t{%P1, %0|%0, %P1}
1723    mov{l}\t{%a1, %0|%0, %a1}"
1724   [(set_attr "type" "imov")
1725    (set_attr "modrm" "0,*")
1726    (set_attr "length_address" "8,0")
1727    (set_attr "length_immediate" "0")
1728    (set_attr "memory" "load")
1729    (set_attr "mode" "SI")])
1730
1731 (define_insn "*swapsi"
1732   [(set (match_operand:SI 0 "register_operand" "+r")
1733         (match_operand:SI 1 "register_operand" "+r"))
1734    (set (match_dup 1)
1735         (match_dup 0))]
1736   ""
1737   "xchg{l}\t%1, %0"
1738   [(set_attr "type" "imov")
1739    (set_attr "mode" "SI")
1740    (set_attr "pent_pair" "np")
1741    (set_attr "athlon_decode" "vector")
1742    (set_attr "amdfam10_decode" "double")])
1743
1744 (define_expand "movhi"
1745   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1746         (match_operand:HI 1 "general_operand" ""))]
1747   ""
1748   "ix86_expand_move (HImode, operands); DONE;")
1749
1750 (define_insn "*pushhi2"
1751   [(set (match_operand:HI 0 "push_operand" "=X")
1752         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1753   "!TARGET_64BIT"
1754   "push{l}\t%k1"
1755   [(set_attr "type" "push")
1756    (set_attr "mode" "SI")])
1757
1758 ;; For 64BIT abi we always round up to 8 bytes.
1759 (define_insn "*pushhi2_rex64"
1760   [(set (match_operand:HI 0 "push_operand" "=X")
1761         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1762   "TARGET_64BIT"
1763   "push{q}\t%q1"
1764   [(set_attr "type" "push")
1765    (set_attr "mode" "DI")])
1766
1767 (define_insn "*movhi_1"
1768   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1769         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1770   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1771 {
1772   switch (get_attr_type (insn))
1773     {
1774     case TYPE_IMOVX:
1775       /* movzwl is faster than movw on p2 due to partial word stalls,
1776          though not as fast as an aligned movl.  */
1777       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1778     default:
1779       if (get_attr_mode (insn) == MODE_SI)
1780         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1781       else
1782         return "mov{w}\t{%1, %0|%0, %1}";
1783     }
1784 }
1785   [(set (attr "type")
1786      (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
1787               (const_string "imov")
1788             (and (eq_attr "alternative" "0")
1789                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1790                           (const_int 0))
1791                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1792                           (const_int 0))))
1793               (const_string "imov")
1794             (and (eq_attr "alternative" "1,2")
1795                  (match_operand:HI 1 "aligned_operand" ""))
1796               (const_string "imov")
1797             (and (ne (symbol_ref "TARGET_MOVX")
1798                      (const_int 0))
1799                  (eq_attr "alternative" "0,2"))
1800               (const_string "imovx")
1801            ]
1802            (const_string "imov")))
1803     (set (attr "mode")
1804       (cond [(eq_attr "type" "imovx")
1805                (const_string "SI")
1806              (and (eq_attr "alternative" "1,2")
1807                   (match_operand:HI 1 "aligned_operand" ""))
1808                (const_string "SI")
1809              (and (eq_attr "alternative" "0")
1810                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1811                            (const_int 0))
1812                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1813                            (const_int 0))))
1814                (const_string "SI")
1815             ]
1816             (const_string "HI")))])
1817
1818 ;; Stores and loads of ax to arbitrary constant address.
1819 ;; We fake an second form of instruction to force reload to load address
1820 ;; into register when rax is not available
1821 (define_insn "*movabshi_1_rex64"
1822   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1823         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1824   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1825   "@
1826    movabs{w}\t{%1, %P0|%P0, %1}
1827    mov{w}\t{%1, %a0|%a0, %1}"
1828   [(set_attr "type" "imov")
1829    (set_attr "modrm" "0,*")
1830    (set_attr "length_address" "8,0")
1831    (set_attr "length_immediate" "0,*")
1832    (set_attr "memory" "store")
1833    (set_attr "mode" "HI")])
1834
1835 (define_insn "*movabshi_2_rex64"
1836   [(set (match_operand:HI 0 "register_operand" "=a,r")
1837         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1838   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1839   "@
1840    movabs{w}\t{%P1, %0|%0, %P1}
1841    mov{w}\t{%a1, %0|%0, %a1}"
1842   [(set_attr "type" "imov")
1843    (set_attr "modrm" "0,*")
1844    (set_attr "length_address" "8,0")
1845    (set_attr "length_immediate" "0")
1846    (set_attr "memory" "load")
1847    (set_attr "mode" "HI")])
1848
1849 (define_insn "*swaphi_1"
1850   [(set (match_operand:HI 0 "register_operand" "+r")
1851         (match_operand:HI 1 "register_operand" "+r"))
1852    (set (match_dup 1)
1853         (match_dup 0))]
1854   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
1855   "xchg{l}\t%k1, %k0"
1856   [(set_attr "type" "imov")
1857    (set_attr "mode" "SI")
1858    (set_attr "pent_pair" "np")
1859    (set_attr "athlon_decode" "vector")
1860    (set_attr "amdfam10_decode" "double")])
1861
1862 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1863 (define_insn "*swaphi_2"
1864   [(set (match_operand:HI 0 "register_operand" "+r")
1865         (match_operand:HI 1 "register_operand" "+r"))
1866    (set (match_dup 1)
1867         (match_dup 0))]
1868   "TARGET_PARTIAL_REG_STALL"
1869   "xchg{w}\t%1, %0"
1870   [(set_attr "type" "imov")
1871    (set_attr "mode" "HI")
1872    (set_attr "pent_pair" "np")
1873    (set_attr "athlon_decode" "vector")])
1874
1875 (define_expand "movstricthi"
1876   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1877         (match_operand:HI 1 "general_operand" ""))]
1878   ""
1879 {
1880   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
1881     FAIL;
1882   /* Don't generate memory->memory moves, go through a register */
1883   if (MEM_P (operands[0]) && MEM_P (operands[1]))
1884     operands[1] = force_reg (HImode, operands[1]);
1885 })
1886
1887 (define_insn "*movstricthi_1"
1888   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1889         (match_operand:HI 1 "general_operand" "rn,m"))]
1890   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
1891    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1892   "mov{w}\t{%1, %0|%0, %1}"
1893   [(set_attr "type" "imov")
1894    (set_attr "mode" "HI")])
1895
1896 (define_insn "*movstricthi_xor"
1897   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1898         (match_operand:HI 1 "const0_operand" ""))
1899    (clobber (reg:CC FLAGS_REG))]
1900   "reload_completed"
1901   "xor{w}\t%0, %0"
1902   [(set_attr "type" "alu1")
1903    (set_attr "mode" "HI")
1904    (set_attr "length_immediate" "0")])
1905
1906 (define_expand "movqi"
1907   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1908         (match_operand:QI 1 "general_operand" ""))]
1909   ""
1910   "ix86_expand_move (QImode, operands); DONE;")
1911
1912 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1913 ;; "push a byte".  But actually we use pushl, which has the effect
1914 ;; of rounding the amount pushed up to a word.
1915
1916 (define_insn "*pushqi2"
1917   [(set (match_operand:QI 0 "push_operand" "=X")
1918         (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1919   "!TARGET_64BIT"
1920   "push{l}\t%k1"
1921   [(set_attr "type" "push")
1922    (set_attr "mode" "SI")])
1923
1924 ;; For 64BIT abi we always round up to 8 bytes.
1925 (define_insn "*pushqi2_rex64"
1926   [(set (match_operand:QI 0 "push_operand" "=X")
1927         (match_operand:QI 1 "nonmemory_no_elim_operand" "qn"))]
1928   "TARGET_64BIT"
1929   "push{q}\t%q1"
1930   [(set_attr "type" "push")
1931    (set_attr "mode" "DI")])
1932
1933 ;; Situation is quite tricky about when to choose full sized (SImode) move
1934 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1935 ;; partial register dependency machines (such as AMD Athlon), where QImode
1936 ;; moves issue extra dependency and for partial register stalls machines
1937 ;; that don't use QImode patterns (and QImode move cause stall on the next
1938 ;; instruction).
1939 ;;
1940 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1941 ;; register stall machines with, where we use QImode instructions, since
1942 ;; partial register stall can be caused there.  Then we use movzx.
1943 (define_insn "*movqi_1"
1944   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1945         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1946   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1947 {
1948   switch (get_attr_type (insn))
1949     {
1950     case TYPE_IMOVX:
1951       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
1952       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1953     default:
1954       if (get_attr_mode (insn) == MODE_SI)
1955         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1956       else
1957         return "mov{b}\t{%1, %0|%0, %1}";
1958     }
1959 }
1960   [(set (attr "type")
1961      (cond [(and (eq_attr "alternative" "5")
1962                  (not (match_operand:QI 1 "aligned_operand" "")))
1963               (const_string "imovx")
1964             (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
1965               (const_string "imov")
1966             (and (eq_attr "alternative" "3")
1967                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1968                           (const_int 0))
1969                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1970                           (const_int 0))))
1971               (const_string "imov")
1972             (eq_attr "alternative" "3,5")
1973               (const_string "imovx")
1974             (and (ne (symbol_ref "TARGET_MOVX")
1975                      (const_int 0))
1976                  (eq_attr "alternative" "2"))
1977               (const_string "imovx")
1978            ]
1979            (const_string "imov")))
1980    (set (attr "mode")
1981       (cond [(eq_attr "alternative" "3,4,5")
1982                (const_string "SI")
1983              (eq_attr "alternative" "6")
1984                (const_string "QI")
1985              (eq_attr "type" "imovx")
1986                (const_string "SI")
1987              (and (eq_attr "type" "imov")
1988                   (and (eq_attr "alternative" "0,1")
1989                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1990                                 (const_int 0))
1991                             (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
1992                                      (const_int 0))
1993                                  (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1994                                      (const_int 0))))))
1995                (const_string "SI")
1996              ;; Avoid partial register stalls when not using QImode arithmetic
1997              (and (eq_attr "type" "imov")
1998                   (and (eq_attr "alternative" "0,1")
1999                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
2000                                 (const_int 0))
2001                             (eq (symbol_ref "TARGET_QIMODE_MATH")
2002                                 (const_int 0)))))
2003                (const_string "SI")
2004            ]
2005            (const_string "QI")))])
2006
2007 (define_insn "*swapqi_1"
2008   [(set (match_operand:QI 0 "register_operand" "+r")
2009         (match_operand:QI 1 "register_operand" "+r"))
2010    (set (match_dup 1)
2011         (match_dup 0))]
2012   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2013   "xchg{l}\t%k1, %k0"
2014   [(set_attr "type" "imov")
2015    (set_attr "mode" "SI")
2016    (set_attr "pent_pair" "np")
2017    (set_attr "athlon_decode" "vector")
2018    (set_attr "amdfam10_decode" "vector")])
2019
2020 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
2021 (define_insn "*swapqi_2"
2022   [(set (match_operand:QI 0 "register_operand" "+q")
2023         (match_operand:QI 1 "register_operand" "+q"))
2024    (set (match_dup 1)
2025         (match_dup 0))]
2026   "TARGET_PARTIAL_REG_STALL"
2027   "xchg{b}\t%1, %0"
2028   [(set_attr "type" "imov")
2029    (set_attr "mode" "QI")
2030    (set_attr "pent_pair" "np")
2031    (set_attr "athlon_decode" "vector")])
2032
2033 (define_expand "movstrictqi"
2034   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
2035         (match_operand:QI 1 "general_operand" ""))]
2036   ""
2037 {
2038   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2039     FAIL;
2040   /* Don't generate memory->memory moves, go through a register.  */
2041   if (MEM_P (operands[0]) && MEM_P (operands[1]))
2042     operands[1] = force_reg (QImode, operands[1]);
2043 })
2044
2045 (define_insn "*movstrictqi_1"
2046   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
2047         (match_operand:QI 1 "general_operand" "*qn,m"))]
2048   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2049    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2050   "mov{b}\t{%1, %0|%0, %1}"
2051   [(set_attr "type" "imov")
2052    (set_attr "mode" "QI")])
2053
2054 (define_insn "*movstrictqi_xor"
2055   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
2056         (match_operand:QI 1 "const0_operand" ""))
2057    (clobber (reg:CC FLAGS_REG))]
2058   "reload_completed"
2059   "xor{b}\t%0, %0"
2060   [(set_attr "type" "alu1")
2061    (set_attr "mode" "QI")
2062    (set_attr "length_immediate" "0")])
2063
2064 (define_insn "*movsi_extv_1"
2065   [(set (match_operand:SI 0 "register_operand" "=R")
2066         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
2067                          (const_int 8)
2068                          (const_int 8)))]
2069   ""
2070   "movs{bl|x}\t{%h1, %0|%0, %h1}"
2071   [(set_attr "type" "imovx")
2072    (set_attr "mode" "SI")])
2073
2074 (define_insn "*movhi_extv_1"
2075   [(set (match_operand:HI 0 "register_operand" "=R")
2076         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
2077                          (const_int 8)
2078                          (const_int 8)))]
2079   ""
2080   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2081   [(set_attr "type" "imovx")
2082    (set_attr "mode" "SI")])
2083
2084 (define_insn "*movqi_extv_1"
2085   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2086         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2087                          (const_int 8)
2088                          (const_int 8)))]
2089   "!TARGET_64BIT"
2090 {
2091   switch (get_attr_type (insn))
2092     {
2093     case TYPE_IMOVX:
2094       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2095     default:
2096       return "mov{b}\t{%h1, %0|%0, %h1}";
2097     }
2098 }
2099   [(set (attr "type")
2100      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2101                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2102                              (ne (symbol_ref "TARGET_MOVX")
2103                                  (const_int 0))))
2104         (const_string "imovx")
2105         (const_string "imov")))
2106    (set (attr "mode")
2107      (if_then_else (eq_attr "type" "imovx")
2108         (const_string "SI")
2109         (const_string "QI")))])
2110
2111 (define_insn "*movqi_extv_1_rex64"
2112   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2113         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2114                          (const_int 8)
2115                          (const_int 8)))]
2116   "TARGET_64BIT"
2117 {
2118   switch (get_attr_type (insn))
2119     {
2120     case TYPE_IMOVX:
2121       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2122     default:
2123       return "mov{b}\t{%h1, %0|%0, %h1}";
2124     }
2125 }
2126   [(set (attr "type")
2127      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2128                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2129                              (ne (symbol_ref "TARGET_MOVX")
2130                                  (const_int 0))))
2131         (const_string "imovx")
2132         (const_string "imov")))
2133    (set (attr "mode")
2134      (if_then_else (eq_attr "type" "imovx")
2135         (const_string "SI")
2136         (const_string "QI")))])
2137
2138 ;; Stores and loads of ax to arbitrary constant address.
2139 ;; We fake an second form of instruction to force reload to load address
2140 ;; into register when rax is not available
2141 (define_insn "*movabsqi_1_rex64"
2142   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2143         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
2144   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2145   "@
2146    movabs{b}\t{%1, %P0|%P0, %1}
2147    mov{b}\t{%1, %a0|%a0, %1}"
2148   [(set_attr "type" "imov")
2149    (set_attr "modrm" "0,*")
2150    (set_attr "length_address" "8,0")
2151    (set_attr "length_immediate" "0,*")
2152    (set_attr "memory" "store")
2153    (set_attr "mode" "QI")])
2154
2155 (define_insn "*movabsqi_2_rex64"
2156   [(set (match_operand:QI 0 "register_operand" "=a,r")
2157         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2158   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2159   "@
2160    movabs{b}\t{%P1, %0|%0, %P1}
2161    mov{b}\t{%a1, %0|%0, %a1}"
2162   [(set_attr "type" "imov")
2163    (set_attr "modrm" "0,*")
2164    (set_attr "length_address" "8,0")
2165    (set_attr "length_immediate" "0")
2166    (set_attr "memory" "load")
2167    (set_attr "mode" "QI")])
2168
2169 (define_insn "*movdi_extzv_1"
2170   [(set (match_operand:DI 0 "register_operand" "=R")
2171         (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
2172                          (const_int 8)
2173                          (const_int 8)))]
2174   "TARGET_64BIT"
2175   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2176   [(set_attr "type" "imovx")
2177    (set_attr "mode" "SI")])
2178
2179 (define_insn "*movsi_extzv_1"
2180   [(set (match_operand:SI 0 "register_operand" "=R")
2181         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
2182                          (const_int 8)
2183                          (const_int 8)))]
2184   ""
2185   "movz{bl|x}\t{%h1, %0|%0, %h1}"
2186   [(set_attr "type" "imovx")
2187    (set_attr "mode" "SI")])
2188
2189 (define_insn "*movqi_extzv_2"
2190   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2191         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2192                                     (const_int 8)
2193                                     (const_int 8)) 0))]
2194   "!TARGET_64BIT"
2195 {
2196   switch (get_attr_type (insn))
2197     {
2198     case TYPE_IMOVX:
2199       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2200     default:
2201       return "mov{b}\t{%h1, %0|%0, %h1}";
2202     }
2203 }
2204   [(set (attr "type")
2205      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2206                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2207                              (ne (symbol_ref "TARGET_MOVX")
2208                                  (const_int 0))))
2209         (const_string "imovx")
2210         (const_string "imov")))
2211    (set (attr "mode")
2212      (if_then_else (eq_attr "type" "imovx")
2213         (const_string "SI")
2214         (const_string "QI")))])
2215
2216 (define_insn "*movqi_extzv_2_rex64"
2217   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2218         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2219                                     (const_int 8)
2220                                     (const_int 8)) 0))]
2221   "TARGET_64BIT"
2222 {
2223   switch (get_attr_type (insn))
2224     {
2225     case TYPE_IMOVX:
2226       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2227     default:
2228       return "mov{b}\t{%h1, %0|%0, %h1}";
2229     }
2230 }
2231   [(set (attr "type")
2232      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2233                         (ne (symbol_ref "TARGET_MOVX")
2234                             (const_int 0)))
2235         (const_string "imovx")
2236         (const_string "imov")))
2237    (set (attr "mode")
2238      (if_then_else (eq_attr "type" "imovx")
2239         (const_string "SI")
2240         (const_string "QI")))])
2241
2242 (define_insn "movsi_insv_1"
2243   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2244                          (const_int 8)
2245                          (const_int 8))
2246         (match_operand:SI 1 "general_operand" "Qmn"))]
2247   "!TARGET_64BIT"
2248   "mov{b}\t{%b1, %h0|%h0, %b1}"
2249   [(set_attr "type" "imov")
2250    (set_attr "mode" "QI")])
2251
2252 (define_insn "*movsi_insv_1_rex64"
2253   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2254                          (const_int 8)
2255                          (const_int 8))
2256         (match_operand:SI 1 "nonmemory_operand" "Qn"))]
2257   "TARGET_64BIT"
2258   "mov{b}\t{%b1, %h0|%h0, %b1}"
2259   [(set_attr "type" "imov")
2260    (set_attr "mode" "QI")])
2261
2262 (define_insn "movdi_insv_1_rex64"
2263   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
2264                          (const_int 8)
2265                          (const_int 8))
2266         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
2267   "TARGET_64BIT"
2268   "mov{b}\t{%b1, %h0|%h0, %b1}"
2269   [(set_attr "type" "imov")
2270    (set_attr "mode" "QI")])
2271
2272 (define_insn "*movqi_insv_2"
2273   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2274                          (const_int 8)
2275                          (const_int 8))
2276         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2277                      (const_int 8)))]
2278   ""
2279   "mov{b}\t{%h1, %h0|%h0, %h1}"
2280   [(set_attr "type" "imov")
2281    (set_attr "mode" "QI")])
2282
2283 (define_expand "movdi"
2284   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2285         (match_operand:DI 1 "general_operand" ""))]
2286   ""
2287   "ix86_expand_move (DImode, operands); DONE;")
2288
2289 (define_insn "*pushdi"
2290   [(set (match_operand:DI 0 "push_operand" "=<")
2291         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
2292   "!TARGET_64BIT"
2293   "#")
2294
2295 (define_insn "*pushdi2_rex64"
2296   [(set (match_operand:DI 0 "push_operand" "=<,!<")
2297         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
2298   "TARGET_64BIT"
2299   "@
2300    push{q}\t%1
2301    #"
2302   [(set_attr "type" "push,multi")
2303    (set_attr "mode" "DI")])
2304
2305 ;; Convert impossible pushes of immediate to existing instructions.
2306 ;; First try to get scratch register and go through it.  In case this
2307 ;; fails, push sign extended lower part first and then overwrite
2308 ;; upper part by 32bit move.
2309 (define_peephole2
2310   [(match_scratch:DI 2 "r")
2311    (set (match_operand:DI 0 "push_operand" "")
2312         (match_operand:DI 1 "immediate_operand" ""))]
2313   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2314    && !x86_64_immediate_operand (operands[1], DImode)"
2315   [(set (match_dup 2) (match_dup 1))
2316    (set (match_dup 0) (match_dup 2))]
2317   "")
2318
2319 ;; We need to define this as both peepholer and splitter for case
2320 ;; peephole2 pass is not run.
2321 ;; "&& 1" is needed to keep it from matching the previous pattern.
2322 (define_peephole2
2323   [(set (match_operand:DI 0 "push_operand" "")
2324         (match_operand:DI 1 "immediate_operand" ""))]
2325   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2326    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2327   [(set (match_dup 0) (match_dup 1))
2328    (set (match_dup 2) (match_dup 3))]
2329   "split_di (&operands[1], 1, &operands[2], &operands[3]);
2330    operands[1] = gen_lowpart (DImode, operands[2]);
2331    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2332                                                     GEN_INT (4)));
2333   ")
2334
2335 (define_split
2336   [(set (match_operand:DI 0 "push_operand" "")
2337         (match_operand:DI 1 "immediate_operand" ""))]
2338   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2339                     ? epilogue_completed : reload_completed)
2340    && !symbolic_operand (operands[1], DImode)
2341    && !x86_64_immediate_operand (operands[1], DImode)"
2342   [(set (match_dup 0) (match_dup 1))
2343    (set (match_dup 2) (match_dup 3))]
2344   "split_di (&operands[1], 1, &operands[2], &operands[3]);
2345    operands[1] = gen_lowpart (DImode, operands[2]);
2346    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2347                                                     GEN_INT (4)));
2348   ")
2349
2350 (define_insn "*pushdi2_prologue_rex64"
2351   [(set (match_operand:DI 0 "push_operand" "=<")
2352         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
2353    (clobber (mem:BLK (scratch)))]
2354   "TARGET_64BIT"
2355   "push{q}\t%1"
2356   [(set_attr "type" "push")
2357    (set_attr "mode" "DI")])
2358
2359 (define_insn "*popdi1_epilogue_rex64"
2360   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2361         (mem:DI (reg:DI SP_REG)))
2362    (set (reg:DI SP_REG)
2363         (plus:DI (reg:DI SP_REG) (const_int 8)))
2364    (clobber (mem:BLK (scratch)))]
2365   "TARGET_64BIT"
2366   "pop{q}\t%0"
2367   [(set_attr "type" "pop")
2368    (set_attr "mode" "DI")])
2369
2370 (define_insn "popdi1"
2371   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2372         (mem:DI (reg:DI SP_REG)))
2373    (set (reg:DI SP_REG)
2374         (plus:DI (reg:DI SP_REG) (const_int 8)))]
2375   "TARGET_64BIT"
2376   "pop{q}\t%0"
2377   [(set_attr "type" "pop")
2378    (set_attr "mode" "DI")])
2379
2380 (define_insn "*movdi_xor_rex64"
2381   [(set (match_operand:DI 0 "register_operand" "=r")
2382         (match_operand:DI 1 "const0_operand" ""))
2383    (clobber (reg:CC FLAGS_REG))]
2384   "TARGET_64BIT
2385    && reload_completed"
2386   "xor{l}\t%k0, %k0";
2387   [(set_attr "type" "alu1")
2388    (set_attr "mode" "SI")
2389    (set_attr "length_immediate" "0")])
2390
2391 (define_insn "*movdi_or_rex64"
2392   [(set (match_operand:DI 0 "register_operand" "=r")
2393         (match_operand:DI 1 "const_int_operand" "i"))
2394    (clobber (reg:CC FLAGS_REG))]
2395   "TARGET_64BIT
2396    && reload_completed
2397    && operands[1] == constm1_rtx"
2398 {
2399   operands[1] = constm1_rtx;
2400   return "or{q}\t{%1, %0|%0, %1}";
2401 }
2402   [(set_attr "type" "alu1")
2403    (set_attr "mode" "DI")
2404    (set_attr "length_immediate" "1")])
2405
2406 (define_insn "*movdi_2"
2407   [(set (match_operand:DI 0 "nonimmediate_operand"
2408                         "=r  ,o  ,*y,m*y,*y,*Y2,m  ,*Y2,*Y2,*x,m ,*x,*x")
2409         (match_operand:DI 1 "general_operand"
2410                         "riFo,riF,C ,*y ,m ,C  ,*Y2,*Y2,m  ,C ,*x,*x,m "))]
2411   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2412   "@
2413    #
2414    #
2415    pxor\t%0, %0
2416    movq\t{%1, %0|%0, %1}
2417    movq\t{%1, %0|%0, %1}
2418    %vpxor\t%0, %d0
2419    %vmovq\t{%1, %0|%0, %1}
2420    %vmovdqa\t{%1, %0|%0, %1}
2421    %vmovq\t{%1, %0|%0, %1}
2422    xorps\t%0, %0
2423    movlps\t{%1, %0|%0, %1}
2424    movaps\t{%1, %0|%0, %1}
2425    movlps\t{%1, %0|%0, %1}"
2426   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2427    (set (attr "prefix")
2428      (if_then_else (eq_attr "alternative" "5,6,7,8")
2429        (const_string "vex")
2430        (const_string "orig")))
2431    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2432
2433 (define_split
2434   [(set (match_operand:DI 0 "push_operand" "")
2435         (match_operand:DI 1 "general_operand" ""))]
2436   "!TARGET_64BIT && reload_completed
2437    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2438   [(const_int 0)]
2439   "ix86_split_long_move (operands); DONE;")
2440
2441 ;; %%% This multiword shite has got to go.
2442 (define_split
2443   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2444         (match_operand:DI 1 "general_operand" ""))]
2445   "!TARGET_64BIT && reload_completed
2446    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2447    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2448   [(const_int 0)]
2449   "ix86_split_long_move (operands); DONE;")
2450
2451 (define_insn "*movdi_1_rex64"
2452   [(set (match_operand:DI 0 "nonimmediate_operand"
2453           "=r,r  ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2454         (match_operand:DI 1 "general_operand"
2455           "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r   ,m  ,C ,*x,*Yi,*x,r  ,m ,*Ym,*x"))]
2456   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2457 {
2458   switch (get_attr_type (insn))
2459     {
2460     case TYPE_SSECVT:
2461       if (SSE_REG_P (operands[0]))
2462         return "movq2dq\t{%1, %0|%0, %1}";
2463       else
2464         return "movdq2q\t{%1, %0|%0, %1}";
2465
2466     case TYPE_SSEMOV:
2467       if (TARGET_AVX)
2468         {
2469           if (get_attr_mode (insn) == MODE_TI)
2470             return "vmovdqa\t{%1, %0|%0, %1}";
2471           else
2472             return "vmovq\t{%1, %0|%0, %1}";
2473         }
2474
2475       if (get_attr_mode (insn) == MODE_TI)
2476         return "movdqa\t{%1, %0|%0, %1}";
2477       /* FALLTHRU */
2478
2479     case TYPE_MMXMOV:
2480       /* Moves from and into integer register is done using movd
2481          opcode with REX prefix.  */
2482       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2483         return "movd\t{%1, %0|%0, %1}";
2484       return "movq\t{%1, %0|%0, %1}";
2485
2486     case TYPE_SSELOG1:
2487       return "%vpxor\t%0, %d0";
2488
2489     case TYPE_MMX:
2490       return "pxor\t%0, %0";
2491
2492     case TYPE_MULTI:
2493       return "#";
2494
2495     case TYPE_LEA:
2496       return "lea{q}\t{%a1, %0|%0, %a1}";
2497
2498     default:
2499       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2500       if (get_attr_mode (insn) == MODE_SI)
2501         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2502       else if (which_alternative == 2)
2503         return "movabs{q}\t{%1, %0|%0, %1}";
2504       else
2505         return "mov{q}\t{%1, %0|%0, %1}";
2506     }
2507 }
2508   [(set (attr "type")
2509      (cond [(eq_attr "alternative" "5")
2510               (const_string "mmx")
2511             (eq_attr "alternative" "6,7,8,9,10")
2512               (const_string "mmxmov")
2513             (eq_attr "alternative" "11")
2514               (const_string "sselog1")
2515             (eq_attr "alternative" "12,13,14,15,16")
2516               (const_string "ssemov")
2517             (eq_attr "alternative" "17,18")
2518               (const_string "ssecvt")
2519             (eq_attr "alternative" "4")
2520               (const_string "multi")
2521             (match_operand:DI 1 "pic_32bit_operand" "")
2522               (const_string "lea")
2523            ]
2524            (const_string "imov")))
2525    (set (attr "modrm")
2526      (if_then_else
2527        (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2528          (const_string "0")
2529          (const_string "*")))
2530    (set (attr "length_immediate")
2531      (if_then_else
2532        (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2533          (const_string "8")
2534          (const_string "*")))
2535    (set_attr "prefix_rex" "*,*,*,*,*,*,*,1,*,1,*,*,*,*,*,*,*,*,*")
2536    (set_attr "prefix_data16" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,1,*,*,*")
2537    (set (attr "prefix")
2538      (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
2539        (const_string "maybe_vex")
2540        (const_string "orig")))
2541    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2542
2543 ;; Stores and loads of ax to arbitrary constant address.
2544 ;; We fake an second form of instruction to force reload to load address
2545 ;; into register when rax is not available
2546 (define_insn "*movabsdi_1_rex64"
2547   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2548         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2549   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2550   "@
2551    movabs{q}\t{%1, %P0|%P0, %1}
2552    mov{q}\t{%1, %a0|%a0, %1}"
2553   [(set_attr "type" "imov")
2554    (set_attr "modrm" "0,*")
2555    (set_attr "length_address" "8,0")
2556    (set_attr "length_immediate" "0,*")
2557    (set_attr "memory" "store")
2558    (set_attr "mode" "DI")])
2559
2560 (define_insn "*movabsdi_2_rex64"
2561   [(set (match_operand:DI 0 "register_operand" "=a,r")
2562         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2563   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2564   "@
2565    movabs{q}\t{%P1, %0|%0, %P1}
2566    mov{q}\t{%a1, %0|%0, %a1}"
2567   [(set_attr "type" "imov")
2568    (set_attr "modrm" "0,*")
2569    (set_attr "length_address" "8,0")
2570    (set_attr "length_immediate" "0")
2571    (set_attr "memory" "load")
2572    (set_attr "mode" "DI")])
2573
2574 ;; Convert impossible stores of immediate to existing instructions.
2575 ;; First try to get scratch register and go through it.  In case this
2576 ;; fails, move by 32bit parts.
2577 (define_peephole2
2578   [(match_scratch:DI 2 "r")
2579    (set (match_operand:DI 0 "memory_operand" "")
2580         (match_operand:DI 1 "immediate_operand" ""))]
2581   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2582    && !x86_64_immediate_operand (operands[1], DImode)"
2583   [(set (match_dup 2) (match_dup 1))
2584    (set (match_dup 0) (match_dup 2))]
2585   "")
2586
2587 ;; We need to define this as both peepholer and splitter for case
2588 ;; peephole2 pass is not run.
2589 ;; "&& 1" is needed to keep it from matching the previous pattern.
2590 (define_peephole2
2591   [(set (match_operand:DI 0 "memory_operand" "")
2592         (match_operand:DI 1 "immediate_operand" ""))]
2593   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2594    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2595   [(set (match_dup 2) (match_dup 3))
2596    (set (match_dup 4) (match_dup 5))]
2597   "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2598
2599 (define_split
2600   [(set (match_operand:DI 0 "memory_operand" "")
2601         (match_operand:DI 1 "immediate_operand" ""))]
2602   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2603                     ? epilogue_completed : reload_completed)
2604    && !symbolic_operand (operands[1], DImode)
2605    && !x86_64_immediate_operand (operands[1], DImode)"
2606   [(set (match_dup 2) (match_dup 3))
2607    (set (match_dup 4) (match_dup 5))]
2608   "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2609
2610 (define_insn "*swapdi_rex64"
2611   [(set (match_operand:DI 0 "register_operand" "+r")
2612         (match_operand:DI 1 "register_operand" "+r"))
2613    (set (match_dup 1)
2614         (match_dup 0))]
2615   "TARGET_64BIT"
2616   "xchg{q}\t%1, %0"
2617   [(set_attr "type" "imov")
2618    (set_attr "mode" "DI")
2619    (set_attr "pent_pair" "np")
2620    (set_attr "athlon_decode" "vector")
2621    (set_attr "amdfam10_decode" "double")])
2622
2623 (define_expand "movoi"
2624   [(set (match_operand:OI 0 "nonimmediate_operand" "")
2625         (match_operand:OI 1 "general_operand" ""))]
2626   "TARGET_AVX"
2627   "ix86_expand_move (OImode, operands); DONE;")
2628
2629 (define_insn "*movoi_internal"
2630   [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
2631         (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
2632   "TARGET_AVX
2633    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2634 {
2635   switch (which_alternative)
2636     {
2637     case 0:
2638       return "vxorps\t%0, %0, %0";
2639     case 1:
2640     case 2:
2641       if (misaligned_operand (operands[0], OImode)
2642           || misaligned_operand (operands[1], OImode))
2643         return "vmovdqu\t{%1, %0|%0, %1}";
2644       else
2645         return "vmovdqa\t{%1, %0|%0, %1}";
2646     default:
2647       gcc_unreachable ();
2648     }
2649 }
2650   [(set_attr "type" "sselog1,ssemov,ssemov")
2651    (set_attr "prefix" "vex")
2652    (set_attr "mode" "OI")])
2653
2654 (define_expand "movti"
2655   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2656         (match_operand:TI 1 "nonimmediate_operand" ""))]
2657   "TARGET_SSE || TARGET_64BIT"
2658 {
2659   if (TARGET_64BIT)
2660     ix86_expand_move (TImode, operands);
2661   else if (push_operand (operands[0], TImode))
2662     ix86_expand_push (TImode, operands[1]);
2663   else
2664     ix86_expand_vector_move (TImode, operands);
2665   DONE;
2666 })
2667
2668 (define_insn "*movti_internal"
2669   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2670         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2671   "TARGET_SSE && !TARGET_64BIT
2672    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2673 {
2674   switch (which_alternative)
2675     {
2676     case 0:
2677       if (get_attr_mode (insn) == MODE_V4SF)
2678         return "%vxorps\t%0, %d0";
2679       else
2680         return "%vpxor\t%0, %d0";
2681     case 1:
2682     case 2:
2683       /* TDmode values are passed as TImode on the stack.  Moving them
2684          to stack may result in unaligned memory access.  */
2685       if (misaligned_operand (operands[0], TImode)
2686           || misaligned_operand (operands[1], TImode))
2687         {
2688           if (get_attr_mode (insn) == MODE_V4SF)
2689             return "%vmovups\t{%1, %0|%0, %1}";
2690          else
2691            return "%vmovdqu\t{%1, %0|%0, %1}";
2692         }
2693       else
2694         {
2695           if (get_attr_mode (insn) == MODE_V4SF)
2696             return "%vmovaps\t{%1, %0|%0, %1}";
2697          else
2698            return "%vmovdqa\t{%1, %0|%0, %1}";
2699         }
2700     default:
2701       gcc_unreachable ();
2702     }
2703 }
2704   [(set_attr "type" "sselog1,ssemov,ssemov")
2705    (set_attr "prefix" "maybe_vex")
2706    (set (attr "mode")
2707         (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2708                     (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0)))
2709                  (const_string "V4SF")
2710                (and (eq_attr "alternative" "2")
2711                     (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2712                         (const_int 0)))
2713                  (const_string "V4SF")]
2714               (const_string "TI")))])
2715
2716 (define_insn "*movti_rex64"
2717   [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
2718         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2719   "TARGET_64BIT
2720    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2721 {
2722   switch (which_alternative)
2723     {
2724     case 0:
2725     case 1:
2726       return "#";
2727     case 2:
2728       if (get_attr_mode (insn) == MODE_V4SF)
2729         return "%vxorps\t%0, %d0";
2730       else
2731         return "%vpxor\t%0, %d0";
2732     case 3:
2733     case 4:
2734       /* TDmode values are passed as TImode on the stack.  Moving them
2735          to stack may result in unaligned memory access.  */
2736       if (misaligned_operand (operands[0], TImode)
2737           || misaligned_operand (operands[1], TImode))
2738         {
2739           if (get_attr_mode (insn) == MODE_V4SF)
2740             return "%vmovups\t{%1, %0|%0, %1}";
2741          else
2742            return "%vmovdqu\t{%1, %0|%0, %1}";
2743         }
2744       else
2745         {
2746           if (get_attr_mode (insn) == MODE_V4SF)
2747             return "%vmovaps\t{%1, %0|%0, %1}";
2748          else
2749            return "%vmovdqa\t{%1, %0|%0, %1}";
2750         }
2751     default:
2752       gcc_unreachable ();
2753     }
2754 }
2755   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2756    (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
2757    (set (attr "mode")
2758         (cond [(eq_attr "alternative" "2,3")
2759                  (if_then_else
2760                    (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2761                        (const_int 0))
2762                    (const_string "V4SF")
2763                    (const_string "TI"))
2764                (eq_attr "alternative" "4")
2765                  (if_then_else
2766                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2767                             (const_int 0))
2768                         (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2769                             (const_int 0)))
2770                    (const_string "V4SF")
2771                    (const_string "TI"))]
2772                (const_string "DI")))])
2773
2774 (define_split
2775   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2776         (match_operand:TI 1 "general_operand" ""))]
2777   "reload_completed && !SSE_REG_P (operands[0])
2778    && !SSE_REG_P (operands[1])"
2779   [(const_int 0)]
2780   "ix86_split_long_move (operands); DONE;")
2781
2782 ;; This expands to what emit_move_complex would generate if we didn't
2783 ;; have a movti pattern.  Having this avoids problems with reload on
2784 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2785 ;; to have around all the time.
2786 (define_expand "movcdi"
2787   [(set (match_operand:CDI 0 "nonimmediate_operand" "")
2788         (match_operand:CDI 1 "general_operand" ""))]
2789   ""
2790 {
2791   if (push_operand (operands[0], CDImode))
2792     emit_move_complex_push (CDImode, operands[0], operands[1]);
2793   else
2794     emit_move_complex_parts (operands[0], operands[1]);
2795   DONE;
2796 })
2797
2798 (define_expand "movsf"
2799   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2800         (match_operand:SF 1 "general_operand" ""))]
2801   ""
2802   "ix86_expand_move (SFmode, operands); DONE;")
2803
2804 (define_insn "*pushsf"
2805   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2806         (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2807   "!TARGET_64BIT"
2808 {
2809   /* Anything else should be already split before reg-stack.  */
2810   gcc_assert (which_alternative == 1);
2811   return "push{l}\t%1";
2812 }
2813   [(set_attr "type" "multi,push,multi")
2814    (set_attr "unit" "i387,*,*")
2815    (set_attr "mode" "SF,SI,SF")])
2816
2817 (define_insn "*pushsf_rex64"
2818   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2819         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2820   "TARGET_64BIT"
2821 {
2822   /* Anything else should be already split before reg-stack.  */
2823   gcc_assert (which_alternative == 1);
2824   return "push{q}\t%q1";
2825 }
2826   [(set_attr "type" "multi,push,multi")
2827    (set_attr "unit" "i387,*,*")
2828    (set_attr "mode" "SF,DI,SF")])
2829
2830 (define_split
2831   [(set (match_operand:SF 0 "push_operand" "")
2832         (match_operand:SF 1 "memory_operand" ""))]
2833   "reload_completed
2834    && MEM_P (operands[1])
2835    && (operands[2] = find_constant_src (insn))"
2836   [(set (match_dup 0)
2837         (match_dup 2))])
2838
2839 ;; %%% Kill this when call knows how to work this out.
2840 (define_split
2841   [(set (match_operand:SF 0 "push_operand" "")
2842         (match_operand:SF 1 "any_fp_register_operand" ""))]
2843   "!TARGET_64BIT"
2844   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2845    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2846
2847 (define_split
2848   [(set (match_operand:SF 0 "push_operand" "")
2849         (match_operand:SF 1 "any_fp_register_operand" ""))]
2850   "TARGET_64BIT"
2851   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2852    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2853
2854 (define_insn "*movsf_1"
2855   [(set (match_operand:SF 0 "nonimmediate_operand"
2856           "=f,m,f,r  ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
2857         (match_operand:SF 1 "general_operand"
2858           "fm,f,G,rmF,Fr,C,x,xm,x,m  ,*y,*y ,r  ,Yi,r   ,*Ym"))]
2859   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2860    && (reload_in_progress || reload_completed
2861        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2862        || (!TARGET_SSE_MATH && optimize_function_for_size_p (cfun)
2863            && standard_80387_constant_p (operands[1]))
2864        || GET_CODE (operands[1]) != CONST_DOUBLE
2865        || memory_operand (operands[0], SFmode))"
2866 {
2867   switch (which_alternative)
2868     {
2869     case 0:
2870     case 1:
2871       return output_387_reg_move (insn, operands);
2872
2873     case 2:
2874       return standard_80387_constant_opcode (operands[1]);
2875
2876     case 3:
2877     case 4:
2878       return "mov{l}\t{%1, %0|%0, %1}";
2879     case 5:
2880       if (get_attr_mode (insn) == MODE_TI)
2881         return "%vpxor\t%0, %d0";
2882       else
2883         return "%vxorps\t%0, %d0";
2884     case 6:
2885       if (get_attr_mode (insn) == MODE_V4SF)
2886         return "%vmovaps\t{%1, %0|%0, %1}";
2887       else
2888         return "%vmovss\t{%1, %d0|%d0, %1}";
2889     case 7:
2890       if (TARGET_AVX)
2891         return REG_P (operands[1]) ? "vmovss\t{%1, %0, %0|%0, %0, %1}"
2892                                    : "vmovss\t{%1, %0|%0, %1}";
2893       else
2894         return "movss\t{%1, %0|%0, %1}";
2895     case 8:
2896       return "%vmovss\t{%1, %0|%0, %1}";
2897
2898     case 9: case 10: case 14: case 15:
2899       return "movd\t{%1, %0|%0, %1}";
2900     case 12: case 13:
2901       return "%vmovd\t{%1, %0|%0, %1}";
2902
2903     case 11:
2904       return "movq\t{%1, %0|%0, %1}";
2905
2906     default:
2907       gcc_unreachable ();
2908     }
2909 }
2910   [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2911    (set (attr "prefix")
2912      (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
2913        (const_string "maybe_vex")
2914        (const_string "orig")))
2915    (set (attr "mode")
2916         (cond [(eq_attr "alternative" "3,4,9,10")
2917                  (const_string "SI")
2918                (eq_attr "alternative" "5")
2919                  (if_then_else
2920                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2921                                  (const_int 0))
2922                              (ne (symbol_ref "TARGET_SSE2")
2923                                  (const_int 0)))
2924                         (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2925                             (const_int 0)))
2926                    (const_string "TI")
2927                    (const_string "V4SF"))
2928                /* For architectures resolving dependencies on
2929                   whole SSE registers use APS move to break dependency
2930                   chains, otherwise use short move to avoid extra work.
2931
2932                   Do the same for architectures resolving dependencies on
2933                   the parts.  While in DF mode it is better to always handle
2934                   just register parts, the SF mode is different due to lack
2935                   of instructions to load just part of the register.  It is
2936                   better to maintain the whole registers in single format
2937                   to avoid problems on using packed logical operations.  */
2938                (eq_attr "alternative" "6")
2939                  (if_then_else
2940                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2941                             (const_int 0))
2942                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2943                             (const_int 0)))
2944                    (const_string "V4SF")
2945                    (const_string "SF"))
2946                (eq_attr "alternative" "11")
2947                  (const_string "DI")]
2948                (const_string "SF")))])
2949
2950 (define_insn "*swapsf"
2951   [(set (match_operand:SF 0 "fp_register_operand" "+f")
2952         (match_operand:SF 1 "fp_register_operand" "+f"))
2953    (set (match_dup 1)
2954         (match_dup 0))]
2955   "reload_completed || TARGET_80387"
2956 {
2957   if (STACK_TOP_P (operands[0]))
2958     return "fxch\t%1";
2959   else
2960     return "fxch\t%0";
2961 }
2962   [(set_attr "type" "fxch")
2963    (set_attr "mode" "SF")])
2964
2965 (define_expand "movdf"
2966   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2967         (match_operand:DF 1 "general_operand" ""))]
2968   ""
2969   "ix86_expand_move (DFmode, operands); DONE;")
2970
2971 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2972 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2973 ;; On the average, pushdf using integers can be still shorter.  Allow this
2974 ;; pattern for optimize_size too.
2975
2976 (define_insn "*pushdf_nointeger"
2977   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2978         (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2979   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2980 {
2981   /* This insn should be already split before reg-stack.  */
2982   gcc_unreachable ();
2983 }
2984   [(set_attr "type" "multi")
2985    (set_attr "unit" "i387,*,*,*")
2986    (set_attr "mode" "DF,SI,SI,DF")])
2987
2988 (define_insn "*pushdf_integer"
2989   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2990         (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2991   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2992 {
2993   /* This insn should be already split before reg-stack.  */
2994   gcc_unreachable ();
2995 }
2996   [(set_attr "type" "multi")
2997    (set_attr "unit" "i387,*,*")
2998    (set_attr "mode" "DF,SI,DF")])
2999
3000 ;; %%% Kill this when call knows how to work this out.
3001 (define_split
3002   [(set (match_operand:DF 0 "push_operand" "")
3003         (match_operand:DF 1 "any_fp_register_operand" ""))]
3004   "reload_completed"
3005   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3006    (set (mem:DF (reg:P SP_REG)) (match_dup 1))]
3007   "")
3008
3009 (define_split
3010   [(set (match_operand:DF 0 "push_operand" "")
3011         (match_operand:DF 1 "general_operand" ""))]
3012   "reload_completed"
3013   [(const_int 0)]
3014   "ix86_split_long_move (operands); DONE;")
3015
3016 ;; Moving is usually shorter when only FP registers are used. This separate
3017 ;; movdf pattern avoids the use of integer registers for FP operations
3018 ;; when optimizing for size.
3019
3020 (define_insn "*movdf_nointeger"
3021   [(set (match_operand:DF 0 "nonimmediate_operand"
3022                         "=f,m,f,*r  ,o  ,Y2*x,Y2*x,Y2*x ,m  ")
3023         (match_operand:DF 1 "general_operand"
3024                         "fm,f,G,*roF,*Fr,C   ,Y2*x,mY2*x,Y2*x"))]
3025   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3026    && ((optimize_function_for_size_p (cfun)
3027        || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
3028    && (reload_in_progress || reload_completed
3029        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3030        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3031            && optimize_function_for_size_p (cfun)
3032            && !memory_operand (operands[0], DFmode)
3033            && standard_80387_constant_p (operands[1]))
3034        || GET_CODE (operands[1]) != CONST_DOUBLE
3035        || ((optimize_function_for_size_p (cfun)
3036             || !TARGET_MEMORY_MISMATCH_STALL
3037             || reload_in_progress || reload_completed)
3038            && memory_operand (operands[0], DFmode)))"
3039 {
3040   switch (which_alternative)
3041     {
3042     case 0:
3043     case 1:
3044       return output_387_reg_move (insn, operands);
3045
3046     case 2:
3047       return standard_80387_constant_opcode (operands[1]);
3048
3049     case 3:
3050     case 4:
3051       return "#";
3052     case 5:
3053       switch (get_attr_mode (insn))
3054         {
3055         case MODE_V4SF:
3056           return "%vxorps\t%0, %d0";
3057         case MODE_V2DF:
3058           return "%vxorpd\t%0, %d0";
3059         case MODE_TI:
3060           return "%vpxor\t%0, %d0";
3061         default:
3062           gcc_unreachable ();
3063         }
3064     case 6:
3065     case 7:
3066     case 8:
3067       switch (get_attr_mode (insn))
3068         {
3069         case MODE_V4SF:
3070           return "%vmovaps\t{%1, %0|%0, %1}";
3071         case MODE_V2DF:
3072           return "%vmovapd\t{%1, %0|%0, %1}";
3073         case MODE_TI:
3074           return "%vmovdqa\t{%1, %0|%0, %1}";
3075         case MODE_DI:
3076           return "%vmovq\t{%1, %0|%0, %1}";
3077         case MODE_DF:
3078           if (TARGET_AVX)
3079             {
3080               if (REG_P (operands[0]) && REG_P (operands[1]))
3081                 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3082               else
3083                 return "vmovsd\t{%1, %0|%0, %1}";
3084             }
3085           else
3086             return "movsd\t{%1, %0|%0, %1}";
3087         case MODE_V1DF:
3088           if (TARGET_AVX)
3089             {
3090               if (REG_P (operands[0]))
3091                 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
3092               else
3093                 return "vmovlpd\t{%1, %0|%0, %1}";
3094             }
3095           else
3096             return "movlpd\t{%1, %0|%0, %1}";
3097         case MODE_V2SF:
3098           if (TARGET_AVX)
3099             {
3100               if (REG_P (operands[0]))
3101                 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
3102               else
3103                 return "vmovlps\t{%1, %0|%0, %1}";
3104             }
3105           else
3106             return "movlps\t{%1, %0|%0, %1}";
3107         default:
3108           gcc_unreachable ();
3109         }
3110
3111     default:
3112       gcc_unreachable ();
3113     }
3114 }
3115   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3116    (set (attr "prefix")
3117      (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3118        (const_string "orig")
3119        (const_string "maybe_vex")))
3120    (set (attr "prefix_data16")
3121      (if_then_else (eq_attr "mode" "V1DF")
3122        (const_string "1")
3123        (const_string "*")))
3124    (set (attr "mode")
3125         (cond [(eq_attr "alternative" "0,1,2")
3126                  (const_string "DF")
3127                (eq_attr "alternative" "3,4")
3128                  (const_string "SI")
3129
3130                /* For SSE1, we have many fewer alternatives.  */
3131                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3132                  (cond [(eq_attr "alternative" "5,6")
3133                           (const_string "V4SF")
3134                        ]
3135                    (const_string "V2SF"))
3136
3137                /* xorps is one byte shorter.  */
3138                (eq_attr "alternative" "5")
3139                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3140                             (const_int 0))
3141                           (const_string "V4SF")
3142                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3143                             (const_int 0))
3144                           (const_string "TI")
3145                        ]
3146                        (const_string "V2DF"))
3147
3148                /* For architectures resolving dependencies on
3149                   whole SSE registers use APD move to break dependency
3150                   chains, otherwise use short move to avoid extra work.
3151
3152                   movaps encodes one byte shorter.  */
3153                (eq_attr "alternative" "6")
3154                  (cond
3155                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3156                         (const_int 0))
3157                       (const_string "V4SF")
3158                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3159                         (const_int 0))
3160                       (const_string "V2DF")
3161                    ]
3162                    (const_string "DF"))
3163                /* For architectures resolving dependencies on register
3164                   parts we may avoid extra work to zero out upper part
3165                   of register.  */
3166                (eq_attr "alternative" "7")
3167                  (if_then_else
3168                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3169                        (const_int 0))
3170                    (const_string "V1DF")
3171                    (const_string "DF"))
3172               ]
3173               (const_string "DF")))])
3174
3175 (define_insn "*movdf_integer_rex64"
3176   [(set (match_operand:DF 0 "nonimmediate_operand"
3177                 "=f,m,f,r  ,m ,Y2*x,Y2*x,Y2*x,m   ,Yi,r ")
3178         (match_operand:DF 1 "general_operand"
3179                 "fm,f,G,rmF,Fr,C   ,Y2*x,m   ,Y2*x,r ,Yi"))]
3180   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3181    && (reload_in_progress || reload_completed
3182        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3183        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3184            && optimize_function_for_size_p (cfun)
3185            && standard_80387_constant_p (operands[1]))
3186        || GET_CODE (operands[1]) != CONST_DOUBLE
3187        || memory_operand (operands[0], DFmode))"
3188 {
3189   switch (which_alternative)
3190     {
3191     case 0:
3192     case 1:
3193       return output_387_reg_move (insn, operands);
3194
3195     case 2:
3196       return standard_80387_constant_opcode (operands[1]);
3197
3198     case 3:
3199     case 4:
3200       return "#";
3201
3202     case 5:
3203       switch (get_attr_mode (insn))
3204         {
3205         case MODE_V4SF:
3206           return "%vxorps\t%0, %d0";
3207         case MODE_V2DF:
3208           return "%vxorpd\t%0, %d0";
3209         case MODE_TI:
3210           return "%vpxor\t%0, %d0";
3211         default:
3212           gcc_unreachable ();
3213         }
3214     case 6:
3215     case 7:
3216     case 8:
3217       switch (get_attr_mode (insn))
3218         {
3219         case MODE_V4SF:
3220           return "%vmovaps\t{%1, %0|%0, %1}";
3221         case MODE_V2DF:
3222           return "%vmovapd\t{%1, %0|%0, %1}";
3223         case MODE_TI:
3224           return "%vmovdqa\t{%1, %0|%0, %1}";
3225         case MODE_DI:
3226           return "%vmovq\t{%1, %0|%0, %1}";
3227         case MODE_DF:
3228           if (TARGET_AVX)
3229             {
3230               if (REG_P (operands[0]) && REG_P (operands[1]))
3231                 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3232               else
3233                 return "vmovsd\t{%1, %0|%0, %1}";
3234             }
3235           else
3236             return "movsd\t{%1, %0|%0, %1}";
3237         case MODE_V1DF:
3238           return "%vmovlpd\t{%1, %d0|%d0, %1}";
3239         case MODE_V2SF:
3240           return "%vmovlps\t{%1, %d0|%d0, %1}";
3241         default:
3242           gcc_unreachable ();
3243         }
3244
3245     case 9:
3246     case 10:
3247     return "%vmovd\t{%1, %0|%0, %1}";
3248
3249     default:
3250       gcc_unreachable();
3251     }
3252 }
3253   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
3254    (set (attr "prefix")
3255      (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3256        (const_string "orig")
3257        (const_string "maybe_vex")))
3258    (set (attr "prefix_data16")
3259      (if_then_else (eq_attr "mode" "V1DF")
3260        (const_string "1")
3261        (const_string "*")))
3262    (set (attr "mode")
3263         (cond [(eq_attr "alternative" "0,1,2")
3264                  (const_string "DF")
3265                (eq_attr "alternative" "3,4,9,10")
3266                  (const_string "DI")
3267
3268                /* For SSE1, we have many fewer alternatives.  */
3269                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3270                  (cond [(eq_attr "alternative" "5,6")
3271                           (const_string "V4SF")
3272                        ]
3273                    (const_string "V2SF"))
3274
3275                /* xorps is one byte shorter.  */
3276                (eq_attr "alternative" "5")
3277                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3278                             (const_int 0))
3279                           (const_string "V4SF")
3280                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3281                             (const_int 0))
3282                           (const_string "TI")
3283                        ]
3284                        (const_string "V2DF"))
3285
3286                /* For architectures resolving dependencies on
3287                   whole SSE registers use APD move to break dependency
3288                   chains, otherwise use short move to avoid extra work.
3289
3290                   movaps encodes one byte shorter.  */
3291                (eq_attr "alternative" "6")
3292                  (cond
3293                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3294                         (const_int 0))
3295                       (const_string "V4SF")
3296                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3297                         (const_int 0))
3298                       (const_string "V2DF")
3299                    ]
3300                    (const_string "DF"))
3301                /* For architectures resolving dependencies on register
3302                   parts we may avoid extra work to zero out upper part
3303                   of register.  */
3304                (eq_attr "alternative" "7")
3305                  (if_then_else
3306                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3307                        (const_int 0))
3308                    (const_string "V1DF")
3309                    (const_string "DF"))
3310               ]
3311               (const_string "DF")))])
3312
3313 (define_insn "*movdf_integer"
3314   [(set (match_operand:DF 0 "nonimmediate_operand"
3315                 "=f,m,f,r  ,o ,Y2*x,Y2*x,Y2*x,m   ")
3316         (match_operand:DF 1 "general_operand"
3317                 "fm,f,G,roF,Fr,C   ,Y2*x,m   ,Y2*x"))]
3318   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3319    && optimize_function_for_speed_p (cfun)
3320    && TARGET_INTEGER_DFMODE_MOVES
3321    && (reload_in_progress || reload_completed
3322        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3323        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3324            && optimize_function_for_size_p (cfun)
3325            && standard_80387_constant_p (operands[1]))
3326        || GET_CODE (operands[1]) != CONST_DOUBLE
3327        || memory_operand (operands[0], DFmode))"
3328 {
3329   switch (which_alternative)
3330     {
3331     case 0:
3332     case 1:
3333       return output_387_reg_move (insn, operands);
3334
3335     case 2:
3336       return standard_80387_constant_opcode (operands[1]);
3337
3338     case 3:
3339     case 4:
3340       return "#";
3341
3342     case 5:
3343       switch (get_attr_mode (insn))
3344         {
3345         case MODE_V4SF:
3346           return "xorps\t%0, %0";
3347         case MODE_V2DF:
3348           return "xorpd\t%0, %0";
3349         case MODE_TI:
3350           return "pxor\t%0, %0";
3351         default:
3352           gcc_unreachable ();
3353         }
3354     case 6:
3355     case 7:
3356     case 8:
3357       switch (get_attr_mode (insn))
3358         {
3359         case MODE_V4SF:
3360           return "movaps\t{%1, %0|%0, %1}";
3361         case MODE_V2DF:
3362           return "movapd\t{%1, %0|%0, %1}";
3363         case MODE_TI:
3364           return "movdqa\t{%1, %0|%0, %1}";
3365         case MODE_DI:
3366           return "movq\t{%1, %0|%0, %1}";
3367         case MODE_DF:
3368           return "movsd\t{%1, %0|%0, %1}";
3369         case MODE_V1DF:
3370           return "movlpd\t{%1, %0|%0, %1}";
3371         case MODE_V2SF:
3372           return "movlps\t{%1, %0|%0, %1}";
3373         default:
3374           gcc_unreachable ();
3375         }
3376
3377     default:
3378       gcc_unreachable();
3379     }
3380 }
3381   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3382    (set (attr "prefix_data16")
3383      (if_then_else (eq_attr "mode" "V1DF")
3384        (const_string "1")
3385        (const_string "*")))
3386    (set (attr "mode")
3387         (cond [(eq_attr "alternative" "0,1,2")
3388                  (const_string "DF")
3389                (eq_attr "alternative" "3,4")
3390                  (const_string "SI")
3391
3392                /* For SSE1, we have many fewer alternatives.  */
3393                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3394                  (cond [(eq_attr "alternative" "5,6")
3395                           (const_string "V4SF")
3396                        ]
3397                    (const_string "V2SF"))
3398
3399                /* xorps is one byte shorter.  */
3400                (eq_attr "alternative" "5")
3401                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3402                             (const_int 0))
3403                           (const_string "V4SF")
3404                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3405                             (const_int 0))
3406                           (const_string "TI")
3407                        ]
3408                        (const_string "V2DF"))
3409
3410                /* For architectures resolving dependencies on
3411                   whole SSE registers use APD move to break dependency
3412                   chains, otherwise use short move to avoid extra work.
3413
3414                   movaps encodes one byte shorter.  */
3415                (eq_attr "alternative" "6")
3416                  (cond
3417                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3418                         (const_int 0))
3419                       (const_string "V4SF")
3420                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3421                         (const_int 0))
3422                       (const_string "V2DF")
3423                    ]
3424                    (const_string "DF"))
3425                /* For architectures resolving dependencies on register
3426                   parts we may avoid extra work to zero out upper part
3427                   of register.  */
3428                (eq_attr "alternative" "7")
3429                  (if_then_else
3430                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3431                        (const_int 0))
3432                    (const_string "V1DF")
3433                    (const_string "DF"))
3434               ]
3435               (const_string "DF")))])
3436
3437 (define_split
3438   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3439         (match_operand:DF 1 "general_operand" ""))]
3440   "reload_completed
3441    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3442    && ! (ANY_FP_REG_P (operands[0]) ||
3443          (GET_CODE (operands[0]) == SUBREG
3444           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3445    && ! (ANY_FP_REG_P (operands[1]) ||
3446          (GET_CODE (operands[1]) == SUBREG
3447           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3448   [(const_int 0)]
3449   "ix86_split_long_move (operands); DONE;")
3450
3451 (define_insn "*swapdf"
3452   [(set (match_operand:DF 0 "fp_register_operand" "+f")
3453         (match_operand:DF 1 "fp_register_operand" "+f"))
3454    (set (match_dup 1)
3455         (match_dup 0))]
3456   "reload_completed || TARGET_80387"
3457 {
3458   if (STACK_TOP_P (operands[0]))
3459     return "fxch\t%1";
3460   else
3461     return "fxch\t%0";
3462 }
3463   [(set_attr "type" "fxch")
3464    (set_attr "mode" "DF")])
3465
3466 (define_expand "movxf"
3467   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3468         (match_operand:XF 1 "general_operand" ""))]
3469   ""
3470   "ix86_expand_move (XFmode, operands); DONE;")
3471
3472 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3473 ;; Size of pushdf using integer instructions is 3+3*memory operand size
3474 ;; Pushing using integer instructions is longer except for constants
3475 ;; and direct memory references.
3476 ;; (assuming that any given constant is pushed only once, but this ought to be
3477 ;;  handled elsewhere).
3478
3479 (define_insn "*pushxf_nointeger"
3480   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
3481         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
3482   "optimize_function_for_size_p (cfun)"
3483 {
3484   /* This insn should be already split before reg-stack.  */
3485   gcc_unreachable ();
3486 }
3487   [(set_attr "type" "multi")
3488    (set_attr "unit" "i387,*,*")
3489    (set_attr "mode" "XF,SI,SI")])
3490
3491 (define_insn "*pushxf_integer"
3492   [(set (match_operand:XF 0 "push_operand" "=<,<")
3493         (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
3494   "optimize_function_for_speed_p (cfun)"
3495 {
3496   /* This insn should be already split before reg-stack.  */
3497   gcc_unreachable ();
3498 }
3499   [(set_attr "type" "multi")
3500    (set_attr "unit" "i387,*")
3501    (set_attr "mode" "XF,SI")])
3502
3503 (define_split
3504   [(set (match_operand 0 "push_operand" "")
3505         (match_operand 1 "general_operand" ""))]
3506   "reload_completed
3507    && (GET_MODE (operands[0]) == XFmode
3508        || GET_MODE (operands[0]) == DFmode)
3509    && !ANY_FP_REG_P (operands[1])"
3510   [(const_int 0)]
3511   "ix86_split_long_move (operands); DONE;")
3512
3513 (define_split
3514   [(set (match_operand:XF 0 "push_operand" "")
3515         (match_operand:XF 1 "any_fp_register_operand" ""))]
3516   ""
3517   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3518    (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
3519   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3520
3521 ;; Do not use integer registers when optimizing for size
3522 (define_insn "*movxf_nointeger"
3523   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3524         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3525   "optimize_function_for_size_p (cfun)
3526    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3527    && (reload_in_progress || reload_completed
3528        || standard_80387_constant_p (operands[1])
3529        || GET_CODE (operands[1]) != CONST_DOUBLE
3530        || memory_operand (operands[0], XFmode))"
3531 {
3532   switch (which_alternative)
3533     {
3534     case 0:
3535     case 1:
3536       return output_387_reg_move (insn, operands);
3537
3538     case 2:
3539       return standard_80387_constant_opcode (operands[1]);
3540
3541     case 3: case 4:
3542       return "#";
3543     default:
3544       gcc_unreachable ();
3545     }
3546 }
3547   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3548    (set_attr "mode" "XF,XF,XF,SI,SI")])
3549
3550 (define_insn "*movxf_integer"
3551   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
3552         (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
3553   "optimize_function_for_speed_p (cfun)
3554    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3555    && (reload_in_progress || reload_completed
3556        || GET_CODE (operands[1]) != CONST_DOUBLE
3557        || memory_operand (operands[0], XFmode))"
3558 {
3559   switch (which_alternative)
3560     {
3561     case 0:
3562     case 1:
3563       return output_387_reg_move (insn, operands);
3564
3565     case 2:
3566       return standard_80387_constant_opcode (operands[1]);
3567
3568     case 3: case 4:
3569       return "#";
3570
3571     default:
3572       gcc_unreachable ();
3573     }
3574 }
3575   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3576    (set_attr "mode" "XF,XF,XF,SI,SI")])
3577
3578 (define_expand "movtf"
3579   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3580         (match_operand:TF 1 "nonimmediate_operand" ""))]
3581   "TARGET_SSE2"
3582 {
3583   ix86_expand_move (TFmode, operands);
3584   DONE;
3585 })
3586
3587 (define_insn "*movtf_internal"
3588   [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
3589         (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
3590   "TARGET_SSE2
3591    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3592 {
3593   switch (which_alternative)
3594     {
3595     case 0:
3596     case 1:
3597       if (get_attr_mode (insn) == MODE_V4SF)
3598         return "%vmovaps\t{%1, %0|%0, %1}";
3599       else
3600         return "%vmovdqa\t{%1, %0|%0, %1}";
3601     case 2:
3602       if (get_attr_mode (insn) == MODE_V4SF)
3603         return "%vxorps\t%0, %d0";
3604       else
3605         return "%vpxor\t%0, %d0";
3606     case 3:
3607     case 4:
3608         return "#";
3609     default:
3610       gcc_unreachable ();
3611     }
3612 }
3613   [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
3614    (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
3615    (set (attr "mode")
3616         (cond [(eq_attr "alternative" "0,2")
3617                  (if_then_else
3618                    (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3619                        (const_int 0))
3620                    (const_string "V4SF")
3621                    (const_string "TI"))
3622                (eq_attr "alternative" "1")
3623                  (if_then_else
3624                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3625                             (const_int 0))
3626                         (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3627                             (const_int 0)))
3628                    (const_string "V4SF")
3629                    (const_string "TI"))]
3630                (const_string "DI")))])
3631
3632 (define_insn "*pushtf_sse"
3633   [(set (match_operand:TF 0 "push_operand" "=<,<,<")
3634         (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
3635   "TARGET_SSE2"
3636 {
3637   /* This insn should be already split before reg-stack.  */
3638   gcc_unreachable ();
3639 }
3640   [(set_attr "type" "multi")
3641    (set_attr "unit" "sse,*,*")
3642    (set_attr "mode" "TF,SI,SI")])
3643
3644 (define_split
3645   [(set (match_operand:TF 0 "push_operand" "")
3646         (match_operand:TF 1 "general_operand" ""))]
3647   "TARGET_SSE2 && reload_completed
3648    && !SSE_REG_P (operands[1])"
3649   [(const_int 0)]
3650   "ix86_split_long_move (operands); DONE;")
3651
3652 (define_split
3653   [(set (match_operand:TF 0 "push_operand" "")
3654         (match_operand:TF 1 "any_fp_register_operand" ""))]
3655   "TARGET_SSE2"
3656   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3657    (set (mem:TF (reg:P SP_REG)) (match_dup 1))]
3658   "")
3659
3660 (define_split
3661   [(set (match_operand 0 "nonimmediate_operand" "")
3662         (match_operand 1 "general_operand" ""))]
3663   "reload_completed
3664    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3665    && GET_MODE (operands[0]) == XFmode
3666    && ! (ANY_FP_REG_P (operands[0]) ||
3667          (GET_CODE (operands[0]) == SUBREG
3668           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3669    && ! (ANY_FP_REG_P (operands[1]) ||
3670          (GET_CODE (operands[1]) == SUBREG
3671           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3672   [(const_int 0)]
3673   "ix86_split_long_move (operands); DONE;")
3674
3675 (define_split
3676   [(set (match_operand 0 "register_operand" "")
3677         (match_operand 1 "memory_operand" ""))]
3678   "reload_completed
3679    && MEM_P (operands[1])
3680    && (GET_MODE (operands[0]) == TFmode
3681        || GET_MODE (operands[0]) == XFmode
3682        || GET_MODE (operands[0]) == SFmode
3683        || GET_MODE (operands[0]) == DFmode)
3684    && (operands[2] = find_constant_src (insn))"
3685   [(set (match_dup 0) (match_dup 2))]
3686 {
3687   rtx c = operands[2];
3688   rtx r = operands[0];
3689
3690   if (GET_CODE (r) == SUBREG)
3691     r = SUBREG_REG (r);
3692
3693   if (SSE_REG_P (r))
3694     {
3695       if (!standard_sse_constant_p (c))
3696         FAIL;
3697     }
3698   else if (FP_REG_P (r))
3699     {
3700       if (!standard_80387_constant_p (c))
3701         FAIL;
3702     }
3703   else if (MMX_REG_P (r))
3704     FAIL;
3705 })
3706
3707 (define_split
3708   [(set (match_operand 0 "register_operand" "")
3709         (float_extend (match_operand 1 "memory_operand" "")))]
3710   "reload_completed
3711    && MEM_P (operands[1])
3712    && (GET_MODE (operands[0]) == TFmode
3713        || GET_MODE (operands[0]) == XFmode
3714        || GET_MODE (operands[0]) == SFmode
3715        || GET_MODE (operands[0]) == DFmode)
3716    && (operands[2] = find_constant_src (insn))"
3717   [(set (match_dup 0) (match_dup 2))]
3718 {
3719   rtx c = operands[2];
3720   rtx r = operands[0];
3721
3722   if (GET_CODE (r) == SUBREG)
3723     r = SUBREG_REG (r);
3724
3725   if (SSE_REG_P (r))
3726     {
3727       if (!standard_sse_constant_p (c))
3728         FAIL;
3729     }
3730   else if (FP_REG_P (r))
3731     {
3732       if (!standard_80387_constant_p (c))
3733         FAIL;
3734     }
3735   else if (MMX_REG_P (r))
3736     FAIL;
3737 })
3738
3739 (define_insn "swapxf"
3740   [(set (match_operand:XF 0 "register_operand" "+f")
3741         (match_operand:XF 1 "register_operand" "+f"))
3742    (set (match_dup 1)
3743         (match_dup 0))]
3744   "TARGET_80387"
3745 {
3746   if (STACK_TOP_P (operands[0]))
3747     return "fxch\t%1";
3748   else
3749     return "fxch\t%0";
3750 }
3751   [(set_attr "type" "fxch")
3752    (set_attr "mode" "XF")])
3753
3754 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3755 (define_split
3756   [(set (match_operand:X87MODEF 0 "register_operand" "")
3757         (match_operand:X87MODEF 1 "immediate_operand" ""))]
3758   "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3759    && (standard_80387_constant_p (operands[1]) == 8
3760        || standard_80387_constant_p (operands[1]) == 9)"
3761   [(set (match_dup 0)(match_dup 1))
3762    (set (match_dup 0)
3763         (neg:X87MODEF (match_dup 0)))]
3764 {
3765   REAL_VALUE_TYPE r;
3766
3767   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3768   if (real_isnegzero (&r))
3769     operands[1] = CONST0_RTX (<MODE>mode);
3770   else
3771     operands[1] = CONST1_RTX (<MODE>mode);
3772 })
3773
3774 (define_split
3775   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3776         (match_operand:TF 1 "general_operand" ""))]
3777   "reload_completed
3778    && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
3779   [(const_int 0)]
3780   "ix86_split_long_move (operands); DONE;")
3781 \f
3782 ;; Zero extension instructions
3783
3784 (define_expand "zero_extendhisi2"
3785   [(set (match_operand:SI 0 "register_operand" "")
3786      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3787   ""
3788 {
3789   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3790     {
3791       operands[1] = force_reg (HImode, operands[1]);
3792       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3793       DONE;
3794     }
3795 })
3796
3797 (define_insn "zero_extendhisi2_and"
3798   [(set (match_operand:SI 0 "register_operand" "=r")
3799      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3800    (clobber (reg:CC FLAGS_REG))]
3801   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3802   "#"
3803   [(set_attr "type" "alu1")
3804    (set_attr "mode" "SI")])
3805
3806 (define_split
3807   [(set (match_operand:SI 0 "register_operand" "")
3808         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3809    (clobber (reg:CC FLAGS_REG))]
3810   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND
3811    && optimize_function_for_speed_p (cfun)"
3812   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3813               (clobber (reg:CC FLAGS_REG))])]
3814   "")
3815
3816 (define_insn "*zero_extendhisi2_movzwl"
3817   [(set (match_operand:SI 0 "register_operand" "=r")
3818      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3819   "!TARGET_ZERO_EXTEND_WITH_AND
3820    || optimize_function_for_size_p (cfun)"
3821   "movz{wl|x}\t{%1, %0|%0, %1}"
3822   [(set_attr "type" "imovx")
3823    (set_attr "mode" "SI")])
3824
3825 (define_expand "zero_extendqihi2"
3826   [(parallel
3827     [(set (match_operand:HI 0 "register_operand" "")
3828        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3829      (clobber (reg:CC FLAGS_REG))])]
3830   ""
3831   "")
3832
3833 (define_insn "*zero_extendqihi2_and"
3834   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3835      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3836    (clobber (reg:CC FLAGS_REG))]
3837   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3838   "#"
3839   [(set_attr "type" "alu1")
3840    (set_attr "mode" "HI")])
3841
3842 (define_insn "*zero_extendqihi2_movzbw_and"
3843   [(set (match_operand:HI 0 "register_operand" "=r,r")
3844      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3845    (clobber (reg:CC FLAGS_REG))]
3846   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3847   "#"
3848   [(set_attr "type" "imovx,alu1")
3849    (set_attr "mode" "HI")])
3850
3851 ; zero extend to SImode here to avoid partial register stalls
3852 (define_insn "*zero_extendqihi2_movzbl"
3853   [(set (match_operand:HI 0 "register_operand" "=r")
3854      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3855   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3856    && reload_completed"
3857   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3858   [(set_attr "type" "imovx")
3859    (set_attr "mode" "SI")])
3860
3861 ;; For the movzbw case strip only the clobber
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    && (!TARGET_ZERO_EXTEND_WITH_AND
3868        || optimize_function_for_size_p (cfun))
3869    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3870   [(set (match_operand:HI 0 "register_operand" "")
3871         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3872
3873 ;; When source and destination does not overlap, clear destination
3874 ;; first and then do the movb
3875 (define_split
3876   [(set (match_operand:HI 0 "register_operand" "")
3877         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3878    (clobber (reg:CC FLAGS_REG))]
3879   "reload_completed
3880    && ANY_QI_REG_P (operands[0])
3881    && (TARGET_ZERO_EXTEND_WITH_AND
3882        && optimize_function_for_speed_p (cfun))
3883    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3884   [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3885 {
3886   operands[2] = gen_lowpart (QImode, operands[0]);
3887   ix86_expand_clear (operands[0]);
3888 })
3889
3890 ;; Rest is handled by single and.
3891 (define_split
3892   [(set (match_operand:HI 0 "register_operand" "")
3893         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3894    (clobber (reg:CC FLAGS_REG))]
3895   "reload_completed
3896    && true_regnum (operands[0]) == true_regnum (operands[1])"
3897   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3898               (clobber (reg:CC FLAGS_REG))])]
3899   "")
3900
3901 (define_expand "zero_extendqisi2"
3902   [(parallel
3903     [(set (match_operand:SI 0 "register_operand" "")
3904        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3905      (clobber (reg:CC FLAGS_REG))])]
3906   ""
3907   "")
3908
3909 (define_insn "*zero_extendqisi2_and"
3910   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3911      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3912    (clobber (reg:CC FLAGS_REG))]
3913   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3914   "#"
3915   [(set_attr "type" "alu1")
3916    (set_attr "mode" "SI")])
3917
3918 (define_insn "*zero_extendqisi2_movzbl_and"
3919   [(set (match_operand:SI 0 "register_operand" "=r,r")
3920      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3921    (clobber (reg:CC FLAGS_REG))]
3922   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3923   "#"
3924   [(set_attr "type" "imovx,alu1")
3925    (set_attr "mode" "SI")])
3926
3927 (define_insn "*zero_extendqisi2_movzbl"
3928   [(set (match_operand:SI 0 "register_operand" "=r")
3929      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3930   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3931    && reload_completed"
3932   "movz{bl|x}\t{%1, %0|%0, %1}"
3933   [(set_attr "type" "imovx")
3934    (set_attr "mode" "SI")])
3935
3936 ;; For the movzbl case strip only the clobber
3937 (define_split
3938   [(set (match_operand:SI 0 "register_operand" "")
3939         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3940    (clobber (reg:CC FLAGS_REG))]
3941   "reload_completed
3942    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3943    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3944   [(set (match_dup 0)
3945         (zero_extend:SI (match_dup 1)))])
3946
3947 ;; When source and destination does not overlap, clear destination
3948 ;; first and then do the movb
3949 (define_split
3950   [(set (match_operand:SI 0 "register_operand" "")
3951         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3952    (clobber (reg:CC FLAGS_REG))]
3953   "reload_completed
3954    && ANY_QI_REG_P (operands[0])
3955    && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3956    && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3957    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3958   [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3959 {
3960   operands[2] = gen_lowpart (QImode, operands[0]);
3961   ix86_expand_clear (operands[0]);
3962 })
3963
3964 ;; Rest is handled by single and.
3965 (define_split
3966   [(set (match_operand:SI 0 "register_operand" "")
3967         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3968    (clobber (reg:CC FLAGS_REG))]
3969   "reload_completed
3970    && true_regnum (operands[0]) == true_regnum (operands[1])"
3971   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3972               (clobber (reg:CC FLAGS_REG))])]
3973   "")
3974
3975 ;; %%% Kill me once multi-word ops are sane.
3976 (define_expand "zero_extendsidi2"
3977   [(set (match_operand:DI 0 "register_operand" "")
3978      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3979   ""
3980 {
3981   if (!TARGET_64BIT)
3982     {
3983       emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3984       DONE;
3985     }
3986 })
3987
3988 (define_insn "zero_extendsidi2_32"
3989   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3990         (zero_extend:DI
3991          (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r   ,m  ,r   ,m")))
3992    (clobber (reg:CC FLAGS_REG))]
3993   "!TARGET_64BIT"
3994   "@
3995    #
3996    #
3997    #
3998    movd\t{%1, %0|%0, %1}
3999    movd\t{%1, %0|%0, %1}
4000    %vmovd\t{%1, %0|%0, %1}
4001    %vmovd\t{%1, %0|%0, %1}"
4002   [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
4003    (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
4004    (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
4005
4006 (define_insn "zero_extendsidi2_rex64"
4007   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
4008      (zero_extend:DI
4009        (match_operand:SI 1 "nonimmediate_operand"  "rm,0,r   ,m  ,r   ,m")))]
4010   "TARGET_64BIT"
4011   "@
4012    mov\t{%k1, %k0|%k0, %k1}
4013    #
4014    movd\t{%1, %0|%0, %1}
4015    movd\t{%1, %0|%0, %1}
4016    %vmovd\t{%1, %0|%0, %1}
4017    %vmovd\t{%1, %0|%0, %1}"
4018   [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
4019    (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
4020    (set_attr "prefix_0f" "0,*,*,*,*,*")
4021    (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
4022
4023 (define_split
4024   [(set (match_operand:DI 0 "memory_operand" "")
4025      (zero_extend:DI (match_dup 0)))]
4026   "TARGET_64BIT"
4027   [(set (match_dup 4) (const_int 0))]
4028   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4029
4030 (define_split
4031   [(set (match_operand:DI 0 "register_operand" "")
4032         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
4033    (clobber (reg:CC FLAGS_REG))]
4034   "!TARGET_64BIT && reload_completed
4035    && true_regnum (operands[0]) == true_regnum (operands[1])"
4036   [(set (match_dup 4) (const_int 0))]
4037   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4038
4039 (define_split
4040   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4041         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
4042    (clobber (reg:CC FLAGS_REG))]
4043   "!TARGET_64BIT && reload_completed
4044    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
4045   [(set (match_dup 3) (match_dup 1))
4046    (set (match_dup 4) (const_int 0))]
4047   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4048
4049 (define_insn "zero_extendhidi2"
4050   [(set (match_operand:DI 0 "register_operand" "=r")
4051      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
4052   "TARGET_64BIT"
4053   "movz{wl|x}\t{%1, %k0|%k0, %1}"
4054   [(set_attr "type" "imovx")
4055    (set_attr "mode" "SI")])
4056
4057 (define_insn "zero_extendqidi2"
4058   [(set (match_operand:DI 0 "register_operand" "=r")
4059      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
4060   "TARGET_64BIT"
4061   "movz{bl|x}\t{%1, %k0|%k0, %1}"
4062   [(set_attr "type" "imovx")
4063    (set_attr "mode" "SI")])
4064 \f
4065 ;; Sign extension instructions
4066
4067 (define_expand "extendsidi2"
4068   [(parallel [(set (match_operand:DI 0 "register_operand" "")
4069                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4070               (clobber (reg:CC FLAGS_REG))
4071               (clobber (match_scratch:SI 2 ""))])]
4072   ""
4073 {
4074   if (TARGET_64BIT)
4075     {
4076       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
4077       DONE;
4078     }
4079 })
4080
4081 (define_insn "*extendsidi2_1"
4082   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
4083         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
4084    (clobber (reg:CC FLAGS_REG))
4085    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
4086   "!TARGET_64BIT"
4087   "#")
4088
4089 (define_insn "extendsidi2_rex64"
4090   [(set (match_operand:DI 0 "register_operand" "=*a,r")
4091         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
4092   "TARGET_64BIT"
4093   "@
4094    {cltq|cdqe}
4095    movs{lq|x}\t{%1, %0|%0, %1}"
4096   [(set_attr "type" "imovx")
4097    (set_attr "mode" "DI")
4098    (set_attr "prefix_0f" "0")
4099    (set_attr "modrm" "0,1")])
4100
4101 (define_insn "extendhidi2"
4102   [(set (match_operand:DI 0 "register_operand" "=r")
4103         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
4104   "TARGET_64BIT"
4105   "movs{wq|x}\t{%1, %0|%0, %1}"
4106   [(set_attr "type" "imovx")
4107    (set_attr "mode" "DI")])
4108
4109 (define_insn "extendqidi2"
4110   [(set (match_operand:DI 0 "register_operand" "=r")
4111         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4112   "TARGET_64BIT"
4113   "movs{bq|x}\t{%1, %0|%0, %1}"
4114    [(set_attr "type" "imovx")
4115     (set_attr "mode" "DI")])
4116
4117 ;; Extend to memory case when source register does die.
4118 (define_split
4119   [(set (match_operand:DI 0 "memory_operand" "")
4120         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4121    (clobber (reg:CC FLAGS_REG))
4122    (clobber (match_operand:SI 2 "register_operand" ""))]
4123   "(reload_completed
4124     && dead_or_set_p (insn, operands[1])
4125     && !reg_mentioned_p (operands[1], operands[0]))"
4126   [(set (match_dup 3) (match_dup 1))
4127    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4128               (clobber (reg:CC FLAGS_REG))])
4129    (set (match_dup 4) (match_dup 1))]
4130   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4131
4132 ;; Extend to memory case when source register does not die.
4133 (define_split
4134   [(set (match_operand:DI 0 "memory_operand" "")
4135         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4136    (clobber (reg:CC FLAGS_REG))
4137    (clobber (match_operand:SI 2 "register_operand" ""))]
4138   "reload_completed"
4139   [(const_int 0)]
4140 {
4141   split_di (&operands[0], 1, &operands[3], &operands[4]);
4142
4143   emit_move_insn (operands[3], operands[1]);
4144
4145   /* Generate a cltd if possible and doing so it profitable.  */
4146   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4147       && true_regnum (operands[1]) == AX_REG
4148       && true_regnum (operands[2]) == DX_REG)
4149     {
4150       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
4151     }
4152   else
4153     {
4154       emit_move_insn (operands[2], operands[1]);
4155       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
4156     }
4157   emit_move_insn (operands[4], operands[2]);
4158   DONE;
4159 })
4160
4161 ;; Extend to register case.  Optimize case where source and destination
4162 ;; registers match and cases where we can use cltd.
4163 (define_split
4164   [(set (match_operand:DI 0 "register_operand" "")
4165         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4166    (clobber (reg:CC FLAGS_REG))
4167    (clobber (match_scratch:SI 2 ""))]
4168   "reload_completed"
4169   [(const_int 0)]
4170 {
4171   split_di (&operands[0], 1, &operands[3], &operands[4]);
4172
4173   if (true_regnum (operands[3]) != true_regnum (operands[1]))
4174     emit_move_insn (operands[3], operands[1]);
4175
4176   /* Generate a cltd if possible and doing so it profitable.  */
4177   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4178       && true_regnum (operands[3]) == AX_REG)
4179     {
4180       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
4181       DONE;
4182     }
4183
4184   if (true_regnum (operands[4]) != true_regnum (operands[1]))
4185     emit_move_insn (operands[4], operands[1]);
4186
4187   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
4188   DONE;
4189 })
4190
4191 (define_insn "extendhisi2"
4192   [(set (match_operand:SI 0 "register_operand" "=*a,r")
4193         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4194   ""
4195 {
4196   switch (get_attr_prefix_0f (insn))
4197     {
4198     case 0:
4199       return "{cwtl|cwde}";
4200     default:
4201       return "movs{wl|x}\t{%1, %0|%0, %1}";
4202     }
4203 }
4204   [(set_attr "type" "imovx")
4205    (set_attr "mode" "SI")
4206    (set (attr "prefix_0f")
4207      ;; movsx is short decodable while cwtl is vector decoded.
4208      (if_then_else (and (eq_attr "cpu" "!k6")
4209                         (eq_attr "alternative" "0"))
4210         (const_string "0")
4211         (const_string "1")))
4212    (set (attr "modrm")
4213      (if_then_else (eq_attr "prefix_0f" "0")
4214         (const_string "0")
4215         (const_string "1")))])
4216
4217 (define_insn "*extendhisi2_zext"
4218   [(set (match_operand:DI 0 "register_operand" "=*a,r")
4219         (zero_extend:DI
4220           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4221   "TARGET_64BIT"
4222 {
4223   switch (get_attr_prefix_0f (insn))
4224     {
4225     case 0:
4226       return "{cwtl|cwde}";
4227     default:
4228       return "movs{wl|x}\t{%1, %k0|%k0, %1}";
4229     }
4230 }
4231   [(set_attr "type" "imovx")
4232    (set_attr "mode" "SI")
4233    (set (attr "prefix_0f")
4234      ;; movsx is short decodable while cwtl is vector decoded.
4235      (if_then_else (and (eq_attr "cpu" "!k6")
4236                         (eq_attr "alternative" "0"))
4237         (const_string "0")
4238         (const_string "1")))
4239    (set (attr "modrm")
4240      (if_then_else (eq_attr "prefix_0f" "0")
4241         (const_string "0")
4242         (const_string "1")))])
4243
4244 (define_insn "extendqihi2"
4245   [(set (match_operand:HI 0 "register_operand" "=*a,r")
4246         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4247   ""
4248 {
4249   switch (get_attr_prefix_0f (insn))
4250     {
4251     case 0:
4252       return "{cbtw|cbw}";
4253     default:
4254       return "movs{bw|x}\t{%1, %0|%0, %1}";
4255     }
4256 }
4257   [(set_attr "type" "imovx")
4258    (set_attr "mode" "HI")
4259    (set (attr "prefix_0f")
4260      ;; movsx is short decodable while cwtl is vector decoded.
4261      (if_then_else (and (eq_attr "cpu" "!k6")
4262                         (eq_attr "alternative" "0"))
4263         (const_string "0")
4264         (const_string "1")))
4265    (set (attr "modrm")
4266      (if_then_else (eq_attr "prefix_0f" "0")
4267         (const_string "0")
4268         (const_string "1")))])
4269
4270 (define_insn "extendqisi2"
4271   [(set (match_operand:SI 0 "register_operand" "=r")
4272         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4273   ""
4274   "movs{bl|x}\t{%1, %0|%0, %1}"
4275    [(set_attr "type" "imovx")
4276     (set_attr "mode" "SI")])
4277
4278 (define_insn "*extendqisi2_zext"
4279   [(set (match_operand:DI 0 "register_operand" "=r")
4280         (zero_extend:DI
4281           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4282   "TARGET_64BIT"
4283   "movs{bl|x}\t{%1, %k0|%k0, %1}"
4284    [(set_attr "type" "imovx")
4285     (set_attr "mode" "SI")])
4286 \f
4287 ;; Conversions between float and double.
4288
4289 ;; These are all no-ops in the model used for the 80387.  So just
4290 ;; emit moves.
4291
4292 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4293 (define_insn "*dummy_extendsfdf2"
4294   [(set (match_operand:DF 0 "push_operand" "=<")
4295         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY2")))]
4296   "0"
4297   "#")
4298
4299 (define_split
4300   [(set (match_operand:DF 0 "push_operand" "")
4301         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
4302   ""
4303   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4304    (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4305
4306 (define_insn "*dummy_extendsfxf2"
4307   [(set (match_operand:XF 0 "push_operand" "=<")
4308         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
4309   "0"
4310   "#")
4311
4312 (define_split
4313   [(set (match_operand:XF 0 "push_operand" "")
4314         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
4315   ""
4316   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4317    (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4318   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4319
4320 (define_split
4321   [(set (match_operand:XF 0 "push_operand" "")
4322         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
4323   ""
4324   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4325    (set (mem:DF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4326   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4327
4328 (define_expand "extendsfdf2"
4329   [(set (match_operand:DF 0 "nonimmediate_operand" "")
4330         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
4331   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4332 {
4333   /* ??? Needed for compress_float_constant since all fp constants
4334      are LEGITIMATE_CONSTANT_P.  */
4335   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4336     {
4337       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4338           && standard_80387_constant_p (operands[1]) > 0)
4339         {
4340           operands[1] = simplify_const_unary_operation
4341             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4342           emit_move_insn_1 (operands[0], operands[1]);
4343           DONE;
4344         }
4345       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4346     }
4347 })
4348
4349 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4350    cvtss2sd:
4351       unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4352       cvtps2pd xmm2,xmm1
4353    We do the conversion post reload to avoid producing of 128bit spills
4354    that might lead to ICE on 32bit target.  The sequence unlikely combine
4355    anyway.  */
4356 (define_split
4357   [(set (match_operand:DF 0 "register_operand" "")
4358         (float_extend:DF
4359           (match_operand:SF 1 "nonimmediate_operand" "")))]
4360   "TARGET_USE_VECTOR_FP_CONVERTS
4361    && optimize_insn_for_speed_p ()
4362    && reload_completed && SSE_REG_P (operands[0])"
4363    [(set (match_dup 2)
4364          (float_extend:V2DF
4365            (vec_select:V2SF
4366              (match_dup 3)
4367              (parallel [(const_int 0) (const_int 1)]))))]
4368 {
4369   operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4370   operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4371   /* Use movss for loading from memory, unpcklps reg, reg for registers.
4372      Try to avoid move when unpacking can be done in source.  */
4373   if (REG_P (operands[1]))
4374     {
4375       /* If it is unsafe to overwrite upper half of source, we need
4376          to move to destination and unpack there.  */
4377       if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4378            || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4379           && true_regnum (operands[0]) != true_regnum (operands[1]))
4380         {
4381           rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4382           emit_move_insn (tmp, operands[1]);
4383         }
4384       else
4385         operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4386       emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4387                                              operands[3]));
4388     }
4389   else
4390     emit_insn (gen_vec_setv4sf_0 (operands[3],
4391                                   CONST0_RTX (V4SFmode), operands[1]));
4392 })
4393
4394 (define_insn "*extendsfdf2_mixed"
4395   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4396         (float_extend:DF
4397           (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4398   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4399 {
4400   switch (which_alternative)
4401     {
4402     case 0:
4403     case 1:
4404       return output_387_reg_move (insn, operands);
4405
4406     case 2:
4407       return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4408
4409     default:
4410       gcc_unreachable ();
4411     }
4412 }
4413   [(set_attr "type" "fmov,fmov,ssecvt")
4414    (set_attr "prefix" "orig,orig,maybe_vex")
4415    (set_attr "mode" "SF,XF,DF")])
4416
4417 (define_insn "*extendsfdf2_sse"
4418   [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4419         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4420   "TARGET_SSE2 && TARGET_SSE_MATH"
4421   "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4422   [(set_attr "type" "ssecvt")
4423    (set_attr "prefix" "maybe_vex")
4424    (set_attr "mode" "DF")])
4425
4426 (define_insn "*extendsfdf2_i387"
4427   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4428         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4429   "TARGET_80387"
4430   "* return output_387_reg_move (insn, operands);"
4431   [(set_attr "type" "fmov")
4432    (set_attr "mode" "SF,XF")])
4433
4434 (define_expand "extend<mode>xf2"
4435   [(set (match_operand:XF 0 "nonimmediate_operand" "")
4436         (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4437   "TARGET_80387"
4438 {
4439   /* ??? Needed for compress_float_constant since all fp constants
4440      are LEGITIMATE_CONSTANT_P.  */
4441   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4442     {
4443       if (standard_80387_constant_p (operands[1]) > 0)
4444         {
4445           operands[1] = simplify_const_unary_operation
4446             (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4447           emit_move_insn_1 (operands[0], operands[1]);
4448           DONE;
4449         }
4450       operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4451     }
4452 })
4453
4454 (define_insn "*extend<mode>xf2_i387"
4455   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4456         (float_extend:XF
4457           (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4458   "TARGET_80387"
4459   "* return output_387_reg_move (insn, operands);"
4460   [(set_attr "type" "fmov")
4461    (set_attr "mode" "<MODE>,XF")])
4462
4463 ;; %%% This seems bad bad news.
4464 ;; This cannot output into an f-reg because there is no way to be sure
4465 ;; of truncating in that case.  Otherwise this is just like a simple move
4466 ;; insn.  So we pretend we can output to a reg in order to get better
4467 ;; register preferencing, but we really use a stack slot.
4468
4469 ;; Conversion from DFmode to SFmode.
4470
4471 (define_expand "truncdfsf2"
4472   [(set (match_operand:SF 0 "nonimmediate_operand" "")
4473         (float_truncate:SF
4474           (match_operand:DF 1 "nonimmediate_operand" "")))]
4475   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4476 {
4477   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4478     ;
4479   else if (flag_unsafe_math_optimizations)
4480     ;
4481   else
4482     {
4483       enum ix86_stack_slot slot = (virtuals_instantiated
4484                                    ? SLOT_TEMP
4485                                    : SLOT_VIRTUAL);
4486       rtx temp = assign_386_stack_local (SFmode, slot);
4487       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4488       DONE;
4489     }
4490 })
4491
4492 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4493    cvtsd2ss:
4494       unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4495       cvtpd2ps xmm2,xmm1
4496    We do the conversion post reload to avoid producing of 128bit spills
4497    that might lead to ICE on 32bit target.  The sequence unlikely combine
4498    anyway.  */
4499 (define_split
4500   [(set (match_operand:SF 0 "register_operand" "")
4501         (float_truncate:SF
4502           (match_operand:DF 1 "nonimmediate_operand" "")))]
4503   "TARGET_USE_VECTOR_FP_CONVERTS
4504    && optimize_insn_for_speed_p ()
4505    && reload_completed && SSE_REG_P (operands[0])"
4506    [(set (match_dup 2)
4507          (vec_concat:V4SF
4508            (float_truncate:V2SF
4509              (match_dup 4))
4510            (match_dup 3)))]
4511 {
4512   operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4513   operands[3] = CONST0_RTX (V2SFmode);
4514   operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4515   /* Use movsd for loading from memory, unpcklpd for registers.
4516      Try to avoid move when unpacking can be done in source, or SSE3
4517      movddup is available.  */
4518   if (REG_P (operands[1]))
4519     {
4520       if (!TARGET_SSE3
4521           && true_regnum (operands[0]) != true_regnum (operands[1])
4522           && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4523               || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4524         {
4525           rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4526           emit_move_insn (tmp, operands[1]);
4527           operands[1] = tmp;
4528         }
4529       else if (!TARGET_SSE3)
4530         operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4531       emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4532     }
4533   else
4534     emit_insn (gen_sse2_loadlpd (operands[4],
4535                                  CONST0_RTX (V2DFmode), operands[1]));
4536 })
4537
4538 (define_expand "truncdfsf2_with_temp"
4539   [(parallel [(set (match_operand:SF 0 "" "")
4540                    (float_truncate:SF (match_operand:DF 1 "" "")))
4541               (clobber (match_operand:SF 2 "" ""))])]
4542   "")
4543
4544 (define_insn "*truncdfsf_fast_mixed"
4545   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm,x")
4546         (float_truncate:SF
4547           (match_operand:DF 1 "nonimmediate_operand" "f  ,xm")))]
4548   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4549 {
4550   switch (which_alternative)
4551     {
4552     case 0:
4553       return output_387_reg_move (insn, operands);
4554     case 1:
4555       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4556     default:
4557       gcc_unreachable ();
4558     }
4559 }
4560   [(set_attr "type" "fmov,ssecvt")
4561    (set_attr "prefix" "orig,maybe_vex")
4562    (set_attr "mode" "SF")])
4563
4564 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4565 ;; because nothing we do here is unsafe.
4566 (define_insn "*truncdfsf_fast_sse"
4567   [(set (match_operand:SF 0 "nonimmediate_operand"   "=x")
4568         (float_truncate:SF
4569           (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4570   "TARGET_SSE2 && TARGET_SSE_MATH"
4571   "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4572   [(set_attr "type" "ssecvt")
4573    (set_attr "prefix" "maybe_vex")
4574    (set_attr "mode" "SF")])
4575
4576 (define_insn "*truncdfsf_fast_i387"
4577   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
4578         (float_truncate:SF
4579           (match_operand:DF 1 "nonimmediate_operand" "f")))]
4580   "TARGET_80387 && flag_unsafe_math_optimizations"
4581   "* return output_387_reg_move (insn, operands);"
4582   [(set_attr "type" "fmov")
4583    (set_attr "mode" "SF")])
4584
4585 (define_insn "*truncdfsf_mixed"
4586   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,Y2 ,?f,?x,?*r")
4587         (float_truncate:SF
4588           (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4589    (clobber (match_operand:SF 2 "memory_operand"     "=X,X  ,m ,m ,m"))]
4590   "TARGET_MIX_SSE_I387"
4591 {
4592   switch (which_alternative)
4593     {
4594     case 0:
4595       return output_387_reg_move (insn, operands);
4596     case 1:
4597       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4598
4599     default:
4600       return "#";
4601     }
4602 }
4603   [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4604    (set_attr "unit" "*,*,i387,i387,i387")
4605    (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4606    (set_attr "mode" "SF")])
4607
4608 (define_insn "*truncdfsf_i387"
4609   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?f,?x,?*r")
4610         (float_truncate:SF
4611           (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4612    (clobber (match_operand:SF 2 "memory_operand"     "=X,m ,m ,m"))]
4613   "TARGET_80387"
4614 {
4615   switch (which_alternative)
4616     {
4617     case 0:
4618       return output_387_reg_move (insn, operands);
4619
4620     default:
4621       return "#";
4622     }
4623 }
4624   [(set_attr "type" "fmov,multi,multi,multi")
4625    (set_attr "unit" "*,i387,i387,i387")
4626    (set_attr "mode" "SF")])
4627
4628 (define_insn "*truncdfsf2_i387_1"
4629   [(set (match_operand:SF 0 "memory_operand" "=m")
4630         (float_truncate:SF
4631           (match_operand:DF 1 "register_operand" "f")))]
4632   "TARGET_80387
4633    && !(TARGET_SSE2 && TARGET_SSE_MATH)
4634    && !TARGET_MIX_SSE_I387"
4635   "* return output_387_reg_move (insn, operands);"
4636   [(set_attr "type" "fmov")
4637    (set_attr "mode" "SF")])
4638
4639 (define_split
4640   [(set (match_operand:SF 0 "register_operand" "")
4641         (float_truncate:SF
4642          (match_operand:DF 1 "fp_register_operand" "")))
4643    (clobber (match_operand 2 "" ""))]
4644   "reload_completed"
4645   [(set (match_dup 2) (match_dup 1))
4646    (set (match_dup 0) (match_dup 2))]
4647 {
4648   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4649 })
4650
4651 ;; Conversion from XFmode to {SF,DF}mode
4652
4653 (define_expand "truncxf<mode>2"
4654   [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4655                    (float_truncate:MODEF
4656                      (match_operand:XF 1 "register_operand" "")))
4657               (clobber (match_dup 2))])]
4658   "TARGET_80387"
4659 {
4660   if (flag_unsafe_math_optimizations)
4661     {
4662       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4663       emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4664       if (reg != operands[0])
4665         emit_move_insn (operands[0], reg);
4666       DONE;
4667     }
4668   else
4669     {
4670      enum ix86_stack_slot slot = (virtuals_instantiated
4671                                   ? SLOT_TEMP
4672                                   : SLOT_VIRTUAL);
4673       operands[2] = assign_386_stack_local (<MODE>mode, slot);
4674     }
4675 })
4676
4677 (define_insn "*truncxfsf2_mixed"
4678   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4679         (float_truncate:SF
4680           (match_operand:XF 1 "register_operand"   "f ,f ,f ,f")))
4681    (clobber (match_operand:SF 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" "SF")])
4690
4691 (define_insn "*truncxfdf2_mixed"
4692   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4693         (float_truncate:DF
4694           (match_operand:XF 1 "register_operand"   "f ,f ,f  ,f")))
4695    (clobber (match_operand:DF 2 "memory_operand"   "=X,m ,m  ,m"))]
4696   "TARGET_80387"
4697 {
4698   gcc_assert (!which_alternative);
4699   return output_387_reg_move (insn, operands);
4700 }
4701   [(set_attr "type" "fmov,multi,multi,multi")
4702    (set_attr "unit" "*,i387,i387,i387")
4703    (set_attr "mode" "DF")])
4704
4705 (define_insn "truncxf<mode>2_i387_noop"
4706   [(set (match_operand:MODEF 0 "register_operand" "=f")
4707         (float_truncate:MODEF
4708           (match_operand:XF 1 "register_operand" "f")))]
4709   "TARGET_80387 && flag_unsafe_math_optimizations"
4710   "* return output_387_reg_move (insn, operands);"
4711   [(set_attr "type" "fmov")
4712    (set_attr "mode" "<MODE>")])
4713
4714 (define_insn "*truncxf<mode>2_i387"
4715   [(set (match_operand:MODEF 0 "memory_operand" "=m")
4716         (float_truncate:MODEF
4717           (match_operand:XF 1 "register_operand" "f")))]
4718   "TARGET_80387"
4719   "* return output_387_reg_move (insn, operands);"
4720   [(set_attr "type" "fmov")
4721    (set_attr "mode" "<MODE>")])
4722
4723 (define_split
4724   [(set (match_operand:MODEF 0 "register_operand" "")
4725         (float_truncate:MODEF
4726           (match_operand:XF 1 "register_operand" "")))
4727    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4728   "TARGET_80387 && reload_completed"
4729   [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4730    (set (match_dup 0) (match_dup 2))]
4731   "")
4732
4733 (define_split
4734   [(set (match_operand:MODEF 0 "memory_operand" "")
4735         (float_truncate:MODEF
4736           (match_operand:XF 1 "register_operand" "")))
4737    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4738   "TARGET_80387"
4739   [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]
4740   "")
4741 \f
4742 ;; Signed conversion to DImode.
4743
4744 (define_expand "fix_truncxfdi2"
4745   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4746                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4747               (clobber (reg:CC FLAGS_REG))])]
4748   "TARGET_80387"
4749 {
4750   if (TARGET_FISTTP)
4751    {
4752      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4753      DONE;
4754    }
4755 })
4756
4757 (define_expand "fix_trunc<mode>di2"
4758   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4759                    (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4760               (clobber (reg:CC FLAGS_REG))])]
4761   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4762 {
4763   if (TARGET_FISTTP
4764       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4765    {
4766      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4767      DONE;
4768    }
4769   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4770    {
4771      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4772      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4773      if (out != operands[0])
4774         emit_move_insn (operands[0], out);
4775      DONE;
4776    }
4777 })
4778
4779 ;; Signed conversion to SImode.
4780
4781 (define_expand "fix_truncxfsi2"
4782   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4783                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4784               (clobber (reg:CC FLAGS_REG))])]
4785   "TARGET_80387"
4786 {
4787   if (TARGET_FISTTP)
4788    {
4789      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4790      DONE;
4791    }
4792 })
4793
4794 (define_expand "fix_trunc<mode>si2"
4795   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4796                    (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4797               (clobber (reg:CC FLAGS_REG))])]
4798   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4799 {
4800   if (TARGET_FISTTP
4801       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4802    {
4803      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4804      DONE;
4805    }
4806   if (SSE_FLOAT_MODE_P (<MODE>mode))
4807    {
4808      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4809      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4810      if (out != operands[0])
4811         emit_move_insn (operands[0], out);
4812      DONE;
4813    }
4814 })
4815
4816 ;; Signed conversion to HImode.
4817
4818 (define_expand "fix_trunc<mode>hi2"
4819   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4820                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4821               (clobber (reg:CC FLAGS_REG))])]
4822   "TARGET_80387
4823    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4824 {
4825   if (TARGET_FISTTP)
4826    {
4827      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4828      DONE;
4829    }
4830 })
4831
4832 ;; Unsigned conversion to SImode.
4833
4834 (define_expand "fixuns_trunc<mode>si2"
4835   [(parallel
4836     [(set (match_operand:SI 0 "register_operand" "")
4837           (unsigned_fix:SI
4838             (match_operand:MODEF 1 "nonimmediate_operand" "")))
4839      (use (match_dup 2))
4840      (clobber (match_scratch:<ssevecmode> 3 ""))
4841      (clobber (match_scratch:<ssevecmode> 4 ""))])]
4842   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4843 {
4844   enum machine_mode mode = <MODE>mode;
4845   enum machine_mode vecmode = <ssevecmode>mode;
4846   REAL_VALUE_TYPE TWO31r;
4847   rtx two31;
4848
4849   if (optimize_insn_for_size_p ())
4850     FAIL;
4851
4852   real_ldexp (&TWO31r, &dconst1, 31);
4853   two31 = const_double_from_real_value (TWO31r, mode);
4854   two31 = ix86_build_const_vector (mode, true, two31);
4855   operands[2] = force_reg (vecmode, two31);
4856 })
4857
4858 (define_insn_and_split "*fixuns_trunc<mode>_1"
4859   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4860         (unsigned_fix:SI
4861           (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4862    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
4863    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4864    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4865   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4866    && optimize_function_for_speed_p (cfun)"
4867   "#"
4868   "&& reload_completed"
4869   [(const_int 0)]
4870 {
4871   ix86_split_convert_uns_si_sse (operands);
4872   DONE;
4873 })
4874
4875 ;; Unsigned conversion to HImode.
4876 ;; Without these patterns, we'll try the unsigned SI conversion which
4877 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4878
4879 (define_expand "fixuns_trunc<mode>hi2"
4880   [(set (match_dup 2)
4881         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4882    (set (match_operand:HI 0 "nonimmediate_operand" "")
4883         (subreg:HI (match_dup 2) 0))]
4884   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4885   "operands[2] = gen_reg_rtx (SImode);")
4886
4887 ;; When SSE is available, it is always faster to use it!
4888 (define_insn "fix_trunc<mode>di_sse"
4889   [(set (match_operand:DI 0 "register_operand" "=r,r")
4890         (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4891   "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4892    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4893   "%vcvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4894   [(set_attr "type" "sseicvt")
4895    (set_attr "prefix" "maybe_vex")
4896    (set_attr "prefix_rex" "1")
4897    (set_attr "mode" "<MODE>")
4898    (set_attr "athlon_decode" "double,vector")
4899    (set_attr "amdfam10_decode" "double,double")])
4900
4901 (define_insn "fix_trunc<mode>si_sse"
4902   [(set (match_operand:SI 0 "register_operand" "=r,r")
4903         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4904   "SSE_FLOAT_MODE_P (<MODE>mode)
4905    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4906   "%vcvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4907   [(set_attr "type" "sseicvt")
4908    (set_attr "prefix" "maybe_vex")
4909    (set_attr "mode" "<MODE>")
4910    (set_attr "athlon_decode" "double,vector")
4911    (set_attr "amdfam10_decode" "double,double")])
4912
4913 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4914 (define_peephole2
4915   [(set (match_operand:MODEF 0 "register_operand" "")
4916         (match_operand:MODEF 1 "memory_operand" ""))
4917    (set (match_operand:SSEMODEI24 2 "register_operand" "")
4918         (fix:SSEMODEI24 (match_dup 0)))]
4919   "TARGET_SHORTEN_X87_SSE
4920    && peep2_reg_dead_p (2, operands[0])"
4921   [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4922   "")
4923
4924 ;; Avoid vector decoded forms of the instruction.
4925 (define_peephole2
4926   [(match_scratch:DF 2 "Y2")
4927    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4928         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4929   "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4930   [(set (match_dup 2) (match_dup 1))
4931    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4932   "")
4933
4934 (define_peephole2
4935   [(match_scratch:SF 2 "x")
4936    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4937         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4938   "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4939   [(set (match_dup 2) (match_dup 1))
4940    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4941   "")
4942
4943 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4944   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4945         (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4946   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4947    && TARGET_FISTTP
4948    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4949          && (TARGET_64BIT || <MODE>mode != DImode))
4950         && TARGET_SSE_MATH)
4951    && can_create_pseudo_p ()"
4952   "#"
4953   "&& 1"
4954   [(const_int 0)]
4955 {
4956   if (memory_operand (operands[0], VOIDmode))
4957     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4958   else
4959     {
4960       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4961       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4962                                                             operands[1],
4963                                                             operands[2]));
4964     }
4965   DONE;
4966 }
4967   [(set_attr "type" "fisttp")
4968    (set_attr "mode" "<MODE>")])
4969
4970 (define_insn "fix_trunc<mode>_i387_fisttp"
4971   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4972         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4973    (clobber (match_scratch:XF 2 "=&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   "* return output_fix_trunc (insn, operands, 1);"
4980   [(set_attr "type" "fisttp")
4981    (set_attr "mode" "<MODE>")])
4982
4983 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4984   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4985         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4986    (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
4987    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4988   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4989    && TARGET_FISTTP
4990    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4991         && (TARGET_64BIT || <MODE>mode != DImode))
4992         && TARGET_SSE_MATH)"
4993   "#"
4994   [(set_attr "type" "fisttp")
4995    (set_attr "mode" "<MODE>")])
4996
4997 (define_split
4998   [(set (match_operand:X87MODEI 0 "register_operand" "")
4999         (fix:X87MODEI (match_operand 1 "register_operand" "")))
5000    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
5001    (clobber (match_scratch 3 ""))]
5002   "reload_completed"
5003   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
5004               (clobber (match_dup 3))])
5005    (set (match_dup 0) (match_dup 2))]
5006   "")
5007
5008 (define_split
5009   [(set (match_operand:X87MODEI 0 "memory_operand" "")
5010         (fix:X87MODEI (match_operand 1 "register_operand" "")))
5011    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
5012    (clobber (match_scratch 3 ""))]
5013   "reload_completed"
5014   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
5015               (clobber (match_dup 3))])]
5016   "")
5017
5018 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
5019 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
5020 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
5021 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
5022 ;; function in i386.c.
5023 (define_insn_and_split "*fix_trunc<mode>_i387_1"
5024   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
5025         (fix:X87MODEI (match_operand 1 "register_operand" "")))
5026    (clobber (reg:CC FLAGS_REG))]
5027   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5028    && !TARGET_FISTTP
5029    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5030          && (TARGET_64BIT || <MODE>mode != DImode))
5031    && can_create_pseudo_p ()"
5032   "#"
5033   "&& 1"
5034   [(const_int 0)]
5035 {
5036   ix86_optimize_mode_switching[I387_TRUNC] = 1;
5037
5038   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
5039   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
5040   if (memory_operand (operands[0], VOIDmode))
5041     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
5042                                          operands[2], operands[3]));
5043   else
5044     {
5045       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
5046       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
5047                                                      operands[2], operands[3],
5048                                                      operands[4]));
5049     }
5050   DONE;
5051 }
5052   [(set_attr "type" "fistp")
5053    (set_attr "i387_cw" "trunc")
5054    (set_attr "mode" "<MODE>")])
5055
5056 (define_insn "fix_truncdi_i387"
5057   [(set (match_operand:DI 0 "memory_operand" "=m")
5058         (fix:DI (match_operand 1 "register_operand" "f")))
5059    (use (match_operand:HI 2 "memory_operand" "m"))
5060    (use (match_operand:HI 3 "memory_operand" "m"))
5061    (clobber (match_scratch:XF 4 "=&1f"))]
5062   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5063    && !TARGET_FISTTP
5064    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5065   "* return output_fix_trunc (insn, operands, 0);"
5066   [(set_attr "type" "fistp")
5067    (set_attr "i387_cw" "trunc")
5068    (set_attr "mode" "DI")])
5069
5070 (define_insn "fix_truncdi_i387_with_temp"
5071   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
5072         (fix:DI (match_operand 1 "register_operand" "f,f")))
5073    (use (match_operand:HI 2 "memory_operand" "m,m"))
5074    (use (match_operand:HI 3 "memory_operand" "m,m"))
5075    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
5076    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
5077   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5078    && !TARGET_FISTTP
5079    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5080   "#"
5081   [(set_attr "type" "fistp")
5082    (set_attr "i387_cw" "trunc")
5083    (set_attr "mode" "DI")])
5084
5085 (define_split
5086   [(set (match_operand:DI 0 "register_operand" "")
5087         (fix:DI (match_operand 1 "register_operand" "")))
5088    (use (match_operand:HI 2 "memory_operand" ""))
5089    (use (match_operand:HI 3 "memory_operand" ""))
5090    (clobber (match_operand:DI 4 "memory_operand" ""))
5091    (clobber (match_scratch 5 ""))]
5092   "reload_completed"
5093   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
5094               (use (match_dup 2))
5095               (use (match_dup 3))
5096               (clobber (match_dup 5))])
5097    (set (match_dup 0) (match_dup 4))]
5098   "")
5099
5100 (define_split
5101   [(set (match_operand:DI 0 "memory_operand" "")
5102         (fix:DI (match_operand 1 "register_operand" "")))
5103    (use (match_operand:HI 2 "memory_operand" ""))
5104    (use (match_operand:HI 3 "memory_operand" ""))
5105    (clobber (match_operand:DI 4 "memory_operand" ""))
5106    (clobber (match_scratch 5 ""))]
5107   "reload_completed"
5108   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
5109               (use (match_dup 2))
5110               (use (match_dup 3))
5111               (clobber (match_dup 5))])]
5112   "")
5113
5114 (define_insn "fix_trunc<mode>_i387"
5115   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
5116         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
5117    (use (match_operand:HI 2 "memory_operand" "m"))
5118    (use (match_operand:HI 3 "memory_operand" "m"))]
5119   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5120    && !TARGET_FISTTP
5121    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5122   "* return output_fix_trunc (insn, operands, 0);"
5123   [(set_attr "type" "fistp")
5124    (set_attr "i387_cw" "trunc")
5125    (set_attr "mode" "<MODE>")])
5126
5127 (define_insn "fix_trunc<mode>_i387_with_temp"
5128   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
5129         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
5130    (use (match_operand:HI 2 "memory_operand" "m,m"))
5131    (use (match_operand:HI 3 "memory_operand" "m,m"))
5132    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
5133   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5134    && !TARGET_FISTTP
5135    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5136   "#"
5137   [(set_attr "type" "fistp")
5138    (set_attr "i387_cw" "trunc")
5139    (set_attr "mode" "<MODE>")])
5140
5141 (define_split
5142   [(set (match_operand:X87MODEI12 0 "register_operand" "")
5143         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5144    (use (match_operand:HI 2 "memory_operand" ""))
5145    (use (match_operand:HI 3 "memory_operand" ""))
5146    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5147   "reload_completed"
5148   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
5149               (use (match_dup 2))
5150               (use (match_dup 3))])
5151    (set (match_dup 0) (match_dup 4))]
5152   "")
5153
5154 (define_split
5155   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
5156         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5157    (use (match_operand:HI 2 "memory_operand" ""))
5158    (use (match_operand:HI 3 "memory_operand" ""))
5159    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5160   "reload_completed"
5161   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
5162               (use (match_dup 2))
5163               (use (match_dup 3))])]
5164   "")
5165
5166 (define_insn "x86_fnstcw_1"
5167   [(set (match_operand:HI 0 "memory_operand" "=m")
5168         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
5169   "TARGET_80387"
5170   "fnstcw\t%0"
5171   [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5172    (set_attr "mode" "HI")
5173    (set_attr "unit" "i387")])
5174
5175 (define_insn "x86_fldcw_1"
5176   [(set (reg:HI FPCR_REG)
5177         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
5178   "TARGET_80387"
5179   "fldcw\t%0"
5180   [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5181    (set_attr "mode" "HI")
5182    (set_attr "unit" "i387")
5183    (set_attr "athlon_decode" "vector")
5184    (set_attr "amdfam10_decode" "vector")])
5185 \f
5186 ;; Conversion between fixed point and floating point.
5187
5188 ;; Even though we only accept memory inputs, the backend _really_
5189 ;; wants to be able to do this between registers.
5190
5191 (define_expand "floathi<mode>2"
5192   [(set (match_operand:X87MODEF 0 "register_operand" "")
5193         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
5194   "TARGET_80387
5195    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5196        || TARGET_MIX_SSE_I387)"
5197   "")
5198
5199 ;; Pre-reload splitter to add memory clobber to the pattern.
5200 (define_insn_and_split "*floathi<mode>2_1"
5201   [(set (match_operand:X87MODEF 0 "register_operand" "")
5202         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
5203   "TARGET_80387
5204    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5205        || TARGET_MIX_SSE_I387)
5206    && can_create_pseudo_p ()"
5207   "#"
5208   "&& 1"
5209   [(parallel [(set (match_dup 0)
5210               (float:X87MODEF (match_dup 1)))
5211    (clobber (match_dup 2))])]
5212   "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
5213
5214 (define_insn "*floathi<mode>2_i387_with_temp"
5215   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5216         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
5217   (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
5218   "TARGET_80387
5219    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5220        || TARGET_MIX_SSE_I387)"
5221   "#"
5222   [(set_attr "type" "fmov,multi")
5223    (set_attr "mode" "<MODE>")
5224    (set_attr "unit" "*,i387")
5225    (set_attr "fp_int_src" "true")])
5226
5227 (define_insn "*floathi<mode>2_i387"
5228   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5229         (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
5230   "TARGET_80387
5231    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5232        || TARGET_MIX_SSE_I387)"
5233   "fild%Z1\t%1"
5234   [(set_attr "type" "fmov")
5235    (set_attr "mode" "<MODE>")
5236    (set_attr "fp_int_src" "true")])
5237
5238 (define_split
5239   [(set (match_operand:X87MODEF 0 "register_operand" "")
5240         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
5241    (clobber (match_operand:HI 2 "memory_operand" ""))]
5242   "TARGET_80387
5243    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5244        || TARGET_MIX_SSE_I387)
5245    && reload_completed"
5246   [(set (match_dup 2) (match_dup 1))
5247    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5248   "")
5249
5250 (define_split
5251   [(set (match_operand:X87MODEF 0 "register_operand" "")
5252         (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
5253    (clobber (match_operand:HI 2 "memory_operand" ""))]
5254    "TARGET_80387
5255     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5256         || TARGET_MIX_SSE_I387)
5257     && reload_completed"
5258   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5259   "")
5260
5261 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
5262   [(set (match_operand:X87MODEF 0 "register_operand" "")
5263         (float:X87MODEF
5264           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
5265   "TARGET_80387
5266    || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5267        && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
5268 {
5269   if (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5270         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5271       && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode))
5272     {
5273       rtx reg = gen_reg_rtx (XFmode);
5274       rtx insn;
5275
5276       emit_insn (gen_float<SSEMODEI24:mode>xf2 (reg, operands[1]));
5277
5278       if (<X87MODEF:MODE>mode == SFmode)
5279         insn = gen_truncxfsf2 (operands[0], reg);
5280       else if (<X87MODEF:MODE>mode == DFmode)
5281         insn = gen_truncxfdf2 (operands[0], reg);
5282       else
5283         gcc_unreachable ();
5284
5285       emit_insn (insn);
5286       DONE;
5287     }
5288 })
5289
5290 ;; Pre-reload splitter to add memory clobber to the pattern.
5291 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
5292   [(set (match_operand:X87MODEF 0 "register_operand" "")
5293         (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
5294   "((TARGET_80387
5295      && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5296      && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5297            && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5298          || TARGET_MIX_SSE_I387))
5299     || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5300         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
5301         && ((<SSEMODEI24:MODE>mode == SImode
5302              && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
5303              && optimize_function_for_speed_p (cfun)
5304              && flag_trapping_math)
5305             || !(TARGET_INTER_UNIT_CONVERSIONS
5306                  || optimize_function_for_size_p (cfun)))))
5307    && can_create_pseudo_p ()"
5308   "#"
5309   "&& 1"
5310   [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
5311               (clobber (match_dup 2))])]
5312 {
5313   operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
5314
5315   /* Avoid store forwarding (partial memory) stall penalty
5316      by passing DImode value through XMM registers.  */
5317   if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
5318       && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5319       && optimize_function_for_speed_p (cfun))
5320     {
5321       emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
5322                                                             operands[1],
5323                                                             operands[2]));
5324       DONE;
5325     }
5326 })
5327
5328 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
5329   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
5330         (float:MODEF
5331           (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
5332    (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
5333   "TARGET_SSE2 && TARGET_MIX_SSE_I387
5334    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5335   "#"
5336   [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
5337    (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
5338    (set_attr "unit" "*,i387,*,*,*")
5339    (set_attr "athlon_decode" "*,*,double,direct,double")
5340    (set_attr "amdfam10_decode" "*,*,vector,double,double")
5341    (set_attr "fp_int_src" "true")])
5342
5343 (define_insn "*floatsi<mode>2_vector_mixed"
5344   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5345         (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
5346   "TARGET_SSE2 && TARGET_MIX_SSE_I387
5347    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5348   "@
5349    fild%Z1\t%1
5350    #"
5351   [(set_attr "type" "fmov,sseicvt")
5352    (set_attr "mode" "<MODE>,<ssevecmode>")
5353    (set_attr "unit" "i387,*")
5354    (set_attr "athlon_decode" "*,direct")
5355    (set_attr "amdfam10_decode" "*,double")
5356    (set_attr "fp_int_src" "true")])
5357
5358 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
5359   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
5360         (float:MODEF
5361           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
5362   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
5363   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5364    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
5365   "#"
5366   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5367    (set_attr "mode" "<MODEF:MODE>")
5368    (set_attr "unit" "*,i387,*,*")
5369    (set_attr "athlon_decode" "*,*,double,direct")
5370    (set_attr "amdfam10_decode" "*,*,vector,double")
5371    (set_attr "fp_int_src" "true")])
5372
5373 (define_split
5374   [(set (match_operand:MODEF 0 "register_operand" "")
5375         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5376    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5377   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5378    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5379    && TARGET_INTER_UNIT_CONVERSIONS
5380    && reload_completed
5381    && (SSE_REG_P (operands[0])
5382        || (GET_CODE (operands[0]) == SUBREG
5383            && SSE_REG_P (operands[0])))"
5384   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5385   "")
5386
5387 (define_split
5388   [(set (match_operand:MODEF 0 "register_operand" "")
5389         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5390    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5391   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5392    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5393    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5394    && reload_completed
5395    && (SSE_REG_P (operands[0])
5396        || (GET_CODE (operands[0]) == SUBREG
5397            && SSE_REG_P (operands[0])))"
5398   [(set (match_dup 2) (match_dup 1))
5399    (set (match_dup 0) (float:MODEF (match_dup 2)))]
5400   "")
5401
5402 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5403   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5404         (float:MODEF
5405           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
5406   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5407    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5408    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5409   "@
5410    fild%Z1\t%1
5411    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
5412    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5413   [(set_attr "type" "fmov,sseicvt,sseicvt")
5414    (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5415    (set_attr "mode" "<MODEF:MODE>")
5416    (set (attr "prefix_rex")
5417      (if_then_else
5418        (and (eq_attr "prefix" "maybe_vex")
5419             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5420        (const_string "1")
5421        (const_string "*")))
5422    (set_attr "unit" "i387,*,*")
5423    (set_attr "athlon_decode" "*,double,direct")
5424    (set_attr "amdfam10_decode" "*,vector,double")
5425    (set_attr "fp_int_src" "true")])
5426
5427 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5428   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5429         (float:MODEF
5430           (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5431   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5432    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5433    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5434   "@
5435    fild%Z1\t%1
5436    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5437   [(set_attr "type" "fmov,sseicvt")
5438    (set_attr "prefix" "orig,maybe_vex")
5439    (set_attr "mode" "<MODEF:MODE>")
5440    (set (attr "prefix_rex")
5441      (if_then_else
5442        (and (eq_attr "prefix" "maybe_vex")
5443             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5444        (const_string "1")
5445        (const_string "*")))
5446    (set_attr "athlon_decode" "*,direct")
5447    (set_attr "amdfam10_decode" "*,double")
5448    (set_attr "fp_int_src" "true")])
5449
5450 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5451   [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5452         (float:MODEF
5453           (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5454    (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5455   "TARGET_SSE2 && TARGET_SSE_MATH
5456    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5457   "#"
5458   [(set_attr "type" "sseicvt")
5459    (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5460    (set_attr "athlon_decode" "double,direct,double")
5461    (set_attr "amdfam10_decode" "vector,double,double")
5462    (set_attr "fp_int_src" "true")])
5463
5464 (define_insn "*floatsi<mode>2_vector_sse"
5465   [(set (match_operand:MODEF 0 "register_operand" "=x")
5466         (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5467   "TARGET_SSE2 && TARGET_SSE_MATH
5468    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5469   "#"
5470   [(set_attr "type" "sseicvt")
5471    (set_attr "mode" "<MODE>")
5472    (set_attr "athlon_decode" "direct")
5473    (set_attr "amdfam10_decode" "double")
5474    (set_attr "fp_int_src" "true")])
5475
5476 (define_split
5477   [(set (match_operand:MODEF 0 "register_operand" "")
5478         (float:MODEF (match_operand:SI 1 "register_operand" "")))
5479    (clobber (match_operand:SI 2 "memory_operand" ""))]
5480   "TARGET_SSE2 && TARGET_SSE_MATH
5481    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5482    && reload_completed
5483    && (SSE_REG_P (operands[0])
5484        || (GET_CODE (operands[0]) == SUBREG
5485            && SSE_REG_P (operands[0])))"
5486   [(const_int 0)]
5487 {
5488   rtx op1 = operands[1];
5489
5490   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5491                                      <MODE>mode, 0);
5492   if (GET_CODE (op1) == SUBREG)
5493     op1 = SUBREG_REG (op1);
5494
5495   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5496     {
5497       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5498       emit_insn (gen_sse2_loadld (operands[4],
5499                                   CONST0_RTX (V4SImode), operands[1]));
5500     }
5501   /* We can ignore possible trapping value in the
5502      high part of SSE register for non-trapping math. */
5503   else if (SSE_REG_P (op1) && !flag_trapping_math)
5504     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5505   else
5506     {
5507       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5508       emit_move_insn (operands[2], operands[1]);
5509       emit_insn (gen_sse2_loadld (operands[4],
5510                                   CONST0_RTX (V4SImode), operands[2]));
5511     }
5512   emit_insn
5513     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5514   DONE;
5515 })
5516
5517 (define_split
5518   [(set (match_operand:MODEF 0 "register_operand" "")
5519         (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5520    (clobber (match_operand:SI 2 "memory_operand" ""))]
5521   "TARGET_SSE2 && TARGET_SSE_MATH
5522    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5523    && reload_completed
5524    && (SSE_REG_P (operands[0])
5525        || (GET_CODE (operands[0]) == SUBREG
5526            && SSE_REG_P (operands[0])))"
5527   [(const_int 0)]
5528 {
5529   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5530                                      <MODE>mode, 0);
5531   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5532
5533   emit_insn (gen_sse2_loadld (operands[4],
5534                               CONST0_RTX (V4SImode), operands[1]));
5535   emit_insn
5536     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5537   DONE;
5538 })
5539
5540 (define_split
5541   [(set (match_operand:MODEF 0 "register_operand" "")
5542         (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5543   "TARGET_SSE2 && TARGET_SSE_MATH
5544    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5545    && reload_completed
5546    && (SSE_REG_P (operands[0])
5547        || (GET_CODE (operands[0]) == SUBREG
5548            && SSE_REG_P (operands[0])))"
5549   [(const_int 0)]
5550 {
5551   rtx op1 = operands[1];
5552
5553   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5554                                      <MODE>mode, 0);
5555   if (GET_CODE (op1) == SUBREG)
5556     op1 = SUBREG_REG (op1);
5557
5558   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5559     {
5560       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5561       emit_insn (gen_sse2_loadld (operands[4],
5562                                   CONST0_RTX (V4SImode), operands[1]));
5563     }
5564   /* We can ignore possible trapping value in the
5565      high part of SSE register for non-trapping math. */
5566   else if (SSE_REG_P (op1) && !flag_trapping_math)
5567     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5568   else
5569     gcc_unreachable ();
5570   emit_insn
5571     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5572   DONE;
5573 })
5574
5575 (define_split
5576   [(set (match_operand:MODEF 0 "register_operand" "")
5577         (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5578   "TARGET_SSE2 && TARGET_SSE_MATH
5579    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5580    && reload_completed
5581    && (SSE_REG_P (operands[0])
5582        || (GET_CODE (operands[0]) == SUBREG
5583            && SSE_REG_P (operands[0])))"
5584   [(const_int 0)]
5585 {
5586   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5587                                      <MODE>mode, 0);
5588   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5589
5590   emit_insn (gen_sse2_loadld (operands[4],
5591                               CONST0_RTX (V4SImode), operands[1]));
5592   emit_insn
5593     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5594   DONE;
5595 })
5596
5597 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5598   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5599         (float:MODEF
5600           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5601   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5602   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5603    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5604   "#"
5605   [(set_attr "type" "sseicvt")
5606    (set_attr "mode" "<MODEF:MODE>")
5607    (set_attr "athlon_decode" "double,direct")
5608    (set_attr "amdfam10_decode" "vector,double")
5609    (set_attr "fp_int_src" "true")])
5610
5611 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5612   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5613         (float:MODEF
5614           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5615   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5616    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5617    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5618   "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5619   [(set_attr "type" "sseicvt")
5620    (set_attr "prefix" "maybe_vex")
5621    (set_attr "mode" "<MODEF:MODE>")
5622    (set (attr "prefix_rex")
5623      (if_then_else
5624        (and (eq_attr "prefix" "maybe_vex")
5625             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5626        (const_string "1")
5627        (const_string "*")))
5628    (set_attr "athlon_decode" "double,direct")
5629    (set_attr "amdfam10_decode" "vector,double")
5630    (set_attr "fp_int_src" "true")])
5631
5632 (define_split
5633   [(set (match_operand:MODEF 0 "register_operand" "")
5634         (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5635    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5636   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5637    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5638    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5639    && reload_completed
5640    && (SSE_REG_P (operands[0])
5641        || (GET_CODE (operands[0]) == SUBREG
5642            && SSE_REG_P (operands[0])))"
5643   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5644   "")
5645
5646 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5647   [(set (match_operand:MODEF 0 "register_operand" "=x")
5648         (float:MODEF
5649           (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5650   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5651    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5652    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5653   "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5654   [(set_attr "type" "sseicvt")
5655    (set_attr "prefix" "maybe_vex")
5656    (set_attr "mode" "<MODEF:MODE>")
5657    (set (attr "prefix_rex")
5658      (if_then_else
5659        (and (eq_attr "prefix" "maybe_vex")
5660             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5661        (const_string "1")
5662        (const_string "*")))
5663    (set_attr "athlon_decode" "direct")
5664    (set_attr "amdfam10_decode" "double")
5665    (set_attr "fp_int_src" "true")])
5666
5667 (define_split
5668   [(set (match_operand:MODEF 0 "register_operand" "")
5669         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5670    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5671   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5672    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5673    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5674    && reload_completed
5675    && (SSE_REG_P (operands[0])
5676        || (GET_CODE (operands[0]) == SUBREG
5677            && SSE_REG_P (operands[0])))"
5678   [(set (match_dup 2) (match_dup 1))
5679    (set (match_dup 0) (float:MODEF (match_dup 2)))]
5680   "")
5681
5682 (define_split
5683   [(set (match_operand:MODEF 0 "register_operand" "")
5684         (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5685    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5686   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5687    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5688    && reload_completed
5689    && (SSE_REG_P (operands[0])
5690        || (GET_CODE (operands[0]) == SUBREG
5691            && SSE_REG_P (operands[0])))"
5692   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5693   "")
5694
5695 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5696   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5697         (float:X87MODEF
5698           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5699   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5700   "TARGET_80387
5701    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5702   "@
5703    fild%Z1\t%1
5704    #"
5705   [(set_attr "type" "fmov,multi")
5706    (set_attr "mode" "<X87MODEF:MODE>")
5707    (set_attr "unit" "*,i387")
5708    (set_attr "fp_int_src" "true")])
5709
5710 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5711   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5712         (float:X87MODEF
5713           (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5714   "TARGET_80387
5715    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5716   "fild%Z1\t%1"
5717   [(set_attr "type" "fmov")
5718    (set_attr "mode" "<X87MODEF:MODE>")
5719    (set_attr "fp_int_src" "true")])
5720
5721 (define_split
5722   [(set (match_operand:X87MODEF 0 "register_operand" "")
5723         (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5724    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5725   "TARGET_80387
5726    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5727    && reload_completed
5728    && FP_REG_P (operands[0])"
5729   [(set (match_dup 2) (match_dup 1))
5730    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5731   "")
5732
5733 (define_split
5734   [(set (match_operand:X87MODEF 0 "register_operand" "")
5735         (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5736    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5737   "TARGET_80387
5738    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5739    && reload_completed
5740    && FP_REG_P (operands[0])"
5741   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5742   "")
5743
5744 ;; Avoid store forwarding (partial memory) stall penalty
5745 ;; by passing DImode value through XMM registers.  */
5746
5747 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5748   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5749         (float:X87MODEF
5750           (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5751    (clobber (match_scratch:V4SI 3 "=X,x"))
5752    (clobber (match_scratch:V4SI 4 "=X,x"))
5753    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5754   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5755    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5756    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5757   "#"
5758   [(set_attr "type" "multi")
5759    (set_attr "mode" "<X87MODEF:MODE>")
5760    (set_attr "unit" "i387")
5761    (set_attr "fp_int_src" "true")])
5762
5763 (define_split
5764   [(set (match_operand:X87MODEF 0 "register_operand" "")
5765         (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5766    (clobber (match_scratch:V4SI 3 ""))
5767    (clobber (match_scratch:V4SI 4 ""))
5768    (clobber (match_operand:DI 2 "memory_operand" ""))]
5769   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5770    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5771    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5772    && reload_completed
5773    && FP_REG_P (operands[0])"
5774   [(set (match_dup 2) (match_dup 3))
5775    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5776 {
5777   /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5778      Assemble the 64-bit DImode value in an xmm register.  */
5779   emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5780                               gen_rtx_SUBREG (SImode, operands[1], 0)));
5781   emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5782                               gen_rtx_SUBREG (SImode, operands[1], 4)));
5783   emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5784                                          operands[4]));
5785
5786   operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5787 })
5788
5789 (define_split
5790   [(set (match_operand:X87MODEF 0 "register_operand" "")
5791         (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5792    (clobber (match_scratch:V4SI 3 ""))
5793    (clobber (match_scratch:V4SI 4 ""))
5794    (clobber (match_operand:DI 2 "memory_operand" ""))]
5795   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5796    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5797    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5798    && reload_completed
5799    && FP_REG_P (operands[0])"
5800   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5801   "")
5802
5803 ;; Avoid store forwarding (partial memory) stall penalty by extending
5804 ;; SImode value to DImode through XMM register instead of pushing two
5805 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5806 ;; targets benefit from this optimization. Also note that fild
5807 ;; loads from memory only.
5808
5809 (define_insn "*floatunssi<mode>2_1"
5810   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5811         (unsigned_float:X87MODEF
5812           (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5813    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5814    (clobber (match_scratch:SI 3 "=X,x"))]
5815   "!TARGET_64BIT
5816    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5817    && TARGET_SSE"
5818   "#"
5819   [(set_attr "type" "multi")
5820    (set_attr "mode" "<MODE>")])
5821
5822 (define_split
5823   [(set (match_operand:X87MODEF 0 "register_operand" "")
5824         (unsigned_float:X87MODEF
5825           (match_operand:SI 1 "register_operand" "")))
5826    (clobber (match_operand:DI 2 "memory_operand" ""))
5827    (clobber (match_scratch:SI 3 ""))]
5828   "!TARGET_64BIT
5829    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5830    && TARGET_SSE
5831    && reload_completed"
5832   [(set (match_dup 2) (match_dup 1))
5833    (set (match_dup 0)
5834         (float:X87MODEF (match_dup 2)))]
5835   "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5836
5837 (define_split
5838   [(set (match_operand:X87MODEF 0 "register_operand" "")
5839         (unsigned_float:X87MODEF
5840           (match_operand:SI 1 "memory_operand" "")))
5841    (clobber (match_operand:DI 2 "memory_operand" ""))
5842    (clobber (match_scratch:SI 3 ""))]
5843   "!TARGET_64BIT
5844    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5845    && TARGET_SSE
5846    && reload_completed"
5847   [(set (match_dup 2) (match_dup 3))
5848    (set (match_dup 0)
5849         (float:X87MODEF (match_dup 2)))]
5850 {
5851   emit_move_insn (operands[3], operands[1]);
5852   operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5853 })
5854
5855 (define_expand "floatunssi<mode>2"
5856   [(parallel
5857      [(set (match_operand:X87MODEF 0 "register_operand" "")
5858            (unsigned_float:X87MODEF
5859              (match_operand:SI 1 "nonimmediate_operand" "")))
5860       (clobber (match_dup 2))
5861       (clobber (match_scratch:SI 3 ""))])]
5862   "!TARGET_64BIT
5863    && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5864         && TARGET_SSE)
5865        || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5866 {
5867   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5868     {
5869       ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5870       DONE;
5871     }
5872   else
5873     {
5874       enum ix86_stack_slot slot = (virtuals_instantiated
5875                                    ? SLOT_TEMP
5876                                    : SLOT_VIRTUAL);
5877       operands[2] = assign_386_stack_local (DImode, slot);
5878     }
5879 })
5880
5881 (define_expand "floatunsdisf2"
5882   [(use (match_operand:SF 0 "register_operand" ""))
5883    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5884   "TARGET_64BIT && TARGET_SSE_MATH"
5885   "x86_emit_floatuns (operands); DONE;")
5886
5887 (define_expand "floatunsdidf2"
5888   [(use (match_operand:DF 0 "register_operand" ""))
5889    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5890   "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5891    && TARGET_SSE2 && TARGET_SSE_MATH"
5892 {
5893   if (TARGET_64BIT)
5894     x86_emit_floatuns (operands);
5895   else
5896     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5897   DONE;
5898 })
5899 \f
5900 ;; Add instructions
5901
5902 (define_expand "add<mode>3"
5903   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5904         (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5905                     (match_operand:SDWIM 2 "<general_operand>" "")))]
5906   ""
5907   "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5908
5909 (define_insn_and_split "*add<dwi>3_doubleword"
5910   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5911         (plus:<DWI>
5912           (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5913           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5914    (clobber (reg:CC FLAGS_REG))]
5915   "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5916   "#"
5917   "reload_completed"
5918   [(parallel [(set (reg:CC FLAGS_REG)
5919                    (unspec:CC [(match_dup 1) (match_dup 2)]
5920                               UNSPEC_ADD_CARRY))
5921               (set (match_dup 0)
5922                    (plus:DWIH (match_dup 1) (match_dup 2)))])
5923    (parallel [(set (match_dup 3)
5924                    (plus:DWIH
5925                      (match_dup 4)
5926                      (plus:DWIH
5927                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5928                        (match_dup 5))))
5929               (clobber (reg:CC FLAGS_REG))])]
5930   "split_<dwi> (&operands[0], 3, &operands[0], &operands[3]);")
5931
5932 (define_insn "*add<mode>3_cc"
5933   [(set (reg:CC FLAGS_REG)
5934         (unspec:CC
5935           [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5936            (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5937           UNSPEC_ADD_CARRY))
5938    (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5939         (plus:SWI48 (match_dup 1) (match_dup 2)))]
5940   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5941   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5942   [(set_attr "type" "alu")
5943    (set_attr "mode" "<MODE>")])
5944
5945 (define_insn "addqi3_cc"
5946   [(set (reg:CC FLAGS_REG)
5947         (unspec:CC
5948           [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5949            (match_operand:QI 2 "general_operand" "qn,qm")]
5950           UNSPEC_ADD_CARRY))
5951    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5952         (plus:QI (match_dup 1) (match_dup 2)))]
5953   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5954   "add{b}\t{%2, %0|%0, %2}"
5955   [(set_attr "type" "alu")
5956    (set_attr "mode" "QI")])
5957
5958 (define_insn "*lea_1"
5959   [(set (match_operand:DWIH 0 "register_operand" "=r")
5960         (match_operand:DWIH 1 "no_seg_address_operand" "p"))]
5961   ""
5962   "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
5963   [(set_attr "type" "lea")
5964    (set_attr "mode" "<MODE>")])
5965
5966 (define_insn "*lea_2"
5967   [(set (match_operand:SI 0 "register_operand" "=r")
5968         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5969   "TARGET_64BIT"
5970   "lea{l}\t{%a1, %0|%0, %a1}"
5971   [(set_attr "type" "lea")
5972    (set_attr "mode" "SI")])
5973
5974 (define_insn "*lea_2_zext"
5975   [(set (match_operand:DI 0 "register_operand" "=r")
5976         (zero_extend:DI
5977           (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5978   "TARGET_64BIT"
5979   "lea{l}\t{%a1, %k0|%k0, %a1}"
5980   [(set_attr "type" "lea")
5981    (set_attr "mode" "SI")])
5982
5983 (define_insn "*add<mode>_1"
5984   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5985         (plus:SWI48
5986           (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5987           (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,0,l<i>")))
5988    (clobber (reg:CC FLAGS_REG))]
5989   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5990 {
5991   switch (get_attr_type (insn))
5992     {
5993     case TYPE_LEA:
5994       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5995       return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
5996
5997     case TYPE_INCDEC:
5998       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5999       if (operands[2] == const1_rtx)
6000         return "inc{<imodesuffix>}\t%0";
6001       else
6002         {
6003           gcc_assert (operands[2] == constm1_rtx);
6004           return "dec{<imodesuffix>}\t%0";
6005         }
6006
6007     default:
6008       /* Use add as much as possible to replace lea for AGU optimization. */
6009       if (which_alternative == 2 && TARGET_OPT_AGU)
6010         return "add{<imodesuffix>}\t{%1, %0|%0, %1}";
6011         
6012       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6013       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6014         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6015
6016       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6017     }
6018 }
6019   [(set (attr "type")
6020      (cond [(and (eq_attr "alternative" "2") 
6021                  (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
6022               (const_string "lea")
6023             (eq_attr "alternative" "3")
6024               (const_string "lea")
6025             ; Current assemblers are broken and do not allow @GOTOFF in
6026             ; ought but a memory context.
6027             (match_operand:SWI48 2 "pic_symbolic_operand" "")
6028               (const_string "lea")
6029             (match_operand:SWI48 2 "incdec_operand" "")
6030               (const_string "incdec")
6031            ]
6032            (const_string "alu")))
6033    (set (attr "length_immediate")
6034       (if_then_else
6035         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6036         (const_string "1")
6037         (const_string "*")))
6038    (set_attr "mode" "<MODE>")])
6039
6040 ;; It may seem that nonimmediate operand is proper one for operand 1.
6041 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6042 ;; we take care in ix86_binary_operator_ok to not allow two memory
6043 ;; operands so proper swapping will be done in reload.  This allow
6044 ;; patterns constructed from addsi_1 to match.
6045
6046 (define_insn "*addsi_1_zext"
6047   [(set (match_operand:DI 0 "register_operand" "=r,r")
6048         (zero_extend:DI
6049           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6050                    (match_operand:SI 2 "general_operand" "g,li"))))
6051    (clobber (reg:CC FLAGS_REG))]
6052   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6053 {
6054   switch (get_attr_type (insn))
6055     {
6056     case TYPE_LEA:
6057       operands[2] = XEXP (SET_SRC (XVECEXP (PATTERN (insn), 0, 0)), 0);
6058       return "lea{l}\t{%a2, %k0|%k0, %a2}";
6059
6060     case TYPE_INCDEC:
6061       if (operands[2] == const1_rtx)
6062         return "inc{l}\t%k0";
6063       else
6064         {
6065           gcc_assert (operands[2] == constm1_rtx);
6066           return "dec{l}\t%k0";
6067         }
6068
6069     default:
6070       if (x86_maybe_negate_const_int (&operands[2], SImode))
6071         return "sub{l}\t{%2, %k0|%k0, %2}";
6072
6073       return "add{l}\t{%2, %k0|%k0, %2}";
6074     }
6075 }
6076   [(set (attr "type")
6077      (cond [(eq_attr "alternative" "1")
6078               (const_string "lea")
6079             ; Current assemblers are broken and do not allow @GOTOFF in
6080             ; ought but a memory context.
6081             (match_operand:SI 2 "pic_symbolic_operand" "")
6082               (const_string "lea")
6083             (match_operand:SI 2 "incdec_operand" "")
6084               (const_string "incdec")
6085            ]
6086            (const_string "alu")))
6087    (set (attr "length_immediate")
6088       (if_then_else
6089         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6090         (const_string "1")
6091         (const_string "*")))
6092    (set_attr "mode" "SI")])
6093
6094 (define_insn "*addhi_1"
6095   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6096         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6097                  (match_operand:HI 2 "general_operand" "rn,rm")))
6098    (clobber (reg:CC FLAGS_REG))]
6099   "TARGET_PARTIAL_REG_STALL
6100    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6101 {
6102   switch (get_attr_type (insn))
6103     {
6104     case TYPE_INCDEC:
6105       if (operands[2] == const1_rtx)
6106         return "inc{w}\t%0";
6107       else
6108         {
6109           gcc_assert (operands[2] == constm1_rtx);
6110           return "dec{w}\t%0";
6111         }
6112
6113     default:
6114       if (x86_maybe_negate_const_int (&operands[2], HImode))
6115         return "sub{w}\t{%2, %0|%0, %2}";
6116
6117       return "add{w}\t{%2, %0|%0, %2}";
6118     }
6119 }
6120   [(set (attr "type")
6121      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6122         (const_string "incdec")
6123         (const_string "alu")))
6124    (set (attr "length_immediate")
6125       (if_then_else
6126         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6127         (const_string "1")
6128         (const_string "*")))
6129    (set_attr "mode" "HI")])
6130
6131 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6132 ;; type optimizations enabled by define-splits.  This is not important
6133 ;; for PII, and in fact harmful because of partial register stalls.
6134
6135 (define_insn "*addhi_1_lea"
6136   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6137         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6138                  (match_operand:HI 2 "general_operand" "rn,rm,ln")))
6139    (clobber (reg:CC FLAGS_REG))]
6140   "!TARGET_PARTIAL_REG_STALL
6141    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6142 {
6143   switch (get_attr_type (insn))
6144     {
6145     case TYPE_LEA:
6146       return "#";
6147     case TYPE_INCDEC:
6148       if (operands[2] == const1_rtx)
6149         return "inc{w}\t%0";
6150       else
6151         {
6152           gcc_assert (operands[2] == constm1_rtx);
6153           return "dec{w}\t%0";
6154         }
6155
6156     default:
6157       if (x86_maybe_negate_const_int (&operands[2], HImode))
6158         return "sub{w}\t{%2, %0|%0, %2}";
6159
6160       return "add{w}\t{%2, %0|%0, %2}";
6161     }
6162 }
6163   [(set (attr "type")
6164      (if_then_else (eq_attr "alternative" "2")
6165         (const_string "lea")
6166         (if_then_else (match_operand:HI 2 "incdec_operand" "")
6167            (const_string "incdec")
6168            (const_string "alu"))))
6169    (set (attr "length_immediate")
6170       (if_then_else
6171         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6172         (const_string "1")
6173         (const_string "*")))
6174    (set_attr "mode" "HI,HI,SI")])
6175
6176 (define_insn "*addqi_1"
6177   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6178         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6179                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6180    (clobber (reg:CC FLAGS_REG))]
6181   "TARGET_PARTIAL_REG_STALL
6182    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6183 {
6184   int widen = (which_alternative == 2);
6185   switch (get_attr_type (insn))
6186     {
6187     case TYPE_INCDEC:
6188       if (operands[2] == const1_rtx)
6189         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6190       else
6191         {
6192           gcc_assert (operands[2] == constm1_rtx);
6193           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6194         }
6195
6196     default:
6197       if (x86_maybe_negate_const_int (&operands[2], QImode))
6198         {
6199           if (widen)
6200             return "sub{l}\t{%2, %k0|%k0, %2}";
6201           else
6202             return "sub{b}\t{%2, %0|%0, %2}";
6203         }
6204       if (widen)
6205         return "add{l}\t{%k2, %k0|%k0, %k2}";
6206       else
6207         return "add{b}\t{%2, %0|%0, %2}";
6208     }
6209 }
6210   [(set (attr "type")
6211      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6212         (const_string "incdec")
6213         (const_string "alu")))
6214    (set (attr "length_immediate")
6215       (if_then_else
6216         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6217         (const_string "1")
6218         (const_string "*")))
6219    (set_attr "mode" "QI,QI,SI")])
6220
6221 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6222 (define_insn "*addqi_1_lea"
6223   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6224         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6225                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6226    (clobber (reg:CC FLAGS_REG))]
6227   "!TARGET_PARTIAL_REG_STALL
6228    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6229 {
6230   int widen = (which_alternative == 2);
6231   switch (get_attr_type (insn))
6232     {
6233     case TYPE_LEA:
6234       return "#";
6235     case TYPE_INCDEC:
6236       if (operands[2] == const1_rtx)
6237         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6238       else
6239         {
6240           gcc_assert (operands[2] == constm1_rtx);
6241           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6242         }
6243
6244     default:
6245       if (x86_maybe_negate_const_int (&operands[2], QImode))
6246         {
6247           if (widen)
6248             return "sub{l}\t{%2, %k0|%k0, %2}";
6249           else
6250             return "sub{b}\t{%2, %0|%0, %2}";
6251         }
6252       if (widen)
6253         return "add{l}\t{%k2, %k0|%k0, %k2}";
6254       else
6255         return "add{b}\t{%2, %0|%0, %2}";
6256     }
6257 }
6258   [(set (attr "type")
6259      (if_then_else (eq_attr "alternative" "3")
6260         (const_string "lea")
6261         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6262            (const_string "incdec")
6263            (const_string "alu"))))
6264    (set (attr "length_immediate")
6265       (if_then_else
6266         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6267         (const_string "1")
6268         (const_string "*")))
6269    (set_attr "mode" "QI,QI,SI,SI")])
6270
6271 (define_insn "*addqi_1_slp"
6272   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6273         (plus:QI (match_dup 0)
6274                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6275    (clobber (reg:CC FLAGS_REG))]
6276   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6277    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6278 {
6279   switch (get_attr_type (insn))
6280     {
6281     case TYPE_INCDEC:
6282       if (operands[1] == const1_rtx)
6283         return "inc{b}\t%0";
6284       else
6285         {
6286           gcc_assert (operands[1] == constm1_rtx);
6287           return "dec{b}\t%0";
6288         }
6289
6290     default:
6291       if (x86_maybe_negate_const_int (&operands[1], QImode))
6292         return "sub{b}\t{%1, %0|%0, %1}";
6293
6294       return "add{b}\t{%1, %0|%0, %1}";
6295     }
6296 }
6297   [(set (attr "type")
6298      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6299         (const_string "incdec")
6300         (const_string "alu1")))
6301    (set (attr "memory")
6302      (if_then_else (match_operand 1 "memory_operand" "")
6303         (const_string "load")
6304         (const_string "none")))
6305    (set_attr "mode" "QI")])
6306
6307 (define_insn "*add<mode>_2"
6308   [(set (reg FLAGS_REG)
6309         (compare
6310           (plus:SWI48
6311             (match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
6312             (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>"))
6313           (const_int 0)))
6314    (set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm")
6315         (plus:SWI48 (match_dup 1) (match_dup 2)))]
6316   "ix86_match_ccmode (insn, CCGOCmode)
6317    && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
6318    /* Current assemblers are broken and do not allow @GOTOFF in
6319       ought but a memory context.  */
6320    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6321 {
6322   switch (get_attr_type (insn))
6323     {
6324     case TYPE_INCDEC:
6325       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6326       if (operands[2] == const1_rtx)
6327         return "inc{<imodesuffix>}\t%0";
6328       else
6329         {
6330           gcc_assert (operands[2] == constm1_rtx);
6331           return "dec{<imodesuffix>}\t%0";
6332         }
6333
6334     default:
6335       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6336       /* ???? In DImode, we ought to handle there the 32bit case too
6337          - do we need new constraint?  */
6338       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6339         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6340
6341       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6342     }
6343 }
6344   [(set (attr "type")
6345      (if_then_else (match_operand:SWI48 2 "incdec_operand" "")
6346         (const_string "incdec")
6347         (const_string "alu")))
6348    (set (attr "length_immediate")
6349       (if_then_else
6350         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6351         (const_string "1")
6352         (const_string "*")))
6353    (set_attr "mode" "<MODE>")])
6354
6355 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6356 (define_insn "*addsi_2_zext"
6357   [(set (reg FLAGS_REG)
6358         (compare
6359           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6360                    (match_operand:SI 2 "general_operand" "g"))
6361           (const_int 0)))
6362    (set (match_operand:DI 0 "register_operand" "=r")
6363         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6364   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6365    && ix86_binary_operator_ok (PLUS, SImode, operands)
6366    /* Current assemblers are broken and do not allow @GOTOFF in
6367       ought but a memory context.  */
6368    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6369 {
6370   switch (get_attr_type (insn))
6371     {
6372     case TYPE_INCDEC:
6373       if (operands[2] == const1_rtx)
6374         return "inc{l}\t%k0";
6375       else
6376         {
6377           gcc_assert (operands[2] == constm1_rtx);
6378           return "dec{l}\t%k0";
6379         }
6380
6381     default:
6382       if (x86_maybe_negate_const_int (&operands[2], SImode))
6383         return "sub{l}\t{%2, %k0|%k0, %2}";
6384
6385       return "add{l}\t{%2, %k0|%k0, %2}";
6386     }
6387 }
6388   [(set (attr "type")
6389      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6390         (const_string "incdec")
6391         (const_string "alu")))
6392    (set (attr "length_immediate")
6393       (if_then_else
6394         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6395         (const_string "1")
6396         (const_string "*")))
6397    (set_attr "mode" "SI")])
6398
6399 (define_insn "*addhi_2"
6400   [(set (reg FLAGS_REG)
6401         (compare
6402           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6403                    (match_operand:HI 2 "general_operand" "rmn,rn"))
6404           (const_int 0)))
6405    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6406         (plus:HI (match_dup 1) (match_dup 2)))]
6407   "ix86_match_ccmode (insn, CCGOCmode)
6408    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6409 {
6410   switch (get_attr_type (insn))
6411     {
6412     case TYPE_INCDEC:
6413       if (operands[2] == const1_rtx)
6414         return "inc{w}\t%0";
6415       else
6416         {
6417           gcc_assert (operands[2] == constm1_rtx);
6418           return "dec{w}\t%0";
6419         }
6420
6421     default:
6422       if (x86_maybe_negate_const_int (&operands[2], HImode))
6423         return "sub{w}\t{%2, %0|%0, %2}";
6424
6425       return "add{w}\t{%2, %0|%0, %2}";
6426     }
6427 }
6428   [(set (attr "type")
6429      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6430         (const_string "incdec")
6431         (const_string "alu")))
6432    (set (attr "length_immediate")
6433       (if_then_else
6434         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6435         (const_string "1")
6436         (const_string "*")))
6437    (set_attr "mode" "HI")])
6438
6439 (define_insn "*addqi_2"
6440   [(set (reg FLAGS_REG)
6441         (compare
6442           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6443                    (match_operand:QI 2 "general_operand" "qmn,qn"))
6444           (const_int 0)))
6445    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6446         (plus:QI (match_dup 1) (match_dup 2)))]
6447   "ix86_match_ccmode (insn, CCGOCmode)
6448    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6449 {
6450   switch (get_attr_type (insn))
6451     {
6452     case TYPE_INCDEC:
6453       if (operands[2] == const1_rtx)
6454         return "inc{b}\t%0";
6455       else
6456         {
6457           gcc_assert (operands[2] == constm1_rtx
6458                       || (CONST_INT_P (operands[2])
6459                           && INTVAL (operands[2]) == 255));
6460           return "dec{b}\t%0";
6461         }
6462
6463     default:
6464       if (x86_maybe_negate_const_int (&operands[2], QImode))
6465         return "sub{b}\t{%2, %0|%0, %2}";
6466
6467       return "add{b}\t{%2, %0|%0, %2}";
6468     }
6469 }
6470   [(set (attr "type")
6471      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6472         (const_string "incdec")
6473         (const_string "alu")))
6474    (set_attr "mode" "QI")])
6475
6476 (define_insn "*add<mode>_3"
6477   [(set (reg FLAGS_REG)
6478         (compare
6479           (neg:SWI48 (match_operand:SWI48 2 "<general_operand>" "<g>"))
6480           (match_operand:SWI48 1 "nonimmediate_operand" "%0")))
6481    (clobber (match_scratch:SWI48 0 "=r"))]
6482   "ix86_match_ccmode (insn, CCZmode)
6483    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6484    /* Current assemblers are broken and do not allow @GOTOFF in
6485       ought but a memory context.  */
6486    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6487 {
6488   switch (get_attr_type (insn))
6489     {
6490     case TYPE_INCDEC:
6491       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6492       if (operands[2] == const1_rtx)
6493         return "inc{<imodesuffix>}\t%0";
6494       else
6495         {
6496           gcc_assert (operands[2] == constm1_rtx);
6497           return "dec{<imodesuffix>}\t%0";
6498         }
6499
6500     default:
6501       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6502       /* ???? In DImode, we ought to handle there the 32bit case too
6503          - do we need new constraint?  */
6504       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6505         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6506
6507       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6508     }
6509 }
6510   [(set (attr "type")
6511      (if_then_else (match_operand:SWI48 2 "incdec_operand" "")
6512         (const_string "incdec")
6513         (const_string "alu")))
6514    (set (attr "length_immediate")
6515       (if_then_else
6516         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6517         (const_string "1")
6518         (const_string "*")))
6519    (set_attr "mode" "<MODE>")])
6520
6521 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6522 (define_insn "*addsi_3_zext"
6523   [(set (reg FLAGS_REG)
6524         (compare
6525           (neg:SI (match_operand:SI 2 "general_operand" "g"))
6526           (match_operand:SI 1 "nonimmediate_operand" "%0")))
6527    (set (match_operand:DI 0 "register_operand" "=r")
6528         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6529   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6530    && ix86_binary_operator_ok (PLUS, SImode, operands)
6531    /* Current assemblers are broken and do not allow @GOTOFF in
6532       ought but a memory context.  */
6533    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6534 {
6535   switch (get_attr_type (insn))
6536     {
6537     case TYPE_INCDEC:
6538       if (operands[2] == const1_rtx)
6539         return "inc{l}\t%k0";
6540       else
6541         {
6542           gcc_assert (operands[2] == constm1_rtx);
6543           return "dec{l}\t%k0";
6544         }
6545
6546     default:
6547       if (x86_maybe_negate_const_int (&operands[2], SImode))
6548         return "sub{l}\t{%2, %k0|%k0, %2}";
6549
6550       return "add{l}\t{%2, %k0|%k0, %2}";
6551     }
6552 }
6553   [(set (attr "type")
6554      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6555         (const_string "incdec")
6556         (const_string "alu")))
6557    (set (attr "length_immediate")
6558       (if_then_else
6559         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6560         (const_string "1")
6561         (const_string "*")))
6562    (set_attr "mode" "SI")])
6563
6564 (define_insn "*addhi_3"
6565   [(set (reg FLAGS_REG)
6566         (compare
6567           (neg:HI (match_operand:HI 2 "general_operand" "rmn"))
6568           (match_operand:HI 1 "nonimmediate_operand" "%0")))
6569    (clobber (match_scratch:HI 0 "=r"))]
6570   "ix86_match_ccmode (insn, CCZmode)
6571    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6572 {
6573   switch (get_attr_type (insn))
6574     {
6575     case TYPE_INCDEC:
6576       if (operands[2] == const1_rtx)
6577         return "inc{w}\t%0";
6578       else
6579         {
6580           gcc_assert (operands[2] == constm1_rtx);
6581           return "dec{w}\t%0";
6582         }
6583
6584     default:
6585       if (x86_maybe_negate_const_int (&operands[2], HImode))
6586         return "sub{w}\t{%2, %0|%0, %2}";
6587
6588       return "add{w}\t{%2, %0|%0, %2}";
6589     }
6590 }
6591   [(set (attr "type")
6592      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6593         (const_string "incdec")
6594         (const_string "alu")))
6595    (set (attr "length_immediate")
6596       (if_then_else
6597         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6598         (const_string "1")
6599         (const_string "*")))
6600    (set_attr "mode" "HI")])
6601
6602 (define_insn "*addqi_3"
6603   [(set (reg FLAGS_REG)
6604         (compare
6605           (neg:QI (match_operand:QI 2 "general_operand" "qmn"))
6606           (match_operand:QI 1 "nonimmediate_operand" "%0")))
6607    (clobber (match_scratch:QI 0 "=q"))]
6608   "ix86_match_ccmode (insn, CCZmode)
6609    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6610 {
6611   switch (get_attr_type (insn))
6612     {
6613     case TYPE_INCDEC:
6614       if (operands[2] == const1_rtx)
6615         return "inc{b}\t%0";
6616       else
6617         {
6618           gcc_assert (operands[2] == constm1_rtx
6619                       || (CONST_INT_P (operands[2])
6620                           && INTVAL (operands[2]) == 255));
6621           return "dec{b}\t%0";
6622         }
6623
6624     default:
6625       if (x86_maybe_negate_const_int (&operands[2], QImode))
6626         return "sub{b}\t{%2, %0|%0, %2}";
6627
6628       return "add{b}\t{%2, %0|%0, %2}";
6629     }
6630 }
6631   [(set (attr "type")
6632      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6633         (const_string "incdec")
6634         (const_string "alu")))
6635    (set_attr "mode" "QI")])
6636
6637 ; For comparisons against 1, -1 and 128, we may generate better code
6638 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6639 ; is matched then.  We can't accept general immediate, because for
6640 ; case of overflows,  the result is messed up.
6641 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6642 ; only for comparisons not depending on it.
6643
6644 (define_insn "*adddi_4"
6645   [(set (reg FLAGS_REG)
6646         (compare
6647           (match_operand:DI 1 "nonimmediate_operand" "0")
6648           (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6649    (clobber (match_scratch:DI 0 "=rm"))]
6650   "TARGET_64BIT
6651    && ix86_match_ccmode (insn, CCGCmode)"
6652 {
6653   switch (get_attr_type (insn))
6654     {
6655     case TYPE_INCDEC:
6656       if (operands[2] == constm1_rtx)
6657         return "inc{q}\t%0";
6658       else
6659         {
6660           gcc_assert (operands[2] == const1_rtx);
6661           return "dec{q}\t%0";
6662         }
6663
6664     default:
6665       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6666       if (x86_maybe_negate_const_int (&operands[2], DImode))
6667         return "add{q}\t{%2, %0|%0, %2}";
6668
6669       return "sub{q}\t{%2, %0|%0, %2}";
6670     }
6671 }
6672   [(set (attr "type")
6673      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6674         (const_string "incdec")
6675         (const_string "alu")))
6676    (set (attr "length_immediate")
6677       (if_then_else
6678         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6679         (const_string "1")
6680         (const_string "*")))
6681    (set_attr "mode" "DI")])
6682
6683 ; For comparisons against 1, -1 and 128, we may generate better code
6684 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6685 ; is matched then.  We can't accept general immediate, because for
6686 ; case of overflows,  the result is messed up.
6687 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6688 ; only for comparisons not depending on it.
6689
6690 (define_insn "*addsi_4"
6691   [(set (reg FLAGS_REG)
6692         (compare
6693           (match_operand:SI 1 "nonimmediate_operand" "0")
6694           (match_operand:SI 2 "const_int_operand" "n")))
6695    (clobber (match_scratch:SI 0 "=rm"))]
6696   "ix86_match_ccmode (insn, CCGCmode)"
6697 {
6698   switch (get_attr_type (insn))
6699     {
6700     case TYPE_INCDEC:
6701       if (operands[2] == constm1_rtx)
6702         return "inc{l}\t%0";
6703       else
6704         {
6705           gcc_assert (operands[2] == const1_rtx);
6706           return "dec{l}\t%0";
6707         }
6708
6709     default:
6710       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6711       if (x86_maybe_negate_const_int (&operands[2], SImode))
6712         return "add{l}\t{%2, %0|%0, %2}";
6713
6714       return "sub{l}\t{%2, %0|%0, %2}";
6715     }
6716 }
6717   [(set (attr "type")
6718      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6719         (const_string "incdec")
6720         (const_string "alu")))
6721    (set (attr "length_immediate")
6722       (if_then_else
6723         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6724         (const_string "1")
6725         (const_string "*")))
6726    (set_attr "mode" "SI")])
6727
6728 ; See comments above addsi_4 for details.
6729
6730 (define_insn "*addhi_4"
6731   [(set (reg FLAGS_REG)
6732         (compare
6733           (match_operand:HI 1 "nonimmediate_operand" "0")
6734           (match_operand:HI 2 "const_int_operand" "n")))
6735    (clobber (match_scratch:HI 0 "=rm"))]
6736   "ix86_match_ccmode (insn, CCGCmode)"
6737 {
6738   switch (get_attr_type (insn))
6739     {
6740     case TYPE_INCDEC:
6741       if (operands[2] == constm1_rtx)
6742         return "inc{w}\t%0";
6743       else
6744         {
6745           gcc_assert (operands[2] == const1_rtx);
6746           return "dec{w}\t%0";
6747         }
6748
6749     default:
6750       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6751       if (x86_maybe_negate_const_int (&operands[2], HImode))
6752         return "add{w}\t{%2, %0|%0, %2}";
6753
6754       return "sub{w}\t{%2, %0|%0, %2}";
6755     }
6756 }
6757   [(set (attr "type")
6758      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6759         (const_string "incdec")
6760         (const_string "alu")))
6761    (set (attr "length_immediate")
6762       (if_then_else
6763         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6764         (const_string "1")
6765         (const_string "*")))
6766    (set_attr "mode" "HI")])
6767
6768 ; See comments above addsi_4 for details.
6769
6770 (define_insn "*addqi_4"
6771   [(set (reg FLAGS_REG)
6772         (compare
6773           (match_operand:QI 1 "nonimmediate_operand" "0")
6774           (match_operand:QI 2 "const_int_operand" "n")))
6775    (clobber (match_scratch:QI 0 "=qm"))]
6776   "ix86_match_ccmode (insn, CCGCmode)"
6777 {
6778   switch (get_attr_type (insn))
6779     {
6780     case TYPE_INCDEC:
6781       if (operands[2] == constm1_rtx
6782           || (CONST_INT_P (operands[2])
6783               && INTVAL (operands[2]) == 255))
6784         return "inc{b}\t%0";
6785       else
6786         {
6787           gcc_assert (operands[2] == const1_rtx);
6788           return "dec{b}\t%0";
6789         }
6790
6791     default:
6792       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6793       if (x86_maybe_negate_const_int (&operands[2], QImode))
6794         return "add{b}\t{%2, %0|%0, %2}";
6795
6796       return "sub{b}\t{%2, %0|%0, %2}";
6797     }
6798 }
6799   [(set (attr "type")
6800      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6801         (const_string "incdec")
6802         (const_string "alu")))
6803    (set_attr "mode" "QI")])
6804
6805 (define_insn "*add<mode>_5"
6806   [(set (reg FLAGS_REG)
6807         (compare
6808           (plus:SWI48
6809             (match_operand:SWI48 1 "nonimmediate_operand" "%0")
6810             (match_operand:SWI48 2 "<general_operand>" "<g>"))
6811           (const_int 0)))
6812    (clobber (match_scratch:SWI48 0 "=r"))]
6813   "ix86_match_ccmode (insn, CCGOCmode)
6814    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6815    /* Current assemblers are broken and do not allow @GOTOFF in
6816       ought but a memory context.  */
6817    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6818 {
6819   switch (get_attr_type (insn))
6820     {
6821     case TYPE_INCDEC:
6822       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6823       if (operands[2] == const1_rtx)
6824         return "inc{<imodesuffix>}\t%0";
6825       else
6826         {
6827           gcc_assert (operands[2] == constm1_rtx);
6828           return "dec{<imodesuffix>}\t%0";
6829         }
6830
6831     default:
6832       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6833       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6834         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6835
6836       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6837     }
6838 }
6839   [(set (attr "type")
6840      (if_then_else (match_operand:SWI48 2 "incdec_operand" "")
6841         (const_string "incdec")
6842         (const_string "alu")))
6843    (set (attr "length_immediate")
6844       (if_then_else
6845         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6846         (const_string "1")
6847         (const_string "*")))
6848    (set_attr "mode" "<MODE>")])
6849
6850 (define_insn "*addhi_5"
6851   [(set (reg FLAGS_REG)
6852         (compare
6853           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6854                    (match_operand:HI 2 "general_operand" "rmn"))
6855           (const_int 0)))
6856    (clobber (match_scratch:HI 0 "=r"))]
6857   "ix86_match_ccmode (insn, CCGOCmode)
6858    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6859 {
6860   switch (get_attr_type (insn))
6861     {
6862     case TYPE_INCDEC:
6863       if (operands[2] == const1_rtx)
6864         return "inc{w}\t%0";
6865       else
6866         {
6867           gcc_assert (operands[2] == constm1_rtx);
6868           return "dec{w}\t%0";
6869         }
6870
6871     default:
6872       if (x86_maybe_negate_const_int (&operands[2], HImode))
6873         return "sub{w}\t{%2, %0|%0, %2}";
6874
6875       return "add{w}\t{%2, %0|%0, %2}";
6876     }
6877 }
6878   [(set (attr "type")
6879      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6880         (const_string "incdec")
6881         (const_string "alu")))
6882    (set (attr "length_immediate")
6883       (if_then_else
6884         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6885         (const_string "1")
6886         (const_string "*")))
6887    (set_attr "mode" "HI")])
6888
6889 (define_insn "*addqi_5"
6890   [(set (reg FLAGS_REG)
6891         (compare
6892           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6893                    (match_operand:QI 2 "general_operand" "qmn"))
6894           (const_int 0)))
6895    (clobber (match_scratch:QI 0 "=q"))]
6896   "ix86_match_ccmode (insn, CCGOCmode)
6897    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6898 {
6899   switch (get_attr_type (insn))
6900     {
6901     case TYPE_INCDEC:
6902       if (operands[2] == const1_rtx)
6903         return "inc{b}\t%0";
6904       else
6905         {
6906           gcc_assert (operands[2] == constm1_rtx
6907                       || (CONST_INT_P (operands[2])
6908                           && INTVAL (operands[2]) == 255));
6909           return "dec{b}\t%0";
6910         }
6911
6912     default:
6913       if (x86_maybe_negate_const_int (&operands[2], QImode))
6914         return "sub{b}\t{%2, %0|%0, %2}";
6915
6916       return "add{b}\t{%2, %0|%0, %2}";
6917     }
6918 }
6919   [(set (attr "type")
6920      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6921         (const_string "incdec")
6922         (const_string "alu")))
6923    (set_attr "mode" "QI")])
6924
6925 (define_insn "*addqi_ext_1_rex64"
6926   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6927                          (const_int 8)
6928                          (const_int 8))
6929         (plus:SI
6930           (zero_extract:SI
6931             (match_operand 1 "ext_register_operand" "0")
6932             (const_int 8)
6933             (const_int 8))
6934           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6935    (clobber (reg:CC FLAGS_REG))]
6936   "TARGET_64BIT"
6937 {
6938   switch (get_attr_type (insn))
6939     {
6940     case TYPE_INCDEC:
6941       if (operands[2] == const1_rtx)
6942         return "inc{b}\t%h0";
6943       else
6944         {
6945           gcc_assert (operands[2] == constm1_rtx
6946                       || (CONST_INT_P (operands[2])
6947                           && INTVAL (operands[2]) == 255));
6948           return "dec{b}\t%h0";
6949         }
6950
6951     default:
6952       return "add{b}\t{%2, %h0|%h0, %2}";
6953     }
6954 }
6955   [(set (attr "type")
6956      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6957         (const_string "incdec")
6958         (const_string "alu")))
6959    (set_attr "modrm" "1")
6960    (set_attr "mode" "QI")])
6961
6962 (define_insn "addqi_ext_1"
6963   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6964                          (const_int 8)
6965                          (const_int 8))
6966         (plus:SI
6967           (zero_extract:SI
6968             (match_operand 1 "ext_register_operand" "0")
6969             (const_int 8)
6970             (const_int 8))
6971           (match_operand:QI 2 "general_operand" "Qmn")))
6972    (clobber (reg:CC FLAGS_REG))]
6973   "!TARGET_64BIT"
6974 {
6975   switch (get_attr_type (insn))
6976     {
6977     case TYPE_INCDEC:
6978       if (operands[2] == const1_rtx)
6979         return "inc{b}\t%h0";
6980       else
6981         {
6982           gcc_assert (operands[2] == constm1_rtx
6983                       || (CONST_INT_P (operands[2])
6984                           && INTVAL (operands[2]) == 255));
6985           return "dec{b}\t%h0";
6986         }
6987
6988     default:
6989       return "add{b}\t{%2, %h0|%h0, %2}";
6990     }
6991 }
6992   [(set (attr "type")
6993      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6994         (const_string "incdec")
6995         (const_string "alu")))
6996    (set_attr "modrm" "1")
6997    (set_attr "mode" "QI")])
6998
6999 (define_insn "*addqi_ext_2"
7000   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7001                          (const_int 8)
7002                          (const_int 8))
7003         (plus:SI
7004           (zero_extract:SI
7005             (match_operand 1 "ext_register_operand" "%0")
7006             (const_int 8)
7007             (const_int 8))
7008           (zero_extract:SI
7009             (match_operand 2 "ext_register_operand" "Q")
7010             (const_int 8)
7011             (const_int 8))))
7012    (clobber (reg:CC FLAGS_REG))]
7013   ""
7014   "add{b}\t{%h2, %h0|%h0, %h2}"
7015   [(set_attr "type" "alu")
7016    (set_attr "mode" "QI")])
7017
7018 ;; The lea patterns for non-Pmodes needs to be matched by
7019 ;; several insns converted to real lea by splitters.
7020
7021 (define_insn_and_split "*lea_general_1"
7022   [(set (match_operand 0 "register_operand" "=r")
7023         (plus (plus (match_operand 1 "index_register_operand" "l")
7024                     (match_operand 2 "register_operand" "r"))
7025               (match_operand 3 "immediate_operand" "i")))]
7026   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
7027     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
7028    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7029    && GET_MODE (operands[0]) == GET_MODE (operands[1])
7030    && GET_MODE (operands[0]) == GET_MODE (operands[2])
7031    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
7032        || GET_MODE (operands[3]) == VOIDmode)"
7033   "#"
7034   "&& reload_completed"
7035   [(const_int 0)]
7036 {
7037   rtx pat;
7038   operands[0] = gen_lowpart (SImode, operands[0]);
7039   operands[1] = gen_lowpart (Pmode, operands[1]);
7040   operands[2] = gen_lowpart (Pmode, operands[2]);
7041   operands[3] = gen_lowpart (Pmode, operands[3]);
7042   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
7043                       operands[3]);
7044   if (Pmode != SImode)
7045     pat = gen_rtx_SUBREG (SImode, pat, 0);
7046   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7047   DONE;
7048 }
7049   [(set_attr "type" "lea")
7050    (set_attr "mode" "SI")])
7051
7052 (define_insn_and_split "*lea_general_1_zext"
7053   [(set (match_operand:DI 0 "register_operand" "=r")
7054         (zero_extend:DI
7055           (plus:SI (plus:SI
7056                      (match_operand:SI 1 "index_register_operand" "l")
7057                      (match_operand:SI 2 "register_operand" "r"))
7058                    (match_operand:SI 3 "immediate_operand" "i"))))]
7059   "TARGET_64BIT"
7060   "#"
7061   "&& reload_completed"
7062   [(set (match_dup 0)
7063         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
7064                                                      (match_dup 2))
7065                                             (match_dup 3)) 0)))]
7066 {
7067   operands[1] = gen_lowpart (Pmode, operands[1]);
7068   operands[2] = gen_lowpart (Pmode, operands[2]);
7069   operands[3] = gen_lowpart (Pmode, operands[3]);
7070 }
7071   [(set_attr "type" "lea")
7072    (set_attr "mode" "SI")])
7073
7074 (define_insn_and_split "*lea_general_2"
7075   [(set (match_operand 0 "register_operand" "=r")
7076         (plus (mult (match_operand 1 "index_register_operand" "l")
7077                     (match_operand 2 "const248_operand" "i"))
7078               (match_operand 3 "nonmemory_operand" "ri")))]
7079   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
7080     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
7081    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7082    && GET_MODE (operands[0]) == GET_MODE (operands[1])
7083    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
7084        || GET_MODE (operands[3]) == VOIDmode)"
7085   "#"
7086   "&& reload_completed"
7087   [(const_int 0)]
7088 {
7089   rtx pat;
7090   operands[0] = gen_lowpart (SImode, operands[0]);
7091   operands[1] = gen_lowpart (Pmode, operands[1]);
7092   operands[3] = gen_lowpart (Pmode, operands[3]);
7093   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
7094                       operands[3]);
7095   if (Pmode != SImode)
7096     pat = gen_rtx_SUBREG (SImode, pat, 0);
7097   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7098   DONE;
7099 }
7100   [(set_attr "type" "lea")
7101    (set_attr "mode" "SI")])
7102
7103 (define_insn_and_split "*lea_general_2_zext"
7104   [(set (match_operand:DI 0 "register_operand" "=r")
7105         (zero_extend:DI
7106           (plus:SI (mult:SI
7107                      (match_operand:SI 1 "index_register_operand" "l")
7108                      (match_operand:SI 2 "const248_operand" "n"))
7109                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
7110   "TARGET_64BIT"
7111   "#"
7112   "&& reload_completed"
7113   [(set (match_dup 0)
7114         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
7115                                                      (match_dup 2))
7116                                             (match_dup 3)) 0)))]
7117 {
7118   operands[1] = gen_lowpart (Pmode, operands[1]);
7119   operands[3] = gen_lowpart (Pmode, operands[3]);
7120 }
7121   [(set_attr "type" "lea")
7122    (set_attr "mode" "SI")])
7123
7124 (define_insn_and_split "*lea_general_3"
7125   [(set (match_operand 0 "register_operand" "=r")
7126         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
7127                           (match_operand 2 "const248_operand" "i"))
7128                     (match_operand 3 "register_operand" "r"))
7129               (match_operand 4 "immediate_operand" "i")))]
7130   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
7131     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
7132    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7133    && GET_MODE (operands[0]) == GET_MODE (operands[1])
7134    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
7135   "#"
7136   "&& reload_completed"
7137   [(const_int 0)]
7138 {
7139   rtx pat;
7140   operands[0] = gen_lowpart (SImode, operands[0]);
7141   operands[1] = gen_lowpart (Pmode, operands[1]);
7142   operands[3] = gen_lowpart (Pmode, operands[3]);
7143   operands[4] = gen_lowpart (Pmode, operands[4]);
7144   pat = gen_rtx_PLUS (Pmode,
7145                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
7146                                                          operands[2]),
7147                                     operands[3]),
7148                       operands[4]);
7149   if (Pmode != SImode)
7150     pat = gen_rtx_SUBREG (SImode, pat, 0);
7151   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7152   DONE;
7153 }
7154   [(set_attr "type" "lea")
7155    (set_attr "mode" "SI")])
7156
7157 (define_insn_and_split "*lea_general_3_zext"
7158   [(set (match_operand:DI 0 "register_operand" "=r")
7159         (zero_extend:DI
7160           (plus:SI (plus:SI
7161                      (mult:SI
7162                        (match_operand:SI 1 "index_register_operand" "l")
7163                        (match_operand:SI 2 "const248_operand" "n"))
7164                      (match_operand:SI 3 "register_operand" "r"))
7165                    (match_operand:SI 4 "immediate_operand" "i"))))]
7166   "TARGET_64BIT"
7167   "#"
7168   "&& reload_completed"
7169   [(set (match_dup 0)
7170         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
7171                                                               (match_dup 2))
7172                                                      (match_dup 3))
7173                                             (match_dup 4)) 0)))]
7174 {
7175   operands[1] = gen_lowpart (Pmode, operands[1]);
7176   operands[3] = gen_lowpart (Pmode, operands[3]);
7177   operands[4] = gen_lowpart (Pmode, operands[4]);
7178 }
7179   [(set_attr "type" "lea")
7180    (set_attr "mode" "SI")])
7181
7182 ;; Convert lea to the lea pattern to avoid flags dependency.
7183 (define_split
7184   [(set (match_operand:DI 0 "register_operand" "")
7185         (plus:DI (match_operand:DI 1 "register_operand" "")
7186                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
7187    (clobber (reg:CC FLAGS_REG))]
7188   "TARGET_64BIT && reload_completed 
7189    && ix86_lea_for_add_ok (PLUS, insn, operands)"
7190   [(set (match_dup 0)
7191         (plus:DI (match_dup 1)
7192                  (match_dup 2)))]
7193   "")
7194
7195 ;; Convert lea to the lea pattern to avoid flags dependency.
7196 (define_split
7197   [(set (match_operand 0 "register_operand" "")
7198         (plus (match_operand 1 "register_operand" "")
7199               (match_operand 2 "nonmemory_operand" "")))
7200    (clobber (reg:CC FLAGS_REG))]
7201   "reload_completed && ix86_lea_for_add_ok (PLUS, insn, operands)" 
7202   [(const_int 0)]
7203 {
7204   rtx pat;
7205   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
7206      may confuse gen_lowpart.  */
7207   if (GET_MODE (operands[0]) != Pmode)
7208     {
7209       operands[1] = gen_lowpart (Pmode, operands[1]);
7210       operands[2] = gen_lowpart (Pmode, operands[2]);
7211     }
7212   operands[0] = gen_lowpart (SImode, operands[0]);
7213   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
7214   if (Pmode != SImode)
7215     pat = gen_rtx_SUBREG (SImode, pat, 0);
7216   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7217   DONE;
7218 })
7219
7220 ;; Convert lea to the lea pattern to avoid flags dependency.
7221 (define_split
7222   [(set (match_operand:DI 0 "register_operand" "")
7223         (zero_extend:DI
7224           (plus:SI (match_operand:SI 1 "register_operand" "")
7225                    (match_operand:SI 2 "nonmemory_operand" ""))))
7226    (clobber (reg:CC FLAGS_REG))]
7227   "TARGET_64BIT && reload_completed
7228    && true_regnum (operands[0]) != true_regnum (operands[1])"
7229   [(set (match_dup 0)
7230         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
7231 {
7232   operands[1] = gen_lowpart (Pmode, operands[1]);
7233   operands[2] = gen_lowpart (Pmode, operands[2]);
7234 })
7235 \f
7236 ;; Subtract instructions
7237
7238 (define_expand "sub<mode>3"
7239   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
7240         (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
7241                      (match_operand:SDWIM 2 "<general_operand>" "")))]
7242   ""
7243   "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
7244
7245 (define_insn_and_split "*sub<dwi>3_doubleword"
7246   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
7247         (minus:<DWI>
7248           (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
7249           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
7250    (clobber (reg:CC FLAGS_REG))]
7251   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7252   "#"
7253   "reload_completed"
7254   [(parallel [(set (reg:CC FLAGS_REG)
7255                    (compare:CC (match_dup 1) (match_dup 2)))
7256               (set (match_dup 0)
7257                    (minus:DWIH (match_dup 1) (match_dup 2)))])
7258    (parallel [(set (match_dup 3)
7259                    (minus:DWIH
7260                      (match_dup 4)
7261                      (plus:DWIH
7262                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7263                        (match_dup 5))))
7264               (clobber (reg:CC FLAGS_REG))])]
7265   "split_<dwi> (&operands[0], 3, &operands[0], &operands[3]);")
7266
7267 (define_insn "*sub<mode>_1"
7268   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7269         (minus:SWI
7270           (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7271           (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
7272    (clobber (reg:CC FLAGS_REG))]
7273   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7274   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7275   [(set_attr "type" "alu")
7276    (set_attr "mode" "<MODE>")])
7277
7278 (define_insn "*subsi_1_zext"
7279   [(set (match_operand:DI 0 "register_operand" "=r")
7280         (zero_extend:DI
7281           (minus:SI (match_operand:SI 1 "register_operand" "0")
7282                     (match_operand:SI 2 "general_operand" "g"))))
7283    (clobber (reg:CC FLAGS_REG))]
7284   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7285   "sub{l}\t{%2, %k0|%k0, %2}"
7286   [(set_attr "type" "alu")
7287    (set_attr "mode" "SI")])
7288
7289 (define_insn "*subqi_1_slp"
7290   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7291         (minus:QI (match_dup 0)
7292                   (match_operand:QI 1 "general_operand" "qn,qm")))
7293    (clobber (reg:CC FLAGS_REG))]
7294   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7295    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7296   "sub{b}\t{%1, %0|%0, %1}"
7297   [(set_attr "type" "alu1")
7298    (set_attr "mode" "QI")])
7299
7300 (define_insn "*sub<mode>_2"
7301   [(set (reg FLAGS_REG)
7302         (compare
7303           (minus:SWI
7304             (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7305             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
7306           (const_int 0)))
7307    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7308         (minus:SWI (match_dup 1) (match_dup 2)))]
7309   "ix86_match_ccmode (insn, CCGOCmode)
7310    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7311   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7312   [(set_attr "type" "alu")
7313    (set_attr "mode" "<MODE>")])
7314
7315 (define_insn "*subsi_2_zext"
7316   [(set (reg FLAGS_REG)
7317         (compare
7318           (minus:SI (match_operand:SI 1 "register_operand" "0")
7319                     (match_operand:SI 2 "general_operand" "g"))
7320           (const_int 0)))
7321    (set (match_operand:DI 0 "register_operand" "=r")
7322         (zero_extend:DI
7323           (minus:SI (match_dup 1)
7324                     (match_dup 2))))]
7325   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7326    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7327   "sub{l}\t{%2, %k0|%k0, %2}"
7328   [(set_attr "type" "alu")
7329    (set_attr "mode" "SI")])
7330
7331 (define_insn "*sub<mode>_3"
7332   [(set (reg FLAGS_REG)
7333         (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7334                  (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
7335    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7336         (minus:SWI (match_dup 1) (match_dup 2)))]
7337   "ix86_match_ccmode (insn, CCmode)
7338    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7339   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7340   [(set_attr "type" "alu")
7341    (set_attr "mode" "<MODE>")])
7342
7343 (define_insn "*subsi_3_zext"
7344   [(set (reg FLAGS_REG)
7345         (compare (match_operand:SI 1 "register_operand" "0")
7346                  (match_operand:SI 2 "general_operand" "g")))
7347    (set (match_operand:DI 0 "register_operand" "=r")
7348         (zero_extend:DI
7349           (minus:SI (match_dup 1)
7350                     (match_dup 2))))]
7351   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7352    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7353   "sub{l}\t{%2, %1|%1, %2}"
7354   [(set_attr "type" "alu")
7355    (set_attr "mode" "SI")])
7356 \f
7357 ;; Add with carry and subtract with borrow
7358
7359 (define_expand "<plusminus_insn><mode>3_carry"
7360   [(parallel
7361     [(set (match_operand:SWI 0 "nonimmediate_operand" "")
7362           (plusminus:SWI
7363             (match_operand:SWI 1 "nonimmediate_operand" "")
7364             (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
7365                        [(match_operand 3 "flags_reg_operand" "")
7366                         (const_int 0)])
7367                       (match_operand:SWI 2 "<general_operand>" ""))))
7368      (clobber (reg:CC FLAGS_REG))])]
7369   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
7370   "")
7371
7372 (define_insn "*<plusminus_insn><mode>3_carry"
7373   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7374         (plusminus:SWI
7375           (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
7376           (plus:SWI
7377             (match_operator 3 "ix86_carry_flag_operator"
7378              [(reg FLAGS_REG) (const_int 0)])
7379             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
7380    (clobber (reg:CC FLAGS_REG))]
7381   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7382   "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
7383   [(set_attr "type" "alu")
7384    (set_attr "use_carry" "1")
7385    (set_attr "pent_pair" "pu")
7386    (set_attr "mode" "<MODE>")])
7387
7388 (define_insn "*addsi3_carry_zext"
7389   [(set (match_operand:DI 0 "register_operand" "=r")
7390         (zero_extend:DI
7391           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7392                    (plus:SI (match_operator 3 "ix86_carry_flag_operator"
7393                              [(reg FLAGS_REG) (const_int 0)])
7394                             (match_operand:SI 2 "general_operand" "g")))))
7395    (clobber (reg:CC FLAGS_REG))]
7396   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
7397   "adc{l}\t{%2, %k0|%k0, %2}"
7398   [(set_attr "type" "alu")
7399    (set_attr "use_carry" "1")
7400    (set_attr "pent_pair" "pu")
7401    (set_attr "mode" "SI")])
7402
7403 (define_insn "*subsi3_carry_zext"
7404   [(set (match_operand:DI 0 "register_operand" "=r")
7405         (zero_extend:DI
7406           (minus:SI (match_operand:SI 1 "register_operand" "0")
7407                     (plus:SI (match_operator 3 "ix86_carry_flag_operator"
7408                               [(reg FLAGS_REG) (const_int 0)])
7409                              (match_operand:SI 2 "general_operand" "g")))))
7410    (clobber (reg:CC FLAGS_REG))]
7411   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7412   "sbb{l}\t{%2, %k0|%k0, %2}"
7413   [(set_attr "type" "alu")
7414    (set_attr "pent_pair" "pu")
7415    (set_attr "mode" "SI")])
7416 \f
7417 ;; Overflow setting add and subtract instructions
7418
7419 (define_insn "*add<mode>3_cconly_overflow"
7420   [(set (reg:CCC FLAGS_REG)
7421         (compare:CCC
7422           (plus:SWI
7423             (match_operand:SWI 1 "nonimmediate_operand" "%0")
7424             (match_operand:SWI 2 "<general_operand>" "<r><i>m"))
7425           (match_dup 1)))
7426    (clobber (match_scratch:SWI 0 "=<r>"))]
7427   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7428   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7429   [(set_attr "type" "alu")
7430    (set_attr "mode" "<MODE>")])
7431
7432 (define_insn "*sub<mode>3_cconly_overflow"
7433   [(set (reg:CCC FLAGS_REG)
7434         (compare:CCC
7435           (minus:SWI
7436             (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
7437             (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
7438           (match_dup 0)))]
7439   ""
7440   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
7441   [(set_attr "type" "icmp")
7442    (set_attr "mode" "<MODE>")])
7443
7444 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
7445   [(set (reg:CCC FLAGS_REG)
7446         (compare:CCC
7447             (plusminus:SWI
7448                 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
7449                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
7450             (match_dup 1)))
7451    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7452         (plusminus:SWI (match_dup 1) (match_dup 2)))]
7453   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
7454   "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
7455   [(set_attr "type" "alu")
7456    (set_attr "mode" "<MODE>")])
7457
7458 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
7459   [(set (reg:CCC FLAGS_REG)
7460         (compare:CCC
7461           (plusminus:SI
7462             (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
7463             (match_operand:SI 2 "general_operand" "g"))
7464           (match_dup 1)))
7465    (set (match_operand:DI 0 "register_operand" "=r")
7466         (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
7467   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
7468   "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
7469   [(set_attr "type" "alu")
7470    (set_attr "mode" "SI")])
7471
7472 ;; The patterns that match these are at the end of this file.
7473
7474 (define_expand "<plusminus_insn>xf3"
7475   [(set (match_operand:XF 0 "register_operand" "")
7476         (plusminus:XF
7477           (match_operand:XF 1 "register_operand" "")
7478           (match_operand:XF 2 "register_operand" "")))]
7479   "TARGET_80387"
7480   "")
7481
7482 (define_expand "<plusminus_insn><mode>3"
7483   [(set (match_operand:MODEF 0 "register_operand" "")
7484         (plusminus:MODEF
7485           (match_operand:MODEF 1 "register_operand" "")
7486           (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7487   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7488     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7489   "")
7490 \f
7491 ;; Multiply instructions
7492
7493 (define_expand "mul<mode>3"
7494   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7495                    (mult:SWIM248
7496                      (match_operand:SWIM248 1 "register_operand" "")
7497                      (match_operand:SWIM248 2 "<general_operand>" "")))
7498               (clobber (reg:CC FLAGS_REG))])]
7499   ""
7500   "")
7501
7502 (define_expand "mulqi3"
7503   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7504                    (mult:QI
7505                      (match_operand:QI 1 "register_operand" "")
7506                      (match_operand:QI 2 "nonimmediate_operand" "")))
7507               (clobber (reg:CC FLAGS_REG))])]
7508   "TARGET_QIMODE_MATH"
7509   "")
7510
7511 ;; On AMDFAM10
7512 ;; IMUL reg32/64, reg32/64, imm8        Direct
7513 ;; IMUL reg32/64, mem32/64, imm8        VectorPath
7514 ;; IMUL reg32/64, reg32/64, imm32       Direct
7515 ;; IMUL reg32/64, mem32/64, imm32       VectorPath
7516 ;; IMUL reg32/64, reg32/64              Direct
7517 ;; IMUL reg32/64, mem32/64              Direct
7518
7519 (define_insn "*mul<mode>3_1"
7520   [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
7521         (mult:SWI48
7522           (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
7523           (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
7524    (clobber (reg:CC FLAGS_REG))]
7525   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7526   "@
7527    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7528    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7529    imul{<imodesuffix>}\t{%2, %0|%0, %2}"
7530   [(set_attr "type" "imul")
7531    (set_attr "prefix_0f" "0,0,1")
7532    (set (attr "athlon_decode")
7533         (cond [(eq_attr "cpu" "athlon")
7534                   (const_string "vector")
7535                (eq_attr "alternative" "1")
7536                   (const_string "vector")
7537                (and (eq_attr "alternative" "2")
7538                     (match_operand 1 "memory_operand" ""))
7539                   (const_string "vector")]
7540               (const_string "direct")))
7541    (set (attr "amdfam10_decode")
7542         (cond [(and (eq_attr "alternative" "0,1")
7543                     (match_operand 1 "memory_operand" ""))
7544                   (const_string "vector")]
7545               (const_string "direct")))
7546    (set_attr "mode" "<MODE>")])
7547
7548 (define_insn "*mulsi3_1_zext"
7549   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7550         (zero_extend:DI
7551           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7552                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
7553    (clobber (reg:CC FLAGS_REG))]
7554   "TARGET_64BIT
7555    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7556   "@
7557    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7558    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7559    imul{l}\t{%2, %k0|%k0, %2}"
7560   [(set_attr "type" "imul")
7561    (set_attr "prefix_0f" "0,0,1")
7562    (set (attr "athlon_decode")
7563         (cond [(eq_attr "cpu" "athlon")
7564                   (const_string "vector")
7565                (eq_attr "alternative" "1")
7566                   (const_string "vector")
7567                (and (eq_attr "alternative" "2")
7568                     (match_operand 1 "memory_operand" ""))
7569                   (const_string "vector")]
7570               (const_string "direct")))
7571    (set (attr "amdfam10_decode")
7572         (cond [(and (eq_attr "alternative" "0,1")
7573                     (match_operand 1 "memory_operand" ""))
7574                   (const_string "vector")]
7575               (const_string "direct")))
7576    (set_attr "mode" "SI")])
7577
7578 ;; On AMDFAM10
7579 ;; IMUL reg16, reg16, imm8      VectorPath
7580 ;; IMUL reg16, mem16, imm8      VectorPath
7581 ;; IMUL reg16, reg16, imm16     VectorPath
7582 ;; IMUL reg16, mem16, imm16     VectorPath
7583 ;; IMUL reg16, reg16            Direct
7584 ;; IMUL reg16, mem16            Direct
7585
7586 (define_insn "*mulhi3_1"
7587   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7588         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7589                  (match_operand:HI 2 "general_operand" "K,n,mr")))
7590    (clobber (reg:CC FLAGS_REG))]
7591   "TARGET_HIMODE_MATH
7592    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7593   "@
7594    imul{w}\t{%2, %1, %0|%0, %1, %2}
7595    imul{w}\t{%2, %1, %0|%0, %1, %2}
7596    imul{w}\t{%2, %0|%0, %2}"
7597   [(set_attr "type" "imul")
7598    (set_attr "prefix_0f" "0,0,1")
7599    (set (attr "athlon_decode")
7600         (cond [(eq_attr "cpu" "athlon")
7601                   (const_string "vector")
7602                (eq_attr "alternative" "1,2")
7603                   (const_string "vector")]
7604               (const_string "direct")))
7605    (set (attr "amdfam10_decode")
7606         (cond [(eq_attr "alternative" "0,1")
7607                   (const_string "vector")]
7608               (const_string "direct")))
7609    (set_attr "mode" "HI")])
7610
7611 ;;On AMDFAM10
7612 ;; MUL reg8     Direct
7613 ;; MUL mem8     Direct
7614
7615 (define_insn "*mulqi3_1"
7616   [(set (match_operand:QI 0 "register_operand" "=a")
7617         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7618                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7619    (clobber (reg:CC FLAGS_REG))]
7620   "TARGET_QIMODE_MATH
7621    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7622   "mul{b}\t%2"
7623   [(set_attr "type" "imul")
7624    (set_attr "length_immediate" "0")
7625    (set (attr "athlon_decode")
7626      (if_then_else (eq_attr "cpu" "athlon")
7627         (const_string "vector")
7628         (const_string "direct")))
7629    (set_attr "amdfam10_decode" "direct")
7630    (set_attr "mode" "QI")])
7631
7632 (define_expand "<u>mul<mode><dwi>3"
7633   [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
7634                    (mult:<DWI>
7635                      (any_extend:<DWI>
7636                        (match_operand:DWIH 1 "nonimmediate_operand" ""))
7637                      (any_extend:<DWI>
7638                        (match_operand:DWIH 2 "register_operand" ""))))
7639               (clobber (reg:CC FLAGS_REG))])]
7640   ""
7641   "")
7642
7643 (define_expand "<u>mulqihi3"
7644   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7645                    (mult:HI
7646                      (any_extend:HI
7647                        (match_operand:QI 1 "nonimmediate_operand" ""))
7648                      (any_extend:HI
7649                        (match_operand:QI 2 "register_operand" ""))))
7650               (clobber (reg:CC FLAGS_REG))])]
7651   "TARGET_QIMODE_MATH"
7652   "")
7653
7654 (define_insn "*<u>mul<mode><dwi>3_1"
7655   [(set (match_operand:<DWI> 0 "register_operand" "=A")
7656         (mult:<DWI>
7657           (any_extend:<DWI>
7658             (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
7659           (any_extend:<DWI>
7660             (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7661    (clobber (reg:CC FLAGS_REG))]
7662   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7663   "<sgnprefix>mul{<imodesuffix>}\t%2"
7664   [(set_attr "type" "imul")
7665    (set_attr "length_immediate" "0")
7666    (set (attr "athlon_decode")
7667      (if_then_else (eq_attr "cpu" "athlon")
7668         (const_string "vector")
7669         (const_string "double")))
7670    (set_attr "amdfam10_decode" "double")
7671    (set_attr "mode" "<MODE>")])
7672
7673 (define_insn "*<u>mulqihi3_1"
7674   [(set (match_operand:HI 0 "register_operand" "=a")
7675         (mult:HI
7676           (any_extend:HI
7677             (match_operand:QI 1 "nonimmediate_operand" "%0"))
7678           (any_extend:HI
7679             (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7680    (clobber (reg:CC FLAGS_REG))]
7681   "TARGET_QIMODE_MATH
7682    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7683   "<sgnprefix>mul{b}\t%2"
7684   [(set_attr "type" "imul")
7685    (set_attr "length_immediate" "0")
7686    (set (attr "athlon_decode")
7687      (if_then_else (eq_attr "cpu" "athlon")
7688         (const_string "vector")
7689         (const_string "direct")))
7690    (set_attr "amdfam10_decode" "direct")
7691    (set_attr "mode" "QI")])
7692
7693 (define_expand "<s>mul<mode>3_highpart"
7694   [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
7695                    (truncate:SWI48
7696                      (lshiftrt:<DWI>
7697                        (mult:<DWI>
7698                          (any_extend:<DWI>
7699                            (match_operand:SWI48 1 "nonimmediate_operand" ""))
7700                          (any_extend:<DWI>
7701                            (match_operand:SWI48 2 "register_operand" "")))
7702                        (match_dup 4))))
7703               (clobber (match_scratch:SWI48 3 ""))
7704               (clobber (reg:CC FLAGS_REG))])]
7705   ""
7706   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7707
7708 (define_insn "*<s>muldi3_highpart_1"
7709   [(set (match_operand:DI 0 "register_operand" "=d")
7710         (truncate:DI
7711           (lshiftrt:TI
7712             (mult:TI
7713               (any_extend:TI
7714                 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7715               (any_extend:TI
7716                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7717             (const_int 64))))
7718    (clobber (match_scratch:DI 3 "=1"))
7719    (clobber (reg:CC FLAGS_REG))]
7720   "TARGET_64BIT
7721    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7722   "<sgnprefix>mul{q}\t%2"
7723   [(set_attr "type" "imul")
7724    (set_attr "length_immediate" "0")
7725    (set (attr "athlon_decode")
7726      (if_then_else (eq_attr "cpu" "athlon")
7727         (const_string "vector")
7728         (const_string "double")))
7729    (set_attr "amdfam10_decode" "double")
7730    (set_attr "mode" "DI")])
7731
7732 (define_insn "*<s>mulsi3_highpart_1"
7733   [(set (match_operand:SI 0 "register_operand" "=d")
7734         (truncate:SI
7735           (lshiftrt:DI
7736             (mult:DI
7737               (any_extend:DI
7738                 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7739               (any_extend:DI
7740                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7741             (const_int 32))))
7742    (clobber (match_scratch:SI 3 "=1"))
7743    (clobber (reg:CC FLAGS_REG))]
7744   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7745   "<sgnprefix>mul{l}\t%2"
7746   [(set_attr "type" "imul")
7747    (set_attr "length_immediate" "0")
7748    (set (attr "athlon_decode")
7749      (if_then_else (eq_attr "cpu" "athlon")
7750         (const_string "vector")
7751         (const_string "double")))
7752    (set_attr "amdfam10_decode" "double")
7753    (set_attr "mode" "SI")])
7754
7755 (define_insn "*<s>mulsi3_highpart_zext"
7756   [(set (match_operand:DI 0 "register_operand" "=d")
7757         (zero_extend:DI (truncate:SI
7758           (lshiftrt:DI
7759             (mult:DI (any_extend:DI
7760                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7761                      (any_extend:DI
7762                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7763             (const_int 32)))))
7764    (clobber (match_scratch:SI 3 "=1"))
7765    (clobber (reg:CC FLAGS_REG))]
7766   "TARGET_64BIT
7767    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7768   "<sgnprefix>mul{l}\t%2"
7769   [(set_attr "type" "imul")
7770    (set_attr "length_immediate" "0")
7771    (set (attr "athlon_decode")
7772      (if_then_else (eq_attr "cpu" "athlon")
7773         (const_string "vector")
7774         (const_string "double")))
7775    (set_attr "amdfam10_decode" "double")
7776    (set_attr "mode" "SI")])
7777
7778 ;; The patterns that match these are at the end of this file.
7779
7780 (define_expand "mulxf3"
7781   [(set (match_operand:XF 0 "register_operand" "")
7782         (mult:XF (match_operand:XF 1 "register_operand" "")
7783                  (match_operand:XF 2 "register_operand" "")))]
7784   "TARGET_80387"
7785   "")
7786
7787 (define_expand "mul<mode>3"
7788   [(set (match_operand:MODEF 0 "register_operand" "")
7789         (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
7790                     (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7791   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7792     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7793   "")
7794 \f
7795 ;; Divide instructions
7796
7797 (define_insn "<u>divqi3"
7798   [(set (match_operand:QI 0 "register_operand" "=a")
7799         (any_div:QI
7800           (match_operand:HI 1 "register_operand" "0")
7801           (match_operand:QI 2 "nonimmediate_operand" "qm")))
7802    (clobber (reg:CC FLAGS_REG))]
7803   "TARGET_QIMODE_MATH"
7804   "<sgnprefix>div{b}\t%2"
7805   [(set_attr "type" "idiv")
7806    (set_attr "mode" "QI")])
7807
7808 ;; The patterns that match these are at the end of this file.
7809
7810 (define_expand "divxf3"
7811   [(set (match_operand:XF 0 "register_operand" "")
7812         (div:XF (match_operand:XF 1 "register_operand" "")
7813                 (match_operand:XF 2 "register_operand" "")))]
7814   "TARGET_80387"
7815   "")
7816
7817 (define_expand "divdf3"
7818   [(set (match_operand:DF 0 "register_operand" "")
7819         (div:DF (match_operand:DF 1 "register_operand" "")
7820                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7821    "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7822     || (TARGET_SSE2 && TARGET_SSE_MATH)"
7823    "")
7824
7825 (define_expand "divsf3"
7826   [(set (match_operand:SF 0 "register_operand" "")
7827         (div:SF (match_operand:SF 1 "register_operand" "")
7828                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7829   "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7830     || TARGET_SSE_MATH"
7831 {
7832   if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
7833       && flag_finite_math_only && !flag_trapping_math
7834       && flag_unsafe_math_optimizations)
7835     {
7836       ix86_emit_swdivsf (operands[0], operands[1],
7837                          operands[2], SFmode);
7838       DONE;
7839     }
7840 })
7841 \f
7842 ;; Divmod instructions.
7843
7844 (define_expand "divmod<mode>4"
7845   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7846                    (div:SWIM248
7847                      (match_operand:SWIM248 1 "register_operand" "")
7848                      (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7849               (set (match_operand:SWIM248 3 "register_operand" "")
7850                    (mod:SWIM248 (match_dup 1) (match_dup 2)))
7851               (clobber (reg:CC FLAGS_REG))])]
7852   ""
7853   "")
7854
7855 (define_insn_and_split "*divmod<mode>4"
7856   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7857         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7858                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7859    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7860         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7861    (clobber (reg:CC FLAGS_REG))]
7862   ""
7863   "#"
7864   "&& reload_completed"
7865   [(parallel [(set (match_dup 1)
7866                    (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7867               (clobber (reg:CC FLAGS_REG))])
7868    (parallel [(set (match_dup 0)
7869                    (div:SWIM248 (match_dup 2) (match_dup 3)))
7870               (set (match_dup 1)
7871                    (mod:SWIM248 (match_dup 2) (match_dup 3)))
7872               (use (match_dup 1))
7873               (clobber (reg:CC FLAGS_REG))])]
7874 {
7875   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - 1);
7876
7877   if (<MODE>mode != HImode
7878       && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7879     operands[4] = operands[2];
7880   else
7881     {
7882       /* Avoid use of cltd in favor of a mov+shift.  */
7883       emit_move_insn (operands[1], operands[2]);
7884       operands[4] = operands[1];
7885     }
7886 }
7887   [(set_attr "type" "multi")
7888    (set_attr "mode" "<MODE>")])
7889
7890 (define_insn "*divmod<mode>4_noext"
7891   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7892         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7893                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7894    (set (match_operand:SWIM248 1 "register_operand" "=d")
7895         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7896    (use (match_operand:SWIM248 4 "register_operand" "1"))
7897    (clobber (reg:CC FLAGS_REG))]
7898   ""
7899   "idiv{<imodesuffix>}\t%3"
7900   [(set_attr "type" "idiv")
7901    (set_attr "mode" "<MODE>")])
7902
7903 (define_expand "udivmod<mode>4"
7904   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7905                    (udiv:SWIM248
7906                      (match_operand:SWIM248 1 "register_operand" "")
7907                      (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7908               (set (match_operand:SWIM248 3 "register_operand" "")
7909                    (umod:SWIM248 (match_dup 1) (match_dup 2)))
7910               (clobber (reg:CC FLAGS_REG))])]
7911   ""
7912   "")
7913
7914 (define_insn_and_split "*udivmod<mode>4"
7915   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7916         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7917                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7918    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7919         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7920    (clobber (reg:CC FLAGS_REG))]
7921   ""
7922   "#"
7923   "&& reload_completed"
7924   [(set (match_dup 1) (const_int 0))
7925    (parallel [(set (match_dup 0)
7926                    (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7927               (set (match_dup 1)
7928                    (umod:SWIM248 (match_dup 2) (match_dup 3)))
7929               (use (match_dup 1))
7930               (clobber (reg:CC FLAGS_REG))])]
7931   ""
7932   [(set_attr "type" "multi")
7933    (set_attr "mode" "<MODE>")])
7934
7935 (define_insn "*udivmod<mode>4_noext"
7936   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7937         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7938                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7939    (set (match_operand:SWIM248 1 "register_operand" "=d")
7940         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7941    (use (match_operand:SWIM248 4 "register_operand" "1"))
7942    (clobber (reg:CC FLAGS_REG))]
7943   ""
7944   "div{<imodesuffix>}\t%3"
7945   [(set_attr "type" "idiv")
7946    (set_attr "mode" "<MODE>")])
7947
7948 ;; We cannot use div/idiv for double division, because it causes
7949 ;; "division by zero" on the overflow and that's not what we expect
7950 ;; from truncate.  Because true (non truncating) double division is
7951 ;; never generated, we can't create this insn anyway.
7952 ;
7953 ;(define_insn ""
7954 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7955 ;       (truncate:SI
7956 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7957 ;                  (zero_extend:DI
7958 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7959 ;   (set (match_operand:SI 3 "register_operand" "=d")
7960 ;       (truncate:SI
7961 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7962 ;   (clobber (reg:CC FLAGS_REG))]
7963 ;  ""
7964 ;  "div{l}\t{%2, %0|%0, %2}"
7965 ;  [(set_attr "type" "idiv")])
7966 \f
7967 ;;- Logical AND instructions
7968
7969 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7970 ;; Note that this excludes ah.
7971
7972 (define_expand "testsi_ccno_1"
7973   [(set (reg:CCNO FLAGS_REG)
7974         (compare:CCNO
7975           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7976                   (match_operand:SI 1 "nonmemory_operand" ""))
7977           (const_int 0)))]
7978   ""
7979   "")
7980
7981 (define_expand "testqi_ccz_1"
7982   [(set (reg:CCZ FLAGS_REG)
7983         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7984                              (match_operand:QI 1 "nonmemory_operand" ""))
7985                  (const_int 0)))]
7986   ""
7987   "")
7988
7989 (define_insn "*testdi_1"
7990   [(set (reg FLAGS_REG)
7991         (compare
7992          (and:DI
7993           (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7994           (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7995          (const_int 0)))]
7996   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7997    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7998   "@
7999    test{l}\t{%k1, %k0|%k0, %k1}
8000    test{l}\t{%k1, %k0|%k0, %k1}
8001    test{q}\t{%1, %0|%0, %1}
8002    test{q}\t{%1, %0|%0, %1}
8003    test{q}\t{%1, %0|%0, %1}"
8004   [(set_attr "type" "test")
8005    (set_attr "modrm" "0,1,0,1,1")
8006    (set_attr "mode" "SI,SI,DI,DI,DI")])
8007
8008 (define_insn "*testqi_1_maybe_si"
8009   [(set (reg FLAGS_REG)
8010         (compare
8011           (and:QI
8012             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8013             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8014           (const_int 0)))]
8015    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8016     && ix86_match_ccmode (insn,
8017                          CONST_INT_P (operands[1])
8018                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8019 {
8020   if (which_alternative == 3)
8021     {
8022       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8023         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8024       return "test{l}\t{%1, %k0|%k0, %1}";
8025     }
8026   return "test{b}\t{%1, %0|%0, %1}";
8027 }
8028   [(set_attr "type" "test")
8029    (set_attr "modrm" "0,1,1,1")
8030    (set_attr "mode" "QI,QI,QI,SI")
8031    (set_attr "pent_pair" "uv,np,uv,np")])
8032
8033 (define_insn "*test<mode>_1"
8034   [(set (reg FLAGS_REG)
8035         (compare
8036          (and:SWI124
8037           (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
8038           (match_operand:SWI124 1 "general_operand" "<i>,<i>,<r><i>"))
8039          (const_int 0)))]
8040   "ix86_match_ccmode (insn, CCNOmode)
8041    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8042   "test{<imodesuffix>}\t{%1, %0|%0, %1}"
8043   [(set_attr "type" "test")
8044    (set_attr "modrm" "0,1,1")
8045    (set_attr "mode" "<MODE>")
8046    (set_attr "pent_pair" "uv,np,uv")])
8047
8048 (define_expand "testqi_ext_ccno_0"
8049   [(set (reg:CCNO FLAGS_REG)
8050         (compare:CCNO
8051           (and:SI
8052             (zero_extract:SI
8053               (match_operand 0 "ext_register_operand" "")
8054               (const_int 8)
8055               (const_int 8))
8056             (match_operand 1 "const_int_operand" ""))
8057           (const_int 0)))]
8058   ""
8059   "")
8060
8061 (define_insn "*testqi_ext_0"
8062   [(set (reg FLAGS_REG)
8063         (compare
8064           (and:SI
8065             (zero_extract:SI
8066               (match_operand 0 "ext_register_operand" "Q")
8067               (const_int 8)
8068               (const_int 8))
8069             (match_operand 1 "const_int_operand" "n"))
8070           (const_int 0)))]
8071   "ix86_match_ccmode (insn, CCNOmode)"
8072   "test{b}\t{%1, %h0|%h0, %1}"
8073   [(set_attr "type" "test")
8074    (set_attr "mode" "QI")
8075    (set_attr "length_immediate" "1")
8076    (set_attr "modrm" "1")
8077    (set_attr "pent_pair" "np")])
8078
8079 (define_insn "*testqi_ext_1_rex64"
8080   [(set (reg FLAGS_REG)
8081         (compare
8082           (and:SI
8083             (zero_extract:SI
8084               (match_operand 0 "ext_register_operand" "Q")
8085               (const_int 8)
8086               (const_int 8))
8087             (zero_extend:SI
8088               (match_operand:QI 1 "register_operand" "Q")))
8089           (const_int 0)))]
8090   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8091   "test{b}\t{%1, %h0|%h0, %1}"
8092   [(set_attr "type" "test")
8093    (set_attr "mode" "QI")])
8094
8095 (define_insn "*testqi_ext_1"
8096   [(set (reg FLAGS_REG)
8097         (compare
8098           (and:SI
8099             (zero_extract:SI
8100               (match_operand 0 "ext_register_operand" "Q")
8101               (const_int 8)
8102               (const_int 8))
8103             (zero_extend:SI
8104               (match_operand:QI 1 "general_operand" "Qm")))
8105           (const_int 0)))]
8106   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8107   "test{b}\t{%1, %h0|%h0, %1}"
8108   [(set_attr "type" "test")
8109    (set_attr "mode" "QI")])
8110
8111 (define_insn "*testqi_ext_2"
8112   [(set (reg FLAGS_REG)
8113         (compare
8114           (and:SI
8115             (zero_extract:SI
8116               (match_operand 0 "ext_register_operand" "Q")
8117               (const_int 8)
8118               (const_int 8))
8119             (zero_extract:SI
8120               (match_operand 1 "ext_register_operand" "Q")
8121               (const_int 8)
8122               (const_int 8)))
8123           (const_int 0)))]
8124   "ix86_match_ccmode (insn, CCNOmode)"
8125   "test{b}\t{%h1, %h0|%h0, %h1}"
8126   [(set_attr "type" "test")
8127    (set_attr "mode" "QI")])
8128
8129 (define_insn "*testqi_ext_3_rex64"
8130   [(set (reg FLAGS_REG)
8131         (compare (zero_extract:DI
8132                    (match_operand 0 "nonimmediate_operand" "rm")
8133                    (match_operand:DI 1 "const_int_operand" "")
8134                    (match_operand:DI 2 "const_int_operand" ""))
8135                  (const_int 0)))]
8136   "TARGET_64BIT
8137    && ix86_match_ccmode (insn, CCNOmode)
8138    && INTVAL (operands[1]) > 0
8139    && INTVAL (operands[2]) >= 0
8140    /* Ensure that resulting mask is zero or sign extended operand.  */
8141    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8142        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8143            && INTVAL (operands[1]) > 32))
8144    && (GET_MODE (operands[0]) == SImode
8145        || GET_MODE (operands[0]) == DImode
8146        || GET_MODE (operands[0]) == HImode
8147        || GET_MODE (operands[0]) == QImode)"
8148   "#")
8149
8150 ;; Combine likes to form bit extractions for some tests.  Humor it.
8151 (define_insn "*testqi_ext_3"
8152   [(set (reg FLAGS_REG)
8153         (compare (zero_extract:SI
8154                    (match_operand 0 "nonimmediate_operand" "rm")
8155                    (match_operand:SI 1 "const_int_operand" "")
8156                    (match_operand:SI 2 "const_int_operand" ""))
8157                  (const_int 0)))]
8158   "ix86_match_ccmode (insn, CCNOmode)
8159    && INTVAL (operands[1]) > 0
8160    && INTVAL (operands[2]) >= 0
8161    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8162    && (GET_MODE (operands[0]) == SImode
8163        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8164        || GET_MODE (operands[0]) == HImode
8165        || GET_MODE (operands[0]) == QImode)"
8166   "#")
8167
8168 (define_split
8169   [(set (match_operand 0 "flags_reg_operand" "")
8170         (match_operator 1 "compare_operator"
8171           [(zero_extract
8172              (match_operand 2 "nonimmediate_operand" "")
8173              (match_operand 3 "const_int_operand" "")
8174              (match_operand 4 "const_int_operand" ""))
8175            (const_int 0)]))]
8176   "ix86_match_ccmode (insn, CCNOmode)"
8177   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8178 {
8179   rtx val = operands[2];
8180   HOST_WIDE_INT len = INTVAL (operands[3]);
8181   HOST_WIDE_INT pos = INTVAL (operands[4]);
8182   HOST_WIDE_INT mask;
8183   enum machine_mode mode, submode;
8184
8185   mode = GET_MODE (val);
8186   if (MEM_P (val))
8187     {
8188       /* ??? Combine likes to put non-volatile mem extractions in QImode
8189          no matter the size of the test.  So find a mode that works.  */
8190       if (! MEM_VOLATILE_P (val))
8191         {
8192           mode = smallest_mode_for_size (pos + len, MODE_INT);
8193           val = adjust_address (val, mode, 0);
8194         }
8195     }
8196   else if (GET_CODE (val) == SUBREG
8197            && (submode = GET_MODE (SUBREG_REG (val)),
8198                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8199            && pos + len <= GET_MODE_BITSIZE (submode)
8200            && GET_MODE_CLASS (submode) == MODE_INT)
8201     {
8202       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
8203       mode = submode;
8204       val = SUBREG_REG (val);
8205     }
8206   else if (mode == HImode && pos + len <= 8)
8207     {
8208       /* Small HImode tests can be converted to QImode.  */
8209       mode = QImode;
8210       val = gen_lowpart (QImode, val);
8211     }
8212
8213   if (len == HOST_BITS_PER_WIDE_INT)
8214     mask = -1;
8215   else
8216     mask = ((HOST_WIDE_INT)1 << len) - 1;
8217   mask <<= pos;
8218
8219   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8220 })
8221
8222 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8223 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8224 ;; this is relatively important trick.
8225 ;; Do the conversion only post-reload to avoid limiting of the register class
8226 ;; to QI regs.
8227 (define_split
8228   [(set (match_operand 0 "flags_reg_operand" "")
8229         (match_operator 1 "compare_operator"
8230           [(and (match_operand 2 "register_operand" "")
8231                 (match_operand 3 "const_int_operand" ""))
8232            (const_int 0)]))]
8233    "reload_completed
8234     && QI_REG_P (operands[2])
8235     && GET_MODE (operands[2]) != QImode
8236     && ((ix86_match_ccmode (insn, CCZmode)
8237          && !(INTVAL (operands[3]) & ~(255 << 8)))
8238         || (ix86_match_ccmode (insn, CCNOmode)
8239             && !(INTVAL (operands[3]) & ~(127 << 8))))"
8240   [(set (match_dup 0)
8241         (match_op_dup 1
8242           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8243                    (match_dup 3))
8244            (const_int 0)]))]
8245   "operands[2] = gen_lowpart (SImode, operands[2]);
8246    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8247
8248 (define_split
8249   [(set (match_operand 0 "flags_reg_operand" "")
8250         (match_operator 1 "compare_operator"
8251           [(and (match_operand 2 "nonimmediate_operand" "")
8252                 (match_operand 3 "const_int_operand" ""))
8253            (const_int 0)]))]
8254    "reload_completed
8255     && GET_MODE (operands[2]) != QImode
8256     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8257     && ((ix86_match_ccmode (insn, CCZmode)
8258          && !(INTVAL (operands[3]) & ~255))
8259         || (ix86_match_ccmode (insn, CCNOmode)
8260             && !(INTVAL (operands[3]) & ~127)))"
8261   [(set (match_dup 0)
8262         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8263                          (const_int 0)]))]
8264   "operands[2] = gen_lowpart (QImode, operands[2]);
8265    operands[3] = gen_lowpart (QImode, operands[3]);")
8266
8267 ;; %%% This used to optimize known byte-wide and operations to memory,
8268 ;; and sometimes to QImode registers.  If this is considered useful,
8269 ;; it should be done with splitters.
8270
8271 (define_expand "and<mode>3"
8272   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8273         (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8274                   (match_operand:SWIM 2 "<general_szext_operand>" "")))]
8275   ""
8276   "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
8277
8278 (define_insn "*anddi_1"
8279   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8280         (and:DI
8281          (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8282          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8283    (clobber (reg:CC FLAGS_REG))]
8284   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8285 {
8286   switch (get_attr_type (insn))
8287     {
8288     case TYPE_IMOVX:
8289       {
8290         enum machine_mode mode;
8291
8292         gcc_assert (CONST_INT_P (operands[2]));
8293         if (INTVAL (operands[2]) == 0xff)
8294           mode = QImode;
8295         else
8296           {
8297             gcc_assert (INTVAL (operands[2]) == 0xffff);
8298             mode = HImode;
8299           }
8300
8301         operands[1] = gen_lowpart (mode, operands[1]);
8302         if (mode == QImode)
8303           return "movz{bl|x}\t{%1, %k0|%k0, %1}";
8304         else
8305           return "movz{wl|x}\t{%1, %k0|%k0, %1}";
8306       }
8307
8308     default:
8309       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8310       if (get_attr_mode (insn) == MODE_SI)
8311         return "and{l}\t{%k2, %k0|%k0, %k2}";
8312       else
8313         return "and{q}\t{%2, %0|%0, %2}";
8314     }
8315 }
8316   [(set_attr "type" "alu,alu,alu,imovx")
8317    (set_attr "length_immediate" "*,*,*,0")
8318    (set (attr "prefix_rex")
8319      (if_then_else
8320        (and (eq_attr "type" "imovx")
8321             (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
8322                  (match_operand 1 "ext_QIreg_nomode_operand" "")))
8323        (const_string "1")
8324        (const_string "*")))
8325    (set_attr "mode" "SI,DI,DI,SI")])
8326
8327 (define_insn "*andsi_1"
8328   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8329         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8330                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8331    (clobber (reg:CC FLAGS_REG))]
8332   "ix86_binary_operator_ok (AND, SImode, operands)"
8333 {
8334   switch (get_attr_type (insn))
8335     {
8336     case TYPE_IMOVX:
8337       {
8338         enum machine_mode mode;
8339
8340         gcc_assert (CONST_INT_P (operands[2]));
8341         if (INTVAL (operands[2]) == 0xff)
8342           mode = QImode;
8343         else
8344           {
8345             gcc_assert (INTVAL (operands[2]) == 0xffff);
8346             mode = HImode;
8347           }
8348
8349         operands[1] = gen_lowpart (mode, operands[1]);
8350         if (mode == QImode)
8351           return "movz{bl|x}\t{%1, %0|%0, %1}";
8352         else
8353           return "movz{wl|x}\t{%1, %0|%0, %1}";
8354       }
8355
8356     default:
8357       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8358       return "and{l}\t{%2, %0|%0, %2}";
8359     }
8360 }
8361   [(set_attr "type" "alu,alu,imovx")
8362    (set (attr "prefix_rex")
8363      (if_then_else
8364        (and (eq_attr "type" "imovx")
8365             (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
8366                  (match_operand 1 "ext_QIreg_nomode_operand" "")))
8367        (const_string "1")
8368        (const_string "*")))
8369    (set_attr "length_immediate" "*,*,0")
8370    (set_attr "mode" "SI")])
8371
8372 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8373 (define_insn "*andsi_1_zext"
8374   [(set (match_operand:DI 0 "register_operand" "=r")
8375         (zero_extend:DI
8376           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8377                   (match_operand:SI 2 "general_operand" "g"))))
8378    (clobber (reg:CC FLAGS_REG))]
8379   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8380   "and{l}\t{%2, %k0|%k0, %2}"
8381   [(set_attr "type" "alu")
8382    (set_attr "mode" "SI")])
8383
8384 (define_insn "*andhi_1"
8385   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8386         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8387                 (match_operand:HI 2 "general_operand" "rn,rm,L")))
8388    (clobber (reg:CC FLAGS_REG))]
8389   "ix86_binary_operator_ok (AND, HImode, operands)"
8390 {
8391   switch (get_attr_type (insn))
8392     {
8393     case TYPE_IMOVX:
8394       gcc_assert (CONST_INT_P (operands[2]));
8395       gcc_assert (INTVAL (operands[2]) == 0xff);
8396       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8397
8398     default:
8399       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8400
8401       return "and{w}\t{%2, %0|%0, %2}";
8402     }
8403 }
8404   [(set_attr "type" "alu,alu,imovx")
8405    (set_attr "length_immediate" "*,*,0")
8406    (set (attr "prefix_rex")
8407      (if_then_else
8408        (and (eq_attr "type" "imovx")
8409             (match_operand 1 "ext_QIreg_nomode_operand" ""))
8410        (const_string "1")
8411        (const_string "*")))
8412    (set_attr "mode" "HI,HI,SI")])
8413
8414 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8415 (define_insn "*andqi_1"
8416   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8417         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8418                 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
8419    (clobber (reg:CC FLAGS_REG))]
8420   "ix86_binary_operator_ok (AND, QImode, operands)"
8421   "@
8422    and{b}\t{%2, %0|%0, %2}
8423    and{b}\t{%2, %0|%0, %2}
8424    and{l}\t{%k2, %k0|%k0, %k2}"
8425   [(set_attr "type" "alu")
8426    (set_attr "mode" "QI,QI,SI")])
8427
8428 (define_insn "*andqi_1_slp"
8429   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8430         (and:QI (match_dup 0)
8431                 (match_operand:QI 1 "general_operand" "qn,qmn")))
8432    (clobber (reg:CC FLAGS_REG))]
8433   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8434    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8435   "and{b}\t{%1, %0|%0, %1}"
8436   [(set_attr "type" "alu1")
8437    (set_attr "mode" "QI")])
8438
8439 (define_split
8440   [(set (match_operand 0 "register_operand" "")
8441         (and (match_dup 0)
8442              (const_int -65536)))
8443    (clobber (reg:CC FLAGS_REG))]
8444   "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
8445     || optimize_function_for_size_p (cfun)"
8446   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8447   "operands[1] = gen_lowpart (HImode, operands[0]);")
8448
8449 (define_split
8450   [(set (match_operand 0 "ext_register_operand" "")
8451         (and (match_dup 0)
8452              (const_int -256)))
8453    (clobber (reg:CC FLAGS_REG))]
8454   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8455    && reload_completed"
8456   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8457   "operands[1] = gen_lowpart (QImode, operands[0]);")
8458
8459 (define_split
8460   [(set (match_operand 0 "ext_register_operand" "")
8461         (and (match_dup 0)
8462              (const_int -65281)))
8463    (clobber (reg:CC FLAGS_REG))]
8464   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8465    && reload_completed"
8466   [(parallel [(set (zero_extract:SI (match_dup 0)
8467                                     (const_int 8)
8468                                     (const_int 8))
8469                    (xor:SI
8470                      (zero_extract:SI (match_dup 0)
8471                                       (const_int 8)
8472                                       (const_int 8))
8473                      (zero_extract:SI (match_dup 0)
8474                                       (const_int 8)
8475                                       (const_int 8))))
8476               (clobber (reg:CC FLAGS_REG))])]
8477   "operands[0] = gen_lowpart (SImode, operands[0]);")
8478
8479 (define_insn "*anddi_2"
8480   [(set (reg FLAGS_REG)
8481         (compare
8482          (and:DI
8483           (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8484           (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8485          (const_int 0)))
8486    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8487         (and:DI (match_dup 1) (match_dup 2)))]
8488   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8489    && ix86_binary_operator_ok (AND, DImode, operands)"
8490   "@
8491    and{l}\t{%k2, %k0|%k0, %k2}
8492    and{q}\t{%2, %0|%0, %2}
8493    and{q}\t{%2, %0|%0, %2}"
8494   [(set_attr "type" "alu")
8495    (set_attr "mode" "SI,DI,DI")])
8496
8497 (define_insn "*andqi_2_maybe_si"
8498   [(set (reg FLAGS_REG)
8499         (compare (and:QI
8500                   (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8501                   (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8502                  (const_int 0)))
8503    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8504         (and:QI (match_dup 1) (match_dup 2)))]
8505   "ix86_binary_operator_ok (AND, QImode, operands)
8506    && ix86_match_ccmode (insn,
8507                          CONST_INT_P (operands[2])
8508                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8509 {
8510   if (which_alternative == 2)
8511     {
8512       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8513         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8514       return "and{l}\t{%2, %k0|%k0, %2}";
8515     }
8516   return "and{b}\t{%2, %0|%0, %2}";
8517 }
8518   [(set_attr "type" "alu")
8519    (set_attr "mode" "QI,QI,SI")])
8520
8521 (define_insn "*and<mode>_2"
8522   [(set (reg FLAGS_REG)
8523         (compare (and:SWI124
8524                   (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8525                   (match_operand:SWI124 2 "general_operand" "<g>,<r><i>"))
8526                  (const_int 0)))
8527    (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8528         (and:SWI124 (match_dup 1) (match_dup 2)))]
8529   "ix86_match_ccmode (insn, CCNOmode)
8530    && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8531   "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8532   [(set_attr "type" "alu")
8533    (set_attr "mode" "<MODE>")])
8534
8535 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8536 (define_insn "*andsi_2_zext"
8537   [(set (reg FLAGS_REG)
8538         (compare (and:SI
8539                   (match_operand:SI 1 "nonimmediate_operand" "%0")
8540                   (match_operand:SI 2 "general_operand" "g"))
8541                  (const_int 0)))
8542    (set (match_operand:DI 0 "register_operand" "=r")
8543         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8544   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8545    && ix86_binary_operator_ok (AND, SImode, operands)"
8546   "and{l}\t{%2, %k0|%k0, %2}"
8547   [(set_attr "type" "alu")
8548    (set_attr "mode" "SI")])
8549
8550 (define_insn "*andqi_2_slp"
8551   [(set (reg FLAGS_REG)
8552         (compare (and:QI
8553                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8554                    (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8555                  (const_int 0)))
8556    (set (strict_low_part (match_dup 0))
8557         (and:QI (match_dup 0) (match_dup 1)))]
8558   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8559    && ix86_match_ccmode (insn, CCNOmode)
8560    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8561   "and{b}\t{%1, %0|%0, %1}"
8562   [(set_attr "type" "alu1")
8563    (set_attr "mode" "QI")])
8564
8565 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8566 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8567 ;; for a QImode operand, which of course failed.
8568 (define_insn "andqi_ext_0"
8569   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8570                          (const_int 8)
8571                          (const_int 8))
8572         (and:SI
8573           (zero_extract:SI
8574             (match_operand 1 "ext_register_operand" "0")
8575             (const_int 8)
8576             (const_int 8))
8577           (match_operand 2 "const_int_operand" "n")))
8578    (clobber (reg:CC FLAGS_REG))]
8579   ""
8580   "and{b}\t{%2, %h0|%h0, %2}"
8581   [(set_attr "type" "alu")
8582    (set_attr "length_immediate" "1")
8583    (set_attr "modrm" "1")
8584    (set_attr "mode" "QI")])
8585
8586 ;; Generated by peephole translating test to and.  This shows up
8587 ;; often in fp comparisons.
8588 (define_insn "*andqi_ext_0_cc"
8589   [(set (reg FLAGS_REG)
8590         (compare
8591           (and:SI
8592             (zero_extract:SI
8593               (match_operand 1 "ext_register_operand" "0")
8594               (const_int 8)
8595               (const_int 8))
8596             (match_operand 2 "const_int_operand" "n"))
8597           (const_int 0)))
8598    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8599                          (const_int 8)
8600                          (const_int 8))
8601         (and:SI
8602           (zero_extract:SI
8603             (match_dup 1)
8604             (const_int 8)
8605             (const_int 8))
8606           (match_dup 2)))]
8607   "ix86_match_ccmode (insn, CCNOmode)"
8608   "and{b}\t{%2, %h0|%h0, %2}"
8609   [(set_attr "type" "alu")
8610    (set_attr "length_immediate" "1")
8611    (set_attr "modrm" "1")
8612    (set_attr "mode" "QI")])
8613
8614 (define_insn "*andqi_ext_1_rex64"
8615   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8616                          (const_int 8)
8617                          (const_int 8))
8618         (and:SI
8619           (zero_extract:SI
8620             (match_operand 1 "ext_register_operand" "0")
8621             (const_int 8)
8622             (const_int 8))
8623           (zero_extend:SI
8624             (match_operand 2 "ext_register_operand" "Q"))))
8625    (clobber (reg:CC FLAGS_REG))]
8626   "TARGET_64BIT"
8627   "and{b}\t{%2, %h0|%h0, %2}"
8628   [(set_attr "type" "alu")
8629    (set_attr "length_immediate" "0")
8630    (set_attr "mode" "QI")])
8631
8632 (define_insn "*andqi_ext_1"
8633   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8634                          (const_int 8)
8635                          (const_int 8))
8636         (and:SI
8637           (zero_extract:SI
8638             (match_operand 1 "ext_register_operand" "0")
8639             (const_int 8)
8640             (const_int 8))
8641           (zero_extend:SI
8642             (match_operand:QI 2 "general_operand" "Qm"))))
8643    (clobber (reg:CC FLAGS_REG))]
8644   "!TARGET_64BIT"
8645   "and{b}\t{%2, %h0|%h0, %2}"
8646   [(set_attr "type" "alu")
8647    (set_attr "length_immediate" "0")
8648    (set_attr "mode" "QI")])
8649
8650 (define_insn "*andqi_ext_2"
8651   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8652                          (const_int 8)
8653                          (const_int 8))
8654         (and:SI
8655           (zero_extract:SI
8656             (match_operand 1 "ext_register_operand" "%0")
8657             (const_int 8)
8658             (const_int 8))
8659           (zero_extract:SI
8660             (match_operand 2 "ext_register_operand" "Q")
8661             (const_int 8)
8662             (const_int 8))))
8663    (clobber (reg:CC FLAGS_REG))]
8664   ""
8665   "and{b}\t{%h2, %h0|%h0, %h2}"
8666   [(set_attr "type" "alu")
8667    (set_attr "length_immediate" "0")
8668    (set_attr "mode" "QI")])
8669
8670 ;; Convert wide AND instructions with immediate operand to shorter QImode
8671 ;; equivalents when possible.
8672 ;; Don't do the splitting with memory operands, since it introduces risk
8673 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8674 ;; for size, but that can (should?) be handled by generic code instead.
8675 (define_split
8676   [(set (match_operand 0 "register_operand" "")
8677         (and (match_operand 1 "register_operand" "")
8678              (match_operand 2 "const_int_operand" "")))
8679    (clobber (reg:CC FLAGS_REG))]
8680    "reload_completed
8681     && QI_REG_P (operands[0])
8682     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8683     && !(~INTVAL (operands[2]) & ~(255 << 8))
8684     && GET_MODE (operands[0]) != QImode"
8685   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8686                    (and:SI (zero_extract:SI (match_dup 1)
8687                                             (const_int 8) (const_int 8))
8688                            (match_dup 2)))
8689               (clobber (reg:CC FLAGS_REG))])]
8690   "operands[0] = gen_lowpart (SImode, operands[0]);
8691    operands[1] = gen_lowpart (SImode, operands[1]);
8692    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8693
8694 ;; Since AND can be encoded with sign extended immediate, this is only
8695 ;; profitable when 7th bit is not set.
8696 (define_split
8697   [(set (match_operand 0 "register_operand" "")
8698         (and (match_operand 1 "general_operand" "")
8699              (match_operand 2 "const_int_operand" "")))
8700    (clobber (reg:CC FLAGS_REG))]
8701    "reload_completed
8702     && ANY_QI_REG_P (operands[0])
8703     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8704     && !(~INTVAL (operands[2]) & ~255)
8705     && !(INTVAL (operands[2]) & 128)
8706     && GET_MODE (operands[0]) != QImode"
8707   [(parallel [(set (strict_low_part (match_dup 0))
8708                    (and:QI (match_dup 1)
8709                            (match_dup 2)))
8710               (clobber (reg:CC FLAGS_REG))])]
8711   "operands[0] = gen_lowpart (QImode, operands[0]);
8712    operands[1] = gen_lowpart (QImode, operands[1]);
8713    operands[2] = gen_lowpart (QImode, operands[2]);")
8714 \f
8715 ;; Logical inclusive and exclusive OR instructions
8716
8717 ;; %%% This used to optimize known byte-wide and operations to memory.
8718 ;; If this is considered useful, it should be done with splitters.
8719
8720 (define_expand "<code><mode>3"
8721   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8722         (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8723                      (match_operand:SWIM 2 "<general_operand>" "")))]
8724   ""
8725   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8726
8727 (define_insn "*<code><mode>_1"
8728   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8729         (any_or:SWI248
8730          (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8731          (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8732    (clobber (reg:CC FLAGS_REG))]
8733   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8734   "<logicprefix>{<imodesuffix>}\t{%2, %0|%0, %2}"
8735   [(set_attr "type" "alu")
8736    (set_attr "mode" "<MODE>")])
8737
8738 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8739 (define_insn "*<code>qi_1"
8740   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8741         (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8742                    (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8743    (clobber (reg:CC FLAGS_REG))]
8744   "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8745   "@
8746    <logicprefix>{b}\t{%2, %0|%0, %2}
8747    <logicprefix>{b}\t{%2, %0|%0, %2}
8748    <logicprefix>{l}\t{%k2, %k0|%k0, %k2}"
8749   [(set_attr "type" "alu")
8750    (set_attr "mode" "QI,QI,SI")])
8751
8752 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8753 (define_insn "*<code>si_1_zext"
8754   [(set (match_operand:DI 0 "register_operand" "=r")
8755         (zero_extend:DI
8756          (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8757                     (match_operand:SI 2 "general_operand" "g"))))
8758    (clobber (reg:CC FLAGS_REG))]
8759   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8760   "<logicprefix>{l}\t{%2, %k0|%k0, %2}"
8761   [(set_attr "type" "alu")
8762    (set_attr "mode" "SI")])
8763
8764 (define_insn "*<code>si_1_zext_imm"
8765   [(set (match_operand:DI 0 "register_operand" "=r")
8766         (any_or:DI
8767          (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8768          (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8769    (clobber (reg:CC FLAGS_REG))]
8770   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8771   "<logicprefix>{l}\t{%2, %k0|%k0, %2}"
8772   [(set_attr "type" "alu")
8773    (set_attr "mode" "SI")])
8774
8775 (define_insn "*<code>qi_1_slp"
8776   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8777         (any_or:QI (match_dup 0)
8778                    (match_operand:QI 1 "general_operand" "qmn,qn")))
8779    (clobber (reg:CC FLAGS_REG))]
8780   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8781    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8782   "<logicprefix>{b}\t{%1, %0|%0, %1}"
8783   [(set_attr "type" "alu1")
8784    (set_attr "mode" "QI")])
8785
8786 (define_insn "*<code><mode>_2"
8787   [(set (reg FLAGS_REG)
8788         (compare (any_or:SWI
8789                   (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8790                   (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8791                  (const_int 0)))
8792    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8793         (any_or:SWI (match_dup 1) (match_dup 2)))]
8794   "ix86_match_ccmode (insn, CCNOmode)
8795    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8796   "<logicprefix>{<imodesuffix>}\t{%2, %0|%0, %2}"
8797   [(set_attr "type" "alu")
8798    (set_attr "mode" "<MODE>")])
8799
8800 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8801 ;; ??? Special case for immediate operand is missing - it is tricky.
8802 (define_insn "*<code>si_2_zext"
8803   [(set (reg FLAGS_REG)
8804         (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8805                             (match_operand:SI 2 "general_operand" "g"))
8806                  (const_int 0)))
8807    (set (match_operand:DI 0 "register_operand" "=r")
8808         (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8809   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8810    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8811   "<logicprefix>{l}\t{%2, %k0|%k0, %2}"
8812   [(set_attr "type" "alu")
8813    (set_attr "mode" "SI")])
8814
8815 (define_insn "*<code>si_2_zext_imm"
8816   [(set (reg FLAGS_REG)
8817         (compare (any_or:SI
8818                   (match_operand:SI 1 "nonimmediate_operand" "%0")
8819                   (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8820                  (const_int 0)))
8821    (set (match_operand:DI 0 "register_operand" "=r")
8822         (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8823   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8824    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8825   "<logicprefix>{l}\t{%2, %k0|%k0, %2}"
8826   [(set_attr "type" "alu")
8827    (set_attr "mode" "SI")])
8828
8829 (define_insn "*<code>qi_2_slp"
8830   [(set (reg FLAGS_REG)
8831         (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8832                             (match_operand:QI 1 "general_operand" "qmn,qn"))
8833                  (const_int 0)))
8834    (set (strict_low_part (match_dup 0))
8835         (any_or:QI (match_dup 0) (match_dup 1)))]
8836   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8837    && ix86_match_ccmode (insn, CCNOmode)
8838    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8839   "<logicprefix>{b}\t{%1, %0|%0, %1}"
8840   [(set_attr "type" "alu1")
8841    (set_attr "mode" "QI")])
8842
8843 (define_insn "*<code><mode>_3"
8844   [(set (reg FLAGS_REG)
8845         (compare (any_or:SWI
8846                   (match_operand:SWI 1 "nonimmediate_operand" "%0")
8847                   (match_operand:SWI 2 "<general_operand>" "<g>"))
8848                  (const_int 0)))
8849    (clobber (match_scratch:SWI 0 "=<r>"))]
8850   "ix86_match_ccmode (insn, CCNOmode)
8851    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8852   "<logicprefix>{<imodesuffix>}\t{%2, %0|%0, %2}"
8853   [(set_attr "type" "alu")
8854    (set_attr "mode" "<MODE>")])
8855
8856 (define_insn "*<code>qi_ext_0"
8857   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8858                          (const_int 8)
8859                          (const_int 8))
8860         (any_or:SI
8861           (zero_extract:SI
8862             (match_operand 1 "ext_register_operand" "0")
8863             (const_int 8)
8864             (const_int 8))
8865           (match_operand 2 "const_int_operand" "n")))
8866    (clobber (reg:CC FLAGS_REG))]
8867   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8868   "<logicprefix>{b}\t{%2, %h0|%h0, %2}"
8869   [(set_attr "type" "alu")
8870    (set_attr "length_immediate" "1")
8871    (set_attr "modrm" "1")
8872    (set_attr "mode" "QI")])
8873
8874 (define_insn "*<code>qi_ext_1_rex64"
8875   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8876                          (const_int 8)
8877                          (const_int 8))
8878         (any_or:SI
8879           (zero_extract:SI
8880             (match_operand 1 "ext_register_operand" "0")
8881             (const_int 8)
8882             (const_int 8))
8883           (zero_extend:SI
8884             (match_operand 2 "ext_register_operand" "Q"))))
8885    (clobber (reg:CC FLAGS_REG))]
8886   "TARGET_64BIT
8887    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8888   "<logicprefix>{b}\t{%2, %h0|%h0, %2}"
8889   [(set_attr "type" "alu")
8890    (set_attr "length_immediate" "0")
8891    (set_attr "mode" "QI")])
8892
8893 (define_insn "*<code>qi_ext_1"
8894   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8895                          (const_int 8)
8896                          (const_int 8))
8897         (any_or:SI
8898           (zero_extract:SI
8899             (match_operand 1 "ext_register_operand" "0")
8900             (const_int 8)
8901             (const_int 8))
8902           (zero_extend:SI
8903             (match_operand:QI 2 "general_operand" "Qm"))))
8904    (clobber (reg:CC FLAGS_REG))]
8905   "!TARGET_64BIT
8906    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8907   "<logicprefix>{b}\t{%2, %h0|%h0, %2}"
8908   [(set_attr "type" "alu")
8909    (set_attr "length_immediate" "0")
8910    (set_attr "mode" "QI")])
8911
8912 (define_insn "*<code>qi_ext_2"
8913   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8914                          (const_int 8)
8915                          (const_int 8))
8916         (any_or:SI
8917           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8918                            (const_int 8)
8919                            (const_int 8))
8920           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8921                            (const_int 8)
8922                            (const_int 8))))
8923    (clobber (reg:CC FLAGS_REG))]
8924   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8925   "<logicprefix>{b}\t{%h2, %h0|%h0, %h2}"
8926   [(set_attr "type" "alu")
8927    (set_attr "length_immediate" "0")
8928    (set_attr "mode" "QI")])
8929
8930 (define_split
8931   [(set (match_operand 0 "register_operand" "")
8932         (any_or (match_operand 1 "register_operand" "")
8933                 (match_operand 2 "const_int_operand" "")))
8934    (clobber (reg:CC FLAGS_REG))]
8935    "reload_completed
8936     && QI_REG_P (operands[0])
8937     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8938     && !(INTVAL (operands[2]) & ~(255 << 8))
8939     && GET_MODE (operands[0]) != QImode"
8940   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8941                    (any_or:SI (zero_extract:SI (match_dup 1)
8942                                                (const_int 8) (const_int 8))
8943                               (match_dup 2)))
8944               (clobber (reg:CC FLAGS_REG))])]
8945   "operands[0] = gen_lowpart (SImode, operands[0]);
8946    operands[1] = gen_lowpart (SImode, operands[1]);
8947    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8948
8949 ;; Since OR can be encoded with sign extended immediate, this is only
8950 ;; profitable when 7th bit is set.
8951 (define_split
8952   [(set (match_operand 0 "register_operand" "")
8953         (any_or (match_operand 1 "general_operand" "")
8954                 (match_operand 2 "const_int_operand" "")))
8955    (clobber (reg:CC FLAGS_REG))]
8956    "reload_completed
8957     && ANY_QI_REG_P (operands[0])
8958     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8959     && !(INTVAL (operands[2]) & ~255)
8960     && (INTVAL (operands[2]) & 128)
8961     && GET_MODE (operands[0]) != QImode"
8962   [(parallel [(set (strict_low_part (match_dup 0))
8963                    (any_or:QI (match_dup 1)
8964                               (match_dup 2)))
8965               (clobber (reg:CC FLAGS_REG))])]
8966   "operands[0] = gen_lowpart (QImode, operands[0]);
8967    operands[1] = gen_lowpart (QImode, operands[1]);
8968    operands[2] = gen_lowpart (QImode, operands[2]);")
8969
8970 (define_expand "xorqi_cc_ext_1"
8971   [(parallel [
8972      (set (reg:CCNO FLAGS_REG)
8973           (compare:CCNO
8974             (xor:SI
8975               (zero_extract:SI
8976                 (match_operand 1 "ext_register_operand" "")
8977                 (const_int 8)
8978                 (const_int 8))
8979               (match_operand:QI 2 "general_operand" ""))
8980             (const_int 0)))
8981      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8982                            (const_int 8)
8983                            (const_int 8))
8984           (xor:SI
8985             (zero_extract:SI
8986              (match_dup 1)
8987              (const_int 8)
8988              (const_int 8))
8989             (match_dup 2)))])]
8990   ""
8991   "")
8992
8993 (define_insn "*xorqi_cc_ext_1_rex64"
8994   [(set (reg FLAGS_REG)
8995         (compare
8996           (xor:SI
8997             (zero_extract:SI
8998               (match_operand 1 "ext_register_operand" "0")
8999               (const_int 8)
9000               (const_int 8))
9001             (match_operand:QI 2 "nonmemory_operand" "Qn"))
9002           (const_int 0)))
9003    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9004                          (const_int 8)
9005                          (const_int 8))
9006         (xor:SI
9007           (zero_extract:SI
9008            (match_dup 1)
9009            (const_int 8)
9010            (const_int 8))
9011           (match_dup 2)))]
9012   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9013   "xor{b}\t{%2, %h0|%h0, %2}"
9014   [(set_attr "type" "alu")
9015    (set_attr "modrm" "1")
9016    (set_attr "mode" "QI")])
9017
9018 (define_insn "*xorqi_cc_ext_1"
9019   [(set (reg FLAGS_REG)
9020         (compare
9021           (xor:SI
9022             (zero_extract:SI
9023               (match_operand 1 "ext_register_operand" "0")
9024               (const_int 8)
9025               (const_int 8))
9026             (match_operand:QI 2 "general_operand" "qmn"))
9027           (const_int 0)))
9028    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9029                          (const_int 8)
9030                          (const_int 8))
9031         (xor:SI
9032           (zero_extract:SI
9033            (match_dup 1)
9034            (const_int 8)
9035            (const_int 8))
9036           (match_dup 2)))]
9037   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9038   "xor{b}\t{%2, %h0|%h0, %2}"
9039   [(set_attr "type" "alu")
9040    (set_attr "modrm" "1")
9041    (set_attr "mode" "QI")])
9042 \f
9043 ;; Negation instructions
9044
9045 (define_expand "neg<mode>2"
9046   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
9047         (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
9048   ""
9049   "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
9050
9051 (define_insn_and_split "*neg<dwi>2_doubleword"
9052   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
9053         (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
9054    (clobber (reg:CC FLAGS_REG))]
9055   "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
9056   "#"
9057   "reload_completed"
9058   [(parallel
9059     [(set (reg:CCZ FLAGS_REG)
9060           (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
9061      (set (match_dup 0) (neg:DWIH (match_dup 1)))])
9062    (parallel
9063     [(set (match_dup 2)
9064           (plus:DWIH (match_dup 3)
9065                      (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
9066                                 (const_int 0))))
9067      (clobber (reg:CC FLAGS_REG))])
9068    (parallel
9069     [(set (match_dup 2)
9070           (neg:DWIH (match_dup 2)))
9071      (clobber (reg:CC FLAGS_REG))])]
9072   "split_<dwi> (&operands[0], 2, &operands[0], &operands[2]);")
9073
9074 (define_insn "*neg<mode>2_1"
9075   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9076         (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
9077    (clobber (reg:CC FLAGS_REG))]
9078   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9079   "neg{<imodesuffix>}\t%0"
9080   [(set_attr "type" "negnot")
9081    (set_attr "mode" "<MODE>")])
9082
9083 ;; Combine is quite creative about this pattern.
9084 (define_insn "*negsi2_1_zext"
9085   [(set (match_operand:DI 0 "register_operand" "=r")
9086         (lshiftrt:DI
9087           (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9088                              (const_int 32)))
9089         (const_int 32)))
9090    (clobber (reg:CC FLAGS_REG))]
9091   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9092   "neg{l}\t%k0"
9093   [(set_attr "type" "negnot")
9094    (set_attr "mode" "SI")])
9095
9096 ;; The problem with neg is that it does not perform (compare x 0),
9097 ;; it really performs (compare 0 x), which leaves us with the zero
9098 ;; flag being the only useful item.
9099
9100 (define_insn "*neg<mode>2_cmpz"
9101   [(set (reg:CCZ FLAGS_REG)
9102         (compare:CCZ
9103           (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9104                    (const_int 0)))
9105    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9106         (neg:SWI (match_dup 1)))]
9107   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9108   "neg{<imodesuffix>}\t%0"
9109   [(set_attr "type" "negnot")
9110    (set_attr "mode" "<MODE>")])
9111
9112 (define_insn "*negsi2_cmpz_zext"
9113   [(set (reg:CCZ FLAGS_REG)
9114         (compare:CCZ
9115           (lshiftrt:DI
9116             (neg:DI (ashift:DI
9117                       (match_operand:DI 1 "register_operand" "0")
9118                       (const_int 32)))
9119             (const_int 32))
9120           (const_int 0)))
9121    (set (match_operand:DI 0 "register_operand" "=r")
9122         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9123                                         (const_int 32)))
9124                      (const_int 32)))]
9125   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9126   "neg{l}\t%k0"
9127   [(set_attr "type" "negnot")
9128    (set_attr "mode" "SI")])
9129
9130 ;; Changing of sign for FP values is doable using integer unit too.
9131
9132 (define_expand "<code><mode>2"
9133   [(set (match_operand:X87MODEF 0 "register_operand" "")
9134         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
9135   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9136   "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
9137
9138 (define_insn "*absneg<mode>2_mixed"
9139   [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
9140         (match_operator:MODEF 3 "absneg_operator"
9141           [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
9142    (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
9143    (clobber (reg:CC FLAGS_REG))]
9144   "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
9145   "#")
9146
9147 (define_insn "*absneg<mode>2_sse"
9148   [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
9149         (match_operator:MODEF 3 "absneg_operator"
9150           [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
9151    (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
9152    (clobber (reg:CC FLAGS_REG))]
9153   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
9154   "#")
9155
9156 (define_insn "*absneg<mode>2_i387"
9157   [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
9158         (match_operator:X87MODEF 3 "absneg_operator"
9159           [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
9160    (use (match_operand 2 "" ""))
9161    (clobber (reg:CC FLAGS_REG))]
9162   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9163   "#")
9164
9165 (define_expand "<code>tf2"
9166   [(set (match_operand:TF 0 "register_operand" "")
9167         (absneg:TF (match_operand:TF 1 "register_operand" "")))]
9168   "TARGET_SSE2"
9169   "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
9170
9171 (define_insn "*absnegtf2_sse"
9172   [(set (match_operand:TF 0 "register_operand" "=x,x")
9173         (match_operator:TF 3 "absneg_operator"
9174           [(match_operand:TF 1 "register_operand" "0,x")]))
9175    (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
9176    (clobber (reg:CC FLAGS_REG))]
9177   "TARGET_SSE2"
9178   "#")
9179
9180 ;; Splitters for fp abs and neg.
9181
9182 (define_split
9183   [(set (match_operand 0 "fp_register_operand" "")
9184         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9185    (use (match_operand 2 "" ""))
9186    (clobber (reg:CC FLAGS_REG))]
9187   "reload_completed"
9188   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9189
9190 (define_split
9191   [(set (match_operand 0 "register_operand" "")
9192         (match_operator 3 "absneg_operator"
9193           [(match_operand 1 "register_operand" "")]))
9194    (use (match_operand 2 "nonimmediate_operand" ""))
9195    (clobber (reg:CC FLAGS_REG))]
9196   "reload_completed && SSE_REG_P (operands[0])"
9197   [(set (match_dup 0) (match_dup 3))]
9198 {
9199   enum machine_mode mode = GET_MODE (operands[0]);
9200   enum machine_mode vmode = GET_MODE (operands[2]);
9201   rtx tmp;
9202
9203   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9204   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9205   if (operands_match_p (operands[0], operands[2]))
9206     {
9207       tmp = operands[1];
9208       operands[1] = operands[2];
9209       operands[2] = tmp;
9210     }
9211   if (GET_CODE (operands[3]) == ABS)
9212     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9213   else
9214     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9215   operands[3] = tmp;
9216 })
9217
9218 (define_split
9219   [(set (match_operand:SF 0 "register_operand" "")
9220         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9221    (use (match_operand:V4SF 2 "" ""))
9222    (clobber (reg:CC FLAGS_REG))]
9223   "reload_completed"
9224   [(parallel [(set (match_dup 0) (match_dup 1))
9225               (clobber (reg:CC FLAGS_REG))])]
9226 {
9227   rtx tmp;
9228   operands[0] = gen_lowpart (SImode, operands[0]);
9229   if (GET_CODE (operands[1]) == ABS)
9230     {
9231       tmp = gen_int_mode (0x7fffffff, SImode);
9232       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9233     }
9234   else
9235     {
9236       tmp = gen_int_mode (0x80000000, SImode);
9237       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9238     }
9239   operands[1] = tmp;
9240 })
9241
9242 (define_split
9243   [(set (match_operand:DF 0 "register_operand" "")
9244         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9245    (use (match_operand 2 "" ""))
9246    (clobber (reg:CC FLAGS_REG))]
9247   "reload_completed"
9248   [(parallel [(set (match_dup 0) (match_dup 1))
9249               (clobber (reg:CC FLAGS_REG))])]
9250 {
9251   rtx tmp;
9252   if (TARGET_64BIT)
9253     {
9254       tmp = gen_lowpart (DImode, operands[0]);
9255       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9256       operands[0] = tmp;
9257
9258       if (GET_CODE (operands[1]) == ABS)
9259         tmp = const0_rtx;
9260       else
9261         tmp = gen_rtx_NOT (DImode, tmp);
9262     }
9263   else
9264     {
9265       operands[0] = gen_highpart (SImode, operands[0]);
9266       if (GET_CODE (operands[1]) == ABS)
9267         {
9268           tmp = gen_int_mode (0x7fffffff, SImode);
9269           tmp = gen_rtx_AND (SImode, operands[0], tmp);
9270         }
9271       else
9272         {
9273           tmp = gen_int_mode (0x80000000, SImode);
9274           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9275         }
9276     }
9277   operands[1] = tmp;
9278 })
9279
9280 (define_split
9281   [(set (match_operand:XF 0 "register_operand" "")
9282         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9283    (use (match_operand 2 "" ""))
9284    (clobber (reg:CC FLAGS_REG))]
9285   "reload_completed"
9286   [(parallel [(set (match_dup 0) (match_dup 1))
9287               (clobber (reg:CC FLAGS_REG))])]
9288 {
9289   rtx tmp;
9290   operands[0] = gen_rtx_REG (SImode,
9291                              true_regnum (operands[0])
9292                              + (TARGET_64BIT ? 1 : 2));
9293   if (GET_CODE (operands[1]) == ABS)
9294     {
9295       tmp = GEN_INT (0x7fff);
9296       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9297     }
9298   else
9299     {
9300       tmp = GEN_INT (0x8000);
9301       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9302     }
9303   operands[1] = tmp;
9304 })
9305
9306 ;; Conditionalize these after reload. If they match before reload, we
9307 ;; lose the clobber and ability to use integer instructions.
9308
9309 (define_insn "*<code><mode>2_1"
9310   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
9311         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
9312   "TARGET_80387
9313    && (reload_completed
9314        || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
9315   "f<absnegprefix>"
9316   [(set_attr "type" "fsgn")
9317    (set_attr "mode" "<MODE>")])
9318
9319 (define_insn "*<code>extendsfdf2"
9320   [(set (match_operand:DF 0 "register_operand" "=f")
9321         (absneg:DF (float_extend:DF
9322                      (match_operand:SF 1 "register_operand" "0"))))]
9323   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9324   "f<absnegprefix>"
9325   [(set_attr "type" "fsgn")
9326    (set_attr "mode" "DF")])
9327
9328 (define_insn "*<code>extendsfxf2"
9329   [(set (match_operand:XF 0 "register_operand" "=f")
9330         (absneg:XF (float_extend:XF
9331                      (match_operand:SF 1 "register_operand" "0"))))]
9332   "TARGET_80387"
9333   "f<absnegprefix>"
9334   [(set_attr "type" "fsgn")
9335    (set_attr "mode" "XF")])
9336
9337 (define_insn "*<code>extenddfxf2"
9338   [(set (match_operand:XF 0 "register_operand" "=f")
9339         (absneg:XF (float_extend:XF
9340                       (match_operand:DF 1 "register_operand" "0"))))]
9341   "TARGET_80387"
9342   "f<absnegprefix>"
9343   [(set_attr "type" "fsgn")
9344    (set_attr "mode" "XF")])
9345
9346 ;; Copysign instructions
9347
9348 (define_mode_iterator CSGNMODE [SF DF TF])
9349 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
9350
9351 (define_expand "copysign<mode>3"
9352   [(match_operand:CSGNMODE 0 "register_operand" "")
9353    (match_operand:CSGNMODE 1 "nonmemory_operand" "")
9354    (match_operand:CSGNMODE 2 "register_operand" "")]
9355   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9356    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
9357 {
9358   ix86_expand_copysign (operands);
9359   DONE;
9360 })
9361
9362 (define_insn_and_split "copysign<mode>3_const"
9363   [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
9364         (unspec:CSGNMODE
9365           [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
9366            (match_operand:CSGNMODE 2 "register_operand" "0")
9367            (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
9368           UNSPEC_COPYSIGN))]
9369   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9370    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
9371   "#"
9372   "&& reload_completed"
9373   [(const_int 0)]
9374 {
9375   ix86_split_copysign_const (operands);
9376   DONE;
9377 })
9378
9379 (define_insn "copysign<mode>3_var"
9380   [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
9381         (unspec:CSGNMODE
9382           [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
9383            (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
9384            (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
9385            (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
9386           UNSPEC_COPYSIGN))
9387    (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
9388   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9389    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
9390   "#")
9391
9392 (define_split
9393   [(set (match_operand:CSGNMODE 0 "register_operand" "")
9394         (unspec:CSGNMODE
9395           [(match_operand:CSGNMODE 2 "register_operand" "")
9396            (match_operand:CSGNMODE 3 "register_operand" "")
9397            (match_operand:<CSGNVMODE> 4 "" "")
9398            (match_operand:<CSGNVMODE> 5 "" "")]
9399           UNSPEC_COPYSIGN))
9400    (clobber (match_scratch:<CSGNVMODE> 1 ""))]
9401   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9402     || (TARGET_SSE2 && (<MODE>mode == TFmode)))
9403    && reload_completed"
9404   [(const_int 0)]
9405 {
9406   ix86_split_copysign_var (operands);
9407   DONE;
9408 })
9409 \f
9410 ;; One complement instructions
9411
9412 (define_expand "one_cmpl<mode>2"
9413   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
9414         (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
9415   ""
9416   "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
9417
9418 (define_insn "*one_cmpl<mode>2_1"
9419   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
9420         (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
9421   "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9422   "not{<imodesuffix>}\t%0"
9423   [(set_attr "type" "negnot")
9424    (set_attr "mode" "<MODE>")])
9425
9426 ;; %%% Potential partial reg stall on alternative 1.  What to do?
9427 (define_insn "*one_cmplqi2_1"
9428   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9429         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
9430   "ix86_unary_operator_ok (NOT, QImode, operands)"
9431   "@
9432    not{b}\t%0
9433    not{l}\t%k0"
9434   [(set_attr "type" "negnot")
9435    (set_attr "mode" "QI,SI")])
9436
9437 ;; ??? Currently never generated - xor is used instead.
9438 (define_insn "*one_cmplsi2_1_zext"
9439   [(set (match_operand:DI 0 "register_operand" "=r")
9440         (zero_extend:DI
9441           (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9442   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9443   "not{l}\t%k0"
9444   [(set_attr "type" "negnot")
9445    (set_attr "mode" "SI")])
9446
9447 (define_insn "*one_cmpl<mode>2_2"
9448   [(set (reg FLAGS_REG)
9449         (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9450                  (const_int 0)))
9451    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9452         (not:SWI (match_dup 1)))]
9453   "ix86_match_ccmode (insn, CCNOmode)
9454    && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9455   "#"
9456   [(set_attr "type" "alu1")
9457    (set_attr "mode" "<MODE>")])
9458
9459 (define_split
9460   [(set (match_operand 0 "flags_reg_operand" "")
9461         (match_operator 2 "compare_operator"
9462           [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
9463            (const_int 0)]))
9464    (set (match_operand:SWI 1 "nonimmediate_operand" "")
9465         (not:SWI (match_dup 3)))]
9466   "ix86_match_ccmode (insn, CCNOmode)"
9467   [(parallel [(set (match_dup 0)
9468                    (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9469                                     (const_int 0)]))
9470               (set (match_dup 1)
9471                    (xor:SWI (match_dup 3) (const_int -1)))])]
9472   "")
9473
9474 ;; ??? Currently never generated - xor is used instead.
9475 (define_insn "*one_cmplsi2_2_zext"
9476   [(set (reg FLAGS_REG)
9477         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9478                  (const_int 0)))
9479    (set (match_operand:DI 0 "register_operand" "=r")
9480         (zero_extend:DI (not:SI (match_dup 1))))]
9481   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9482    && ix86_unary_operator_ok (NOT, SImode, operands)"
9483   "#"
9484   [(set_attr "type" "alu1")
9485    (set_attr "mode" "SI")])
9486
9487 (define_split
9488   [(set (match_operand 0 "flags_reg_operand" "")
9489         (match_operator 2 "compare_operator"
9490           [(not:SI (match_operand:SI 3 "register_operand" ""))
9491            (const_int 0)]))
9492    (set (match_operand:DI 1 "register_operand" "")
9493         (zero_extend:DI (not:SI (match_dup 3))))]
9494   "ix86_match_ccmode (insn, CCNOmode)"
9495   [(parallel [(set (match_dup 0)
9496                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9497                                     (const_int 0)]))
9498               (set (match_dup 1)
9499                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
9500   "")
9501 \f
9502 ;; Arithmetic shift instructions
9503
9504 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9505 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
9506 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9507 ;; from the assembler input.
9508 ;;
9509 ;; This instruction shifts the target reg/mem as usual, but instead of
9510 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
9511 ;; is a left shift double, bits are taken from the high order bits of
9512 ;; reg, else if the insn is a shift right double, bits are taken from the
9513 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
9514 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9515 ;;
9516 ;; Since sh[lr]d does not change the `reg' operand, that is done
9517 ;; separately, making all shifts emit pairs of shift double and normal
9518 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
9519 ;; support a 63 bit shift, each shift where the count is in a reg expands
9520 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9521 ;;
9522 ;; If the shift count is a constant, we need never emit more than one
9523 ;; shift pair, instead using moves and sign extension for counts greater
9524 ;; than 31.
9525
9526 (define_expand "ashlti3"
9527   [(set (match_operand:TI 0 "register_operand" "")
9528         (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "")
9529                    (match_operand:QI 2 "nonmemory_operand" "")))]
9530   "TARGET_64BIT"
9531   "ix86_expand_binary_operator (ASHIFT, TImode, operands); DONE;")
9532
9533 (define_insn "*ashlti3_1"
9534   [(set (match_operand:TI 0 "register_operand" "=&r,r")
9535         (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "n,0")
9536                    (match_operand:QI 2 "nonmemory_operand" "Oc,Oc")))
9537    (clobber (reg:CC FLAGS_REG))]
9538   "TARGET_64BIT"
9539   "#"
9540   [(set_attr "type" "multi")])
9541
9542 (define_peephole2
9543   [(match_scratch:DI 3 "r")
9544    (parallel [(set (match_operand:TI 0 "register_operand" "")
9545                    (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
9546                               (match_operand:QI 2 "nonmemory_operand" "")))
9547               (clobber (reg:CC FLAGS_REG))])
9548    (match_dup 3)]
9549   "TARGET_64BIT"
9550   [(const_int 0)]
9551   "ix86_split_ashl (operands, operands[3], TImode); DONE;")
9552
9553 (define_split
9554   [(set (match_operand:TI 0 "register_operand" "")
9555         (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
9556                    (match_operand:QI 2 "nonmemory_operand" "")))
9557    (clobber (reg:CC FLAGS_REG))]
9558   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
9559                     ? epilogue_completed : reload_completed)"
9560   [(const_int 0)]
9561   "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
9562
9563 (define_insn "x86_64_shld"
9564   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9565         (ior:DI (ashift:DI (match_dup 0)
9566                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
9567                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9568                   (minus:QI (const_int 64) (match_dup 2)))))
9569    (clobber (reg:CC FLAGS_REG))]
9570   "TARGET_64BIT"
9571   "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9572   [(set_attr "type" "ishift")
9573    (set_attr "prefix_0f" "1")
9574    (set_attr "mode" "DI")
9575    (set_attr "athlon_decode" "vector")
9576    (set_attr "amdfam10_decode" "vector")])
9577
9578 (define_expand "x86_64_shift_adj_1"
9579   [(set (reg:CCZ FLAGS_REG)
9580         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
9581                              (const_int 64))
9582                      (const_int 0)))
9583    (set (match_operand:DI 0 "register_operand" "")
9584         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
9585                          (match_operand:DI 1 "register_operand" "")
9586                          (match_dup 0)))
9587    (set (match_dup 1)
9588         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
9589                          (match_operand:DI 3 "register_operand" "r")
9590                          (match_dup 1)))]
9591   "TARGET_64BIT"
9592   "")
9593
9594 (define_expand "x86_64_shift_adj_2"
9595   [(use (match_operand:DI 0 "register_operand" ""))
9596    (use (match_operand:DI 1 "register_operand" ""))
9597    (use (match_operand:QI 2 "register_operand" ""))]
9598   "TARGET_64BIT"
9599 {
9600   rtx label = gen_label_rtx ();
9601   rtx tmp;
9602
9603   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (64)));
9604
9605   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9606   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9607   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9608                               gen_rtx_LABEL_REF (VOIDmode, label),
9609                               pc_rtx);
9610   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9611   JUMP_LABEL (tmp) = label;
9612
9613   emit_move_insn (operands[0], operands[1]);
9614   ix86_expand_clear (operands[1]);
9615
9616   emit_label (label);
9617   LABEL_NUSES (label) = 1;
9618
9619   DONE;
9620 })
9621
9622 (define_expand "ashldi3"
9623   [(set (match_operand:DI 0 "shiftdi_operand" "")
9624         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
9625                    (match_operand:QI 2 "nonmemory_operand" "")))]
9626   ""
9627   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
9628
9629 (define_insn "*ashldi3_1_rex64"
9630   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9631         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
9632                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
9633    (clobber (reg:CC FLAGS_REG))]
9634   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
9635 {
9636   switch (get_attr_type (insn))
9637     {
9638     case TYPE_ALU:
9639       gcc_assert (operands[2] == const1_rtx);
9640       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9641       return "add{q}\t%0, %0";
9642
9643     case TYPE_LEA:
9644       gcc_assert (CONST_INT_P (operands[2]));
9645       gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
9646       operands[1] = gen_rtx_MULT (DImode, operands[1],
9647                                   GEN_INT (1 << INTVAL (operands[2])));
9648       return "lea{q}\t{%a1, %0|%0, %a1}";
9649
9650     default:
9651       if (REG_P (operands[2]))
9652         return "sal{q}\t{%b2, %0|%0, %b2}";
9653       else if (operands[2] == const1_rtx
9654                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9655         return "sal{q}\t%0";
9656       else
9657         return "sal{q}\t{%2, %0|%0, %2}";
9658     }
9659 }
9660   [(set (attr "type")
9661      (cond [(eq_attr "alternative" "1")
9662               (const_string "lea")
9663             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9664                           (const_int 0))
9665                       (match_operand 0 "register_operand" ""))
9666                  (match_operand 2 "const1_operand" ""))
9667               (const_string "alu")
9668            ]
9669            (const_string "ishift")))
9670    (set (attr "length_immediate")
9671      (if_then_else
9672        (ior (eq_attr "type" "alu")
9673             (and (eq_attr "type" "ishift")
9674                  (and (match_operand 2 "const1_operand" "")
9675                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9676                           (const_int 0)))))
9677        (const_string "0")
9678        (const_string "*")))
9679    (set_attr "mode" "DI")])
9680
9681 ;; Convert lea to the lea pattern to avoid flags dependency.
9682 (define_split
9683   [(set (match_operand:DI 0 "register_operand" "")
9684         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
9685                    (match_operand:QI 2 "immediate_operand" "")))
9686    (clobber (reg:CC FLAGS_REG))]
9687   "TARGET_64BIT && reload_completed
9688    && true_regnum (operands[0]) != true_regnum (operands[1])"
9689   [(set (match_dup 0)
9690         (mult:DI (match_dup 1)
9691                  (match_dup 2)))]
9692   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
9693
9694 ;; This pattern can't accept a variable shift count, since shifts by
9695 ;; zero don't affect the flags.  We assume that shifts by constant
9696 ;; zero are optimized away.
9697 (define_insn "*ashldi3_cmp_rex64"
9698   [(set (reg FLAGS_REG)
9699         (compare
9700           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
9701                      (match_operand:QI 2 "const_1_to_63_operand" "J"))
9702           (const_int 0)))
9703    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9704         (ashift:DI (match_dup 1) (match_dup 2)))]
9705   "TARGET_64BIT
9706    && (optimize_function_for_size_p (cfun)
9707        || !TARGET_PARTIAL_FLAG_REG_STALL
9708        || (operands[2] == const1_rtx
9709            && (TARGET_SHIFT1
9710                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9711    && ix86_match_ccmode (insn, CCGOCmode)
9712    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
9713 {
9714   switch (get_attr_type (insn))
9715     {
9716     case TYPE_ALU:
9717       gcc_assert (operands[2] == const1_rtx);
9718       return "add{q}\t%0, %0";
9719
9720     default:
9721       if (REG_P (operands[2]))
9722         return "sal{q}\t{%b2, %0|%0, %b2}";
9723       else if (operands[2] == const1_rtx
9724                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9725         return "sal{q}\t%0";
9726       else
9727         return "sal{q}\t{%2, %0|%0, %2}";
9728     }
9729 }
9730   [(set (attr "type")
9731      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9732                           (const_int 0))
9733                       (match_operand 0 "register_operand" ""))
9734                  (match_operand 2 "const1_operand" ""))
9735               (const_string "alu")
9736            ]
9737            (const_string "ishift")))
9738    (set (attr "length_immediate")
9739      (if_then_else
9740        (ior (eq_attr "type" "alu")
9741             (and (eq_attr "type" "ishift")
9742                  (and (match_operand 2 "const1_operand" "")
9743                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9744                           (const_int 0)))))
9745        (const_string "0")
9746        (const_string "*")))
9747    (set_attr "mode" "DI")])
9748
9749 (define_insn "*ashldi3_cconly_rex64"
9750   [(set (reg FLAGS_REG)
9751         (compare
9752           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
9753                      (match_operand:QI 2 "const_1_to_63_operand" "J"))
9754           (const_int 0)))
9755    (clobber (match_scratch:DI 0 "=r"))]
9756   "TARGET_64BIT
9757    && (optimize_function_for_size_p (cfun)
9758        || !TARGET_PARTIAL_FLAG_REG_STALL
9759        || (operands[2] == const1_rtx
9760            && (TARGET_SHIFT1
9761                || TARGET_DOUBLE_WITH_ADD)))
9762    && ix86_match_ccmode (insn, CCGOCmode)
9763    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
9764 {
9765   switch (get_attr_type (insn))
9766     {
9767     case TYPE_ALU:
9768       gcc_assert (operands[2] == const1_rtx);
9769       return "add{q}\t%0, %0";
9770
9771     default:
9772       if (REG_P (operands[2]))
9773         return "sal{q}\t{%b2, %0|%0, %b2}";
9774       else if (operands[2] == const1_rtx
9775                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9776         return "sal{q}\t%0";
9777       else
9778         return "sal{q}\t{%2, %0|%0, %2}";
9779     }
9780 }
9781   [(set (attr "type")
9782      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9783                           (const_int 0))
9784                       (match_operand 0 "register_operand" ""))
9785                  (match_operand 2 "const1_operand" ""))
9786               (const_string "alu")
9787            ]
9788            (const_string "ishift")))
9789    (set (attr "length_immediate")
9790      (if_then_else
9791        (ior (eq_attr "type" "alu")
9792             (and (eq_attr "type" "ishift")
9793                  (and (match_operand 2 "const1_operand" "")
9794                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9795                           (const_int 0)))))
9796        (const_string "0")
9797        (const_string "*")))
9798    (set_attr "mode" "DI")])
9799
9800 (define_insn "*ashldi3_1"
9801   [(set (match_operand:DI 0 "register_operand" "=&r,r")
9802         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
9803                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
9804    (clobber (reg:CC FLAGS_REG))]
9805   "!TARGET_64BIT"
9806   "#"
9807   [(set_attr "type" "multi")])
9808
9809 ;; By default we don't ask for a scratch register, because when DImode
9810 ;; values are manipulated, registers are already at a premium.  But if
9811 ;; we have one handy, we won't turn it away.
9812 (define_peephole2
9813   [(match_scratch:SI 3 "r")
9814    (parallel [(set (match_operand:DI 0 "register_operand" "")
9815                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
9816                               (match_operand:QI 2 "nonmemory_operand" "")))
9817               (clobber (reg:CC FLAGS_REG))])
9818    (match_dup 3)]
9819   "!TARGET_64BIT && TARGET_CMOVE"
9820   [(const_int 0)]
9821   "ix86_split_ashl (operands, operands[3], DImode); DONE;")
9822
9823 (define_split
9824   [(set (match_operand:DI 0 "register_operand" "")
9825         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
9826                    (match_operand:QI 2 "nonmemory_operand" "")))
9827    (clobber (reg:CC FLAGS_REG))]
9828   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
9829                      ? epilogue_completed : reload_completed)"
9830   [(const_int 0)]
9831   "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
9832
9833 (define_insn "x86_shld"
9834   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9835         (ior:SI (ashift:SI (match_dup 0)
9836                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
9837                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9838                   (minus:QI (const_int 32) (match_dup 2)))))
9839    (clobber (reg:CC FLAGS_REG))]
9840   ""
9841   "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9842   [(set_attr "type" "ishift")
9843    (set_attr "prefix_0f" "1")
9844    (set_attr "mode" "SI")
9845    (set_attr "pent_pair" "np")
9846    (set_attr "athlon_decode" "vector")
9847    (set_attr "amdfam10_decode" "vector")])
9848
9849 (define_expand "x86_shift_adj_1"
9850   [(set (reg:CCZ FLAGS_REG)
9851         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
9852                              (const_int 32))
9853                      (const_int 0)))
9854    (set (match_operand:SI 0 "register_operand" "")
9855         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
9856                          (match_operand:SI 1 "register_operand" "")
9857                          (match_dup 0)))
9858    (set (match_dup 1)
9859         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
9860                          (match_operand:SI 3 "register_operand" "r")
9861                          (match_dup 1)))]
9862   "TARGET_CMOVE"
9863   "")
9864
9865 (define_expand "x86_shift_adj_2"
9866   [(use (match_operand:SI 0 "register_operand" ""))
9867    (use (match_operand:SI 1 "register_operand" ""))
9868    (use (match_operand:QI 2 "register_operand" ""))]
9869   ""
9870 {
9871   rtx label = gen_label_rtx ();
9872   rtx tmp;
9873
9874   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
9875
9876   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9877   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9878   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9879                               gen_rtx_LABEL_REF (VOIDmode, label),
9880                               pc_rtx);
9881   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9882   JUMP_LABEL (tmp) = label;
9883
9884   emit_move_insn (operands[0], operands[1]);
9885   ix86_expand_clear (operands[1]);
9886
9887   emit_label (label);
9888   LABEL_NUSES (label) = 1;
9889
9890   DONE;
9891 })
9892
9893 (define_expand "ashlsi3"
9894   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9895         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
9896                    (match_operand:QI 2 "nonmemory_operand" "")))]
9897   ""
9898   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
9899
9900 (define_insn "*ashlsi3_1"
9901   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9902         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
9903                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9904    (clobber (reg:CC FLAGS_REG))]
9905   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9906 {
9907   switch (get_attr_type (insn))
9908     {
9909     case TYPE_ALU:
9910       gcc_assert (operands[2] == const1_rtx);
9911       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9912       return "add{l}\t%0, %0";
9913
9914     case TYPE_LEA:
9915       return "#";
9916
9917     default:
9918       if (REG_P (operands[2]))
9919         return "sal{l}\t{%b2, %0|%0, %b2}";
9920       else if (operands[2] == const1_rtx
9921                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9922         return "sal{l}\t%0";
9923       else
9924         return "sal{l}\t{%2, %0|%0, %2}";
9925     }
9926 }
9927   [(set (attr "type")
9928      (cond [(eq_attr "alternative" "1")
9929               (const_string "lea")
9930             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9931                           (const_int 0))
9932                       (match_operand 0 "register_operand" ""))
9933                  (match_operand 2 "const1_operand" ""))
9934               (const_string "alu")
9935            ]
9936            (const_string "ishift")))
9937    (set (attr "length_immediate")
9938      (if_then_else
9939        (ior (eq_attr "type" "alu")
9940             (and (eq_attr "type" "ishift")
9941                  (and (match_operand 2 "const1_operand" "")
9942                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9943                           (const_int 0)))))
9944        (const_string "0")
9945        (const_string "*")))
9946    (set_attr "mode" "SI")])
9947
9948 ;; Convert lea to the lea pattern to avoid flags dependency.
9949 (define_split
9950   [(set (match_operand 0 "register_operand" "")
9951         (ashift (match_operand 1 "index_register_operand" "")
9952                 (match_operand:QI 2 "const_int_operand" "")))
9953    (clobber (reg:CC FLAGS_REG))]
9954   "reload_completed
9955    && true_regnum (operands[0]) != true_regnum (operands[1])
9956    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
9957   [(const_int 0)]
9958 {
9959   rtx pat;
9960   enum machine_mode mode = GET_MODE (operands[0]);
9961
9962   if (GET_MODE_SIZE (mode) < 4)
9963     operands[0] = gen_lowpart (SImode, operands[0]);
9964   if (mode != Pmode)
9965     operands[1] = gen_lowpart (Pmode, operands[1]);
9966   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
9967
9968   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
9969   if (Pmode != SImode)
9970     pat = gen_rtx_SUBREG (SImode, pat, 0);
9971   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9972   DONE;
9973 })
9974
9975 ;; Rare case of shifting RSP is handled by generating move and shift
9976 (define_split
9977   [(set (match_operand 0 "register_operand" "")
9978         (ashift (match_operand 1 "register_operand" "")
9979                 (match_operand:QI 2 "const_int_operand" "")))
9980    (clobber (reg:CC FLAGS_REG))]
9981   "reload_completed
9982    && true_regnum (operands[0]) != true_regnum (operands[1])"
9983   [(const_int 0)]
9984 {
9985   rtx pat, clob;
9986   emit_move_insn (operands[0], operands[1]);
9987   pat = gen_rtx_SET (VOIDmode, operands[0],
9988                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
9989                                      operands[0], operands[2]));
9990   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
9991   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
9992   DONE;
9993 })
9994
9995 (define_insn "*ashlsi3_1_zext"
9996   [(set (match_operand:DI 0 "register_operand" "=r,r")
9997         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
9998                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
9999    (clobber (reg:CC FLAGS_REG))]
10000   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10001 {
10002   switch (get_attr_type (insn))
10003     {
10004     case TYPE_ALU:
10005       gcc_assert (operands[2] == const1_rtx);
10006       return "add{l}\t%k0, %k0";
10007
10008     case TYPE_LEA:
10009       return "#";
10010
10011     default:
10012       if (REG_P (operands[2]))
10013         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10014       else if (operands[2] == const1_rtx
10015                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10016         return "sal{l}\t%k0";
10017       else
10018         return "sal{l}\t{%2, %k0|%k0, %2}";
10019     }
10020 }
10021   [(set (attr "type")
10022      (cond [(eq_attr "alternative" "1")
10023               (const_string "lea")
10024             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10025                      (const_int 0))
10026                  (match_operand 2 "const1_operand" ""))
10027               (const_string "alu")
10028            ]
10029            (const_string "ishift")))
10030    (set (attr "length_immediate")
10031      (if_then_else
10032        (ior (eq_attr "type" "alu")
10033             (and (eq_attr "type" "ishift")
10034                  (and (match_operand 2 "const1_operand" "")
10035                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10036                           (const_int 0)))))
10037        (const_string "0")
10038        (const_string "*")))
10039    (set_attr "mode" "SI")])
10040
10041 ;; Convert lea to the lea pattern to avoid flags dependency.
10042 (define_split
10043   [(set (match_operand:DI 0 "register_operand" "")
10044         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10045                                 (match_operand:QI 2 "const_int_operand" ""))))
10046    (clobber (reg:CC FLAGS_REG))]
10047   "TARGET_64BIT && reload_completed
10048    && true_regnum (operands[0]) != true_regnum (operands[1])"
10049   [(set (match_dup 0) (zero_extend:DI
10050                         (subreg:SI (mult:SI (match_dup 1)
10051                                             (match_dup 2)) 0)))]
10052 {
10053   operands[1] = gen_lowpart (Pmode, operands[1]);
10054   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10055 })
10056
10057 ;; This pattern can't accept a variable shift count, since shifts by
10058 ;; zero don't affect the flags.  We assume that shifts by constant
10059 ;; zero are optimized away.
10060 (define_insn "*ashlsi3_cmp"
10061   [(set (reg FLAGS_REG)
10062         (compare
10063           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10064                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10065           (const_int 0)))
10066    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10067         (ashift:SI (match_dup 1) (match_dup 2)))]
10068    "(optimize_function_for_size_p (cfun)
10069      || !TARGET_PARTIAL_FLAG_REG_STALL
10070      || (operands[2] == const1_rtx
10071          && (TARGET_SHIFT1
10072              || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
10073    && ix86_match_ccmode (insn, CCGOCmode)
10074    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10075 {
10076   switch (get_attr_type (insn))
10077     {
10078     case TYPE_ALU:
10079       gcc_assert (operands[2] == const1_rtx);
10080       return "add{l}\t%0, %0";
10081
10082     default:
10083       if (REG_P (operands[2]))
10084         return "sal{l}\t{%b2, %0|%0, %b2}";
10085       else if (operands[2] == const1_rtx
10086                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10087         return "sal{l}\t%0";
10088       else
10089         return "sal{l}\t{%2, %0|%0, %2}";
10090     }
10091 }
10092   [(set (attr "type")
10093      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10094                           (const_int 0))
10095                       (match_operand 0 "register_operand" ""))
10096                  (match_operand 2 "const1_operand" ""))
10097               (const_string "alu")
10098            ]
10099            (const_string "ishift")))
10100    (set (attr "length_immediate")
10101      (if_then_else
10102        (ior (eq_attr "type" "alu")
10103             (and (eq_attr "type" "ishift")
10104                  (and (match_operand 2 "const1_operand" "")
10105                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10106                           (const_int 0)))))
10107        (const_string "0")
10108        (const_string "*")))
10109    (set_attr "mode" "SI")])
10110
10111 (define_insn "*ashlsi3_cconly"
10112   [(set (reg FLAGS_REG)
10113         (compare
10114           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10115                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10116           (const_int 0)))
10117    (clobber (match_scratch:SI 0 "=r"))]
10118   "(optimize_function_for_size_p (cfun)
10119     || !TARGET_PARTIAL_FLAG_REG_STALL
10120     || (operands[2] == const1_rtx
10121         && (TARGET_SHIFT1
10122             || TARGET_DOUBLE_WITH_ADD)))
10123    && ix86_match_ccmode (insn, CCGOCmode)
10124    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10125 {
10126   switch (get_attr_type (insn))
10127     {
10128     case TYPE_ALU:
10129       gcc_assert (operands[2] == const1_rtx);
10130       return "add{l}\t%0, %0";
10131
10132     default:
10133       if (REG_P (operands[2]))
10134         return "sal{l}\t{%b2, %0|%0, %b2}";
10135       else if (operands[2] == const1_rtx
10136                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10137         return "sal{l}\t%0";
10138       else
10139         return "sal{l}\t{%2, %0|%0, %2}";
10140     }
10141 }
10142   [(set (attr "type")
10143      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10144                           (const_int 0))
10145                       (match_operand 0 "register_operand" ""))
10146                  (match_operand 2 "const1_operand" ""))
10147               (const_string "alu")
10148            ]
10149            (const_string "ishift")))
10150    (set (attr "length_immediate")
10151      (if_then_else
10152        (ior (eq_attr "type" "alu")
10153             (and (eq_attr "type" "ishift")
10154                  (and (match_operand 2 "const1_operand" "")
10155                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10156                           (const_int 0)))))
10157        (const_string "0")
10158        (const_string "*")))
10159    (set_attr "mode" "SI")])
10160
10161 (define_insn "*ashlsi3_cmp_zext"
10162   [(set (reg FLAGS_REG)
10163         (compare
10164           (ashift:SI (match_operand:SI 1 "register_operand" "0")
10165                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10166           (const_int 0)))
10167    (set (match_operand:DI 0 "register_operand" "=r")
10168         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10169   "TARGET_64BIT
10170    && (optimize_function_for_size_p (cfun)
10171        || !TARGET_PARTIAL_FLAG_REG_STALL
10172        || (operands[2] == const1_rtx
10173            && (TARGET_SHIFT1
10174                || TARGET_DOUBLE_WITH_ADD)))
10175    && ix86_match_ccmode (insn, CCGOCmode)
10176    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10177 {
10178   switch (get_attr_type (insn))
10179     {
10180     case TYPE_ALU:
10181       gcc_assert (operands[2] == const1_rtx);
10182       return "add{l}\t%k0, %k0";
10183
10184     default:
10185       if (REG_P (operands[2]))
10186         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10187       else if (operands[2] == const1_rtx
10188                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10189         return "sal{l}\t%k0";
10190       else
10191         return "sal{l}\t{%2, %k0|%k0, %2}";
10192     }
10193 }
10194   [(set (attr "type")
10195      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10196                      (const_int 0))
10197                  (match_operand 2 "const1_operand" ""))
10198               (const_string "alu")
10199            ]
10200            (const_string "ishift")))
10201    (set (attr "length_immediate")
10202      (if_then_else
10203        (ior (eq_attr "type" "alu")
10204             (and (eq_attr "type" "ishift")
10205                  (and (match_operand 2 "const1_operand" "")
10206                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10207                           (const_int 0)))))
10208        (const_string "0")
10209        (const_string "*")))
10210    (set_attr "mode" "SI")])
10211
10212 (define_expand "ashlhi3"
10213   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10214         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10215                    (match_operand:QI 2 "nonmemory_operand" "")))]
10216   "TARGET_HIMODE_MATH"
10217   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10218
10219 (define_insn "*ashlhi3_1_lea"
10220   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10221         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10222                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10223    (clobber (reg:CC FLAGS_REG))]
10224   "!TARGET_PARTIAL_REG_STALL
10225    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10226 {
10227   switch (get_attr_type (insn))
10228     {
10229     case TYPE_LEA:
10230       return "#";
10231     case TYPE_ALU:
10232       gcc_assert (operands[2] == const1_rtx);
10233       return "add{w}\t%0, %0";
10234
10235     default:
10236       if (REG_P (operands[2]))
10237         return "sal{w}\t{%b2, %0|%0, %b2}";
10238       else if (operands[2] == const1_rtx
10239                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10240         return "sal{w}\t%0";
10241       else
10242         return "sal{w}\t{%2, %0|%0, %2}";
10243     }
10244 }
10245   [(set (attr "type")
10246      (cond [(eq_attr "alternative" "1")
10247               (const_string "lea")
10248             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10249                           (const_int 0))
10250                       (match_operand 0 "register_operand" ""))
10251                  (match_operand 2 "const1_operand" ""))
10252               (const_string "alu")
10253            ]
10254            (const_string "ishift")))
10255    (set (attr "length_immediate")
10256      (if_then_else
10257        (ior (eq_attr "type" "alu")
10258             (and (eq_attr "type" "ishift")
10259                  (and (match_operand 2 "const1_operand" "")
10260                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10261                           (const_int 0)))))
10262        (const_string "0")
10263        (const_string "*")))
10264    (set_attr "mode" "HI,SI")])
10265
10266 (define_insn "*ashlhi3_1"
10267   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10268         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10269                    (match_operand:QI 2 "nonmemory_operand" "cI")))
10270    (clobber (reg:CC FLAGS_REG))]
10271   "TARGET_PARTIAL_REG_STALL
10272    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10273 {
10274   switch (get_attr_type (insn))
10275     {
10276     case TYPE_ALU:
10277       gcc_assert (operands[2] == const1_rtx);
10278       return "add{w}\t%0, %0";
10279
10280     default:
10281       if (REG_P (operands[2]))
10282         return "sal{w}\t{%b2, %0|%0, %b2}";
10283       else if (operands[2] == const1_rtx
10284                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10285         return "sal{w}\t%0";
10286       else
10287         return "sal{w}\t{%2, %0|%0, %2}";
10288     }
10289 }
10290   [(set (attr "type")
10291      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10292                           (const_int 0))
10293                       (match_operand 0 "register_operand" ""))
10294                  (match_operand 2 "const1_operand" ""))
10295               (const_string "alu")
10296            ]
10297            (const_string "ishift")))
10298    (set (attr "length_immediate")
10299      (if_then_else
10300        (ior (eq_attr "type" "alu")
10301             (and (eq_attr "type" "ishift")
10302                  (and (match_operand 2 "const1_operand" "")
10303                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10304                           (const_int 0)))))
10305        (const_string "0")
10306        (const_string "*")))
10307    (set_attr "mode" "HI")])
10308
10309 ;; This pattern can't accept a variable shift count, since shifts by
10310 ;; zero don't affect the flags.  We assume that shifts by constant
10311 ;; zero are optimized away.
10312 (define_insn "*ashlhi3_cmp"
10313   [(set (reg FLAGS_REG)
10314         (compare
10315           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10316                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10317           (const_int 0)))
10318    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10319         (ashift:HI (match_dup 1) (match_dup 2)))]
10320   "(optimize_function_for_size_p (cfun)
10321     || !TARGET_PARTIAL_FLAG_REG_STALL
10322     || (operands[2] == const1_rtx
10323         && (TARGET_SHIFT1
10324             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
10325    && ix86_match_ccmode (insn, CCGOCmode)
10326    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10327 {
10328   switch (get_attr_type (insn))
10329     {
10330     case TYPE_ALU:
10331       gcc_assert (operands[2] == const1_rtx);
10332       return "add{w}\t%0, %0";
10333
10334     default:
10335       if (REG_P (operands[2]))
10336         return "sal{w}\t{%b2, %0|%0, %b2}";
10337       else if (operands[2] == const1_rtx
10338                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10339         return "sal{w}\t%0";
10340       else
10341         return "sal{w}\t{%2, %0|%0, %2}";
10342     }
10343 }
10344   [(set (attr "type")
10345      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10346                           (const_int 0))
10347                       (match_operand 0 "register_operand" ""))
10348                  (match_operand 2 "const1_operand" ""))
10349               (const_string "alu")
10350            ]
10351            (const_string "ishift")))
10352    (set (attr "length_immediate")
10353      (if_then_else
10354        (ior (eq_attr "type" "alu")
10355             (and (eq_attr "type" "ishift")
10356                  (and (match_operand 2 "const1_operand" "")
10357                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10358                           (const_int 0)))))
10359        (const_string "0")
10360        (const_string "*")))
10361    (set_attr "mode" "HI")])
10362
10363 (define_insn "*ashlhi3_cconly"
10364   [(set (reg FLAGS_REG)
10365         (compare
10366           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10367                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10368           (const_int 0)))
10369    (clobber (match_scratch:HI 0 "=r"))]
10370   "(optimize_function_for_size_p (cfun)
10371     || !TARGET_PARTIAL_FLAG_REG_STALL
10372     || (operands[2] == const1_rtx
10373         && (TARGET_SHIFT1
10374             || TARGET_DOUBLE_WITH_ADD)))
10375    && ix86_match_ccmode (insn, CCGOCmode)
10376    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10377 {
10378   switch (get_attr_type (insn))
10379     {
10380     case TYPE_ALU:
10381       gcc_assert (operands[2] == const1_rtx);
10382       return "add{w}\t%0, %0";
10383
10384     default:
10385       if (REG_P (operands[2]))
10386         return "sal{w}\t{%b2, %0|%0, %b2}";
10387       else if (operands[2] == const1_rtx
10388                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10389         return "sal{w}\t%0";
10390       else
10391         return "sal{w}\t{%2, %0|%0, %2}";
10392     }
10393 }
10394   [(set (attr "type")
10395      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10396                           (const_int 0))
10397                       (match_operand 0 "register_operand" ""))
10398                  (match_operand 2 "const1_operand" ""))
10399               (const_string "alu")
10400            ]
10401            (const_string "ishift")))
10402    (set (attr "length_immediate")
10403      (if_then_else
10404        (ior (eq_attr "type" "alu")
10405             (and (eq_attr "type" "ishift")
10406                  (and (match_operand 2 "const1_operand" "")
10407                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10408                           (const_int 0)))))
10409        (const_string "0")
10410        (const_string "*")))
10411    (set_attr "mode" "HI")])
10412
10413 (define_expand "ashlqi3"
10414   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10415         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
10416                    (match_operand:QI 2 "nonmemory_operand" "")))]
10417   "TARGET_QIMODE_MATH"
10418   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
10419
10420 ;; %%% Potential partial reg stall on alternative 2.  What to do?
10421
10422 (define_insn "*ashlqi3_1_lea"
10423   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
10424         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
10425                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
10426    (clobber (reg:CC FLAGS_REG))]
10427   "!TARGET_PARTIAL_REG_STALL
10428    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10429 {
10430   switch (get_attr_type (insn))
10431     {
10432     case TYPE_LEA:
10433       return "#";
10434     case TYPE_ALU:
10435       gcc_assert (operands[2] == const1_rtx);
10436       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10437         return "add{l}\t%k0, %k0";
10438       else
10439         return "add{b}\t%0, %0";
10440
10441     default:
10442       if (REG_P (operands[2]))
10443         {
10444           if (get_attr_mode (insn) == MODE_SI)
10445             return "sal{l}\t{%b2, %k0|%k0, %b2}";
10446           else
10447             return "sal{b}\t{%b2, %0|%0, %b2}";
10448         }
10449       else if (operands[2] == const1_rtx
10450                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10451         {
10452           if (get_attr_mode (insn) == MODE_SI)
10453             return "sal{l}\t%0";
10454           else
10455             return "sal{b}\t%0";
10456         }
10457       else
10458         {
10459           if (get_attr_mode (insn) == MODE_SI)
10460             return "sal{l}\t{%2, %k0|%k0, %2}";
10461           else
10462             return "sal{b}\t{%2, %0|%0, %2}";
10463         }
10464     }
10465 }
10466   [(set (attr "type")
10467      (cond [(eq_attr "alternative" "2")
10468               (const_string "lea")
10469             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10470                           (const_int 0))
10471                       (match_operand 0 "register_operand" ""))
10472                  (match_operand 2 "const1_operand" ""))
10473               (const_string "alu")
10474            ]
10475            (const_string "ishift")))
10476    (set (attr "length_immediate")
10477      (if_then_else
10478        (ior (eq_attr "type" "alu")
10479             (and (eq_attr "type" "ishift")
10480                  (and (match_operand 2 "const1_operand" "")
10481                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10482                           (const_int 0)))))
10483        (const_string "0")
10484        (const_string "*")))
10485    (set_attr "mode" "QI,SI,SI")])
10486
10487 (define_insn "*ashlqi3_1"
10488   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10489         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
10490                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
10491    (clobber (reg:CC FLAGS_REG))]
10492   "TARGET_PARTIAL_REG_STALL
10493    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10494 {
10495   switch (get_attr_type (insn))
10496     {
10497     case TYPE_ALU:
10498       gcc_assert (operands[2] == const1_rtx);
10499       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10500         return "add{l}\t%k0, %k0";
10501       else
10502         return "add{b}\t%0, %0";
10503
10504     default:
10505       if (REG_P (operands[2]))
10506         {
10507           if (get_attr_mode (insn) == MODE_SI)
10508             return "sal{l}\t{%b2, %k0|%k0, %b2}";
10509           else
10510             return "sal{b}\t{%b2, %0|%0, %b2}";
10511         }
10512       else if (operands[2] == const1_rtx
10513                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10514         {
10515           if (get_attr_mode (insn) == MODE_SI)
10516             return "sal{l}\t%0";
10517           else
10518             return "sal{b}\t%0";
10519         }
10520       else
10521         {
10522           if (get_attr_mode (insn) == MODE_SI)
10523             return "sal{l}\t{%2, %k0|%k0, %2}";
10524           else
10525             return "sal{b}\t{%2, %0|%0, %2}";
10526         }
10527     }
10528 }
10529   [(set (attr "type")
10530      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10531                           (const_int 0))
10532                       (match_operand 0 "register_operand" ""))
10533                  (match_operand 2 "const1_operand" ""))
10534               (const_string "alu")
10535            ]
10536            (const_string "ishift")))
10537    (set (attr "length_immediate")
10538      (if_then_else
10539        (ior (eq_attr "type" "alu")
10540             (and (eq_attr "type" "ishift")
10541                  (and (match_operand 2 "const1_operand" "")
10542                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10543                           (const_int 0)))))
10544        (const_string "0")
10545        (const_string "*")))
10546    (set_attr "mode" "QI,SI")])
10547
10548 ;; This pattern can't accept a variable shift count, since shifts by
10549 ;; zero don't affect the flags.  We assume that shifts by constant
10550 ;; zero are optimized away.
10551 (define_insn "*ashlqi3_cmp"
10552   [(set (reg FLAGS_REG)
10553         (compare
10554           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
10555                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10556           (const_int 0)))
10557    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10558         (ashift:QI (match_dup 1) (match_dup 2)))]
10559   "(optimize_function_for_size_p (cfun)
10560     || !TARGET_PARTIAL_FLAG_REG_STALL
10561     || (operands[2] == const1_rtx
10562         && (TARGET_SHIFT1
10563             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
10564    && ix86_match_ccmode (insn, CCGOCmode)
10565    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10566 {
10567   switch (get_attr_type (insn))
10568     {
10569     case TYPE_ALU:
10570       gcc_assert (operands[2] == const1_rtx);
10571       return "add{b}\t%0, %0";
10572
10573     default:
10574       if (REG_P (operands[2]))
10575         return "sal{b}\t{%b2, %0|%0, %b2}";
10576       else if (operands[2] == const1_rtx
10577                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10578         return "sal{b}\t%0";
10579       else
10580         return "sal{b}\t{%2, %0|%0, %2}";
10581     }
10582 }
10583   [(set (attr "type")
10584      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10585                           (const_int 0))
10586                       (match_operand 0 "register_operand" ""))
10587                  (match_operand 2 "const1_operand" ""))
10588               (const_string "alu")
10589            ]
10590            (const_string "ishift")))
10591    (set (attr "length_immediate")
10592      (if_then_else
10593        (ior (eq_attr "type" "alu")
10594             (and (eq_attr "type" "ishift")
10595                  (and (match_operand 2 "const1_operand" "")
10596                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10597                           (const_int 0)))))
10598        (const_string "0")
10599        (const_string "*")))
10600    (set_attr "mode" "QI")])
10601
10602 (define_insn "*ashlqi3_cconly"
10603   [(set (reg FLAGS_REG)
10604         (compare
10605           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
10606                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10607           (const_int 0)))
10608    (clobber (match_scratch:QI 0 "=q"))]
10609   "(optimize_function_for_size_p (cfun)
10610     || !TARGET_PARTIAL_FLAG_REG_STALL
10611     || (operands[2] == const1_rtx
10612         && (TARGET_SHIFT1
10613             || TARGET_DOUBLE_WITH_ADD)))
10614    && ix86_match_ccmode (insn, CCGOCmode)
10615    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10616 {
10617   switch (get_attr_type (insn))
10618     {
10619     case TYPE_ALU:
10620       gcc_assert (operands[2] == const1_rtx);
10621       return "add{b}\t%0, %0";
10622
10623     default:
10624       if (REG_P (operands[2]))
10625         return "sal{b}\t{%b2, %0|%0, %b2}";
10626       else if (operands[2] == const1_rtx
10627                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10628         return "sal{b}\t%0";
10629       else
10630         return "sal{b}\t{%2, %0|%0, %2}";
10631     }
10632 }
10633   [(set (attr "type")
10634      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10635                           (const_int 0))
10636                       (match_operand 0 "register_operand" ""))
10637                  (match_operand 2 "const1_operand" ""))
10638               (const_string "alu")
10639            ]
10640            (const_string "ishift")))
10641    (set (attr "length_immediate")
10642      (if_then_else
10643        (ior (eq_attr "type" "alu")
10644             (and (eq_attr "type" "ishift")
10645                  (and (match_operand 2 "const1_operand" "")
10646                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10647                           (const_int 0)))))
10648        (const_string "0")
10649        (const_string "*")))
10650    (set_attr "mode" "QI")])
10651
10652 ;; See comment above `ashldi3' about how this works.
10653
10654 (define_expand "ashrti3"
10655   [(set (match_operand:TI 0 "register_operand" "")
10656         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
10657                      (match_operand:QI 2 "nonmemory_operand" "")))]
10658   "TARGET_64BIT"
10659   "ix86_expand_binary_operator (ASHIFTRT, TImode, operands); DONE;")
10660
10661 (define_insn "*ashrti3_1"
10662   [(set (match_operand:TI 0 "register_operand" "=r")
10663         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
10664                      (match_operand:QI 2 "nonmemory_operand" "Oc")))
10665    (clobber (reg:CC FLAGS_REG))]
10666   "TARGET_64BIT"
10667   "#"
10668   [(set_attr "type" "multi")])
10669
10670 (define_peephole2
10671   [(match_scratch:DI 3 "r")
10672    (parallel [(set (match_operand:TI 0 "register_operand" "")
10673                    (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
10674                                 (match_operand:QI 2 "nonmemory_operand" "")))
10675               (clobber (reg:CC FLAGS_REG))])
10676    (match_dup 3)]
10677   "TARGET_64BIT"
10678   [(const_int 0)]
10679   "ix86_split_ashr (operands, operands[3], TImode); DONE;")
10680
10681 (define_split
10682   [(set (match_operand:TI 0 "register_operand" "")
10683         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
10684                      (match_operand:QI 2 "nonmemory_operand" "")))
10685    (clobber (reg:CC FLAGS_REG))]
10686   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10687                     ? epilogue_completed : reload_completed)"
10688   [(const_int 0)]
10689   "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
10690
10691 (define_insn "x86_64_shrd"
10692   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
10693         (ior:DI (ashiftrt:DI (match_dup 0)
10694                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
10695                 (ashift:DI (match_operand:DI 1 "register_operand" "r")
10696                   (minus:QI (const_int 64) (match_dup 2)))))
10697    (clobber (reg:CC FLAGS_REG))]
10698   "TARGET_64BIT"
10699   "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
10700   [(set_attr "type" "ishift")
10701    (set_attr "prefix_0f" "1")
10702    (set_attr "mode" "DI")
10703    (set_attr "athlon_decode" "vector")
10704    (set_attr "amdfam10_decode" "vector")])
10705
10706 (define_expand "ashrdi3"
10707   [(set (match_operand:DI 0 "shiftdi_operand" "")
10708         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
10709                      (match_operand:QI 2 "nonmemory_operand" "")))]
10710   ""
10711   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
10712
10713 (define_expand "x86_64_shift_adj_3"
10714   [(use (match_operand:DI 0 "register_operand" ""))
10715    (use (match_operand:DI 1 "register_operand" ""))
10716    (use (match_operand:QI 2 "register_operand" ""))]
10717   ""
10718 {
10719   rtx label = gen_label_rtx ();
10720   rtx tmp;
10721
10722   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (64)));
10723
10724   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10725   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10726   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10727                               gen_rtx_LABEL_REF (VOIDmode, label),
10728                               pc_rtx);
10729   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10730   JUMP_LABEL (tmp) = label;
10731
10732   emit_move_insn (operands[0], operands[1]);
10733   emit_insn (gen_ashrdi3_63_rex64 (operands[1], operands[1], GEN_INT (63)));
10734
10735   emit_label (label);
10736   LABEL_NUSES (label) = 1;
10737
10738   DONE;
10739 })
10740
10741 (define_insn "ashrdi3_63_rex64"
10742   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
10743         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
10744                      (match_operand:DI 2 "const_int_operand" "i,i")))
10745    (clobber (reg:CC FLAGS_REG))]
10746   "TARGET_64BIT && INTVAL (operands[2]) == 63
10747    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10748    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10749   "@
10750    {cqto|cqo}
10751    sar{q}\t{%2, %0|%0, %2}"
10752   [(set_attr "type" "imovx,ishift")
10753    (set_attr "prefix_0f" "0,*")
10754    (set_attr "length_immediate" "0,*")
10755    (set_attr "modrm" "0,1")
10756    (set_attr "mode" "DI")])
10757
10758 (define_insn "*ashrdi3_1_one_bit_rex64"
10759   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10760         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10761                      (match_operand:QI 2 "const1_operand" "")))
10762    (clobber (reg:CC FLAGS_REG))]
10763   "TARGET_64BIT
10764    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
10765    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10766   "sar{q}\t%0"
10767   [(set_attr "type" "ishift")
10768    (set_attr "length_immediate" "0")
10769    (set_attr "mode" "DI")])
10770
10771 (define_insn "*ashrdi3_1_rex64"
10772   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
10773         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
10774                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
10775    (clobber (reg:CC FLAGS_REG))]
10776   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10777   "@
10778    sar{q}\t{%2, %0|%0, %2}
10779    sar{q}\t{%b2, %0|%0, %b2}"
10780   [(set_attr "type" "ishift")
10781    (set_attr "mode" "DI")])
10782
10783 ;; This pattern can't accept a variable shift count, since shifts by
10784 ;; zero don't affect the flags.  We assume that shifts by constant
10785 ;; zero are optimized away.
10786 (define_insn "*ashrdi3_one_bit_cmp_rex64"
10787   [(set (reg FLAGS_REG)
10788         (compare
10789           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10790                        (match_operand:QI 2 "const1_operand" ""))
10791           (const_int 0)))
10792    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10793         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
10794   "TARGET_64BIT
10795    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
10796    && ix86_match_ccmode (insn, CCGOCmode)
10797    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10798   "sar{q}\t%0"
10799   [(set_attr "type" "ishift")
10800    (set_attr "length_immediate" "0")
10801    (set_attr "mode" "DI")])
10802
10803 (define_insn "*ashrdi3_one_bit_cconly_rex64"
10804   [(set (reg FLAGS_REG)
10805         (compare
10806           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10807                        (match_operand:QI 2 "const1_operand" ""))
10808           (const_int 0)))
10809    (clobber (match_scratch:DI 0 "=r"))]
10810   "TARGET_64BIT
10811    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
10812    && ix86_match_ccmode (insn, CCGOCmode)
10813    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10814   "sar{q}\t%0"
10815   [(set_attr "type" "ishift")
10816    (set_attr "length_immediate" "0")
10817    (set_attr "mode" "DI")])
10818
10819 ;; This pattern can't accept a variable shift count, since shifts by
10820 ;; zero don't affect the flags.  We assume that shifts by constant
10821 ;; zero are optimized away.
10822 (define_insn "*ashrdi3_cmp_rex64"
10823   [(set (reg FLAGS_REG)
10824         (compare
10825           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10826                        (match_operand:QI 2 "const_1_to_63_operand" "J"))
10827           (const_int 0)))
10828    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10829         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
10830   "TARGET_64BIT
10831    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
10832    && ix86_match_ccmode (insn, CCGOCmode)
10833    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10834   "sar{q}\t{%2, %0|%0, %2}"
10835   [(set_attr "type" "ishift")
10836    (set_attr "mode" "DI")])
10837
10838 (define_insn "*ashrdi3_cconly_rex64"
10839   [(set (reg FLAGS_REG)
10840         (compare
10841           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10842                        (match_operand:QI 2 "const_1_to_63_operand" "J"))
10843           (const_int 0)))
10844    (clobber (match_scratch:DI 0 "=r"))]
10845   "TARGET_64BIT
10846    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
10847    && ix86_match_ccmode (insn, CCGOCmode)
10848    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10849   "sar{q}\t{%2, %0|%0, %2}"
10850   [(set_attr "type" "ishift")
10851    (set_attr "mode" "DI")])
10852
10853 (define_insn "*ashrdi3_1"
10854   [(set (match_operand:DI 0 "register_operand" "=r")
10855         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
10856                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
10857    (clobber (reg:CC FLAGS_REG))]
10858   "!TARGET_64BIT"
10859   "#"
10860   [(set_attr "type" "multi")])
10861
10862 ;; By default we don't ask for a scratch register, because when DImode
10863 ;; values are manipulated, registers are already at a premium.  But if
10864 ;; we have one handy, we won't turn it away.
10865 (define_peephole2
10866   [(match_scratch:SI 3 "r")
10867    (parallel [(set (match_operand:DI 0 "register_operand" "")
10868                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
10869                                 (match_operand:QI 2 "nonmemory_operand" "")))
10870               (clobber (reg:CC FLAGS_REG))])
10871    (match_dup 3)]
10872   "!TARGET_64BIT && TARGET_CMOVE"
10873   [(const_int 0)]
10874   "ix86_split_ashr (operands, operands[3], DImode); DONE;")
10875
10876 (define_split
10877   [(set (match_operand:DI 0 "register_operand" "")
10878         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
10879                      (match_operand:QI 2 "nonmemory_operand" "")))
10880    (clobber (reg:CC FLAGS_REG))]
10881   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10882                      ? epilogue_completed : reload_completed)"
10883   [(const_int 0)]
10884   "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
10885
10886 (define_insn "x86_shrd"
10887   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
10888         (ior:SI (ashiftrt:SI (match_dup 0)
10889                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
10890                 (ashift:SI (match_operand:SI 1 "register_operand" "r")
10891                   (minus:QI (const_int 32) (match_dup 2)))))
10892    (clobber (reg:CC FLAGS_REG))]
10893   ""
10894   "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
10895   [(set_attr "type" "ishift")
10896    (set_attr "prefix_0f" "1")
10897    (set_attr "pent_pair" "np")
10898    (set_attr "mode" "SI")])
10899
10900 (define_expand "x86_shift_adj_3"
10901   [(use (match_operand:SI 0 "register_operand" ""))
10902    (use (match_operand:SI 1 "register_operand" ""))
10903    (use (match_operand:QI 2 "register_operand" ""))]
10904   ""
10905 {
10906   rtx label = gen_label_rtx ();
10907   rtx tmp;
10908
10909   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10910
10911   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10912   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10913   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10914                               gen_rtx_LABEL_REF (VOIDmode, label),
10915                               pc_rtx);
10916   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10917   JUMP_LABEL (tmp) = label;
10918
10919   emit_move_insn (operands[0], operands[1]);
10920   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
10921
10922   emit_label (label);
10923   LABEL_NUSES (label) = 1;
10924
10925   DONE;
10926 })
10927
10928 (define_expand "ashrsi3_31"
10929   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
10930                    (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
10931                                 (match_operand:SI 2 "const_int_operand" "i,i")))
10932               (clobber (reg:CC FLAGS_REG))])]
10933   "")
10934
10935 (define_insn "*ashrsi3_31"
10936   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
10937         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
10938                      (match_operand:SI 2 "const_int_operand" "i,i")))
10939    (clobber (reg:CC FLAGS_REG))]
10940   "INTVAL (operands[2]) == 31
10941    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10942    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10943   "@
10944    {cltd|cdq}
10945    sar{l}\t{%2, %0|%0, %2}"
10946   [(set_attr "type" "imovx,ishift")
10947    (set_attr "prefix_0f" "0,*")
10948    (set_attr "length_immediate" "0,*")
10949    (set_attr "modrm" "0,1")
10950    (set_attr "mode" "SI")])
10951
10952 (define_insn "*ashrsi3_31_zext"
10953   [(set (match_operand:DI 0 "register_operand" "=*d,r")
10954         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
10955                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
10956    (clobber (reg:CC FLAGS_REG))]
10957   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10958    && INTVAL (operands[2]) == 31
10959    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10960   "@
10961    {cltd|cdq}
10962    sar{l}\t{%2, %k0|%k0, %2}"
10963   [(set_attr "type" "imovx,ishift")
10964    (set_attr "prefix_0f" "0,*")
10965    (set_attr "length_immediate" "0,*")
10966    (set_attr "modrm" "0,1")
10967    (set_attr "mode" "SI")])
10968
10969 (define_expand "ashrsi3"
10970   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10971         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
10972                      (match_operand:QI 2 "nonmemory_operand" "")))]
10973   ""
10974   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
10975
10976 (define_insn "*ashrsi3_1_one_bit"
10977   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10978         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10979                      (match_operand:QI 2 "const1_operand" "")))
10980    (clobber (reg:CC FLAGS_REG))]
10981   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
10982    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10983   "sar{l}\t%0"
10984   [(set_attr "type" "ishift")
10985    (set_attr "length_immediate" "0")
10986    (set_attr "mode" "SI")])
10987
10988 (define_insn "*ashrsi3_1_one_bit_zext"
10989   [(set (match_operand:DI 0 "register_operand" "=r")
10990         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
10991                                      (match_operand:QI 2 "const1_operand" ""))))
10992    (clobber (reg:CC FLAGS_REG))]
10993   "TARGET_64BIT
10994    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
10995    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10996   "sar{l}\t%k0"
10997   [(set_attr "type" "ishift")
10998    (set_attr "length_immediate" "0")
10999    (set_attr "mode" "SI")])
11000
11001 (define_insn "*ashrsi3_1"
11002   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11003         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11004                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11005    (clobber (reg:CC FLAGS_REG))]
11006   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11007   "@
11008    sar{l}\t{%2, %0|%0, %2}
11009    sar{l}\t{%b2, %0|%0, %b2}"
11010   [(set_attr "type" "ishift")
11011    (set_attr "mode" "SI")])
11012
11013 (define_insn "*ashrsi3_1_zext"
11014   [(set (match_operand:DI 0 "register_operand" "=r,r")
11015         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11016                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11017    (clobber (reg:CC FLAGS_REG))]
11018   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11019   "@
11020    sar{l}\t{%2, %k0|%k0, %2}
11021    sar{l}\t{%b2, %k0|%k0, %b2}"
11022   [(set_attr "type" "ishift")
11023    (set_attr "mode" "SI")])
11024
11025 ;; This pattern can't accept a variable shift count, since shifts by
11026 ;; zero don't affect the flags.  We assume that shifts by constant
11027 ;; zero are optimized away.
11028 (define_insn "*ashrsi3_one_bit_cmp"
11029   [(set (reg FLAGS_REG)
11030         (compare
11031           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11032                        (match_operand:QI 2 "const1_operand" ""))
11033           (const_int 0)))
11034    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11035         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11036   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11037    && ix86_match_ccmode (insn, CCGOCmode)
11038    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11039   "sar{l}\t%0"
11040   [(set_attr "type" "ishift")
11041    (set_attr "length_immediate" "0")
11042    (set_attr "mode" "SI")])
11043
11044 (define_insn "*ashrsi3_one_bit_cconly"
11045   [(set (reg FLAGS_REG)
11046         (compare
11047           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11048                        (match_operand:QI 2 "const1_operand" ""))
11049           (const_int 0)))
11050    (clobber (match_scratch:SI 0 "=r"))]
11051   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11052    && ix86_match_ccmode (insn, CCGOCmode)
11053    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11054   "sar{l}\t%0"
11055   [(set_attr "type" "ishift")
11056    (set_attr "length_immediate" "0")
11057    (set_attr "mode" "SI")])
11058
11059 (define_insn "*ashrsi3_one_bit_cmp_zext"
11060   [(set (reg FLAGS_REG)
11061         (compare
11062           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11063                        (match_operand:QI 2 "const1_operand" ""))
11064           (const_int 0)))
11065    (set (match_operand:DI 0 "register_operand" "=r")
11066         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11067   "TARGET_64BIT
11068    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11069    && ix86_match_ccmode (insn, CCmode)
11070    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11071   "sar{l}\t%k0"
11072   [(set_attr "type" "ishift")
11073    (set_attr "length_immediate" "0")
11074    (set_attr "mode" "SI")])
11075
11076 ;; This pattern can't accept a variable shift count, since shifts by
11077 ;; zero don't affect the flags.  We assume that shifts by constant
11078 ;; zero are optimized away.
11079 (define_insn "*ashrsi3_cmp"
11080   [(set (reg FLAGS_REG)
11081         (compare
11082           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11083                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11084           (const_int 0)))
11085    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11086         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11087   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11088    && ix86_match_ccmode (insn, CCGOCmode)
11089    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11090   "sar{l}\t{%2, %0|%0, %2}"
11091   [(set_attr "type" "ishift")
11092    (set_attr "mode" "SI")])
11093
11094 (define_insn "*ashrsi3_cconly"
11095   [(set (reg FLAGS_REG)
11096         (compare
11097           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11098                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11099           (const_int 0)))
11100    (clobber (match_scratch:SI 0 "=r"))]
11101   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11102    && ix86_match_ccmode (insn, CCGOCmode)
11103    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11104   "sar{l}\t{%2, %0|%0, %2}"
11105   [(set_attr "type" "ishift")
11106    (set_attr "mode" "SI")])
11107
11108 (define_insn "*ashrsi3_cmp_zext"
11109   [(set (reg FLAGS_REG)
11110         (compare
11111           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11112                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11113           (const_int 0)))
11114    (set (match_operand:DI 0 "register_operand" "=r")
11115         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11116   "TARGET_64BIT
11117    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11118    && ix86_match_ccmode (insn, CCGOCmode)
11119    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11120   "sar{l}\t{%2, %k0|%k0, %2}"
11121   [(set_attr "type" "ishift")
11122    (set_attr "mode" "SI")])
11123
11124 (define_expand "ashrhi3"
11125   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11126         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11127                      (match_operand:QI 2 "nonmemory_operand" "")))]
11128   "TARGET_HIMODE_MATH"
11129   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11130
11131 (define_insn "*ashrhi3_1_one_bit"
11132   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11133         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11134                      (match_operand:QI 2 "const1_operand" "")))
11135    (clobber (reg:CC FLAGS_REG))]
11136   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11137    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11138   "sar{w}\t%0"
11139   [(set_attr "type" "ishift")
11140    (set_attr "length_immediate" "0")
11141    (set_attr "mode" "HI")])
11142
11143 (define_insn "*ashrhi3_1"
11144   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11145         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11146                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11147    (clobber (reg:CC FLAGS_REG))]
11148   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11149   "@
11150    sar{w}\t{%2, %0|%0, %2}
11151    sar{w}\t{%b2, %0|%0, %b2}"
11152   [(set_attr "type" "ishift")
11153    (set_attr "mode" "HI")])
11154
11155 ;; This pattern can't accept a variable shift count, since shifts by
11156 ;; zero don't affect the flags.  We assume that shifts by constant
11157 ;; zero are optimized away.
11158 (define_insn "*ashrhi3_one_bit_cmp"
11159   [(set (reg FLAGS_REG)
11160         (compare
11161           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11162                        (match_operand:QI 2 "const1_operand" ""))
11163           (const_int 0)))
11164    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11165         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11166   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11167    && ix86_match_ccmode (insn, CCGOCmode)
11168    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11169   "sar{w}\t%0"
11170   [(set_attr "type" "ishift")
11171    (set_attr "length_immediate" "0")
11172    (set_attr "mode" "HI")])
11173
11174 (define_insn "*ashrhi3_one_bit_cconly"
11175   [(set (reg FLAGS_REG)
11176         (compare
11177           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11178                        (match_operand:QI 2 "const1_operand" ""))
11179           (const_int 0)))
11180    (clobber (match_scratch:HI 0 "=r"))]
11181   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11182    && ix86_match_ccmode (insn, CCGOCmode)
11183    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11184   "sar{w}\t%0"
11185   [(set_attr "type" "ishift")
11186    (set_attr "length_immediate" "0")
11187    (set_attr "mode" "HI")])
11188
11189 ;; This pattern can't accept a variable shift count, since shifts by
11190 ;; zero don't affect the flags.  We assume that shifts by constant
11191 ;; zero are optimized away.
11192 (define_insn "*ashrhi3_cmp"
11193   [(set (reg FLAGS_REG)
11194         (compare
11195           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11196                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11197           (const_int 0)))
11198    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11199         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11200   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11201    && ix86_match_ccmode (insn, CCGOCmode)
11202    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11203   "sar{w}\t{%2, %0|%0, %2}"
11204   [(set_attr "type" "ishift")
11205    (set_attr "mode" "HI")])
11206
11207 (define_insn "*ashrhi3_cconly"
11208   [(set (reg FLAGS_REG)
11209         (compare
11210           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11211                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11212           (const_int 0)))
11213    (clobber (match_scratch:HI 0 "=r"))]
11214   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11215    && ix86_match_ccmode (insn, CCGOCmode)
11216    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11217   "sar{w}\t{%2, %0|%0, %2}"
11218   [(set_attr "type" "ishift")
11219    (set_attr "mode" "HI")])
11220
11221 (define_expand "ashrqi3"
11222   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11223         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11224                      (match_operand:QI 2 "nonmemory_operand" "")))]
11225   "TARGET_QIMODE_MATH"
11226   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11227
11228 (define_insn "*ashrqi3_1_one_bit"
11229   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11230         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11231                      (match_operand:QI 2 "const1_operand" "")))
11232    (clobber (reg:CC FLAGS_REG))]
11233   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11234    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11235   "sar{b}\t%0"
11236   [(set_attr "type" "ishift")
11237    (set_attr "length_immediate" "0")
11238    (set_attr "mode" "QI")])
11239
11240 (define_insn "*ashrqi3_1_one_bit_slp"
11241   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11242         (ashiftrt:QI (match_dup 0)
11243                      (match_operand:QI 1 "const1_operand" "")))
11244    (clobber (reg:CC FLAGS_REG))]
11245   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11246    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11247    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11248   "sar{b}\t%0"
11249   [(set_attr "type" "ishift1")
11250    (set_attr "length_immediate" "0")
11251    (set_attr "mode" "QI")])
11252
11253 (define_insn "*ashrqi3_1"
11254   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11255         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11256                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11257    (clobber (reg:CC FLAGS_REG))]
11258   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11259   "@
11260    sar{b}\t{%2, %0|%0, %2}
11261    sar{b}\t{%b2, %0|%0, %b2}"
11262   [(set_attr "type" "ishift")
11263    (set_attr "mode" "QI")])
11264
11265 (define_insn "*ashrqi3_1_slp"
11266   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11267         (ashiftrt:QI (match_dup 0)
11268                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11269    (clobber (reg:CC FLAGS_REG))]
11270   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11271    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
11272   "@
11273    sar{b}\t{%1, %0|%0, %1}
11274    sar{b}\t{%b1, %0|%0, %b1}"
11275   [(set_attr "type" "ishift1")
11276    (set_attr "mode" "QI")])
11277
11278 ;; This pattern can't accept a variable shift count, since shifts by
11279 ;; zero don't affect the flags.  We assume that shifts by constant
11280 ;; zero are optimized away.
11281 (define_insn "*ashrqi3_one_bit_cmp"
11282   [(set (reg FLAGS_REG)
11283         (compare
11284           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11285                        (match_operand:QI 2 "const1_operand" "I"))
11286           (const_int 0)))
11287    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11288         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11289   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11290    && ix86_match_ccmode (insn, CCGOCmode)
11291    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11292   "sar{b}\t%0"
11293   [(set_attr "type" "ishift")
11294    (set_attr "length_immediate" "0")
11295    (set_attr "mode" "QI")])
11296
11297 (define_insn "*ashrqi3_one_bit_cconly"
11298   [(set (reg FLAGS_REG)
11299         (compare
11300           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11301                        (match_operand:QI 2 "const1_operand" ""))
11302           (const_int 0)))
11303    (clobber (match_scratch:QI 0 "=q"))]
11304   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11305    && ix86_match_ccmode (insn, CCGOCmode)
11306    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11307   "sar{b}\t%0"
11308   [(set_attr "type" "ishift")
11309    (set_attr "length_immediate" "0")
11310    (set_attr "mode" "QI")])
11311
11312 ;; This pattern can't accept a variable shift count, since shifts by
11313 ;; zero don't affect the flags.  We assume that shifts by constant
11314 ;; zero are optimized away.
11315 (define_insn "*ashrqi3_cmp"
11316   [(set (reg FLAGS_REG)
11317         (compare
11318           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11319                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11320           (const_int 0)))
11321    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11322         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11323   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11324    && ix86_match_ccmode (insn, CCGOCmode)
11325    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11326   "sar{b}\t{%2, %0|%0, %2}"
11327   [(set_attr "type" "ishift")
11328    (set_attr "mode" "QI")])
11329
11330 (define_insn "*ashrqi3_cconly"
11331   [(set (reg FLAGS_REG)
11332         (compare
11333           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11334                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11335           (const_int 0)))
11336    (clobber (match_scratch:QI 0 "=q"))]
11337   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11338    && ix86_match_ccmode (insn, CCGOCmode)
11339    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11340   "sar{b}\t{%2, %0|%0, %2}"
11341   [(set_attr "type" "ishift")
11342    (set_attr "mode" "QI")])
11343
11344 \f
11345 ;; Logical shift instructions
11346
11347 ;; See comment above `ashldi3' about how this works.
11348
11349 (define_expand "lshrti3"
11350   [(set (match_operand:TI 0 "register_operand" "")
11351         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11352                      (match_operand:QI 2 "nonmemory_operand" "")))]
11353   "TARGET_64BIT"
11354   "ix86_expand_binary_operator (LSHIFTRT, TImode, operands); DONE;")
11355
11356 (define_insn "*lshrti3_1"
11357   [(set (match_operand:TI 0 "register_operand" "=r")
11358         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11359                      (match_operand:QI 2 "nonmemory_operand" "Oc")))
11360    (clobber (reg:CC FLAGS_REG))]
11361   "TARGET_64BIT"
11362   "#"
11363   [(set_attr "type" "multi")])
11364
11365 (define_peephole2
11366   [(match_scratch:DI 3 "r")
11367    (parallel [(set (match_operand:TI 0 "register_operand" "")
11368                    (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11369                                 (match_operand:QI 2 "nonmemory_operand" "")))
11370               (clobber (reg:CC FLAGS_REG))])
11371    (match_dup 3)]
11372   "TARGET_64BIT"
11373   [(const_int 0)]
11374   "ix86_split_lshr (operands, operands[3], TImode); DONE;")
11375
11376 (define_split
11377   [(set (match_operand:TI 0 "register_operand" "")
11378         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11379                      (match_operand:QI 2 "nonmemory_operand" "")))
11380    (clobber (reg:CC FLAGS_REG))]
11381   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11382                     ? epilogue_completed : reload_completed)"
11383   [(const_int 0)]
11384   "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
11385
11386 (define_expand "lshrdi3"
11387   [(set (match_operand:DI 0 "shiftdi_operand" "")
11388         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11389                      (match_operand:QI 2 "nonmemory_operand" "")))]
11390   ""
11391   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
11392
11393 (define_insn "*lshrdi3_1_one_bit_rex64"
11394   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11395         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11396                      (match_operand:QI 2 "const1_operand" "")))
11397    (clobber (reg:CC FLAGS_REG))]
11398   "TARGET_64BIT
11399    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11400    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11401   "shr{q}\t%0"
11402   [(set_attr "type" "ishift")
11403    (set_attr "length_immediate" "0")
11404    (set_attr "mode" "DI")])
11405
11406 (define_insn "*lshrdi3_1_rex64"
11407   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11408         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11409                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11410    (clobber (reg:CC FLAGS_REG))]
11411   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11412   "@
11413    shr{q}\t{%2, %0|%0, %2}
11414    shr{q}\t{%b2, %0|%0, %b2}"
11415   [(set_attr "type" "ishift")
11416    (set_attr "mode" "DI")])
11417
11418 ;; This pattern can't accept a variable shift count, since shifts by
11419 ;; zero don't affect the flags.  We assume that shifts by constant
11420 ;; zero are optimized away.
11421 (define_insn "*lshrdi3_cmp_one_bit_rex64"
11422   [(set (reg FLAGS_REG)
11423         (compare
11424           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11425                        (match_operand:QI 2 "const1_operand" ""))
11426           (const_int 0)))
11427    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11428         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11429   "TARGET_64BIT
11430    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11431    && ix86_match_ccmode (insn, CCGOCmode)
11432    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11433   "shr{q}\t%0"
11434   [(set_attr "type" "ishift")
11435    (set_attr "length_immediate" "0")
11436    (set_attr "mode" "DI")])
11437
11438 (define_insn "*lshrdi3_cconly_one_bit_rex64"
11439   [(set (reg FLAGS_REG)
11440         (compare
11441           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11442                        (match_operand:QI 2 "const1_operand" ""))
11443           (const_int 0)))
11444    (clobber (match_scratch:DI 0 "=r"))]
11445   "TARGET_64BIT
11446    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11447    && ix86_match_ccmode (insn, CCGOCmode)
11448    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11449   "shr{q}\t%0"
11450   [(set_attr "type" "ishift")
11451    (set_attr "length_immediate" "0")
11452    (set_attr "mode" "DI")])
11453
11454 ;; This pattern can't accept a variable shift count, since shifts by
11455 ;; zero don't affect the flags.  We assume that shifts by constant
11456 ;; zero are optimized away.
11457 (define_insn "*lshrdi3_cmp_rex64"
11458   [(set (reg FLAGS_REG)
11459         (compare
11460           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11461                        (match_operand:QI 2 "const_1_to_63_operand" "J"))
11462           (const_int 0)))
11463    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11464         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11465   "TARGET_64BIT
11466    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11467    && ix86_match_ccmode (insn, CCGOCmode)
11468    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11469   "shr{q}\t{%2, %0|%0, %2}"
11470   [(set_attr "type" "ishift")
11471    (set_attr "mode" "DI")])
11472
11473 (define_insn "*lshrdi3_cconly_rex64"
11474   [(set (reg FLAGS_REG)
11475         (compare
11476           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11477                        (match_operand:QI 2 "const_1_to_63_operand" "J"))
11478           (const_int 0)))
11479    (clobber (match_scratch:DI 0 "=r"))]
11480   "TARGET_64BIT
11481    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11482    && ix86_match_ccmode (insn, CCGOCmode)
11483    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11484   "shr{q}\t{%2, %0|%0, %2}"
11485   [(set_attr "type" "ishift")
11486    (set_attr "mode" "DI")])
11487
11488 (define_insn "*lshrdi3_1"
11489   [(set (match_operand:DI 0 "register_operand" "=r")
11490         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11491                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11492    (clobber (reg:CC FLAGS_REG))]
11493   "!TARGET_64BIT"
11494   "#"
11495   [(set_attr "type" "multi")])
11496
11497 ;; By default we don't ask for a scratch register, because when DImode
11498 ;; values are manipulated, registers are already at a premium.  But if
11499 ;; we have one handy, we won't turn it away.
11500 (define_peephole2
11501   [(match_scratch:SI 3 "r")
11502    (parallel [(set (match_operand:DI 0 "register_operand" "")
11503                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11504                                 (match_operand:QI 2 "nonmemory_operand" "")))
11505               (clobber (reg:CC FLAGS_REG))])
11506    (match_dup 3)]
11507   "!TARGET_64BIT && TARGET_CMOVE"
11508   [(const_int 0)]
11509   "ix86_split_lshr (operands, operands[3], DImode); DONE;")
11510
11511 (define_split
11512   [(set (match_operand:DI 0 "register_operand" "")
11513         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11514                      (match_operand:QI 2 "nonmemory_operand" "")))
11515    (clobber (reg:CC FLAGS_REG))]
11516   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11517                      ? epilogue_completed : reload_completed)"
11518   [(const_int 0)]
11519   "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
11520
11521 (define_expand "lshrsi3"
11522   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11523         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11524                      (match_operand:QI 2 "nonmemory_operand" "")))]
11525   ""
11526   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11527
11528 (define_insn "*lshrsi3_1_one_bit"
11529   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11530         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11531                      (match_operand:QI 2 "const1_operand" "")))
11532    (clobber (reg:CC FLAGS_REG))]
11533   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11534    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11535   "shr{l}\t%0"
11536   [(set_attr "type" "ishift")
11537    (set_attr "length_immediate" "0")
11538    (set_attr "mode" "SI")])
11539
11540 (define_insn "*lshrsi3_1_one_bit_zext"
11541   [(set (match_operand:DI 0 "register_operand" "=r")
11542         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
11543                      (match_operand:QI 2 "const1_operand" "")))
11544    (clobber (reg:CC FLAGS_REG))]
11545   "TARGET_64BIT
11546    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11547    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11548   "shr{l}\t%k0"
11549   [(set_attr "type" "ishift")
11550    (set_attr "length_immediate" "0")
11551    (set_attr "mode" "SI")])
11552
11553 (define_insn "*lshrsi3_1"
11554   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11555         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11556                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11557    (clobber (reg:CC FLAGS_REG))]
11558   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11559   "@
11560    shr{l}\t{%2, %0|%0, %2}
11561    shr{l}\t{%b2, %0|%0, %b2}"
11562   [(set_attr "type" "ishift")
11563    (set_attr "mode" "SI")])
11564
11565 (define_insn "*lshrsi3_1_zext"
11566   [(set (match_operand:DI 0 "register_operand" "=r,r")
11567         (zero_extend:DI
11568           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11569                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11570    (clobber (reg:CC FLAGS_REG))]
11571   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11572   "@
11573    shr{l}\t{%2, %k0|%k0, %2}
11574    shr{l}\t{%b2, %k0|%k0, %b2}"
11575   [(set_attr "type" "ishift")
11576    (set_attr "mode" "SI")])
11577
11578 ;; This pattern can't accept a variable shift count, since shifts by
11579 ;; zero don't affect the flags.  We assume that shifts by constant
11580 ;; zero are optimized away.
11581 (define_insn "*lshrsi3_one_bit_cmp"
11582   [(set (reg FLAGS_REG)
11583         (compare
11584           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11585                        (match_operand:QI 2 "const1_operand" ""))
11586           (const_int 0)))
11587    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11588         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11589   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11590    && ix86_match_ccmode (insn, CCGOCmode)
11591    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11592   "shr{l}\t%0"
11593   [(set_attr "type" "ishift")
11594    (set_attr "length_immediate" "0")
11595    (set_attr "mode" "SI")])
11596
11597 (define_insn "*lshrsi3_one_bit_cconly"
11598   [(set (reg FLAGS_REG)
11599         (compare
11600           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11601                        (match_operand:QI 2 "const1_operand" ""))
11602           (const_int 0)))
11603    (clobber (match_scratch:SI 0 "=r"))]
11604   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11605    && ix86_match_ccmode (insn, CCGOCmode)
11606    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11607   "shr{l}\t%0"
11608   [(set_attr "type" "ishift")
11609    (set_attr "length_immediate" "0")
11610    (set_attr "mode" "SI")])
11611
11612 (define_insn "*lshrsi3_cmp_one_bit_zext"
11613   [(set (reg FLAGS_REG)
11614         (compare
11615           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11616                        (match_operand:QI 2 "const1_operand" ""))
11617           (const_int 0)))
11618    (set (match_operand:DI 0 "register_operand" "=r")
11619         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11620   "TARGET_64BIT
11621    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11622    && ix86_match_ccmode (insn, CCGOCmode)
11623    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11624   "shr{l}\t%k0"
11625   [(set_attr "type" "ishift")
11626    (set_attr "length_immediate" "0")
11627    (set_attr "mode" "SI")])
11628
11629 ;; This pattern can't accept a variable shift count, since shifts by
11630 ;; zero don't affect the flags.  We assume that shifts by constant
11631 ;; zero are optimized away.
11632 (define_insn "*lshrsi3_cmp"
11633   [(set (reg FLAGS_REG)
11634         (compare
11635           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11636                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11637           (const_int 0)))
11638    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11639         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11640   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11641    && ix86_match_ccmode (insn, CCGOCmode)
11642    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11643   "shr{l}\t{%2, %0|%0, %2}"
11644   [(set_attr "type" "ishift")
11645    (set_attr "mode" "SI")])
11646
11647 (define_insn "*lshrsi3_cconly"
11648   [(set (reg FLAGS_REG)
11649       (compare
11650         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11651                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11652         (const_int 0)))
11653    (clobber (match_scratch:SI 0 "=r"))]
11654   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11655    && ix86_match_ccmode (insn, CCGOCmode)
11656    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11657   "shr{l}\t{%2, %0|%0, %2}"
11658   [(set_attr "type" "ishift")
11659    (set_attr "mode" "SI")])
11660
11661 (define_insn "*lshrsi3_cmp_zext"
11662   [(set (reg FLAGS_REG)
11663         (compare
11664           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11665                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11666           (const_int 0)))
11667    (set (match_operand:DI 0 "register_operand" "=r")
11668         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11669   "TARGET_64BIT
11670    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11671    && ix86_match_ccmode (insn, CCGOCmode)
11672    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11673   "shr{l}\t{%2, %k0|%k0, %2}"
11674   [(set_attr "type" "ishift")
11675    (set_attr "mode" "SI")])
11676
11677 (define_expand "lshrhi3"
11678   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11679         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11680                      (match_operand:QI 2 "nonmemory_operand" "")))]
11681   "TARGET_HIMODE_MATH"
11682   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
11683
11684 (define_insn "*lshrhi3_1_one_bit"
11685   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11686         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11687                      (match_operand:QI 2 "const1_operand" "")))
11688    (clobber (reg:CC FLAGS_REG))]
11689   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11690    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11691   "shr{w}\t%0"
11692   [(set_attr "type" "ishift")
11693    (set_attr "length_immediate" "0")
11694    (set_attr "mode" "HI")])
11695
11696 (define_insn "*lshrhi3_1"
11697   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11698         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11699                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11700    (clobber (reg:CC FLAGS_REG))]
11701   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11702   "@
11703    shr{w}\t{%2, %0|%0, %2}
11704    shr{w}\t{%b2, %0|%0, %b2}"
11705   [(set_attr "type" "ishift")
11706    (set_attr "mode" "HI")])
11707
11708 ;; This pattern can't accept a variable shift count, since shifts by
11709 ;; zero don't affect the flags.  We assume that shifts by constant
11710 ;; zero are optimized away.
11711 (define_insn "*lshrhi3_one_bit_cmp"
11712   [(set (reg FLAGS_REG)
11713         (compare
11714           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11715                        (match_operand:QI 2 "const1_operand" ""))
11716           (const_int 0)))
11717    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11718         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11719   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11720    && ix86_match_ccmode (insn, CCGOCmode)
11721    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11722   "shr{w}\t%0"
11723   [(set_attr "type" "ishift")
11724    (set_attr "length_immediate" "0")
11725    (set_attr "mode" "HI")])
11726
11727 (define_insn "*lshrhi3_one_bit_cconly"
11728   [(set (reg FLAGS_REG)
11729         (compare
11730           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11731                        (match_operand:QI 2 "const1_operand" ""))
11732           (const_int 0)))
11733    (clobber (match_scratch:HI 0 "=r"))]
11734   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11735    && ix86_match_ccmode (insn, CCGOCmode)
11736    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11737   "shr{w}\t%0"
11738   [(set_attr "type" "ishift")
11739    (set_attr "length_immediate" "0")
11740    (set_attr "mode" "HI")])
11741
11742 ;; This pattern can't accept a variable shift count, since shifts by
11743 ;; zero don't affect the flags.  We assume that shifts by constant
11744 ;; zero are optimized away.
11745 (define_insn "*lshrhi3_cmp"
11746   [(set (reg FLAGS_REG)
11747         (compare
11748           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11749                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11750           (const_int 0)))
11751    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11752         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11753   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11754    && ix86_match_ccmode (insn, CCGOCmode)
11755    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11756   "shr{w}\t{%2, %0|%0, %2}"
11757   [(set_attr "type" "ishift")
11758    (set_attr "mode" "HI")])
11759
11760 (define_insn "*lshrhi3_cconly"
11761   [(set (reg FLAGS_REG)
11762         (compare
11763           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11764                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11765           (const_int 0)))
11766    (clobber (match_scratch:HI 0 "=r"))]
11767   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11768    && ix86_match_ccmode (insn, CCGOCmode)
11769    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11770   "shr{w}\t{%2, %0|%0, %2}"
11771   [(set_attr "type" "ishift")
11772    (set_attr "mode" "HI")])
11773
11774 (define_expand "lshrqi3"
11775   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11776         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11777                      (match_operand:QI 2 "nonmemory_operand" "")))]
11778   "TARGET_QIMODE_MATH"
11779   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
11780
11781 (define_insn "*lshrqi3_1_one_bit"
11782   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11783         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11784                      (match_operand:QI 2 "const1_operand" "")))
11785    (clobber (reg:CC FLAGS_REG))]
11786   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11787    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11788   "shr{b}\t%0"
11789   [(set_attr "type" "ishift")
11790    (set_attr "length_immediate" "0")
11791    (set_attr "mode" "QI")])
11792
11793 (define_insn "*lshrqi3_1_one_bit_slp"
11794   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11795         (lshiftrt:QI (match_dup 0)
11796                      (match_operand:QI 1 "const1_operand" "")))
11797    (clobber (reg:CC FLAGS_REG))]
11798   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11799    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
11800   "shr{b}\t%0"
11801   [(set_attr "type" "ishift1")
11802    (set_attr "length_immediate" "0")
11803    (set_attr "mode" "QI")])
11804
11805 (define_insn "*lshrqi3_1"
11806   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11807         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11808                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11809    (clobber (reg:CC FLAGS_REG))]
11810   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11811   "@
11812    shr{b}\t{%2, %0|%0, %2}
11813    shr{b}\t{%b2, %0|%0, %b2}"
11814   [(set_attr "type" "ishift")
11815    (set_attr "mode" "QI")])
11816
11817 (define_insn "*lshrqi3_1_slp"
11818   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11819         (lshiftrt:QI (match_dup 0)
11820                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11821    (clobber (reg:CC FLAGS_REG))]
11822   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11823    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
11824   "@
11825    shr{b}\t{%1, %0|%0, %1}
11826    shr{b}\t{%b1, %0|%0, %b1}"
11827   [(set_attr "type" "ishift1")
11828    (set_attr "mode" "QI")])
11829
11830 ;; This pattern can't accept a variable shift count, since shifts by
11831 ;; zero don't affect the flags.  We assume that shifts by constant
11832 ;; zero are optimized away.
11833 (define_insn "*lshrqi2_one_bit_cmp"
11834   [(set (reg FLAGS_REG)
11835         (compare
11836           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11837                        (match_operand:QI 2 "const1_operand" ""))
11838           (const_int 0)))
11839    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11840         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11841   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11842    && ix86_match_ccmode (insn, CCGOCmode)
11843    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11844   "shr{b}\t%0"
11845   [(set_attr "type" "ishift")
11846    (set_attr "length_immediate" "0")
11847    (set_attr "mode" "QI")])
11848
11849 (define_insn "*lshrqi2_one_bit_cconly"
11850   [(set (reg FLAGS_REG)
11851         (compare
11852           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11853                        (match_operand:QI 2 "const1_operand" ""))
11854           (const_int 0)))
11855    (clobber (match_scratch:QI 0 "=q"))]
11856   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11857    && ix86_match_ccmode (insn, CCGOCmode)
11858    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11859   "shr{b}\t%0"
11860   [(set_attr "type" "ishift")
11861    (set_attr "length_immediate" "0")
11862    (set_attr "mode" "QI")])
11863
11864 ;; This pattern can't accept a variable shift count, since shifts by
11865 ;; zero don't affect the flags.  We assume that shifts by constant
11866 ;; zero are optimized away.
11867 (define_insn "*lshrqi2_cmp"
11868   [(set (reg FLAGS_REG)
11869         (compare
11870           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11871                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11872           (const_int 0)))
11873    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11874         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11875   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11876    && ix86_match_ccmode (insn, CCGOCmode)
11877    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11878   "shr{b}\t{%2, %0|%0, %2}"
11879   [(set_attr "type" "ishift")
11880    (set_attr "mode" "QI")])
11881
11882 (define_insn "*lshrqi2_cconly"
11883   [(set (reg FLAGS_REG)
11884         (compare
11885           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11886                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11887           (const_int 0)))
11888    (clobber (match_scratch:QI 0 "=q"))]
11889   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11890    && ix86_match_ccmode (insn, CCGOCmode)
11891    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11892   "shr{b}\t{%2, %0|%0, %2}"
11893   [(set_attr "type" "ishift")
11894    (set_attr "mode" "QI")])
11895 \f
11896 ;; Rotate instructions
11897
11898 (define_expand "rotldi3"
11899   [(set (match_operand:DI 0 "shiftdi_operand" "")
11900         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
11901                    (match_operand:QI 2 "nonmemory_operand" "")))]
11902  ""
11903 {
11904   if (TARGET_64BIT)
11905     {
11906       ix86_expand_binary_operator (ROTATE, DImode, operands);
11907       DONE;
11908     }
11909   if (!const_1_to_31_operand (operands[2], VOIDmode))
11910     FAIL;
11911   emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
11912   DONE;
11913 })
11914
11915 ;; Implement rotation using two double-precision shift instructions
11916 ;; and a scratch register.
11917 (define_insn_and_split "ix86_rotldi3"
11918  [(set (match_operand:DI 0 "register_operand" "=r")
11919        (rotate:DI (match_operand:DI 1 "register_operand" "0")
11920                   (match_operand:QI 2 "const_1_to_31_operand" "I")))
11921   (clobber (reg:CC FLAGS_REG))
11922   (clobber (match_scratch:SI 3 "=&r"))]
11923  "!TARGET_64BIT"
11924  ""
11925  "&& reload_completed"
11926  [(set (match_dup 3) (match_dup 4))
11927   (parallel
11928    [(set (match_dup 4)
11929          (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
11930                  (lshiftrt:SI (match_dup 5)
11931                               (minus:QI (const_int 32) (match_dup 2)))))
11932     (clobber (reg:CC FLAGS_REG))])
11933   (parallel
11934    [(set (match_dup 5)
11935          (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
11936                  (lshiftrt:SI (match_dup 3)
11937                               (minus:QI (const_int 32) (match_dup 2)))))
11938     (clobber (reg:CC FLAGS_REG))])]
11939  "split_di (&operands[0], 1, &operands[4], &operands[5]);")
11940
11941 (define_insn "*rotlsi3_1_one_bit_rex64"
11942   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11943         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11944                    (match_operand:QI 2 "const1_operand" "")))
11945    (clobber (reg:CC FLAGS_REG))]
11946   "TARGET_64BIT
11947    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11948    && ix86_binary_operator_ok (ROTATE, DImode, operands)"
11949   "rol{q}\t%0"
11950   [(set_attr "type" "rotate")
11951    (set_attr "length_immediate" "0")
11952    (set_attr "mode" "DI")])
11953
11954 (define_insn "*rotldi3_1_rex64"
11955   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11956         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11957                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
11958    (clobber (reg:CC FLAGS_REG))]
11959   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
11960   "@
11961    rol{q}\t{%2, %0|%0, %2}
11962    rol{q}\t{%b2, %0|%0, %b2}"
11963   [(set_attr "type" "rotate")
11964    (set_attr "mode" "DI")])
11965
11966 (define_expand "rotlsi3"
11967   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11968         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
11969                    (match_operand:QI 2 "nonmemory_operand" "")))]
11970   ""
11971   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
11972
11973 (define_insn "*rotlsi3_1_one_bit"
11974   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11975         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11976                    (match_operand:QI 2 "const1_operand" "")))
11977    (clobber (reg:CC FLAGS_REG))]
11978   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11979    && ix86_binary_operator_ok (ROTATE, SImode, operands)"
11980   "rol{l}\t%0"
11981   [(set_attr "type" "rotate")
11982    (set_attr "length_immediate" "0")
11983    (set_attr "mode" "SI")])
11984
11985 (define_insn "*rotlsi3_1_one_bit_zext"
11986   [(set (match_operand:DI 0 "register_operand" "=r")
11987         (zero_extend:DI
11988           (rotate:SI (match_operand:SI 1 "register_operand" "0")
11989                      (match_operand:QI 2 "const1_operand" ""))))
11990    (clobber (reg:CC FLAGS_REG))]
11991   "TARGET_64BIT
11992    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11993    && ix86_binary_operator_ok (ROTATE, SImode, operands)"
11994   "rol{l}\t%k0"
11995   [(set_attr "type" "rotate")
11996    (set_attr "length_immediate" "0")
11997    (set_attr "mode" "SI")])
11998
11999 (define_insn "*rotlsi3_1"
12000   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12001         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12002                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12003    (clobber (reg:CC FLAGS_REG))]
12004   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12005   "@
12006    rol{l}\t{%2, %0|%0, %2}
12007    rol{l}\t{%b2, %0|%0, %b2}"
12008   [(set_attr "type" "rotate")
12009    (set_attr "mode" "SI")])
12010
12011 (define_insn "*rotlsi3_1_zext"
12012   [(set (match_operand:DI 0 "register_operand" "=r,r")
12013         (zero_extend:DI
12014           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12015                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12016    (clobber (reg:CC FLAGS_REG))]
12017   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12018   "@
12019    rol{l}\t{%2, %k0|%k0, %2}
12020    rol{l}\t{%b2, %k0|%k0, %b2}"
12021   [(set_attr "type" "rotate")
12022    (set_attr "mode" "SI")])
12023
12024 (define_expand "rotlhi3"
12025   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12026         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12027                    (match_operand:QI 2 "nonmemory_operand" "")))]
12028   "TARGET_HIMODE_MATH"
12029   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12030
12031 (define_insn "*rotlhi3_1_one_bit"
12032   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12033         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12034                    (match_operand:QI 2 "const1_operand" "")))
12035    (clobber (reg:CC FLAGS_REG))]
12036   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12037    && ix86_binary_operator_ok (ROTATE, HImode, operands)"
12038   "rol{w}\t%0"
12039   [(set_attr "type" "rotate")
12040    (set_attr "length_immediate" "0")
12041    (set_attr "mode" "HI")])
12042
12043 (define_insn "*rotlhi3_1"
12044   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12045         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12046                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12047    (clobber (reg:CC FLAGS_REG))]
12048   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12049   "@
12050    rol{w}\t{%2, %0|%0, %2}
12051    rol{w}\t{%b2, %0|%0, %b2}"
12052   [(set_attr "type" "rotate")
12053    (set_attr "mode" "HI")])
12054
12055 (define_split
12056  [(set (match_operand:HI 0 "register_operand" "")
12057        (rotate:HI (match_dup 0) (const_int 8)))
12058   (clobber (reg:CC FLAGS_REG))]
12059  "reload_completed"
12060  [(parallel [(set (strict_low_part (match_dup 0))
12061                   (bswap:HI (match_dup 0)))
12062              (clobber (reg:CC FLAGS_REG))])]
12063  "")
12064
12065 (define_expand "rotlqi3"
12066   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12067         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12068                    (match_operand:QI 2 "nonmemory_operand" "")))]
12069   "TARGET_QIMODE_MATH"
12070   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12071
12072 (define_insn "*rotlqi3_1_one_bit_slp"
12073   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12074         (rotate:QI (match_dup 0)
12075                    (match_operand:QI 1 "const1_operand" "")))
12076    (clobber (reg:CC FLAGS_REG))]
12077   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12078    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
12079   "rol{b}\t%0"
12080   [(set_attr "type" "rotate1")
12081    (set_attr "length_immediate" "0")
12082    (set_attr "mode" "QI")])
12083
12084 (define_insn "*rotlqi3_1_one_bit"
12085   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12086         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12087                    (match_operand:QI 2 "const1_operand" "")))
12088    (clobber (reg:CC FLAGS_REG))]
12089   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12090    && ix86_binary_operator_ok (ROTATE, QImode, operands)"
12091   "rol{b}\t%0"
12092   [(set_attr "type" "rotate")
12093    (set_attr "length_immediate" "0")
12094    (set_attr "mode" "QI")])
12095
12096 (define_insn "*rotlqi3_1_slp"
12097   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12098         (rotate:QI (match_dup 0)
12099                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
12100    (clobber (reg:CC FLAGS_REG))]
12101   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12102    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12103   "@
12104    rol{b}\t{%1, %0|%0, %1}
12105    rol{b}\t{%b1, %0|%0, %b1}"
12106   [(set_attr "type" "rotate1")
12107    (set_attr "mode" "QI")])
12108
12109 (define_insn "*rotlqi3_1"
12110   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12111         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12112                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12113    (clobber (reg:CC FLAGS_REG))]
12114   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12115   "@
12116    rol{b}\t{%2, %0|%0, %2}
12117    rol{b}\t{%b2, %0|%0, %b2}"
12118   [(set_attr "type" "rotate")
12119    (set_attr "mode" "QI")])
12120
12121 (define_expand "rotrdi3"
12122   [(set (match_operand:DI 0 "shiftdi_operand" "")
12123         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12124                    (match_operand:QI 2 "nonmemory_operand" "")))]
12125  ""
12126 {
12127   if (TARGET_64BIT)
12128     {
12129       ix86_expand_binary_operator (ROTATERT, DImode, operands);
12130       DONE;
12131     }
12132   if (!const_1_to_31_operand (operands[2], VOIDmode))
12133     FAIL;
12134   emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
12135   DONE;
12136 })
12137
12138 ;; Implement rotation using two double-precision shift instructions
12139 ;; and a scratch register.
12140 (define_insn_and_split "ix86_rotrdi3"
12141  [(set (match_operand:DI 0 "register_operand" "=r")
12142        (rotatert:DI (match_operand:DI 1 "register_operand" "0")
12143                     (match_operand:QI 2 "const_1_to_31_operand" "I")))
12144   (clobber (reg:CC FLAGS_REG))
12145   (clobber (match_scratch:SI 3 "=&r"))]
12146  "!TARGET_64BIT"
12147  ""
12148  "&& reload_completed"
12149  [(set (match_dup 3) (match_dup 4))
12150   (parallel
12151    [(set (match_dup 4)
12152          (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
12153                  (ashift:SI (match_dup 5)
12154                             (minus:QI (const_int 32) (match_dup 2)))))
12155     (clobber (reg:CC FLAGS_REG))])
12156   (parallel
12157    [(set (match_dup 5)
12158          (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
12159                  (ashift:SI (match_dup 3)
12160                             (minus:QI (const_int 32) (match_dup 2)))))
12161     (clobber (reg:CC FLAGS_REG))])]
12162  "split_di (&operands[0], 1, &operands[4], &operands[5]);")
12163
12164 (define_insn "*rotrdi3_1_one_bit_rex64"
12165   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12166         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12167                      (match_operand:QI 2 "const1_operand" "")))
12168    (clobber (reg:CC FLAGS_REG))]
12169   "TARGET_64BIT
12170    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12171    && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12172   "ror{q}\t%0"
12173   [(set_attr "type" "rotate")
12174    (set_attr "length_immediate" "0")
12175    (set_attr "mode" "DI")])
12176
12177 (define_insn "*rotrdi3_1_rex64"
12178   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12179         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12180                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12181    (clobber (reg:CC FLAGS_REG))]
12182   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12183   "@
12184    ror{q}\t{%2, %0|%0, %2}
12185    ror{q}\t{%b2, %0|%0, %b2}"
12186   [(set_attr "type" "rotate")
12187    (set_attr "mode" "DI")])
12188
12189 (define_expand "rotrsi3"
12190   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12191         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12192                      (match_operand:QI 2 "nonmemory_operand" "")))]
12193   ""
12194   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12195
12196 (define_insn "*rotrsi3_1_one_bit"
12197   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12198         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12199                      (match_operand:QI 2 "const1_operand" "")))
12200    (clobber (reg:CC FLAGS_REG))]
12201   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12202    && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12203   "ror{l}\t%0"
12204   [(set_attr "type" "rotate")
12205    (set_attr "length_immediate" "0")
12206    (set_attr "mode" "SI")])
12207
12208 (define_insn "*rotrsi3_1_one_bit_zext"
12209   [(set (match_operand:DI 0 "register_operand" "=r")
12210         (zero_extend:DI
12211           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12212                        (match_operand:QI 2 "const1_operand" ""))))
12213    (clobber (reg:CC FLAGS_REG))]
12214   "TARGET_64BIT
12215    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12216    && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12217   "ror{l}\t%k0"
12218   [(set_attr "type" "rotate")
12219    (set_attr "length_immediate" "0")
12220    (set_attr "mode" "SI")])
12221
12222 (define_insn "*rotrsi3_1"
12223   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12224         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12225                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12226    (clobber (reg:CC FLAGS_REG))]
12227   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12228   "@
12229    ror{l}\t{%2, %0|%0, %2}
12230    ror{l}\t{%b2, %0|%0, %b2}"
12231   [(set_attr "type" "rotate")
12232    (set_attr "mode" "SI")])
12233
12234 (define_insn "*rotrsi3_1_zext"
12235   [(set (match_operand:DI 0 "register_operand" "=r,r")
12236         (zero_extend:DI
12237           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12238                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12239    (clobber (reg:CC FLAGS_REG))]
12240   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12241   "@
12242    ror{l}\t{%2, %k0|%k0, %2}
12243    ror{l}\t{%b2, %k0|%k0, %b2}"
12244   [(set_attr "type" "rotate")
12245    (set_attr "mode" "SI")])
12246
12247 (define_expand "rotrhi3"
12248   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12249         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12250                      (match_operand:QI 2 "nonmemory_operand" "")))]
12251   "TARGET_HIMODE_MATH"
12252   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12253
12254 (define_insn "*rotrhi3_one_bit"
12255   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12256         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12257                      (match_operand:QI 2 "const1_operand" "")))
12258    (clobber (reg:CC FLAGS_REG))]
12259   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12260    && ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12261   "ror{w}\t%0"
12262   [(set_attr "type" "rotate")
12263    (set_attr "length_immediate" "0")
12264    (set_attr "mode" "HI")])
12265
12266 (define_insn "*rotrhi3_1"
12267   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12268         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12269                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12270    (clobber (reg:CC FLAGS_REG))]
12271   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12272   "@
12273    ror{w}\t{%2, %0|%0, %2}
12274    ror{w}\t{%b2, %0|%0, %b2}"
12275   [(set_attr "type" "rotate")
12276    (set_attr "mode" "HI")])
12277
12278 (define_split
12279  [(set (match_operand:HI 0 "register_operand" "")
12280        (rotatert:HI (match_dup 0) (const_int 8)))
12281   (clobber (reg:CC FLAGS_REG))]
12282  "reload_completed"
12283  [(parallel [(set (strict_low_part (match_dup 0))
12284                   (bswap:HI (match_dup 0)))
12285              (clobber (reg:CC FLAGS_REG))])]
12286  "")
12287
12288 (define_expand "rotrqi3"
12289   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12290         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12291                      (match_operand:QI 2 "nonmemory_operand" "")))]
12292   "TARGET_QIMODE_MATH"
12293   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12294
12295 (define_insn "*rotrqi3_1_one_bit"
12296   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12297         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12298                      (match_operand:QI 2 "const1_operand" "")))
12299    (clobber (reg:CC FLAGS_REG))]
12300   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12301    && ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12302   "ror{b}\t%0"
12303   [(set_attr "type" "rotate")
12304    (set_attr "length_immediate" "0")
12305    (set_attr "mode" "QI")])
12306
12307 (define_insn "*rotrqi3_1_one_bit_slp"
12308   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12309         (rotatert:QI (match_dup 0)
12310                      (match_operand:QI 1 "const1_operand" "")))
12311    (clobber (reg:CC FLAGS_REG))]
12312   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12313    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
12314   "ror{b}\t%0"
12315   [(set_attr "type" "rotate1")
12316    (set_attr "length_immediate" "0")
12317    (set_attr "mode" "QI")])
12318
12319 (define_insn "*rotrqi3_1"
12320   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12321         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12322                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12323    (clobber (reg:CC FLAGS_REG))]
12324   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12325   "@
12326    ror{b}\t{%2, %0|%0, %2}
12327    ror{b}\t{%b2, %0|%0, %b2}"
12328   [(set_attr "type" "rotate")
12329    (set_attr "mode" "QI")])
12330
12331 (define_insn "*rotrqi3_1_slp"
12332   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12333         (rotatert:QI (match_dup 0)
12334                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12335    (clobber (reg:CC FLAGS_REG))]
12336   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12337    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12338   "@
12339    ror{b}\t{%1, %0|%0, %1}
12340    ror{b}\t{%b1, %0|%0, %b1}"
12341   [(set_attr "type" "rotate1")
12342    (set_attr "mode" "QI")])
12343 \f
12344 ;; Bit set / bit test instructions
12345
12346 (define_expand "extv"
12347   [(set (match_operand:SI 0 "register_operand" "")
12348         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12349                          (match_operand:SI 2 "const8_operand" "")
12350                          (match_operand:SI 3 "const8_operand" "")))]
12351   ""
12352 {
12353   /* Handle extractions from %ah et al.  */
12354   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12355     FAIL;
12356
12357   /* From mips.md: extract_bit_field doesn't verify that our source
12358      matches the predicate, so check it again here.  */
12359   if (! ext_register_operand (operands[1], VOIDmode))
12360     FAIL;
12361 })
12362
12363 (define_expand "extzv"
12364   [(set (match_operand:SI 0 "register_operand" "")
12365         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12366                          (match_operand:SI 2 "const8_operand" "")
12367                          (match_operand:SI 3 "const8_operand" "")))]
12368   ""
12369 {
12370   /* Handle extractions from %ah et al.  */
12371   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12372     FAIL;
12373
12374   /* From mips.md: extract_bit_field doesn't verify that our source
12375      matches the predicate, so check it again here.  */
12376   if (! ext_register_operand (operands[1], VOIDmode))
12377     FAIL;
12378 })
12379
12380 (define_expand "insv"
12381   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12382                       (match_operand 1 "const8_operand" "")
12383                       (match_operand 2 "const8_operand" ""))
12384         (match_operand 3 "register_operand" ""))]
12385   ""
12386 {
12387   /* Handle insertions to %ah et al.  */
12388   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12389     FAIL;
12390
12391   /* From mips.md: insert_bit_field doesn't verify that our source
12392      matches the predicate, so check it again here.  */
12393   if (! ext_register_operand (operands[0], VOIDmode))
12394     FAIL;
12395
12396   if (TARGET_64BIT)
12397     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
12398   else
12399     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
12400
12401   DONE;
12402 })
12403
12404 ;; %%% bts, btr, btc, bt.
12405 ;; In general these instructions are *slow* when applied to memory,
12406 ;; since they enforce atomic operation.  When applied to registers,
12407 ;; it depends on the cpu implementation.  They're never faster than
12408 ;; the corresponding and/ior/xor operations, so with 32-bit there's
12409 ;; no point.  But in 64-bit, we can't hold the relevant immediates
12410 ;; within the instruction itself, so operating on bits in the high
12411 ;; 32-bits of a register becomes easier.
12412 ;;
12413 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
12414 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
12415 ;; negdf respectively, so they can never be disabled entirely.
12416
12417 (define_insn "*btsq"
12418   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12419                          (const_int 1)
12420                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12421         (const_int 1))
12422    (clobber (reg:CC FLAGS_REG))]
12423   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12424   "bts{q}\t{%1, %0|%0, %1}"
12425   [(set_attr "type" "alu1")
12426    (set_attr "prefix_0f" "1")
12427    (set_attr "mode" "DI")])
12428
12429 (define_insn "*btrq"
12430   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12431                          (const_int 1)
12432                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12433         (const_int 0))
12434    (clobber (reg:CC FLAGS_REG))]
12435   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12436   "btr{q}\t{%1, %0|%0, %1}"
12437   [(set_attr "type" "alu1")
12438    (set_attr "prefix_0f" "1")
12439    (set_attr "mode" "DI")])
12440
12441 (define_insn "*btcq"
12442   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12443                          (const_int 1)
12444                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12445         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
12446    (clobber (reg:CC FLAGS_REG))]
12447   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12448   "btc{q}\t{%1, %0|%0, %1}"
12449   [(set_attr "type" "alu1")
12450    (set_attr "prefix_0f" "1")
12451    (set_attr "mode" "DI")])
12452
12453 ;; Allow Nocona to avoid these instructions if a register is available.
12454
12455 (define_peephole2
12456   [(match_scratch:DI 2 "r")
12457    (parallel [(set (zero_extract:DI
12458                      (match_operand:DI 0 "register_operand" "")
12459                      (const_int 1)
12460                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12461                    (const_int 1))
12462               (clobber (reg:CC FLAGS_REG))])]
12463   "TARGET_64BIT && !TARGET_USE_BT"
12464   [(const_int 0)]
12465 {
12466   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12467   rtx op1;
12468
12469   if (HOST_BITS_PER_WIDE_INT >= 64)
12470     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12471   else if (i < HOST_BITS_PER_WIDE_INT)
12472     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12473   else
12474     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12475
12476   op1 = immed_double_const (lo, hi, DImode);
12477   if (i >= 31)
12478     {
12479       emit_move_insn (operands[2], op1);
12480       op1 = operands[2];
12481     }
12482
12483   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
12484   DONE;
12485 })
12486
12487 (define_peephole2
12488   [(match_scratch:DI 2 "r")
12489    (parallel [(set (zero_extract:DI
12490                      (match_operand:DI 0 "register_operand" "")
12491                      (const_int 1)
12492                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12493                    (const_int 0))
12494               (clobber (reg:CC FLAGS_REG))])]
12495   "TARGET_64BIT && !TARGET_USE_BT"
12496   [(const_int 0)]
12497 {
12498   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12499   rtx op1;
12500
12501   if (HOST_BITS_PER_WIDE_INT >= 64)
12502     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12503   else if (i < HOST_BITS_PER_WIDE_INT)
12504     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12505   else
12506     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12507
12508   op1 = immed_double_const (~lo, ~hi, DImode);
12509   if (i >= 32)
12510     {
12511       emit_move_insn (operands[2], op1);
12512       op1 = operands[2];
12513     }
12514
12515   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
12516   DONE;
12517 })
12518
12519 (define_peephole2
12520   [(match_scratch:DI 2 "r")
12521    (parallel [(set (zero_extract:DI
12522                      (match_operand:DI 0 "register_operand" "")
12523                      (const_int 1)
12524                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12525               (not:DI (zero_extract:DI
12526                         (match_dup 0) (const_int 1) (match_dup 1))))
12527               (clobber (reg:CC FLAGS_REG))])]
12528   "TARGET_64BIT && !TARGET_USE_BT"
12529   [(const_int 0)]
12530 {
12531   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12532   rtx op1;
12533
12534   if (HOST_BITS_PER_WIDE_INT >= 64)
12535     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12536   else if (i < HOST_BITS_PER_WIDE_INT)
12537     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12538   else
12539     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12540
12541   op1 = immed_double_const (lo, hi, DImode);
12542   if (i >= 31)
12543     {
12544       emit_move_insn (operands[2], op1);
12545       op1 = operands[2];
12546     }
12547
12548   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
12549   DONE;
12550 })
12551
12552 (define_insn "*btdi_rex64"
12553   [(set (reg:CCC FLAGS_REG)
12554         (compare:CCC
12555           (zero_extract:DI
12556             (match_operand:DI 0 "register_operand" "r")
12557             (const_int 1)
12558             (match_operand:DI 1 "nonmemory_operand" "rN"))
12559           (const_int 0)))]
12560   "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
12561   "bt{q}\t{%1, %0|%0, %1}"
12562   [(set_attr "type" "alu1")
12563    (set_attr "prefix_0f" "1")
12564    (set_attr "mode" "DI")])
12565
12566 (define_insn "*btsi"
12567   [(set (reg:CCC FLAGS_REG)
12568         (compare:CCC
12569           (zero_extract:SI
12570             (match_operand:SI 0 "register_operand" "r")
12571             (const_int 1)
12572             (match_operand:SI 1 "nonmemory_operand" "rN"))
12573           (const_int 0)))]
12574   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
12575   "bt{l}\t{%1, %0|%0, %1}"
12576   [(set_attr "type" "alu1")
12577    (set_attr "prefix_0f" "1")
12578    (set_attr "mode" "SI")])
12579 \f
12580 ;; Store-flag instructions.
12581
12582 ;; For all sCOND expanders, also expand the compare or test insn that
12583 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
12584
12585 (define_insn_and_split "*setcc_di_1"
12586   [(set (match_operand:DI 0 "register_operand" "=q")
12587         (match_operator:DI 1 "ix86_comparison_operator"
12588           [(reg FLAGS_REG) (const_int 0)]))]
12589   "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
12590   "#"
12591   "&& reload_completed"
12592   [(set (match_dup 2) (match_dup 1))
12593    (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
12594 {
12595   PUT_MODE (operands[1], QImode);
12596   operands[2] = gen_lowpart (QImode, operands[0]);
12597 })
12598
12599 (define_insn_and_split "*setcc_si_1_and"
12600   [(set (match_operand:SI 0 "register_operand" "=q")
12601         (match_operator:SI 1 "ix86_comparison_operator"
12602           [(reg FLAGS_REG) (const_int 0)]))
12603    (clobber (reg:CC FLAGS_REG))]
12604   "!TARGET_PARTIAL_REG_STALL
12605    && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
12606   "#"
12607   "&& reload_completed"
12608   [(set (match_dup 2) (match_dup 1))
12609    (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
12610               (clobber (reg:CC FLAGS_REG))])]
12611 {
12612   PUT_MODE (operands[1], QImode);
12613   operands[2] = gen_lowpart (QImode, operands[0]);
12614 })
12615
12616 (define_insn_and_split "*setcc_si_1_movzbl"
12617   [(set (match_operand:SI 0 "register_operand" "=q")
12618         (match_operator:SI 1 "ix86_comparison_operator"
12619           [(reg FLAGS_REG) (const_int 0)]))]
12620   "!TARGET_PARTIAL_REG_STALL
12621    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
12622   "#"
12623   "&& reload_completed"
12624   [(set (match_dup 2) (match_dup 1))
12625    (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
12626 {
12627   PUT_MODE (operands[1], QImode);
12628   operands[2] = gen_lowpart (QImode, operands[0]);
12629 })
12630
12631 (define_insn "*setcc_qi"
12632   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12633         (match_operator:QI 1 "ix86_comparison_operator"
12634           [(reg FLAGS_REG) (const_int 0)]))]
12635   ""
12636   "set%C1\t%0"
12637   [(set_attr "type" "setcc")
12638    (set_attr "mode" "QI")])
12639
12640 (define_insn "*setcc_qi_slp"
12641   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12642         (match_operator:QI 1 "ix86_comparison_operator"
12643           [(reg FLAGS_REG) (const_int 0)]))]
12644   ""
12645   "set%C1\t%0"
12646   [(set_attr "type" "setcc")
12647    (set_attr "mode" "QI")])
12648
12649 ;; In general it is not safe to assume too much about CCmode registers,
12650 ;; so simplify-rtx stops when it sees a second one.  Under certain
12651 ;; conditions this is safe on x86, so help combine not create
12652 ;;
12653 ;;      seta    %al
12654 ;;      testb   %al, %al
12655 ;;      sete    %al
12656
12657 (define_split
12658   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12659         (ne:QI (match_operator 1 "ix86_comparison_operator"
12660                  [(reg FLAGS_REG) (const_int 0)])
12661             (const_int 0)))]
12662   ""
12663   [(set (match_dup 0) (match_dup 1))]
12664 {
12665   PUT_MODE (operands[1], QImode);
12666 })
12667
12668 (define_split
12669   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12670         (ne:QI (match_operator 1 "ix86_comparison_operator"
12671                  [(reg FLAGS_REG) (const_int 0)])
12672             (const_int 0)))]
12673   ""
12674   [(set (match_dup 0) (match_dup 1))]
12675 {
12676   PUT_MODE (operands[1], QImode);
12677 })
12678
12679 (define_split
12680   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12681         (eq:QI (match_operator 1 "ix86_comparison_operator"
12682                  [(reg FLAGS_REG) (const_int 0)])
12683             (const_int 0)))]
12684   ""
12685   [(set (match_dup 0) (match_dup 1))]
12686 {
12687   rtx new_op1 = copy_rtx (operands[1]);
12688   operands[1] = new_op1;
12689   PUT_MODE (new_op1, QImode);
12690   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12691                                              GET_MODE (XEXP (new_op1, 0))));
12692
12693   /* Make sure that (a) the CCmode we have for the flags is strong
12694      enough for the reversed compare or (b) we have a valid FP compare.  */
12695   if (! ix86_comparison_operator (new_op1, VOIDmode))
12696     FAIL;
12697 })
12698
12699 (define_split
12700   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12701         (eq:QI (match_operator 1 "ix86_comparison_operator"
12702                  [(reg FLAGS_REG) (const_int 0)])
12703             (const_int 0)))]
12704   ""
12705   [(set (match_dup 0) (match_dup 1))]
12706 {
12707   rtx new_op1 = copy_rtx (operands[1]);
12708   operands[1] = new_op1;
12709   PUT_MODE (new_op1, QImode);
12710   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12711                                              GET_MODE (XEXP (new_op1, 0))));
12712
12713   /* Make sure that (a) the CCmode we have for the flags is strong
12714      enough for the reversed compare or (b) we have a valid FP compare.  */
12715   if (! ix86_comparison_operator (new_op1, VOIDmode))
12716     FAIL;
12717 })
12718
12719 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12720 ;; subsequent logical operations are used to imitate conditional moves.
12721 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12722 ;; it directly.
12723
12724 (define_insn "*avx_setcc<mode>"
12725   [(set (match_operand:MODEF 0 "register_operand" "=x")
12726         (match_operator:MODEF 1 "avx_comparison_float_operator"
12727           [(match_operand:MODEF 2 "register_operand" "x")
12728            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
12729   "TARGET_AVX"
12730   "vcmp%D1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
12731   [(set_attr "type" "ssecmp")
12732    (set_attr "prefix" "vex")
12733    (set_attr "length_immediate" "1")
12734    (set_attr "mode" "<MODE>")])
12735
12736 (define_insn "*sse_setcc<mode>"
12737   [(set (match_operand:MODEF 0 "register_operand" "=x")
12738         (match_operator:MODEF 1 "sse_comparison_operator"
12739           [(match_operand:MODEF 2 "register_operand" "0")
12740            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
12741   "SSE_FLOAT_MODE_P (<MODE>mode)"
12742   "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
12743   [(set_attr "type" "ssecmp")
12744    (set_attr "length_immediate" "1")
12745    (set_attr "mode" "<MODE>")])
12746 \f
12747 ;; Basic conditional jump instructions.
12748 ;; We ignore the overflow flag for signed branch instructions.
12749
12750 (define_insn "*jcc_1"
12751   [(set (pc)
12752         (if_then_else (match_operator 1 "ix86_comparison_operator"
12753                                       [(reg FLAGS_REG) (const_int 0)])
12754                       (label_ref (match_operand 0 "" ""))
12755                       (pc)))]
12756   ""
12757   "%+j%C1\t%l0"
12758   [(set_attr "type" "ibr")
12759    (set_attr "modrm" "0")
12760    (set (attr "length")
12761            (if_then_else (and (ge (minus (match_dup 0) (pc))
12762                                   (const_int -126))
12763                               (lt (minus (match_dup 0) (pc))
12764                                   (const_int 128)))
12765              (const_int 2)
12766              (const_int 6)))])
12767
12768 (define_insn "*jcc_2"
12769   [(set (pc)
12770         (if_then_else (match_operator 1 "ix86_comparison_operator"
12771                                       [(reg FLAGS_REG) (const_int 0)])
12772                       (pc)
12773                       (label_ref (match_operand 0 "" ""))))]
12774   ""
12775   "%+j%c1\t%l0"
12776   [(set_attr "type" "ibr")
12777    (set_attr "modrm" "0")
12778    (set (attr "length")
12779            (if_then_else (and (ge (minus (match_dup 0) (pc))
12780                                   (const_int -126))
12781                               (lt (minus (match_dup 0) (pc))
12782                                   (const_int 128)))
12783              (const_int 2)
12784              (const_int 6)))])
12785
12786 ;; In general it is not safe to assume too much about CCmode registers,
12787 ;; so simplify-rtx stops when it sees a second one.  Under certain
12788 ;; conditions this is safe on x86, so help combine not create
12789 ;;
12790 ;;      seta    %al
12791 ;;      testb   %al, %al
12792 ;;      je      Lfoo
12793
12794 (define_split
12795   [(set (pc)
12796         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
12797                                       [(reg FLAGS_REG) (const_int 0)])
12798                           (const_int 0))
12799                       (label_ref (match_operand 1 "" ""))
12800                       (pc)))]
12801   ""
12802   [(set (pc)
12803         (if_then_else (match_dup 0)
12804                       (label_ref (match_dup 1))
12805                       (pc)))]
12806 {
12807   PUT_MODE (operands[0], VOIDmode);
12808 })
12809
12810 (define_split
12811   [(set (pc)
12812         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
12813                                       [(reg FLAGS_REG) (const_int 0)])
12814                           (const_int 0))
12815                       (label_ref (match_operand 1 "" ""))
12816                       (pc)))]
12817   ""
12818   [(set (pc)
12819         (if_then_else (match_dup 0)
12820                       (label_ref (match_dup 1))
12821                       (pc)))]
12822 {
12823   rtx new_op0 = copy_rtx (operands[0]);
12824   operands[0] = new_op0;
12825   PUT_MODE (new_op0, VOIDmode);
12826   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
12827                                              GET_MODE (XEXP (new_op0, 0))));
12828
12829   /* Make sure that (a) the CCmode we have for the flags is strong
12830      enough for the reversed compare or (b) we have a valid FP compare.  */
12831   if (! ix86_comparison_operator (new_op0, VOIDmode))
12832     FAIL;
12833 })
12834
12835 ;; zero_extend in SImode is correct, since this is what combine pass
12836 ;; generates from shift insn with QImode operand.  Actually, the mode of
12837 ;; operand 2 (bit offset operand) doesn't matter since bt insn takes
12838 ;; appropriate modulo of the bit offset value.
12839
12840 (define_insn_and_split "*jcc_btdi_rex64"
12841   [(set (pc)
12842         (if_then_else (match_operator 0 "bt_comparison_operator"
12843                         [(zero_extract:DI
12844                            (match_operand:DI 1 "register_operand" "r")
12845                            (const_int 1)
12846                            (zero_extend:SI
12847                              (match_operand:QI 2 "register_operand" "r")))
12848                          (const_int 0)])
12849                       (label_ref (match_operand 3 "" ""))
12850                       (pc)))
12851    (clobber (reg:CC FLAGS_REG))]
12852   "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
12853   "#"
12854   "&& 1"
12855   [(set (reg:CCC FLAGS_REG)
12856         (compare:CCC
12857           (zero_extract:DI
12858             (match_dup 1)
12859             (const_int 1)
12860             (match_dup 2))
12861           (const_int 0)))
12862    (set (pc)
12863         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
12864                       (label_ref (match_dup 3))
12865                       (pc)))]
12866 {
12867   operands[2] = simplify_gen_subreg (DImode, operands[2], QImode, 0);
12868
12869   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
12870 })
12871
12872 ;; avoid useless masking of bit offset operand
12873 (define_insn_and_split "*jcc_btdi_mask_rex64"
12874   [(set (pc)
12875         (if_then_else (match_operator 0 "bt_comparison_operator"
12876                         [(zero_extract:DI
12877                            (match_operand:DI 1 "register_operand" "r")
12878                            (const_int 1)
12879                            (and:SI
12880                              (match_operand:SI 2 "register_operand" "r")
12881                              (match_operand:SI 3 "const_int_operand" "n")))])
12882                       (label_ref (match_operand 4 "" ""))
12883                       (pc)))
12884    (clobber (reg:CC FLAGS_REG))]
12885   "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))
12886    && (INTVAL (operands[3]) & 0x3f) == 0x3f"
12887   "#"
12888   "&& 1"
12889   [(set (reg:CCC FLAGS_REG)
12890         (compare:CCC
12891           (zero_extract:DI
12892             (match_dup 1)
12893             (const_int 1)
12894             (match_dup 2))
12895           (const_int 0)))
12896    (set (pc)
12897         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
12898                       (label_ref (match_dup 4))
12899                       (pc)))]
12900 {
12901   operands[2] = simplify_gen_subreg (DImode, operands[2], SImode, 0);
12902
12903   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
12904 })
12905
12906 (define_insn_and_split "*jcc_btsi"
12907   [(set (pc)
12908         (if_then_else (match_operator 0 "bt_comparison_operator"
12909                         [(zero_extract:SI
12910                            (match_operand:SI 1 "register_operand" "r")
12911                            (const_int 1)
12912                            (zero_extend:SI
12913                              (match_operand:QI 2 "register_operand" "r")))
12914                          (const_int 0)])
12915                       (label_ref (match_operand 3 "" ""))
12916                       (pc)))
12917    (clobber (reg:CC FLAGS_REG))]
12918   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
12919   "#"
12920   "&& 1"
12921   [(set (reg:CCC FLAGS_REG)
12922         (compare:CCC
12923           (zero_extract:SI
12924             (match_dup 1)
12925             (const_int 1)
12926             (match_dup 2))
12927           (const_int 0)))
12928    (set (pc)
12929         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
12930                       (label_ref (match_dup 3))
12931                       (pc)))]
12932 {
12933   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
12934
12935   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
12936 })
12937
12938 ;; avoid useless masking of bit offset operand
12939 (define_insn_and_split "*jcc_btsi_mask"
12940   [(set (pc)
12941         (if_then_else (match_operator 0 "bt_comparison_operator"
12942                         [(zero_extract:SI
12943                            (match_operand:SI 1 "register_operand" "r")
12944                            (const_int 1)
12945                            (and:SI
12946                              (match_operand:SI 2 "register_operand" "r")
12947                              (match_operand:SI 3 "const_int_operand" "n")))])
12948                       (label_ref (match_operand 4 "" ""))
12949                       (pc)))
12950    (clobber (reg:CC FLAGS_REG))]
12951   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
12952    && (INTVAL (operands[3]) & 0x1f) == 0x1f"
12953   "#"
12954   "&& 1"
12955   [(set (reg:CCC FLAGS_REG)
12956         (compare:CCC
12957           (zero_extract:SI
12958             (match_dup 1)
12959             (const_int 1)
12960             (match_dup 2))
12961           (const_int 0)))
12962    (set (pc)
12963         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
12964                       (label_ref (match_dup 4))
12965                       (pc)))]
12966   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
12967
12968 (define_insn_and_split "*jcc_btsi_1"
12969   [(set (pc)
12970         (if_then_else (match_operator 0 "bt_comparison_operator"
12971                         [(and:SI
12972                            (lshiftrt:SI
12973                              (match_operand:SI 1 "register_operand" "r")
12974                              (match_operand:QI 2 "register_operand" "r"))
12975                            (const_int 1))
12976                          (const_int 0)])
12977                       (label_ref (match_operand 3 "" ""))
12978                       (pc)))
12979    (clobber (reg:CC FLAGS_REG))]
12980   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
12981   "#"
12982   "&& 1"
12983   [(set (reg:CCC FLAGS_REG)
12984         (compare:CCC
12985           (zero_extract:SI
12986             (match_dup 1)
12987             (const_int 1)
12988             (match_dup 2))
12989           (const_int 0)))
12990    (set (pc)
12991         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
12992                       (label_ref (match_dup 3))
12993                       (pc)))]
12994 {
12995   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
12996
12997   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
12998 })
12999
13000 ;; avoid useless masking of bit offset operand
13001 (define_insn_and_split "*jcc_btsi_mask_1"
13002   [(set (pc)
13003         (if_then_else
13004           (match_operator 0 "bt_comparison_operator"
13005             [(and:SI
13006                (lshiftrt:SI
13007                  (match_operand:SI 1 "register_operand" "r")
13008                  (subreg:QI
13009                    (and:SI
13010                      (match_operand:SI 2 "register_operand" "r")
13011                      (match_operand:SI 3 "const_int_operand" "n")) 0))
13012                (const_int 1))
13013              (const_int 0)])
13014           (label_ref (match_operand 4 "" ""))
13015           (pc)))
13016    (clobber (reg:CC FLAGS_REG))]
13017   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
13018    && (INTVAL (operands[3]) & 0x1f) == 0x1f"
13019   "#"
13020   "&& 1"
13021   [(set (reg:CCC FLAGS_REG)
13022         (compare:CCC
13023           (zero_extract:SI
13024             (match_dup 1)
13025             (const_int 1)
13026             (match_dup 2))
13027           (const_int 0)))
13028    (set (pc)
13029         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
13030                       (label_ref (match_dup 4))
13031                       (pc)))]
13032   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
13033
13034 ;; Define combination compare-and-branch fp compare instructions to help
13035 ;; combine.
13036
13037 (define_insn "*fp_jcc_3_387"
13038   [(set (pc)
13039         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13040                         [(match_operand 1 "register_operand" "f")
13041                          (match_operand 2 "nonimmediate_operand" "fm")])
13042           (label_ref (match_operand 3 "" ""))
13043           (pc)))
13044    (clobber (reg:CCFP FPSR_REG))
13045    (clobber (reg:CCFP FLAGS_REG))
13046    (clobber (match_scratch:HI 4 "=a"))]
13047   "TARGET_80387
13048    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13049    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13050    && SELECT_CC_MODE (GET_CODE (operands[0]),
13051                       operands[1], operands[2]) == CCFPmode
13052    && !TARGET_CMOVE"
13053   "#")
13054
13055 (define_insn "*fp_jcc_4_387"
13056   [(set (pc)
13057         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13058                         [(match_operand 1 "register_operand" "f")
13059                          (match_operand 2 "nonimmediate_operand" "fm")])
13060           (pc)
13061           (label_ref (match_operand 3 "" ""))))
13062    (clobber (reg:CCFP FPSR_REG))
13063    (clobber (reg:CCFP FLAGS_REG))
13064    (clobber (match_scratch:HI 4 "=a"))]
13065   "TARGET_80387
13066    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13067    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13068    && SELECT_CC_MODE (GET_CODE (operands[0]),
13069                       operands[1], operands[2]) == CCFPmode
13070    && !TARGET_CMOVE"
13071   "#")
13072
13073 (define_insn "*fp_jcc_5_387"
13074   [(set (pc)
13075         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13076                         [(match_operand 1 "register_operand" "f")
13077                          (match_operand 2 "register_operand" "f")])
13078           (label_ref (match_operand 3 "" ""))
13079           (pc)))
13080    (clobber (reg:CCFP FPSR_REG))
13081    (clobber (reg:CCFP FLAGS_REG))
13082    (clobber (match_scratch:HI 4 "=a"))]
13083   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
13084    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13085    && !TARGET_CMOVE"
13086   "#")
13087
13088 (define_insn "*fp_jcc_6_387"
13089   [(set (pc)
13090         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13091                         [(match_operand 1 "register_operand" "f")
13092                          (match_operand 2 "register_operand" "f")])
13093           (pc)
13094           (label_ref (match_operand 3 "" ""))))
13095    (clobber (reg:CCFP FPSR_REG))
13096    (clobber (reg:CCFP FLAGS_REG))
13097    (clobber (match_scratch:HI 4 "=a"))]
13098   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
13099    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13100    && !TARGET_CMOVE"
13101   "#")
13102
13103 (define_insn "*fp_jcc_7_387"
13104   [(set (pc)
13105         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13106                         [(match_operand 1 "register_operand" "f")
13107                          (match_operand 2 "const0_operand" "")])
13108           (label_ref (match_operand 3 "" ""))
13109           (pc)))
13110    (clobber (reg:CCFP FPSR_REG))
13111    (clobber (reg:CCFP FLAGS_REG))
13112    (clobber (match_scratch:HI 4 "=a"))]
13113   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
13114    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13115    && SELECT_CC_MODE (GET_CODE (operands[0]),
13116                       operands[1], operands[2]) == CCFPmode
13117    && !TARGET_CMOVE"
13118   "#")
13119
13120 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
13121 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13122 ;; with a precedence over other operators and is always put in the first
13123 ;; place. Swap condition and operands to match ficom instruction.
13124
13125 (define_insn "*fp_jcc_8<mode>_387"
13126   [(set (pc)
13127         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13128                         [(match_operator 1 "float_operator"
13129                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
13130                            (match_operand 3 "register_operand" "f,f")])
13131           (label_ref (match_operand 4 "" ""))
13132           (pc)))
13133    (clobber (reg:CCFP FPSR_REG))
13134    (clobber (reg:CCFP FLAGS_REG))
13135    (clobber (match_scratch:HI 5 "=a,a"))]
13136   "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
13137    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
13138    && GET_MODE (operands[1]) == GET_MODE (operands[3])
13139    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13140    && !TARGET_CMOVE"
13141   "#")
13142
13143 (define_split
13144   [(set (pc)
13145         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13146                         [(match_operand 1 "register_operand" "")
13147                          (match_operand 2 "nonimmediate_operand" "")])
13148           (match_operand 3 "" "")
13149           (match_operand 4 "" "")))
13150    (clobber (reg:CCFP FPSR_REG))
13151    (clobber (reg:CCFP FLAGS_REG))]
13152   "reload_completed"
13153   [(const_int 0)]
13154 {
13155   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13156                         operands[3], operands[4], NULL_RTX, NULL_RTX);
13157   DONE;
13158 })
13159
13160 (define_split
13161   [(set (pc)
13162         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13163                         [(match_operand 1 "register_operand" "")
13164                          (match_operand 2 "general_operand" "")])
13165           (match_operand 3 "" "")
13166           (match_operand 4 "" "")))
13167    (clobber (reg:CCFP FPSR_REG))
13168    (clobber (reg:CCFP FLAGS_REG))
13169    (clobber (match_scratch:HI 5 "=a"))]
13170   "reload_completed"
13171   [(const_int 0)]
13172 {
13173   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13174                         operands[3], operands[4], operands[5], NULL_RTX);
13175   DONE;
13176 })
13177
13178 (define_split
13179   [(set (pc)
13180         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13181                         [(match_operator 1 "float_operator"
13182                            [(match_operand:X87MODEI12 2 "memory_operand" "")])
13183                            (match_operand 3 "register_operand" "")])
13184           (match_operand 4 "" "")
13185           (match_operand 5 "" "")))
13186    (clobber (reg:CCFP FPSR_REG))
13187    (clobber (reg:CCFP FLAGS_REG))
13188    (clobber (match_scratch:HI 6 "=a"))]
13189   "reload_completed"
13190   [(const_int 0)]
13191 {
13192   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13193   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13194                         operands[3], operands[7],
13195                         operands[4], operands[5], operands[6], NULL_RTX);
13196   DONE;
13197 })
13198
13199 ;; %%% Kill this when reload knows how to do it.
13200 (define_split
13201   [(set (pc)
13202         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13203                         [(match_operator 1 "float_operator"
13204                            [(match_operand:X87MODEI12 2 "register_operand" "")])
13205                            (match_operand 3 "register_operand" "")])
13206           (match_operand 4 "" "")
13207           (match_operand 5 "" "")))
13208    (clobber (reg:CCFP FPSR_REG))
13209    (clobber (reg:CCFP FLAGS_REG))
13210    (clobber (match_scratch:HI 6 "=a"))]
13211   "reload_completed"
13212   [(const_int 0)]
13213 {
13214   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13215   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13216   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13217                         operands[3], operands[7],
13218                         operands[4], operands[5], operands[6], operands[2]);
13219   DONE;
13220 })
13221 \f
13222 ;; Unconditional and other jump instructions
13223
13224 (define_insn "jump"
13225   [(set (pc)
13226         (label_ref (match_operand 0 "" "")))]
13227   ""
13228   "jmp\t%l0"
13229   [(set_attr "type" "ibr")
13230    (set (attr "length")
13231            (if_then_else (and (ge (minus (match_dup 0) (pc))
13232                                   (const_int -126))
13233                               (lt (minus (match_dup 0) (pc))
13234                                   (const_int 128)))
13235              (const_int 2)
13236              (const_int 5)))
13237    (set_attr "modrm" "0")])
13238
13239 (define_expand "indirect_jump"
13240   [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
13241   ""
13242   "")
13243
13244 (define_insn "*indirect_jump"
13245   [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
13246   ""
13247   "jmp\t%A0"
13248   [(set_attr "type" "ibr")
13249    (set_attr "length_immediate" "0")])
13250
13251 (define_expand "tablejump"
13252   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
13253               (use (label_ref (match_operand 1 "" "")))])]
13254   ""
13255 {
13256   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13257      relative.  Convert the relative address to an absolute address.  */
13258   if (flag_pic)
13259     {
13260       rtx op0, op1;
13261       enum rtx_code code;
13262
13263       /* We can't use @GOTOFF for text labels on VxWorks;
13264          see gotoff_operand.  */
13265       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
13266         {
13267           code = PLUS;
13268           op0 = operands[0];
13269           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13270         }
13271       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13272         {
13273           code = PLUS;
13274           op0 = operands[0];
13275           op1 = pic_offset_table_rtx;
13276         }
13277       else
13278         {
13279           code = MINUS;
13280           op0 = pic_offset_table_rtx;
13281           op1 = operands[0];
13282         }
13283
13284       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13285                                          OPTAB_DIRECT);
13286     }
13287 })
13288
13289 (define_insn "*tablejump_1"
13290   [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
13291    (use (label_ref (match_operand 1 "" "")))]
13292   ""
13293   "jmp\t%A0"
13294   [(set_attr "type" "ibr")
13295    (set_attr "length_immediate" "0")])
13296 \f
13297 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13298
13299 (define_peephole2
13300   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13301    (set (match_operand:QI 1 "register_operand" "")
13302         (match_operator:QI 2 "ix86_comparison_operator"
13303           [(reg FLAGS_REG) (const_int 0)]))
13304    (set (match_operand 3 "q_regs_operand" "")
13305         (zero_extend (match_dup 1)))]
13306   "(peep2_reg_dead_p (3, operands[1])
13307     || operands_match_p (operands[1], operands[3]))
13308    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13309   [(set (match_dup 4) (match_dup 0))
13310    (set (strict_low_part (match_dup 5))
13311         (match_dup 2))]
13312 {
13313   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13314   operands[5] = gen_lowpart (QImode, operands[3]);
13315   ix86_expand_clear (operands[3]);
13316 })
13317
13318 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13319
13320 (define_peephole2
13321   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13322    (set (match_operand:QI 1 "register_operand" "")
13323         (match_operator:QI 2 "ix86_comparison_operator"
13324           [(reg FLAGS_REG) (const_int 0)]))
13325    (parallel [(set (match_operand 3 "q_regs_operand" "")
13326                    (zero_extend (match_dup 1)))
13327               (clobber (reg:CC FLAGS_REG))])]
13328   "(peep2_reg_dead_p (3, operands[1])
13329     || operands_match_p (operands[1], operands[3]))
13330    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13331   [(set (match_dup 4) (match_dup 0))
13332    (set (strict_low_part (match_dup 5))
13333         (match_dup 2))]
13334 {
13335   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13336   operands[5] = gen_lowpart (QImode, operands[3]);
13337   ix86_expand_clear (operands[3]);
13338 })
13339 \f
13340 ;; Call instructions.
13341
13342 ;; The predicates normally associated with named expanders are not properly
13343 ;; checked for calls.  This is a bug in the generic code, but it isn't that
13344 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
13345
13346 ;; P6 processors will jump to the address after the decrement when %esp
13347 ;; is used as a call operand, so they will execute return address as a code.
13348 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
13349  
13350 ;; Call subroutine returning no value.
13351
13352 (define_expand "call_pop"
13353   [(parallel [(call (match_operand:QI 0 "" "")
13354                     (match_operand:SI 1 "" ""))
13355               (set (reg:SI SP_REG)
13356                    (plus:SI (reg:SI SP_REG)
13357                             (match_operand:SI 3 "" "")))])]
13358   "!TARGET_64BIT"
13359 {
13360   ix86_expand_call (NULL, operands[0], operands[1],
13361                     operands[2], operands[3], 0);
13362   DONE;
13363 })
13364
13365 (define_insn "*call_pop_0"
13366   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13367          (match_operand:SI 1 "" ""))
13368    (set (reg:SI SP_REG)
13369         (plus:SI (reg:SI SP_REG)
13370                  (match_operand:SI 2 "immediate_operand" "")))]
13371   "!TARGET_64BIT"
13372 {
13373   if (SIBLING_CALL_P (insn))
13374     return "jmp\t%P0";
13375   else
13376     return "call\t%P0";
13377 }
13378   [(set_attr "type" "call")])
13379
13380 (define_insn "*call_pop_1"
13381   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
13382          (match_operand:SI 1 "" ""))
13383    (set (reg:SI SP_REG)
13384         (plus:SI (reg:SI SP_REG)
13385                  (match_operand:SI 2 "immediate_operand" "i")))]
13386   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
13387 {
13388   if (constant_call_address_operand (operands[0], Pmode))
13389     return "call\t%P0";
13390   return "call\t%A0";
13391 }
13392   [(set_attr "type" "call")])
13393
13394 (define_insn "*sibcall_pop_1"
13395   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
13396          (match_operand:SI 1 "" ""))
13397    (set (reg:SI SP_REG)
13398         (plus:SI (reg:SI SP_REG)
13399                  (match_operand:SI 2 "immediate_operand" "i,i")))]
13400   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
13401   "@
13402    jmp\t%P0
13403    jmp\t%A0"
13404   [(set_attr "type" "call")])
13405
13406 (define_expand "call"
13407   [(call (match_operand:QI 0 "" "")
13408          (match_operand 1 "" ""))
13409    (use (match_operand 2 "" ""))]
13410   ""
13411 {
13412   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
13413   DONE;
13414 })
13415
13416 (define_expand "sibcall"
13417   [(call (match_operand:QI 0 "" "")
13418          (match_operand 1 "" ""))
13419    (use (match_operand 2 "" ""))]
13420   ""
13421 {
13422   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
13423   DONE;
13424 })
13425
13426 (define_insn "*call_0"
13427   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13428          (match_operand 1 "" ""))]
13429   ""
13430 {
13431   if (SIBLING_CALL_P (insn))
13432     return "jmp\t%P0";
13433   else
13434     return "call\t%P0";
13435 }
13436   [(set_attr "type" "call")])
13437
13438 (define_insn "*call_1"
13439   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
13440          (match_operand 1 "" ""))]
13441   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
13442 {
13443   if (constant_call_address_operand (operands[0], Pmode))
13444     return "call\t%P0";
13445   return "call\t%A0";
13446 }
13447   [(set_attr "type" "call")])
13448
13449 (define_insn "*sibcall_1"
13450   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
13451          (match_operand 1 "" ""))]
13452   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
13453   "@
13454    jmp\t%P0
13455    jmp\t%A0"
13456   [(set_attr "type" "call")])
13457
13458 (define_insn "*call_1_rex64"
13459   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13460          (match_operand 1 "" ""))]
13461   "TARGET_64BIT && !SIBLING_CALL_P (insn)
13462    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
13463 {
13464   if (constant_call_address_operand (operands[0], Pmode))
13465     return "call\t%P0";
13466   return "call\t%A0";
13467 }
13468   [(set_attr "type" "call")])
13469
13470 (define_insn "*call_1_rex64_ms_sysv"
13471   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13472          (match_operand 1 "" ""))
13473    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
13474    (clobber (reg:TI XMM6_REG))
13475    (clobber (reg:TI XMM7_REG))
13476    (clobber (reg:TI XMM8_REG))
13477    (clobber (reg:TI XMM9_REG))
13478    (clobber (reg:TI XMM10_REG))
13479    (clobber (reg:TI XMM11_REG))
13480    (clobber (reg:TI XMM12_REG))
13481    (clobber (reg:TI XMM13_REG))
13482    (clobber (reg:TI XMM14_REG))
13483    (clobber (reg:TI XMM15_REG))
13484    (clobber (reg:DI SI_REG))
13485    (clobber (reg:DI DI_REG))]
13486   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
13487 {
13488   if (constant_call_address_operand (operands[0], Pmode))
13489     return "call\t%P0";
13490   return "call\t%A0";
13491 }
13492   [(set_attr "type" "call")])
13493
13494 (define_insn "*call_1_rex64_large"
13495   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
13496          (match_operand 1 "" ""))]
13497   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
13498   "call\t%A0"
13499   [(set_attr "type" "call")])
13500
13501 (define_insn "*sibcall_1_rex64"
13502   [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
13503          (match_operand 1 "" ""))]
13504   "TARGET_64BIT && SIBLING_CALL_P (insn)"
13505   "@
13506    jmp\t%P0
13507    jmp\t%A0"
13508   [(set_attr "type" "call")])
13509
13510 ;; Call subroutine, returning value in operand 0
13511 (define_expand "call_value_pop"
13512   [(parallel [(set (match_operand 0 "" "")
13513                    (call (match_operand:QI 1 "" "")
13514                          (match_operand:SI 2 "" "")))
13515               (set (reg:SI SP_REG)
13516                    (plus:SI (reg:SI SP_REG)
13517                             (match_operand:SI 4 "" "")))])]
13518   "!TARGET_64BIT"
13519 {
13520   ix86_expand_call (operands[0], operands[1], operands[2],
13521                     operands[3], operands[4], 0);
13522   DONE;
13523 })
13524
13525 (define_expand "call_value"
13526   [(set (match_operand 0 "" "")
13527         (call (match_operand:QI 1 "" "")
13528               (match_operand:SI 2 "" "")))
13529    (use (match_operand:SI 3 "" ""))]
13530   ;; Operand 3 is not used on the i386.
13531   ""
13532 {
13533   ix86_expand_call (operands[0], operands[1], operands[2],
13534                     operands[3], NULL, 0);
13535   DONE;
13536 })
13537
13538 (define_expand "sibcall_value"
13539   [(set (match_operand 0 "" "")
13540         (call (match_operand:QI 1 "" "")
13541               (match_operand:SI 2 "" "")))
13542    (use (match_operand:SI 3 "" ""))]
13543   ;; Operand 3 is not used on the i386.
13544   ""
13545 {
13546   ix86_expand_call (operands[0], operands[1], operands[2],
13547                     operands[3], NULL, 1);
13548   DONE;
13549 })
13550
13551 ;; Call subroutine returning any type.
13552
13553 (define_expand "untyped_call"
13554   [(parallel [(call (match_operand 0 "" "")
13555                     (const_int 0))
13556               (match_operand 1 "" "")
13557               (match_operand 2 "" "")])]
13558   ""
13559 {
13560   int i;
13561
13562   /* In order to give reg-stack an easier job in validating two
13563      coprocessor registers as containing a possible return value,
13564      simply pretend the untyped call returns a complex long double
13565      value. 
13566
13567      We can't use SSE_REGPARM_MAX here since callee is unprototyped
13568      and should have the default ABI.  */
13569
13570   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13571                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13572                     operands[0], const0_rtx,
13573                     GEN_INT ((TARGET_64BIT
13574                               ? (ix86_abi == SYSV_ABI
13575                                  ? X86_64_SSE_REGPARM_MAX
13576                                  : X86_64_MS_SSE_REGPARM_MAX)
13577                               : X86_32_SSE_REGPARM_MAX)
13578                              - 1),
13579                     NULL, 0);
13580
13581   for (i = 0; i < XVECLEN (operands[2], 0); i++)
13582     {
13583       rtx set = XVECEXP (operands[2], 0, i);
13584       emit_move_insn (SET_DEST (set), SET_SRC (set));
13585     }
13586
13587   /* The optimizer does not know that the call sets the function value
13588      registers we stored in the result block.  We avoid problems by
13589      claiming that all hard registers are used and clobbered at this
13590      point.  */
13591   emit_insn (gen_blockage ());
13592
13593   DONE;
13594 })
13595 \f
13596 ;; Prologue and epilogue instructions
13597
13598 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13599 ;; all of memory.  This blocks insns from being moved across this point.
13600
13601 (define_insn "blockage"
13602   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
13603   ""
13604   ""
13605   [(set_attr "length" "0")])
13606
13607 ;; Do not schedule instructions accessing memory across this point.
13608
13609 (define_expand "memory_blockage"
13610   [(set (match_dup 0)
13611         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
13612   ""
13613 {
13614   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
13615   MEM_VOLATILE_P (operands[0]) = 1;
13616 })
13617
13618 (define_insn "*memory_blockage"
13619   [(set (match_operand:BLK 0 "" "")
13620         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
13621   ""
13622   ""
13623   [(set_attr "length" "0")])
13624
13625 ;; As USE insns aren't meaningful after reload, this is used instead
13626 ;; to prevent deleting instructions setting registers for PIC code
13627 (define_insn "prologue_use"
13628   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
13629   ""
13630   ""
13631   [(set_attr "length" "0")])
13632
13633 ;; Insn emitted into the body of a function to return from a function.
13634 ;; This is only done if the function's epilogue is known to be simple.
13635 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13636
13637 (define_expand "return"
13638   [(return)]
13639   "ix86_can_use_return_insn_p ()"
13640 {
13641   if (crtl->args.pops_args)
13642     {
13643       rtx popc = GEN_INT (crtl->args.pops_args);
13644       emit_jump_insn (gen_return_pop_internal (popc));
13645       DONE;
13646     }
13647 })
13648
13649 (define_insn "return_internal"
13650   [(return)]
13651   "reload_completed"
13652   "ret"
13653   [(set_attr "length" "1")
13654    (set_attr "atom_unit" "jeu")
13655    (set_attr "length_immediate" "0")
13656    (set_attr "modrm" "0")])
13657
13658 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13659 ;; instruction Athlon and K8 have.
13660
13661 (define_insn "return_internal_long"
13662   [(return)
13663    (unspec [(const_int 0)] UNSPEC_REP)]
13664   "reload_completed"
13665   "rep\;ret"
13666   [(set_attr "length" "2")
13667    (set_attr "atom_unit" "jeu")
13668    (set_attr "length_immediate" "0")
13669    (set_attr "prefix_rep" "1")
13670    (set_attr "modrm" "0")])
13671
13672 (define_insn "return_pop_internal"
13673   [(return)
13674    (use (match_operand:SI 0 "const_int_operand" ""))]
13675   "reload_completed"
13676   "ret\t%0"
13677   [(set_attr "length" "3")
13678    (set_attr "atom_unit" "jeu")
13679    (set_attr "length_immediate" "2")
13680    (set_attr "modrm" "0")])
13681
13682 (define_insn "return_indirect_internal"
13683   [(return)
13684    (use (match_operand:SI 0 "register_operand" "r"))]
13685   "reload_completed"
13686   "jmp\t%A0"
13687   [(set_attr "type" "ibr")
13688    (set_attr "length_immediate" "0")])
13689
13690 (define_insn "nop"
13691   [(const_int 0)]
13692   ""
13693   "nop"
13694   [(set_attr "length" "1")
13695    (set_attr "length_immediate" "0")
13696    (set_attr "modrm" "0")])
13697
13698 (define_insn "vswapmov"
13699   [(set (match_operand:SI 0 "register_operand" "=r")
13700         (match_operand:SI 1 "register_operand" "r"))
13701    (unspec_volatile [(const_int 0)] UNSPECV_VSWAPMOV)]
13702   ""
13703   "movl.s\t{%1, %0|%0, %1}"
13704   [(set_attr "length" "2")
13705    (set_attr "length_immediate" "0")
13706    (set_attr "modrm" "0")])
13707
13708 ;; Pad to 16-byte boundary, max skip in op0.  Used to avoid
13709 ;; branch prediction penalty for the third jump in a 16-byte
13710 ;; block on K8.
13711
13712 (define_insn "pad"
13713   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
13714   ""
13715 {
13716 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
13717   ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
13718 #else
13719   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13720      The align insn is used to avoid 3 jump instructions in the row to improve
13721      branch prediction and the benefits hardly outweigh the cost of extra 8
13722      nops on the average inserted by full alignment pseudo operation.  */
13723 #endif
13724   return "";
13725 }
13726   [(set_attr "length" "16")])
13727
13728 (define_expand "prologue"
13729   [(const_int 0)]
13730   ""
13731   "ix86_expand_prologue (); DONE;")
13732
13733 (define_insn "set_got"
13734   [(set (match_operand:SI 0 "register_operand" "=r")
13735         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13736    (clobber (reg:CC FLAGS_REG))]
13737   "!TARGET_64BIT"
13738   { return output_set_got (operands[0], NULL_RTX); }
13739   [(set_attr "type" "multi")
13740    (set_attr "length" "12")])
13741
13742 (define_insn "set_got_labelled"
13743   [(set (match_operand:SI 0 "register_operand" "=r")
13744         (unspec:SI [(label_ref (match_operand 1 "" ""))]
13745          UNSPEC_SET_GOT))
13746    (clobber (reg:CC FLAGS_REG))]
13747   "!TARGET_64BIT"
13748   { return output_set_got (operands[0], operands[1]); }
13749   [(set_attr "type" "multi")
13750    (set_attr "length" "12")])
13751
13752 (define_insn "set_got_rex64"
13753   [(set (match_operand:DI 0 "register_operand" "=r")
13754         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
13755   "TARGET_64BIT"
13756   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
13757   [(set_attr "type" "lea")
13758    (set_attr "length_address" "4")
13759    (set_attr "mode" "DI")])
13760
13761 (define_insn "set_rip_rex64"
13762   [(set (match_operand:DI 0 "register_operand" "=r")
13763         (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
13764   "TARGET_64BIT"
13765   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
13766   [(set_attr "type" "lea")
13767    (set_attr "length_address" "4")
13768    (set_attr "mode" "DI")])
13769
13770 (define_insn "set_got_offset_rex64"
13771   [(set (match_operand:DI 0 "register_operand" "=r")
13772         (unspec:DI
13773           [(label_ref (match_operand 1 "" ""))]
13774           UNSPEC_SET_GOT_OFFSET))]
13775   "TARGET_64BIT"
13776   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
13777   [(set_attr "type" "imov")
13778    (set_attr "length_immediate" "0")
13779    (set_attr "length_address" "8")
13780    (set_attr "mode" "DI")])
13781
13782 (define_expand "epilogue"
13783   [(const_int 0)]
13784   ""
13785   "ix86_expand_epilogue (1); DONE;")
13786
13787 (define_expand "sibcall_epilogue"
13788   [(const_int 0)]
13789   ""
13790   "ix86_expand_epilogue (0); DONE;")
13791
13792 (define_expand "eh_return"
13793   [(use (match_operand 0 "register_operand" ""))]
13794   ""
13795 {
13796   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13797
13798   /* Tricky bit: we write the address of the handler to which we will
13799      be returning into someone else's stack frame, one word below the
13800      stack address we wish to restore.  */
13801   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13802   tmp = plus_constant (tmp, -UNITS_PER_WORD);
13803   tmp = gen_rtx_MEM (Pmode, tmp);
13804   emit_move_insn (tmp, ra);
13805
13806   emit_jump_insn (gen_eh_return_internal ());
13807   emit_barrier ();
13808   DONE;
13809 })
13810
13811 (define_insn_and_split "eh_return_internal"
13812   [(eh_return)]
13813   ""
13814   "#"
13815   "epilogue_completed"
13816   [(const_int 0)]
13817   "ix86_expand_epilogue (2); DONE;")
13818
13819 (define_insn "leave"
13820   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13821    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
13822    (clobber (mem:BLK (scratch)))]
13823   "!TARGET_64BIT"
13824   "leave"
13825   [(set_attr "type" "leave")])
13826
13827 (define_insn "leave_rex64"
13828   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13829    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
13830    (clobber (mem:BLK (scratch)))]
13831   "TARGET_64BIT"
13832   "leave"
13833   [(set_attr "type" "leave")])
13834 \f
13835 (define_expand "ffssi2"
13836   [(parallel
13837      [(set (match_operand:SI 0 "register_operand" "")
13838            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
13839       (clobber (match_scratch:SI 2 ""))
13840       (clobber (reg:CC FLAGS_REG))])]
13841   ""
13842 {
13843   if (TARGET_CMOVE)
13844     {
13845       emit_insn (gen_ffs_cmove (operands[0], operands[1]));
13846       DONE;
13847     }
13848 })
13849
13850 (define_expand "ffs_cmove"
13851   [(set (match_dup 2) (const_int -1))
13852    (parallel [(set (reg:CCZ FLAGS_REG)
13853                    (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "")
13854                                 (const_int 0)))
13855               (set (match_operand:SI 0 "register_operand" "")
13856                    (ctz:SI (match_dup 1)))])
13857    (set (match_dup 0) (if_then_else:SI
13858                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
13859                         (match_dup 2)
13860                         (match_dup 0)))
13861    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13862               (clobber (reg:CC FLAGS_REG))])]
13863   "TARGET_CMOVE"
13864   "operands[2] = gen_reg_rtx (SImode);")
13865
13866 (define_insn_and_split "*ffs_no_cmove"
13867   [(set (match_operand:SI 0 "register_operand" "=r")
13868         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13869    (clobber (match_scratch:SI 2 "=&q"))
13870    (clobber (reg:CC FLAGS_REG))]
13871   "!TARGET_CMOVE"
13872   "#"
13873   "&& reload_completed"
13874   [(parallel [(set (reg:CCZ FLAGS_REG)
13875                    (compare:CCZ (match_dup 1) (const_int 0)))
13876               (set (match_dup 0) (ctz:SI (match_dup 1)))])
13877    (set (strict_low_part (match_dup 3))
13878         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
13879    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
13880               (clobber (reg:CC FLAGS_REG))])
13881    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
13882               (clobber (reg:CC FLAGS_REG))])
13883    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13884               (clobber (reg:CC FLAGS_REG))])]
13885 {
13886   operands[3] = gen_lowpart (QImode, operands[2]);
13887   ix86_expand_clear (operands[2]);
13888 })
13889
13890 (define_insn "*ffssi_1"
13891   [(set (reg:CCZ FLAGS_REG)
13892         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
13893                      (const_int 0)))
13894    (set (match_operand:SI 0 "register_operand" "=r")
13895         (ctz:SI (match_dup 1)))]
13896   ""
13897   "bsf{l}\t{%1, %0|%0, %1}"
13898   [(set_attr "type" "alu1")
13899    (set_attr "prefix_0f" "1")
13900    (set_attr "mode" "SI")])
13901
13902 (define_expand "ffsdi2"
13903   [(set (match_dup 2) (const_int -1))
13904    (parallel [(set (reg:CCZ FLAGS_REG)
13905                    (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "")
13906                                 (const_int 0)))
13907               (set (match_operand:DI 0 "register_operand" "")
13908                    (ctz:DI (match_dup 1)))])
13909    (set (match_dup 0) (if_then_else:DI
13910                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
13911                         (match_dup 2)
13912                         (match_dup 0)))
13913    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
13914               (clobber (reg:CC FLAGS_REG))])]
13915   "TARGET_64BIT"
13916   "operands[2] = gen_reg_rtx (DImode);")
13917
13918 (define_insn "*ffsdi_1"
13919   [(set (reg:CCZ FLAGS_REG)
13920         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
13921                      (const_int 0)))
13922    (set (match_operand:DI 0 "register_operand" "=r")
13923         (ctz:DI (match_dup 1)))]
13924   "TARGET_64BIT"
13925   "bsf{q}\t{%1, %0|%0, %1}"
13926   [(set_attr "type" "alu1")
13927    (set_attr "prefix_0f" "1")
13928    (set_attr "mode" "DI")])
13929
13930 (define_insn "ctzsi2"
13931   [(set (match_operand:SI 0 "register_operand" "=r")
13932         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13933    (clobber (reg:CC FLAGS_REG))]
13934   ""
13935   "bsf{l}\t{%1, %0|%0, %1}"
13936   [(set_attr "type" "alu1")
13937    (set_attr "prefix_0f" "1")
13938    (set_attr "mode" "SI")])
13939
13940 (define_insn "ctzdi2"
13941   [(set (match_operand:DI 0 "register_operand" "=r")
13942         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
13943    (clobber (reg:CC FLAGS_REG))]
13944   "TARGET_64BIT"
13945   "bsf{q}\t{%1, %0|%0, %1}"
13946   [(set_attr "type" "alu1")
13947    (set_attr "prefix_0f" "1")
13948    (set_attr "mode" "DI")])
13949
13950 (define_expand "clzsi2"
13951   [(parallel
13952      [(set (match_operand:SI 0 "register_operand" "")
13953            (minus:SI (const_int 31)
13954                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
13955       (clobber (reg:CC FLAGS_REG))])
13956    (parallel
13957      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
13958       (clobber (reg:CC FLAGS_REG))])]
13959   ""
13960 {
13961   if (TARGET_ABM)
13962     {
13963       emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
13964       DONE;
13965     }
13966 })
13967
13968 (define_insn "clzsi2_abm"
13969   [(set (match_operand:SI 0 "register_operand" "=r")
13970         (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13971    (clobber (reg:CC FLAGS_REG))]
13972   "TARGET_ABM"
13973   "lzcnt{l}\t{%1, %0|%0, %1}"
13974   [(set_attr "prefix_rep" "1")
13975    (set_attr "type" "bitmanip")
13976    (set_attr "mode" "SI")])
13977
13978 (define_insn "bsr"
13979   [(set (match_operand:SI 0 "register_operand" "=r")
13980         (minus:SI (const_int 31)
13981                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
13982    (clobber (reg:CC FLAGS_REG))]
13983   ""
13984   "bsr{l}\t{%1, %0|%0, %1}"
13985   [(set_attr "type" "alu1")
13986    (set_attr "prefix_0f" "1")
13987    (set_attr "mode" "SI")])
13988
13989 (define_insn "popcount<mode>2"
13990   [(set (match_operand:SWI248 0 "register_operand" "=r")
13991         (popcount:SWI248
13992           (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
13993    (clobber (reg:CC FLAGS_REG))]
13994   "TARGET_POPCNT"
13995 {
13996 #if TARGET_MACHO
13997   return "popcnt\t{%1, %0|%0, %1}";
13998 #else
13999   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
14000 #endif
14001 }
14002   [(set_attr "prefix_rep" "1")
14003    (set_attr "type" "bitmanip")
14004    (set_attr "mode" "<MODE>")])
14005
14006 (define_insn "*popcount<mode>2_cmp"
14007   [(set (reg FLAGS_REG)
14008         (compare
14009           (popcount:SWI248
14010             (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
14011           (const_int 0)))
14012    (set (match_operand:SWI248 0 "register_operand" "=r")
14013         (popcount:SWI248 (match_dup 1)))]
14014   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14015 {
14016 #if TARGET_MACHO
14017   return "popcnt\t{%1, %0|%0, %1}";
14018 #else
14019   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
14020 #endif
14021 }
14022   [(set_attr "prefix_rep" "1")
14023    (set_attr "type" "bitmanip")
14024    (set_attr "mode" "<MODE>")])
14025
14026 (define_insn "*popcountsi2_cmp_zext"
14027   [(set (reg FLAGS_REG)
14028         (compare
14029           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
14030           (const_int 0)))
14031    (set (match_operand:DI 0 "register_operand" "=r")
14032         (zero_extend:DI(popcount:SI (match_dup 1))))]
14033   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14034 {
14035 #if TARGET_MACHO
14036   return "popcnt\t{%1, %0|%0, %1}";
14037 #else
14038   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
14039 #endif
14040 }
14041   [(set_attr "prefix_rep" "1")
14042    (set_attr "type" "bitmanip")
14043    (set_attr "mode" "SI")])
14044
14045 (define_expand "bswapsi2"
14046   [(set (match_operand:SI 0 "register_operand" "")
14047         (bswap:SI (match_operand:SI 1 "register_operand" "")))]
14048   ""
14049 {
14050   if (!(TARGET_BSWAP || TARGET_MOVBE))
14051     {
14052       rtx x = operands[0];
14053
14054       emit_move_insn (x, operands[1]);
14055       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
14056       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
14057       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
14058       DONE;
14059     }
14060 })
14061
14062 (define_insn "*bswapsi_movbe"
14063   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,m")
14064         (bswap:SI (match_operand:SI 1 "nonimmediate_operand" "0,m,r")))]
14065   "TARGET_MOVBE && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
14066   "@
14067     bswap\t%0
14068     movbe\t{%1, %0|%0, %1}
14069     movbe\t{%1, %0|%0, %1}"
14070   [(set_attr "type" "*,imov,imov")
14071    (set_attr "modrm" "*,1,1")
14072    (set_attr "prefix_0f" "1")
14073    (set_attr "prefix_extra" "*,1,1")
14074    (set_attr "length" "2,*,*")
14075    (set_attr "mode" "SI")])
14076
14077 (define_insn "*bswapsi_1"
14078   [(set (match_operand:SI 0 "register_operand" "=r")
14079         (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
14080   "TARGET_BSWAP"
14081   "bswap\t%0"
14082   [(set_attr "prefix_0f" "1")
14083    (set_attr "length" "2")])
14084
14085 (define_insn "*bswaphi_lowpart_1"
14086   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
14087         (bswap:HI (match_dup 0)))
14088    (clobber (reg:CC FLAGS_REG))]
14089   "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
14090   "@
14091     xchg{b}\t{%h0, %b0|%b0, %h0}
14092     rol{w}\t{$8, %0|%0, 8}"
14093   [(set_attr "length" "2,4")
14094    (set_attr "mode" "QI,HI")])
14095
14096 (define_insn "bswaphi_lowpart"
14097   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
14098         (bswap:HI (match_dup 0)))
14099    (clobber (reg:CC FLAGS_REG))]
14100   ""
14101   "rol{w}\t{$8, %0|%0, 8}"
14102   [(set_attr "length" "4")
14103    (set_attr "mode" "HI")])
14104
14105 (define_expand "bswapdi2"
14106   [(set (match_operand:DI 0 "register_operand" "")
14107         (bswap:DI (match_operand:DI 1 "register_operand" "")))]
14108   "TARGET_64BIT"
14109   "")
14110
14111 (define_insn "*bswapdi_movbe"
14112   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m")
14113         (bswap:DI (match_operand:DI 1 "nonimmediate_operand" "0,m,r")))]
14114   "TARGET_64BIT && TARGET_MOVBE
14115    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
14116   "@
14117     bswap\t%0
14118     movbe\t{%1, %0|%0, %1}
14119     movbe\t{%1, %0|%0, %1}"
14120   [(set_attr "type" "*,imov,imov")
14121    (set_attr "modrm" "*,1,1")
14122    (set_attr "prefix_0f" "1")
14123    (set_attr "prefix_extra" "*,1,1")
14124    (set_attr "length" "3,*,*")
14125    (set_attr "mode" "DI")])
14126
14127 (define_insn "*bswapdi_1"
14128   [(set (match_operand:DI 0 "register_operand" "=r")
14129         (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
14130   "TARGET_64BIT"
14131   "bswap\t%0"
14132   [(set_attr "prefix_0f" "1")
14133    (set_attr "length" "3")])
14134
14135 (define_expand "clzdi2"
14136   [(parallel
14137      [(set (match_operand:DI 0 "register_operand" "")
14138            (minus:DI (const_int 63)
14139                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14140       (clobber (reg:CC FLAGS_REG))])
14141    (parallel
14142      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14143       (clobber (reg:CC FLAGS_REG))])]
14144   "TARGET_64BIT"
14145 {
14146   if (TARGET_ABM)
14147     {
14148       emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
14149       DONE;
14150     }
14151 })
14152
14153 (define_insn "clzdi2_abm"
14154   [(set (match_operand:DI 0 "register_operand" "=r")
14155         (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14156    (clobber (reg:CC FLAGS_REG))]
14157   "TARGET_64BIT && TARGET_ABM"
14158   "lzcnt{q}\t{%1, %0|%0, %1}"
14159   [(set_attr "prefix_rep" "1")
14160    (set_attr "type" "bitmanip")
14161    (set_attr "mode" "DI")])
14162
14163 (define_insn "bsr_rex64"
14164   [(set (match_operand:DI 0 "register_operand" "=r")
14165         (minus:DI (const_int 63)
14166                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14167    (clobber (reg:CC FLAGS_REG))]
14168   "TARGET_64BIT"
14169   "bsr{q}\t{%1, %0|%0, %1}"
14170   [(set_attr "type" "alu1")
14171    (set_attr "prefix_0f" "1")
14172    (set_attr "mode" "DI")])
14173
14174 (define_expand "clzhi2"
14175   [(parallel
14176      [(set (match_operand:HI 0 "register_operand" "")
14177            (minus:HI (const_int 15)
14178                      (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
14179       (clobber (reg:CC FLAGS_REG))])
14180    (parallel
14181      [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
14182       (clobber (reg:CC FLAGS_REG))])]
14183   ""
14184 {
14185   if (TARGET_ABM)
14186     {
14187       emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
14188       DONE;
14189     }
14190 })
14191
14192 (define_insn "clzhi2_abm"
14193   [(set (match_operand:HI 0 "register_operand" "=r")
14194         (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm")))
14195    (clobber (reg:CC FLAGS_REG))]
14196   "TARGET_ABM"
14197   "lzcnt{w}\t{%1, %0|%0, %1}"
14198   [(set_attr "prefix_rep" "1")
14199    (set_attr "type" "bitmanip")
14200    (set_attr "mode" "HI")])
14201
14202 (define_insn "*bsrhi"
14203   [(set (match_operand:HI 0 "register_operand" "=r")
14204         (minus:HI (const_int 15)
14205                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
14206    (clobber (reg:CC FLAGS_REG))]
14207   ""
14208   "bsr{w}\t{%1, %0|%0, %1}"
14209   [(set_attr "type" "alu1")
14210    (set_attr "prefix_0f" "1")
14211    (set_attr "mode" "HI")])
14212
14213 (define_expand "paritydi2"
14214   [(set (match_operand:DI 0 "register_operand" "")
14215         (parity:DI (match_operand:DI 1 "register_operand" "")))]
14216   "! TARGET_POPCNT"
14217 {
14218   rtx scratch = gen_reg_rtx (QImode);
14219   rtx cond;
14220
14221   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
14222                                 NULL_RTX, operands[1]));
14223
14224   cond = gen_rtx_fmt_ee (ORDERED, QImode,
14225                          gen_rtx_REG (CCmode, FLAGS_REG),
14226                          const0_rtx);
14227   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
14228
14229   if (TARGET_64BIT)
14230     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
14231   else
14232     {
14233       rtx tmp = gen_reg_rtx (SImode);
14234
14235       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
14236       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
14237     }
14238   DONE;
14239 })
14240
14241 (define_insn_and_split "paritydi2_cmp"
14242   [(set (reg:CC FLAGS_REG)
14243         (parity:CC (match_operand:DI 3 "register_operand" "0")))
14244    (clobber (match_scratch:DI 0 "=r"))
14245    (clobber (match_scratch:SI 1 "=&r"))
14246    (clobber (match_scratch:HI 2 "=Q"))]
14247   "! TARGET_POPCNT"
14248   "#"
14249   "&& reload_completed"
14250   [(parallel
14251      [(set (match_dup 1)
14252            (xor:SI (match_dup 1) (match_dup 4)))
14253       (clobber (reg:CC FLAGS_REG))])
14254    (parallel
14255      [(set (reg:CC FLAGS_REG)
14256            (parity:CC (match_dup 1)))
14257       (clobber (match_dup 1))
14258       (clobber (match_dup 2))])]
14259 {
14260   operands[4] = gen_lowpart (SImode, operands[3]);
14261
14262   if (TARGET_64BIT)
14263     {
14264       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
14265       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
14266     }
14267   else
14268     operands[1] = gen_highpart (SImode, operands[3]);
14269 })
14270
14271 (define_expand "paritysi2"
14272   [(set (match_operand:SI 0 "register_operand" "")
14273         (parity:SI (match_operand:SI 1 "register_operand" "")))]
14274   "! TARGET_POPCNT"
14275 {
14276   rtx scratch = gen_reg_rtx (QImode);
14277   rtx cond;
14278
14279   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
14280
14281   cond = gen_rtx_fmt_ee (ORDERED, QImode,
14282                          gen_rtx_REG (CCmode, FLAGS_REG),
14283                          const0_rtx);
14284   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
14285
14286   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
14287   DONE;
14288 })
14289
14290 (define_insn_and_split "paritysi2_cmp"
14291   [(set (reg:CC FLAGS_REG)
14292         (parity:CC (match_operand:SI 2 "register_operand" "0")))
14293    (clobber (match_scratch:SI 0 "=r"))
14294    (clobber (match_scratch:HI 1 "=&Q"))]
14295   "! TARGET_POPCNT"
14296   "#"
14297   "&& reload_completed"
14298   [(parallel
14299      [(set (match_dup 1)
14300            (xor:HI (match_dup 1) (match_dup 3)))
14301       (clobber (reg:CC FLAGS_REG))])
14302    (parallel
14303      [(set (reg:CC FLAGS_REG)
14304            (parity:CC (match_dup 1)))
14305       (clobber (match_dup 1))])]
14306 {
14307   operands[3] = gen_lowpart (HImode, operands[2]);
14308
14309   emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
14310   emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
14311 })
14312
14313 (define_insn "*parityhi2_cmp"
14314   [(set (reg:CC FLAGS_REG)
14315         (parity:CC (match_operand:HI 1 "register_operand" "0")))
14316    (clobber (match_scratch:HI 0 "=Q"))]
14317   "! TARGET_POPCNT"
14318   "xor{b}\t{%h0, %b0|%b0, %h0}"
14319   [(set_attr "length" "2")
14320    (set_attr "mode" "HI")])
14321
14322 (define_insn "*parityqi2_cmp"
14323   [(set (reg:CC FLAGS_REG)
14324         (parity:CC (match_operand:QI 0 "register_operand" "q")))]
14325   "! TARGET_POPCNT"
14326   "test{b}\t%0, %0"
14327   [(set_attr "length" "2")
14328    (set_attr "mode" "QI")])
14329 \f
14330 ;; Thread-local storage patterns for ELF.
14331 ;;
14332 ;; Note that these code sequences must appear exactly as shown
14333 ;; in order to allow linker relaxation.
14334
14335 (define_insn "*tls_global_dynamic_32_gnu"
14336   [(set (match_operand:SI 0 "register_operand" "=a")
14337         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14338                     (match_operand:SI 2 "tls_symbolic_operand" "")
14339                     (match_operand:SI 3 "call_insn_operand" "")]
14340                     UNSPEC_TLS_GD))
14341    (clobber (match_scratch:SI 4 "=d"))
14342    (clobber (match_scratch:SI 5 "=c"))
14343    (clobber (reg:CC FLAGS_REG))]
14344   "!TARGET_64BIT && TARGET_GNU_TLS"
14345   "lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}\;call\t%P3"
14346   [(set_attr "type" "multi")
14347    (set_attr "length" "12")])
14348
14349 (define_expand "tls_global_dynamic_32"
14350   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14351                    (unspec:SI
14352                     [(match_dup 2)
14353                      (match_operand:SI 1 "tls_symbolic_operand" "")
14354                      (match_dup 3)]
14355                     UNSPEC_TLS_GD))
14356               (clobber (match_scratch:SI 4 ""))
14357               (clobber (match_scratch:SI 5 ""))
14358               (clobber (reg:CC FLAGS_REG))])]
14359   ""
14360 {
14361   if (flag_pic)
14362     operands[2] = pic_offset_table_rtx;
14363   else
14364     {
14365       operands[2] = gen_reg_rtx (Pmode);
14366       emit_insn (gen_set_got (operands[2]));
14367     }
14368   if (TARGET_GNU2_TLS)
14369     {
14370        emit_insn (gen_tls_dynamic_gnu2_32
14371                   (operands[0], operands[1], operands[2]));
14372        DONE;
14373     }
14374   operands[3] = ix86_tls_get_addr ();
14375 })
14376
14377 (define_insn "*tls_global_dynamic_64"
14378   [(set (match_operand:DI 0 "register_operand" "=a")
14379         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14380                  (match_operand:DI 3 "" "")))
14381    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14382               UNSPEC_TLS_GD)]
14383   "TARGET_64BIT"
14384   { 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"; }
14385   [(set_attr "type" "multi")
14386    (set_attr "length" "16")])
14387
14388 (define_expand "tls_global_dynamic_64"
14389   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14390                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
14391               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14392                          UNSPEC_TLS_GD)])]
14393   ""
14394 {
14395   if (TARGET_GNU2_TLS)
14396     {
14397        emit_insn (gen_tls_dynamic_gnu2_64
14398                   (operands[0], operands[1]));
14399        DONE;
14400     }
14401   operands[2] = ix86_tls_get_addr ();
14402 })
14403
14404 (define_insn "*tls_local_dynamic_base_32_gnu"
14405   [(set (match_operand:SI 0 "register_operand" "=a")
14406         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14407                     (match_operand:SI 2 "call_insn_operand" "")]
14408                    UNSPEC_TLS_LD_BASE))
14409    (clobber (match_scratch:SI 3 "=d"))
14410    (clobber (match_scratch:SI 4 "=c"))
14411    (clobber (reg:CC FLAGS_REG))]
14412   "!TARGET_64BIT && TARGET_GNU_TLS"
14413   "lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}\;call\t%P2"
14414   [(set_attr "type" "multi")
14415    (set_attr "length" "11")])
14416
14417 (define_expand "tls_local_dynamic_base_32"
14418   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14419                    (unspec:SI [(match_dup 1) (match_dup 2)]
14420                               UNSPEC_TLS_LD_BASE))
14421               (clobber (match_scratch:SI 3 ""))
14422               (clobber (match_scratch:SI 4 ""))
14423               (clobber (reg:CC FLAGS_REG))])]
14424   ""
14425 {
14426   if (flag_pic)
14427     operands[1] = pic_offset_table_rtx;
14428   else
14429     {
14430       operands[1] = gen_reg_rtx (Pmode);
14431       emit_insn (gen_set_got (operands[1]));
14432     }
14433   if (TARGET_GNU2_TLS)
14434     {
14435        emit_insn (gen_tls_dynamic_gnu2_32
14436                   (operands[0], ix86_tls_module_base (), operands[1]));
14437        DONE;
14438     }
14439   operands[2] = ix86_tls_get_addr ();
14440 })
14441
14442 (define_insn "*tls_local_dynamic_base_64"
14443   [(set (match_operand:DI 0 "register_operand" "=a")
14444         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14445                  (match_operand:DI 2 "" "")))
14446    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14447   "TARGET_64BIT"
14448   "lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}\;call\t%P1"
14449   [(set_attr "type" "multi")
14450    (set_attr "length" "12")])
14451
14452 (define_expand "tls_local_dynamic_base_64"
14453   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14454                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
14455               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14456   ""
14457 {
14458   if (TARGET_GNU2_TLS)
14459     {
14460        emit_insn (gen_tls_dynamic_gnu2_64
14461                   (operands[0], ix86_tls_module_base ()));
14462        DONE;
14463     }
14464   operands[1] = ix86_tls_get_addr ();
14465 })
14466
14467 ;; Local dynamic of a single variable is a lose.  Show combine how
14468 ;; to convert that back to global dynamic.
14469
14470 (define_insn_and_split "*tls_local_dynamic_32_once"
14471   [(set (match_operand:SI 0 "register_operand" "=a")
14472         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14473                              (match_operand:SI 2 "call_insn_operand" "")]
14474                             UNSPEC_TLS_LD_BASE)
14475                  (const:SI (unspec:SI
14476                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
14477                             UNSPEC_DTPOFF))))
14478    (clobber (match_scratch:SI 4 "=d"))
14479    (clobber (match_scratch:SI 5 "=c"))
14480    (clobber (reg:CC FLAGS_REG))]
14481   ""
14482   "#"
14483   ""
14484   [(parallel [(set (match_dup 0)
14485                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14486                               UNSPEC_TLS_GD))
14487               (clobber (match_dup 4))
14488               (clobber (match_dup 5))
14489               (clobber (reg:CC FLAGS_REG))])]
14490   "")
14491
14492 ;; Load and add the thread base pointer from %gs:0.
14493
14494 (define_insn "*load_tp_si"
14495   [(set (match_operand:SI 0 "register_operand" "=r")
14496         (unspec:SI [(const_int 0)] UNSPEC_TP))]
14497   "!TARGET_64BIT"
14498   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
14499   [(set_attr "type" "imov")
14500    (set_attr "modrm" "0")
14501    (set_attr "length" "7")
14502    (set_attr "memory" "load")
14503    (set_attr "imm_disp" "false")])
14504
14505 (define_insn "*add_tp_si"
14506   [(set (match_operand:SI 0 "register_operand" "=r")
14507         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14508                  (match_operand:SI 1 "register_operand" "0")))
14509    (clobber (reg:CC FLAGS_REG))]
14510   "!TARGET_64BIT"
14511   "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
14512   [(set_attr "type" "alu")
14513    (set_attr "modrm" "0")
14514    (set_attr "length" "7")
14515    (set_attr "memory" "load")
14516    (set_attr "imm_disp" "false")])
14517
14518 (define_insn "*load_tp_di"
14519   [(set (match_operand:DI 0 "register_operand" "=r")
14520         (unspec:DI [(const_int 0)] UNSPEC_TP))]
14521   "TARGET_64BIT"
14522   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
14523   [(set_attr "type" "imov")
14524    (set_attr "modrm" "0")
14525    (set_attr "length" "7")
14526    (set_attr "memory" "load")
14527    (set_attr "imm_disp" "false")])
14528
14529 (define_insn "*add_tp_di"
14530   [(set (match_operand:DI 0 "register_operand" "=r")
14531         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14532                  (match_operand:DI 1 "register_operand" "0")))
14533    (clobber (reg:CC FLAGS_REG))]
14534   "TARGET_64BIT"
14535   "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
14536   [(set_attr "type" "alu")
14537    (set_attr "modrm" "0")
14538    (set_attr "length" "7")
14539    (set_attr "memory" "load")
14540    (set_attr "imm_disp" "false")])
14541
14542 ;; GNU2 TLS patterns can be split.
14543
14544 (define_expand "tls_dynamic_gnu2_32"
14545   [(set (match_dup 3)
14546         (plus:SI (match_operand:SI 2 "register_operand" "")
14547                  (const:SI
14548                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
14549                              UNSPEC_TLSDESC))))
14550    (parallel
14551     [(set (match_operand:SI 0 "register_operand" "")
14552           (unspec:SI [(match_dup 1) (match_dup 3)
14553                       (match_dup 2) (reg:SI SP_REG)]
14554                       UNSPEC_TLSDESC))
14555      (clobber (reg:CC FLAGS_REG))])]
14556   "!TARGET_64BIT && TARGET_GNU2_TLS"
14557 {
14558   operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14559   ix86_tls_descriptor_calls_expanded_in_cfun = true;
14560 })
14561
14562 (define_insn "*tls_dynamic_lea_32"
14563   [(set (match_operand:SI 0 "register_operand" "=r")
14564         (plus:SI (match_operand:SI 1 "register_operand" "b")
14565                  (const:SI
14566                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
14567                               UNSPEC_TLSDESC))))]
14568   "!TARGET_64BIT && TARGET_GNU2_TLS"
14569   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
14570   [(set_attr "type" "lea")
14571    (set_attr "mode" "SI")
14572    (set_attr "length" "6")
14573    (set_attr "length_address" "4")])
14574
14575 (define_insn "*tls_dynamic_call_32"
14576   [(set (match_operand:SI 0 "register_operand" "=a")
14577         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
14578                     (match_operand:SI 2 "register_operand" "0")
14579                     ;; we have to make sure %ebx still points to the GOT
14580                     (match_operand:SI 3 "register_operand" "b")
14581                     (reg:SI SP_REG)]
14582                    UNSPEC_TLSDESC))
14583    (clobber (reg:CC FLAGS_REG))]
14584   "!TARGET_64BIT && TARGET_GNU2_TLS"
14585   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
14586   [(set_attr "type" "call")
14587    (set_attr "length" "2")
14588    (set_attr "length_address" "0")])
14589
14590 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
14591   [(set (match_operand:SI 0 "register_operand" "=&a")
14592         (plus:SI
14593          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
14594                      (match_operand:SI 4 "" "")
14595                      (match_operand:SI 2 "register_operand" "b")
14596                      (reg:SI SP_REG)]
14597                     UNSPEC_TLSDESC)
14598          (const:SI (unspec:SI
14599                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
14600                     UNSPEC_DTPOFF))))
14601    (clobber (reg:CC FLAGS_REG))]
14602   "!TARGET_64BIT && TARGET_GNU2_TLS"
14603   "#"
14604   ""
14605   [(set (match_dup 0) (match_dup 5))]
14606 {
14607   operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14608   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
14609 })
14610
14611 (define_expand "tls_dynamic_gnu2_64"
14612   [(set (match_dup 2)
14613         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14614                    UNSPEC_TLSDESC))
14615    (parallel
14616     [(set (match_operand:DI 0 "register_operand" "")
14617           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
14618                      UNSPEC_TLSDESC))
14619      (clobber (reg:CC FLAGS_REG))])]
14620   "TARGET_64BIT && TARGET_GNU2_TLS"
14621 {
14622   operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14623   ix86_tls_descriptor_calls_expanded_in_cfun = true;
14624 })
14625
14626 (define_insn "*tls_dynamic_lea_64"
14627   [(set (match_operand:DI 0 "register_operand" "=r")
14628         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14629                    UNSPEC_TLSDESC))]
14630   "TARGET_64BIT && TARGET_GNU2_TLS"
14631   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
14632   [(set_attr "type" "lea")
14633    (set_attr "mode" "DI")
14634    (set_attr "length" "7")
14635    (set_attr "length_address" "4")])
14636
14637 (define_insn "*tls_dynamic_call_64"
14638   [(set (match_operand:DI 0 "register_operand" "=a")
14639         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
14640                     (match_operand:DI 2 "register_operand" "0")
14641                     (reg:DI SP_REG)]
14642                    UNSPEC_TLSDESC))
14643    (clobber (reg:CC FLAGS_REG))]
14644   "TARGET_64BIT && TARGET_GNU2_TLS"
14645   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
14646   [(set_attr "type" "call")
14647    (set_attr "length" "2")
14648    (set_attr "length_address" "0")])
14649
14650 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
14651   [(set (match_operand:DI 0 "register_operand" "=&a")
14652         (plus:DI
14653          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
14654                      (match_operand:DI 3 "" "")
14655                      (reg:DI SP_REG)]
14656                     UNSPEC_TLSDESC)
14657          (const:DI (unspec:DI
14658                     [(match_operand:DI 1 "tls_symbolic_operand" "")]
14659                     UNSPEC_DTPOFF))))
14660    (clobber (reg:CC FLAGS_REG))]
14661   "TARGET_64BIT && TARGET_GNU2_TLS"
14662   "#"
14663   ""
14664   [(set (match_dup 0) (match_dup 4))]
14665 {
14666   operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14667   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
14668 })
14669
14670 ;;
14671 \f
14672 ;; These patterns match the binary 387 instructions for addM3, subM3,
14673 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
14674 ;; SFmode.  The first is the normal insn, the second the same insn but
14675 ;; with one operand a conversion, and the third the same insn but with
14676 ;; the other operand a conversion.  The conversion may be SFmode or
14677 ;; SImode if the target mode DFmode, but only SImode if the target mode
14678 ;; is SFmode.
14679
14680 ;; Gcc is slightly more smart about handling normal two address instructions
14681 ;; so use special patterns for add and mull.
14682
14683 (define_insn "*fop_<mode>_comm_mixed_avx"
14684   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
14685         (match_operator:MODEF 3 "binary_fp_operator"
14686           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
14687            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
14688   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
14689    && COMMUTATIVE_ARITH_P (operands[3])
14690    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14691   "* return output_387_binary_op (insn, operands);"
14692   [(set (attr "type")
14693         (if_then_else (eq_attr "alternative" "1")
14694            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
14695               (const_string "ssemul")
14696               (const_string "sseadd"))
14697            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
14698               (const_string "fmul")
14699               (const_string "fop"))))
14700    (set_attr "prefix" "orig,maybe_vex")
14701    (set_attr "mode" "<MODE>")])
14702
14703 (define_insn "*fop_<mode>_comm_mixed"
14704   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
14705         (match_operator:MODEF 3 "binary_fp_operator"
14706           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
14707            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
14708   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
14709    && COMMUTATIVE_ARITH_P (operands[3])
14710    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14711   "* return output_387_binary_op (insn, operands);"
14712   [(set (attr "type")
14713         (if_then_else (eq_attr "alternative" "1")
14714            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
14715               (const_string "ssemul")
14716               (const_string "sseadd"))
14717            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
14718               (const_string "fmul")
14719               (const_string "fop"))))
14720    (set_attr "mode" "<MODE>")])
14721
14722 (define_insn "*fop_<mode>_comm_avx"
14723   [(set (match_operand:MODEF 0 "register_operand" "=x")
14724         (match_operator:MODEF 3 "binary_fp_operator"
14725           [(match_operand:MODEF 1 "nonimmediate_operand" "%x")
14726            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
14727   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14728    && COMMUTATIVE_ARITH_P (operands[3])
14729    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14730   "* return output_387_binary_op (insn, operands);"
14731   [(set (attr "type")
14732         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
14733            (const_string "ssemul")
14734            (const_string "sseadd")))
14735    (set_attr "prefix" "vex")
14736    (set_attr "mode" "<MODE>")])
14737
14738 (define_insn "*fop_<mode>_comm_sse"
14739   [(set (match_operand:MODEF 0 "register_operand" "=x")
14740         (match_operator:MODEF 3 "binary_fp_operator"
14741           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
14742            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
14743   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14744    && COMMUTATIVE_ARITH_P (operands[3])
14745    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14746   "* return output_387_binary_op (insn, operands);"
14747   [(set (attr "type")
14748         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
14749            (const_string "ssemul")
14750            (const_string "sseadd")))
14751    (set_attr "mode" "<MODE>")])
14752
14753 (define_insn "*fop_<mode>_comm_i387"
14754   [(set (match_operand:MODEF 0 "register_operand" "=f")
14755         (match_operator:MODEF 3 "binary_fp_operator"
14756           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
14757            (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
14758   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
14759    && COMMUTATIVE_ARITH_P (operands[3])
14760    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14761   "* return output_387_binary_op (insn, operands);"
14762   [(set (attr "type")
14763         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
14764            (const_string "fmul")
14765            (const_string "fop")))
14766    (set_attr "mode" "<MODE>")])
14767
14768 (define_insn "*fop_<mode>_1_mixed_avx"
14769   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
14770         (match_operator:MODEF 3 "binary_fp_operator"
14771           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,x")
14772            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
14773   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
14774    && !COMMUTATIVE_ARITH_P (operands[3])
14775    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14776   "* return output_387_binary_op (insn, operands);"
14777   [(set (attr "type")
14778         (cond [(and (eq_attr "alternative" "2")
14779                     (match_operand:MODEF 3 "mult_operator" ""))
14780                  (const_string "ssemul")
14781                (and (eq_attr "alternative" "2")
14782                     (match_operand:MODEF 3 "div_operator" ""))
14783                  (const_string "ssediv")
14784                (eq_attr "alternative" "2")
14785                  (const_string "sseadd")
14786                (match_operand:MODEF 3 "mult_operator" "")
14787                  (const_string "fmul")
14788                (match_operand:MODEF 3 "div_operator" "")
14789                  (const_string "fdiv")
14790               ]
14791               (const_string "fop")))
14792    (set_attr "prefix" "orig,orig,maybe_vex")
14793    (set_attr "mode" "<MODE>")])
14794
14795 (define_insn "*fop_<mode>_1_mixed"
14796   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
14797         (match_operator:MODEF 3 "binary_fp_operator"
14798           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
14799            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
14800   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
14801    && !COMMUTATIVE_ARITH_P (operands[3])
14802    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14803   "* return output_387_binary_op (insn, operands);"
14804   [(set (attr "type")
14805         (cond [(and (eq_attr "alternative" "2")
14806                     (match_operand:MODEF 3 "mult_operator" ""))
14807                  (const_string "ssemul")
14808                (and (eq_attr "alternative" "2")
14809                     (match_operand:MODEF 3 "div_operator" ""))
14810                  (const_string "ssediv")
14811                (eq_attr "alternative" "2")
14812                  (const_string "sseadd")
14813                (match_operand:MODEF 3 "mult_operator" "")
14814                  (const_string "fmul")
14815                (match_operand:MODEF 3 "div_operator" "")
14816                  (const_string "fdiv")
14817               ]
14818               (const_string "fop")))
14819    (set_attr "mode" "<MODE>")])
14820
14821 (define_insn "*rcpsf2_sse"
14822   [(set (match_operand:SF 0 "register_operand" "=x")
14823         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
14824                    UNSPEC_RCP))]
14825   "TARGET_SSE_MATH"
14826   "%vrcpss\t{%1, %d0|%d0, %1}"
14827   [(set_attr "type" "sse")
14828    (set_attr "atom_sse_attr" "rcp")
14829    (set_attr "prefix" "maybe_vex")
14830    (set_attr "mode" "SF")])
14831
14832 (define_insn "*fop_<mode>_1_avx"
14833   [(set (match_operand:MODEF 0 "register_operand" "=x")
14834         (match_operator:MODEF 3 "binary_fp_operator"
14835           [(match_operand:MODEF 1 "register_operand" "x")
14836            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
14837   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14838    && !COMMUTATIVE_ARITH_P (operands[3])"
14839   "* return output_387_binary_op (insn, operands);"
14840   [(set (attr "type")
14841         (cond [(match_operand:MODEF 3 "mult_operator" "")
14842                  (const_string "ssemul")
14843                (match_operand:MODEF 3 "div_operator" "")
14844                  (const_string "ssediv")
14845               ]
14846               (const_string "sseadd")))
14847    (set_attr "prefix" "vex")
14848    (set_attr "mode" "<MODE>")])
14849
14850 (define_insn "*fop_<mode>_1_sse"
14851   [(set (match_operand:MODEF 0 "register_operand" "=x")
14852         (match_operator:MODEF 3 "binary_fp_operator"
14853           [(match_operand:MODEF 1 "register_operand" "0")
14854            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
14855   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14856    && !COMMUTATIVE_ARITH_P (operands[3])"
14857   "* return output_387_binary_op (insn, operands);"
14858   [(set (attr "type")
14859         (cond [(match_operand:MODEF 3 "mult_operator" "")
14860                  (const_string "ssemul")
14861                (match_operand:MODEF 3 "div_operator" "")
14862                  (const_string "ssediv")
14863               ]
14864               (const_string "sseadd")))
14865    (set_attr "mode" "<MODE>")])
14866
14867 ;; This pattern is not fully shadowed by the pattern above.
14868 (define_insn "*fop_<mode>_1_i387"
14869   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
14870         (match_operator:MODEF 3 "binary_fp_operator"
14871           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
14872            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
14873   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
14874    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14875    && !COMMUTATIVE_ARITH_P (operands[3])
14876    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14877   "* return output_387_binary_op (insn, operands);"
14878   [(set (attr "type")
14879         (cond [(match_operand:MODEF 3 "mult_operator" "")
14880                  (const_string "fmul")
14881                (match_operand:MODEF 3 "div_operator" "")
14882                  (const_string "fdiv")
14883               ]
14884               (const_string "fop")))
14885    (set_attr "mode" "<MODE>")])
14886
14887 ;; ??? Add SSE splitters for these!
14888 (define_insn "*fop_<MODEF:mode>_2_i387"
14889   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
14890         (match_operator:MODEF 3 "binary_fp_operator"
14891           [(float:MODEF
14892              (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14893            (match_operand:MODEF 2 "register_operand" "0,0")]))]
14894   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
14895    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
14896    && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
14897   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14898   [(set (attr "type")
14899         (cond [(match_operand:MODEF 3 "mult_operator" "")
14900                  (const_string "fmul")
14901                (match_operand:MODEF 3 "div_operator" "")
14902                  (const_string "fdiv")
14903               ]
14904               (const_string "fop")))
14905    (set_attr "fp_int_src" "true")
14906    (set_attr "mode" "<X87MODEI12:MODE>")])
14907
14908 (define_insn "*fop_<MODEF:mode>_3_i387"
14909   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
14910         (match_operator:MODEF 3 "binary_fp_operator"
14911           [(match_operand:MODEF 1 "register_operand" "0,0")
14912            (float:MODEF
14913              (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14914   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
14915    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
14916    && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
14917   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14918   [(set (attr "type")
14919         (cond [(match_operand:MODEF 3 "mult_operator" "")
14920                  (const_string "fmul")
14921                (match_operand:MODEF 3 "div_operator" "")
14922                  (const_string "fdiv")
14923               ]
14924               (const_string "fop")))
14925    (set_attr "fp_int_src" "true")
14926    (set_attr "mode" "<MODE>")])
14927
14928 (define_insn "*fop_df_4_i387"
14929   [(set (match_operand:DF 0 "register_operand" "=f,f")
14930         (match_operator:DF 3 "binary_fp_operator"
14931            [(float_extend:DF
14932              (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14933             (match_operand:DF 2 "register_operand" "0,f")]))]
14934   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
14935    && !(TARGET_SSE2 && TARGET_SSE_MATH)
14936    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14937   "* return output_387_binary_op (insn, operands);"
14938   [(set (attr "type")
14939         (cond [(match_operand:DF 3 "mult_operator" "")
14940                  (const_string "fmul")
14941                (match_operand:DF 3 "div_operator" "")
14942                  (const_string "fdiv")
14943               ]
14944               (const_string "fop")))
14945    (set_attr "mode" "SF")])
14946
14947 (define_insn "*fop_df_5_i387"
14948   [(set (match_operand:DF 0 "register_operand" "=f,f")
14949         (match_operator:DF 3 "binary_fp_operator"
14950           [(match_operand:DF 1 "register_operand" "0,f")
14951            (float_extend:DF
14952             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14953   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
14954    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14955   "* return output_387_binary_op (insn, operands);"
14956   [(set (attr "type")
14957         (cond [(match_operand:DF 3 "mult_operator" "")
14958                  (const_string "fmul")
14959                (match_operand:DF 3 "div_operator" "")
14960                  (const_string "fdiv")
14961               ]
14962               (const_string "fop")))
14963    (set_attr "mode" "SF")])
14964
14965 (define_insn "*fop_df_6_i387"
14966   [(set (match_operand:DF 0 "register_operand" "=f,f")
14967         (match_operator:DF 3 "binary_fp_operator"
14968           [(float_extend:DF
14969             (match_operand:SF 1 "register_operand" "0,f"))
14970            (float_extend:DF
14971             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14972   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
14973    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14974   "* return output_387_binary_op (insn, operands);"
14975   [(set (attr "type")
14976         (cond [(match_operand:DF 3 "mult_operator" "")
14977                  (const_string "fmul")
14978                (match_operand:DF 3 "div_operator" "")
14979                  (const_string "fdiv")
14980               ]
14981               (const_string "fop")))
14982    (set_attr "mode" "SF")])
14983
14984 (define_insn "*fop_xf_comm_i387"
14985   [(set (match_operand:XF 0 "register_operand" "=f")
14986         (match_operator:XF 3 "binary_fp_operator"
14987                         [(match_operand:XF 1 "register_operand" "%0")
14988                          (match_operand:XF 2 "register_operand" "f")]))]
14989   "TARGET_80387
14990    && COMMUTATIVE_ARITH_P (operands[3])"
14991   "* return output_387_binary_op (insn, operands);"
14992   [(set (attr "type")
14993         (if_then_else (match_operand:XF 3 "mult_operator" "")
14994            (const_string "fmul")
14995            (const_string "fop")))
14996    (set_attr "mode" "XF")])
14997
14998 (define_insn "*fop_xf_1_i387"
14999   [(set (match_operand:XF 0 "register_operand" "=f,f")
15000         (match_operator:XF 3 "binary_fp_operator"
15001                         [(match_operand:XF 1 "register_operand" "0,f")
15002                          (match_operand:XF 2 "register_operand" "f,0")]))]
15003   "TARGET_80387
15004    && !COMMUTATIVE_ARITH_P (operands[3])"
15005   "* return output_387_binary_op (insn, operands);"
15006   [(set (attr "type")
15007         (cond [(match_operand:XF 3 "mult_operator" "")
15008                  (const_string "fmul")
15009                (match_operand:XF 3 "div_operator" "")
15010                  (const_string "fdiv")
15011               ]
15012               (const_string "fop")))
15013    (set_attr "mode" "XF")])
15014
15015 (define_insn "*fop_xf_2_i387"
15016   [(set (match_operand:XF 0 "register_operand" "=f,f")
15017         (match_operator:XF 3 "binary_fp_operator"
15018           [(float:XF
15019              (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15020            (match_operand:XF 2 "register_operand" "0,0")]))]
15021   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
15022   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15023   [(set (attr "type")
15024         (cond [(match_operand:XF 3 "mult_operator" "")
15025                  (const_string "fmul")
15026                (match_operand:XF 3 "div_operator" "")
15027                  (const_string "fdiv")
15028               ]
15029               (const_string "fop")))
15030    (set_attr "fp_int_src" "true")
15031    (set_attr "mode" "<MODE>")])
15032
15033 (define_insn "*fop_xf_3_i387"
15034   [(set (match_operand:XF 0 "register_operand" "=f,f")
15035         (match_operator:XF 3 "binary_fp_operator"
15036           [(match_operand:XF 1 "register_operand" "0,0")
15037            (float:XF
15038              (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15039   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
15040   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15041   [(set (attr "type")
15042         (cond [(match_operand:XF 3 "mult_operator" "")
15043                  (const_string "fmul")
15044                (match_operand:XF 3 "div_operator" "")
15045                  (const_string "fdiv")
15046               ]
15047               (const_string "fop")))
15048    (set_attr "fp_int_src" "true")
15049    (set_attr "mode" "<MODE>")])
15050
15051 (define_insn "*fop_xf_4_i387"
15052   [(set (match_operand:XF 0 "register_operand" "=f,f")
15053         (match_operator:XF 3 "binary_fp_operator"
15054            [(float_extend:XF
15055               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
15056             (match_operand:XF 2 "register_operand" "0,f")]))]
15057   "TARGET_80387"
15058   "* return output_387_binary_op (insn, operands);"
15059   [(set (attr "type")
15060         (cond [(match_operand:XF 3 "mult_operator" "")
15061                  (const_string "fmul")
15062                (match_operand:XF 3 "div_operator" "")
15063                  (const_string "fdiv")
15064               ]
15065               (const_string "fop")))
15066    (set_attr "mode" "<MODE>")])
15067
15068 (define_insn "*fop_xf_5_i387"
15069   [(set (match_operand:XF 0 "register_operand" "=f,f")
15070         (match_operator:XF 3 "binary_fp_operator"
15071           [(match_operand:XF 1 "register_operand" "0,f")
15072            (float_extend:XF
15073              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
15074   "TARGET_80387"
15075   "* return output_387_binary_op (insn, operands);"
15076   [(set (attr "type")
15077         (cond [(match_operand:XF 3 "mult_operator" "")
15078                  (const_string "fmul")
15079                (match_operand:XF 3 "div_operator" "")
15080                  (const_string "fdiv")
15081               ]
15082               (const_string "fop")))
15083    (set_attr "mode" "<MODE>")])
15084
15085 (define_insn "*fop_xf_6_i387"
15086   [(set (match_operand:XF 0 "register_operand" "=f,f")
15087         (match_operator:XF 3 "binary_fp_operator"
15088           [(float_extend:XF
15089              (match_operand:MODEF 1 "register_operand" "0,f"))
15090            (float_extend:XF
15091              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
15092   "TARGET_80387"
15093   "* return output_387_binary_op (insn, operands);"
15094   [(set (attr "type")
15095         (cond [(match_operand:XF 3 "mult_operator" "")
15096                  (const_string "fmul")
15097                (match_operand:XF 3 "div_operator" "")
15098                  (const_string "fdiv")
15099               ]
15100               (const_string "fop")))
15101    (set_attr "mode" "<MODE>")])
15102
15103 (define_split
15104   [(set (match_operand 0 "register_operand" "")
15105         (match_operator 3 "binary_fp_operator"
15106            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
15107             (match_operand 2 "register_operand" "")]))]
15108   "reload_completed
15109    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
15110    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
15111   [(const_int 0)]
15112 {
15113   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
15114   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15115   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15116                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
15117                                           GET_MODE (operands[3]),
15118                                           operands[4],
15119                                           operands[2])));
15120   ix86_free_from_memory (GET_MODE (operands[1]));
15121   DONE;
15122 })
15123
15124 (define_split
15125   [(set (match_operand 0 "register_operand" "")
15126         (match_operator 3 "binary_fp_operator"
15127            [(match_operand 1 "register_operand" "")
15128             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
15129   "reload_completed
15130    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
15131    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
15132   [(const_int 0)]
15133 {
15134   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
15135   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15136   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15137                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
15138                                           GET_MODE (operands[3]),
15139                                           operands[1],
15140                                           operands[4])));
15141   ix86_free_from_memory (GET_MODE (operands[2]));
15142   DONE;
15143 })
15144 \f
15145 ;; FPU special functions.
15146
15147 ;; This pattern implements a no-op XFmode truncation for
15148 ;; all fancy i386 XFmode math functions.
15149
15150 (define_insn "truncxf<mode>2_i387_noop_unspec"
15151   [(set (match_operand:MODEF 0 "register_operand" "=f")
15152         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
15153         UNSPEC_TRUNC_NOOP))]
15154   "TARGET_USE_FANCY_MATH_387"
15155   "* return output_387_reg_move (insn, operands);"
15156   [(set_attr "type" "fmov")
15157    (set_attr "mode" "<MODE>")])
15158
15159 (define_insn "sqrtxf2"
15160   [(set (match_operand:XF 0 "register_operand" "=f")
15161         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15162   "TARGET_USE_FANCY_MATH_387"
15163   "fsqrt"
15164   [(set_attr "type" "fpspc")
15165    (set_attr "mode" "XF")
15166    (set_attr "athlon_decode" "direct")
15167    (set_attr "amdfam10_decode" "direct")])
15168
15169 (define_insn "sqrt_extend<mode>xf2_i387"
15170   [(set (match_operand:XF 0 "register_operand" "=f")
15171         (sqrt:XF
15172           (float_extend:XF
15173             (match_operand:MODEF 1 "register_operand" "0"))))]
15174   "TARGET_USE_FANCY_MATH_387"
15175   "fsqrt"
15176   [(set_attr "type" "fpspc")
15177    (set_attr "mode" "XF")
15178    (set_attr "athlon_decode" "direct")
15179    (set_attr "amdfam10_decode" "direct")])
15180
15181 (define_insn "*rsqrtsf2_sse"
15182   [(set (match_operand:SF 0 "register_operand" "=x")
15183         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
15184                    UNSPEC_RSQRT))]
15185   "TARGET_SSE_MATH"
15186   "%vrsqrtss\t{%1, %d0|%d0, %1}"
15187   [(set_attr "type" "sse")
15188    (set_attr "atom_sse_attr" "rcp")
15189    (set_attr "prefix" "maybe_vex")
15190    (set_attr "mode" "SF")])
15191
15192 (define_expand "rsqrtsf2"
15193   [(set (match_operand:SF 0 "register_operand" "")
15194         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
15195                    UNSPEC_RSQRT))]
15196   "TARGET_SSE_MATH"
15197 {
15198   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
15199   DONE;
15200 })
15201
15202 (define_insn "*sqrt<mode>2_sse"
15203   [(set (match_operand:MODEF 0 "register_operand" "=x")
15204         (sqrt:MODEF
15205           (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
15206   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
15207   "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}"
15208   [(set_attr "type" "sse")
15209    (set_attr "atom_sse_attr" "sqrt")
15210    (set_attr "prefix" "maybe_vex")
15211    (set_attr "mode" "<MODE>")
15212    (set_attr "athlon_decode" "*")
15213    (set_attr "amdfam10_decode" "*")])
15214
15215 (define_expand "sqrt<mode>2"
15216   [(set (match_operand:MODEF 0 "register_operand" "")
15217         (sqrt:MODEF
15218           (match_operand:MODEF 1 "nonimmediate_operand" "")))]
15219   "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
15220    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15221 {
15222   if (<MODE>mode == SFmode
15223       && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
15224       && flag_finite_math_only && !flag_trapping_math
15225       && flag_unsafe_math_optimizations)
15226     {
15227       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
15228       DONE;
15229     }
15230
15231   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
15232     {
15233       rtx op0 = gen_reg_rtx (XFmode);
15234       rtx op1 = force_reg (<MODE>mode, operands[1]);
15235
15236       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
15237       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
15238       DONE;
15239    }
15240 })
15241
15242 (define_insn "fpremxf4_i387"
15243   [(set (match_operand:XF 0 "register_operand" "=f")
15244         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15245                     (match_operand:XF 3 "register_operand" "1")]
15246                    UNSPEC_FPREM_F))
15247    (set (match_operand:XF 1 "register_operand" "=u")
15248         (unspec:XF [(match_dup 2) (match_dup 3)]
15249                    UNSPEC_FPREM_U))
15250    (set (reg:CCFP FPSR_REG)
15251         (unspec:CCFP [(match_dup 2) (match_dup 3)]
15252                      UNSPEC_C2_FLAG))]
15253   "TARGET_USE_FANCY_MATH_387"
15254   "fprem"
15255   [(set_attr "type" "fpspc")
15256    (set_attr "mode" "XF")])
15257
15258 (define_expand "fmodxf3"
15259   [(use (match_operand:XF 0 "register_operand" ""))
15260    (use (match_operand:XF 1 "general_operand" ""))
15261    (use (match_operand:XF 2 "general_operand" ""))]
15262   "TARGET_USE_FANCY_MATH_387"
15263 {
15264   rtx label = gen_label_rtx ();
15265
15266   rtx op1 = gen_reg_rtx (XFmode);
15267   rtx op2 = gen_reg_rtx (XFmode);
15268
15269   emit_move_insn (op2, operands[2]);
15270   emit_move_insn (op1, operands[1]);
15271
15272   emit_label (label);
15273   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
15274   ix86_emit_fp_unordered_jump (label);
15275   LABEL_NUSES (label) = 1;
15276
15277   emit_move_insn (operands[0], op1);
15278   DONE;
15279 })
15280
15281 (define_expand "fmod<mode>3"
15282   [(use (match_operand:MODEF 0 "register_operand" ""))
15283    (use (match_operand:MODEF 1 "general_operand" ""))
15284    (use (match_operand:MODEF 2 "general_operand" ""))]
15285   "TARGET_USE_FANCY_MATH_387"
15286 {
15287   rtx label = gen_label_rtx ();
15288
15289   rtx op1 = gen_reg_rtx (XFmode);
15290   rtx op2 = gen_reg_rtx (XFmode);
15291
15292   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15293   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15294
15295   emit_label (label);
15296   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
15297   ix86_emit_fp_unordered_jump (label);
15298   LABEL_NUSES (label) = 1;
15299
15300   /* Truncate the result properly for strict SSE math.  */
15301   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15302       && !TARGET_MIX_SSE_I387)
15303     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
15304   else
15305     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
15306
15307   DONE;
15308 })
15309
15310 (define_insn "fprem1xf4_i387"
15311   [(set (match_operand:XF 0 "register_operand" "=f")
15312         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15313                     (match_operand:XF 3 "register_operand" "1")]
15314                    UNSPEC_FPREM1_F))
15315    (set (match_operand:XF 1 "register_operand" "=u")
15316         (unspec:XF [(match_dup 2) (match_dup 3)]
15317                    UNSPEC_FPREM1_U))
15318    (set (reg:CCFP FPSR_REG)
15319         (unspec:CCFP [(match_dup 2) (match_dup 3)]
15320                      UNSPEC_C2_FLAG))]
15321   "TARGET_USE_FANCY_MATH_387"
15322   "fprem1"
15323   [(set_attr "type" "fpspc")
15324    (set_attr "mode" "XF")])
15325
15326 (define_expand "remainderxf3"
15327   [(use (match_operand:XF 0 "register_operand" ""))
15328    (use (match_operand:XF 1 "general_operand" ""))
15329    (use (match_operand:XF 2 "general_operand" ""))]
15330   "TARGET_USE_FANCY_MATH_387"
15331 {
15332   rtx label = gen_label_rtx ();
15333
15334   rtx op1 = gen_reg_rtx (XFmode);
15335   rtx op2 = gen_reg_rtx (XFmode);
15336
15337   emit_move_insn (op2, operands[2]);
15338   emit_move_insn (op1, operands[1]);
15339
15340   emit_label (label);
15341   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
15342   ix86_emit_fp_unordered_jump (label);
15343   LABEL_NUSES (label) = 1;
15344
15345   emit_move_insn (operands[0], op1);
15346   DONE;
15347 })
15348
15349 (define_expand "remainder<mode>3"
15350   [(use (match_operand:MODEF 0 "register_operand" ""))
15351    (use (match_operand:MODEF 1 "general_operand" ""))
15352    (use (match_operand:MODEF 2 "general_operand" ""))]
15353   "TARGET_USE_FANCY_MATH_387"
15354 {
15355   rtx label = gen_label_rtx ();
15356
15357   rtx op1 = gen_reg_rtx (XFmode);
15358   rtx op2 = gen_reg_rtx (XFmode);
15359
15360   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15361   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15362
15363   emit_label (label);
15364
15365   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
15366   ix86_emit_fp_unordered_jump (label);
15367   LABEL_NUSES (label) = 1;
15368
15369   /* Truncate the result properly for strict SSE math.  */
15370   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15371       && !TARGET_MIX_SSE_I387)
15372     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
15373   else
15374     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
15375
15376   DONE;
15377 })
15378
15379 (define_insn "*sinxf2_i387"
15380   [(set (match_operand:XF 0 "register_operand" "=f")
15381         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15382   "TARGET_USE_FANCY_MATH_387
15383    && flag_unsafe_math_optimizations"
15384   "fsin"
15385   [(set_attr "type" "fpspc")
15386    (set_attr "mode" "XF")])
15387
15388 (define_insn "*sin_extend<mode>xf2_i387"
15389   [(set (match_operand:XF 0 "register_operand" "=f")
15390         (unspec:XF [(float_extend:XF
15391                       (match_operand:MODEF 1 "register_operand" "0"))]
15392                    UNSPEC_SIN))]
15393   "TARGET_USE_FANCY_MATH_387
15394    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15395        || TARGET_MIX_SSE_I387)
15396    && flag_unsafe_math_optimizations"
15397   "fsin"
15398   [(set_attr "type" "fpspc")
15399    (set_attr "mode" "XF")])
15400
15401 (define_insn "*cosxf2_i387"
15402   [(set (match_operand:XF 0 "register_operand" "=f")
15403         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15404   "TARGET_USE_FANCY_MATH_387
15405    && flag_unsafe_math_optimizations"
15406   "fcos"
15407   [(set_attr "type" "fpspc")
15408    (set_attr "mode" "XF")])
15409
15410 (define_insn "*cos_extend<mode>xf2_i387"
15411   [(set (match_operand:XF 0 "register_operand" "=f")
15412         (unspec:XF [(float_extend:XF
15413                       (match_operand:MODEF 1 "register_operand" "0"))]
15414                    UNSPEC_COS))]
15415   "TARGET_USE_FANCY_MATH_387
15416    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15417        || TARGET_MIX_SSE_I387)
15418    && flag_unsafe_math_optimizations"
15419   "fcos"
15420   [(set_attr "type" "fpspc")
15421    (set_attr "mode" "XF")])
15422
15423 ;; When sincos pattern is defined, sin and cos builtin functions will be
15424 ;; expanded to sincos pattern with one of its outputs left unused.
15425 ;; CSE pass will figure out if two sincos patterns can be combined,
15426 ;; otherwise sincos pattern will be split back to sin or cos pattern,
15427 ;; depending on the unused output.
15428
15429 (define_insn "sincosxf3"
15430   [(set (match_operand:XF 0 "register_operand" "=f")
15431         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15432                    UNSPEC_SINCOS_COS))
15433    (set (match_operand:XF 1 "register_operand" "=u")
15434         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15435   "TARGET_USE_FANCY_MATH_387
15436    && flag_unsafe_math_optimizations"
15437   "fsincos"
15438   [(set_attr "type" "fpspc")
15439    (set_attr "mode" "XF")])
15440
15441 (define_split
15442   [(set (match_operand:XF 0 "register_operand" "")
15443         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15444                    UNSPEC_SINCOS_COS))
15445    (set (match_operand:XF 1 "register_operand" "")
15446         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15447   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15448    && !(reload_completed || reload_in_progress)"
15449   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15450   "")
15451
15452 (define_split
15453   [(set (match_operand:XF 0 "register_operand" "")
15454         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15455                    UNSPEC_SINCOS_COS))
15456    (set (match_operand:XF 1 "register_operand" "")
15457         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15458   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15459    && !(reload_completed || reload_in_progress)"
15460   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15461   "")
15462
15463 (define_insn "sincos_extend<mode>xf3_i387"
15464   [(set (match_operand:XF 0 "register_operand" "=f")
15465         (unspec:XF [(float_extend:XF
15466                       (match_operand:MODEF 2 "register_operand" "0"))]
15467                    UNSPEC_SINCOS_COS))
15468    (set (match_operand:XF 1 "register_operand" "=u")
15469         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
15470   "TARGET_USE_FANCY_MATH_387
15471    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15472        || TARGET_MIX_SSE_I387)
15473    && flag_unsafe_math_optimizations"
15474   "fsincos"
15475   [(set_attr "type" "fpspc")
15476    (set_attr "mode" "XF")])
15477
15478 (define_split
15479   [(set (match_operand:XF 0 "register_operand" "")
15480         (unspec:XF [(float_extend:XF
15481                       (match_operand:MODEF 2 "register_operand" ""))]
15482                    UNSPEC_SINCOS_COS))
15483    (set (match_operand:XF 1 "register_operand" "")
15484         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
15485   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15486    && !(reload_completed || reload_in_progress)"
15487   [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
15488   "")
15489
15490 (define_split
15491   [(set (match_operand:XF 0 "register_operand" "")
15492         (unspec:XF [(float_extend:XF
15493                       (match_operand:MODEF 2 "register_operand" ""))]
15494                    UNSPEC_SINCOS_COS))
15495    (set (match_operand:XF 1 "register_operand" "")
15496         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
15497   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15498    && !(reload_completed || reload_in_progress)"
15499   [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
15500   "")
15501
15502 (define_expand "sincos<mode>3"
15503   [(use (match_operand:MODEF 0 "register_operand" ""))
15504    (use (match_operand:MODEF 1 "register_operand" ""))
15505    (use (match_operand:MODEF 2 "register_operand" ""))]
15506   "TARGET_USE_FANCY_MATH_387
15507    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15508        || TARGET_MIX_SSE_I387)
15509    && flag_unsafe_math_optimizations"
15510 {
15511   rtx op0 = gen_reg_rtx (XFmode);
15512   rtx op1 = gen_reg_rtx (XFmode);
15513
15514   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
15515   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15516   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
15517   DONE;
15518 })
15519
15520 (define_insn "fptanxf4_i387"
15521   [(set (match_operand:XF 0 "register_operand" "=f")
15522         (match_operand:XF 3 "const_double_operand" "F"))
15523    (set (match_operand:XF 1 "register_operand" "=u")
15524         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15525                    UNSPEC_TAN))]
15526   "TARGET_USE_FANCY_MATH_387
15527    && flag_unsafe_math_optimizations
15528    && standard_80387_constant_p (operands[3]) == 2"
15529   "fptan"
15530   [(set_attr "type" "fpspc")
15531    (set_attr "mode" "XF")])
15532
15533 (define_insn "fptan_extend<mode>xf4_i387"
15534   [(set (match_operand:MODEF 0 "register_operand" "=f")
15535         (match_operand:MODEF 3 "const_double_operand" "F"))
15536    (set (match_operand:XF 1 "register_operand" "=u")
15537         (unspec:XF [(float_extend:XF
15538                       (match_operand:MODEF 2 "register_operand" "0"))]
15539                    UNSPEC_TAN))]
15540   "TARGET_USE_FANCY_MATH_387
15541    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15542        || TARGET_MIX_SSE_I387)
15543    && flag_unsafe_math_optimizations
15544    && standard_80387_constant_p (operands[3]) == 2"
15545   "fptan"
15546   [(set_attr "type" "fpspc")
15547    (set_attr "mode" "XF")])
15548
15549 (define_expand "tanxf2"
15550   [(use (match_operand:XF 0 "register_operand" ""))
15551    (use (match_operand:XF 1 "register_operand" ""))]
15552   "TARGET_USE_FANCY_MATH_387
15553    && flag_unsafe_math_optimizations"
15554 {
15555   rtx one = gen_reg_rtx (XFmode);
15556   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
15557
15558   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
15559   DONE;
15560 })
15561
15562 (define_expand "tan<mode>2"
15563   [(use (match_operand:MODEF 0 "register_operand" ""))
15564    (use (match_operand:MODEF 1 "register_operand" ""))]
15565   "TARGET_USE_FANCY_MATH_387
15566    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15567        || TARGET_MIX_SSE_I387)
15568    && flag_unsafe_math_optimizations"
15569 {
15570   rtx op0 = gen_reg_rtx (XFmode);
15571
15572   rtx one = gen_reg_rtx (<MODE>mode);
15573   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
15574
15575   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
15576                                              operands[1], op2));
15577   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15578   DONE;
15579 })
15580
15581 (define_insn "*fpatanxf3_i387"
15582   [(set (match_operand:XF 0 "register_operand" "=f")
15583         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
15584                     (match_operand:XF 2 "register_operand" "u")]
15585                    UNSPEC_FPATAN))
15586    (clobber (match_scratch:XF 3 "=2"))]
15587   "TARGET_USE_FANCY_MATH_387
15588    && flag_unsafe_math_optimizations"
15589   "fpatan"
15590   [(set_attr "type" "fpspc")
15591    (set_attr "mode" "XF")])
15592
15593 (define_insn "fpatan_extend<mode>xf3_i387"
15594   [(set (match_operand:XF 0 "register_operand" "=f")
15595         (unspec:XF [(float_extend:XF
15596                       (match_operand:MODEF 1 "register_operand" "0"))
15597                     (float_extend:XF
15598                       (match_operand:MODEF 2 "register_operand" "u"))]
15599                    UNSPEC_FPATAN))
15600    (clobber (match_scratch:XF 3 "=2"))]
15601   "TARGET_USE_FANCY_MATH_387
15602    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15603        || TARGET_MIX_SSE_I387)
15604    && flag_unsafe_math_optimizations"
15605   "fpatan"
15606   [(set_attr "type" "fpspc")
15607    (set_attr "mode" "XF")])
15608
15609 (define_expand "atan2xf3"
15610   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15611                    (unspec:XF [(match_operand:XF 2 "register_operand" "")
15612                                (match_operand:XF 1 "register_operand" "")]
15613                               UNSPEC_FPATAN))
15614               (clobber (match_scratch:XF 3 ""))])]
15615   "TARGET_USE_FANCY_MATH_387
15616    && flag_unsafe_math_optimizations"
15617   "")
15618
15619 (define_expand "atan2<mode>3"
15620   [(use (match_operand:MODEF 0 "register_operand" ""))
15621    (use (match_operand:MODEF 1 "register_operand" ""))
15622    (use (match_operand:MODEF 2 "register_operand" ""))]
15623   "TARGET_USE_FANCY_MATH_387
15624    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15625        || TARGET_MIX_SSE_I387)
15626    && flag_unsafe_math_optimizations"
15627 {
15628   rtx op0 = gen_reg_rtx (XFmode);
15629
15630   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
15631   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15632   DONE;
15633 })
15634
15635 (define_expand "atanxf2"
15636   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15637                    (unspec:XF [(match_dup 2)
15638                                (match_operand:XF 1 "register_operand" "")]
15639                               UNSPEC_FPATAN))
15640               (clobber (match_scratch:XF 3 ""))])]
15641   "TARGET_USE_FANCY_MATH_387
15642    && flag_unsafe_math_optimizations"
15643 {
15644   operands[2] = gen_reg_rtx (XFmode);
15645   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15646 })
15647
15648 (define_expand "atan<mode>2"
15649   [(use (match_operand:MODEF 0 "register_operand" ""))
15650    (use (match_operand:MODEF 1 "register_operand" ""))]
15651   "TARGET_USE_FANCY_MATH_387
15652    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15653        || TARGET_MIX_SSE_I387)
15654    && flag_unsafe_math_optimizations"
15655 {
15656   rtx op0 = gen_reg_rtx (XFmode);
15657
15658   rtx op2 = gen_reg_rtx (<MODE>mode);
15659   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
15660
15661   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
15662   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15663   DONE;
15664 })
15665
15666 (define_expand "asinxf2"
15667   [(set (match_dup 2)
15668         (mult:XF (match_operand:XF 1 "register_operand" "")
15669                  (match_dup 1)))
15670    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15671    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15672    (parallel [(set (match_operand:XF 0 "register_operand" "")
15673                    (unspec:XF [(match_dup 5) (match_dup 1)]
15674                               UNSPEC_FPATAN))
15675               (clobber (match_scratch:XF 6 ""))])]
15676   "TARGET_USE_FANCY_MATH_387
15677    && flag_unsafe_math_optimizations"
15678 {
15679   int i;
15680
15681   if (optimize_insn_for_size_p ())
15682     FAIL;
15683
15684   for (i = 2; i < 6; i++)
15685     operands[i] = gen_reg_rtx (XFmode);
15686
15687   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15688 })
15689
15690 (define_expand "asin<mode>2"
15691   [(use (match_operand:MODEF 0 "register_operand" ""))
15692    (use (match_operand:MODEF 1 "general_operand" ""))]
15693  "TARGET_USE_FANCY_MATH_387
15694    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15695        || TARGET_MIX_SSE_I387)
15696    && flag_unsafe_math_optimizations"
15697 {
15698   rtx op0 = gen_reg_rtx (XFmode);
15699   rtx op1 = gen_reg_rtx (XFmode);
15700
15701   if (optimize_insn_for_size_p ())
15702     FAIL;
15703
15704   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15705   emit_insn (gen_asinxf2 (op0, op1));
15706   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15707   DONE;
15708 })
15709
15710 (define_expand "acosxf2"
15711   [(set (match_dup 2)
15712         (mult:XF (match_operand:XF 1 "register_operand" "")
15713                  (match_dup 1)))
15714    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15715    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15716    (parallel [(set (match_operand:XF 0 "register_operand" "")
15717                    (unspec:XF [(match_dup 1) (match_dup 5)]
15718                               UNSPEC_FPATAN))
15719               (clobber (match_scratch:XF 6 ""))])]
15720   "TARGET_USE_FANCY_MATH_387
15721    && flag_unsafe_math_optimizations"
15722 {
15723   int i;
15724
15725   if (optimize_insn_for_size_p ())
15726     FAIL;
15727
15728   for (i = 2; i < 6; i++)
15729     operands[i] = gen_reg_rtx (XFmode);
15730
15731   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15732 })
15733
15734 (define_expand "acos<mode>2"
15735   [(use (match_operand:MODEF 0 "register_operand" ""))
15736    (use (match_operand:MODEF 1 "general_operand" ""))]
15737  "TARGET_USE_FANCY_MATH_387
15738    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15739        || TARGET_MIX_SSE_I387)
15740    && flag_unsafe_math_optimizations"
15741 {
15742   rtx op0 = gen_reg_rtx (XFmode);
15743   rtx op1 = gen_reg_rtx (XFmode);
15744
15745   if (optimize_insn_for_size_p ())
15746     FAIL;
15747
15748   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15749   emit_insn (gen_acosxf2 (op0, op1));
15750   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15751   DONE;
15752 })
15753
15754 (define_insn "fyl2xxf3_i387"
15755   [(set (match_operand:XF 0 "register_operand" "=f")
15756         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
15757                     (match_operand:XF 2 "register_operand" "u")]
15758                    UNSPEC_FYL2X))
15759    (clobber (match_scratch:XF 3 "=2"))]
15760   "TARGET_USE_FANCY_MATH_387
15761    && flag_unsafe_math_optimizations"
15762   "fyl2x"
15763   [(set_attr "type" "fpspc")
15764    (set_attr "mode" "XF")])
15765
15766 (define_insn "fyl2x_extend<mode>xf3_i387"
15767   [(set (match_operand:XF 0 "register_operand" "=f")
15768         (unspec:XF [(float_extend:XF
15769                       (match_operand:MODEF 1 "register_operand" "0"))
15770                     (match_operand:XF 2 "register_operand" "u")]
15771                    UNSPEC_FYL2X))
15772    (clobber (match_scratch:XF 3 "=2"))]
15773   "TARGET_USE_FANCY_MATH_387
15774    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15775        || TARGET_MIX_SSE_I387)
15776    && flag_unsafe_math_optimizations"
15777   "fyl2x"
15778   [(set_attr "type" "fpspc")
15779    (set_attr "mode" "XF")])
15780
15781 (define_expand "logxf2"
15782   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15783                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15784                                (match_dup 2)] UNSPEC_FYL2X))
15785               (clobber (match_scratch:XF 3 ""))])]
15786   "TARGET_USE_FANCY_MATH_387
15787    && flag_unsafe_math_optimizations"
15788 {
15789   operands[2] = gen_reg_rtx (XFmode);
15790   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
15791 })
15792
15793 (define_expand "log<mode>2"
15794   [(use (match_operand:MODEF 0 "register_operand" ""))
15795    (use (match_operand:MODEF 1 "register_operand" ""))]
15796   "TARGET_USE_FANCY_MATH_387
15797    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15798        || TARGET_MIX_SSE_I387)
15799    && flag_unsafe_math_optimizations"
15800 {
15801   rtx op0 = gen_reg_rtx (XFmode);
15802
15803   rtx op2 = gen_reg_rtx (XFmode);
15804   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
15805
15806   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
15807   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15808   DONE;
15809 })
15810
15811 (define_expand "log10xf2"
15812   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15813                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15814                                (match_dup 2)] UNSPEC_FYL2X))
15815               (clobber (match_scratch:XF 3 ""))])]
15816   "TARGET_USE_FANCY_MATH_387
15817    && flag_unsafe_math_optimizations"
15818 {
15819   operands[2] = gen_reg_rtx (XFmode);
15820   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
15821 })
15822
15823 (define_expand "log10<mode>2"
15824   [(use (match_operand:MODEF 0 "register_operand" ""))
15825    (use (match_operand:MODEF 1 "register_operand" ""))]
15826   "TARGET_USE_FANCY_MATH_387
15827    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15828        || TARGET_MIX_SSE_I387)
15829    && flag_unsafe_math_optimizations"
15830 {
15831   rtx op0 = gen_reg_rtx (XFmode);
15832
15833   rtx op2 = gen_reg_rtx (XFmode);
15834   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
15835
15836   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
15837   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15838   DONE;
15839 })
15840
15841 (define_expand "log2xf2"
15842   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15843                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15844                                (match_dup 2)] UNSPEC_FYL2X))
15845               (clobber (match_scratch:XF 3 ""))])]
15846   "TARGET_USE_FANCY_MATH_387
15847    && flag_unsafe_math_optimizations"
15848 {
15849   operands[2] = gen_reg_rtx (XFmode);
15850   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15851 })
15852
15853 (define_expand "log2<mode>2"
15854   [(use (match_operand:MODEF 0 "register_operand" ""))
15855    (use (match_operand:MODEF 1 "register_operand" ""))]
15856   "TARGET_USE_FANCY_MATH_387
15857    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15858        || TARGET_MIX_SSE_I387)
15859    && flag_unsafe_math_optimizations"
15860 {
15861   rtx op0 = gen_reg_rtx (XFmode);
15862
15863   rtx op2 = gen_reg_rtx (XFmode);
15864   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
15865
15866   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
15867   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15868   DONE;
15869 })
15870
15871 (define_insn "fyl2xp1xf3_i387"
15872   [(set (match_operand:XF 0 "register_operand" "=f")
15873         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
15874                     (match_operand:XF 2 "register_operand" "u")]
15875                    UNSPEC_FYL2XP1))
15876    (clobber (match_scratch:XF 3 "=2"))]
15877   "TARGET_USE_FANCY_MATH_387
15878    && flag_unsafe_math_optimizations"
15879   "fyl2xp1"
15880   [(set_attr "type" "fpspc")
15881    (set_attr "mode" "XF")])
15882
15883 (define_insn "fyl2xp1_extend<mode>xf3_i387"
15884   [(set (match_operand:XF 0 "register_operand" "=f")
15885         (unspec:XF [(float_extend:XF
15886                       (match_operand:MODEF 1 "register_operand" "0"))
15887                     (match_operand:XF 2 "register_operand" "u")]
15888                    UNSPEC_FYL2XP1))
15889    (clobber (match_scratch:XF 3 "=2"))]
15890   "TARGET_USE_FANCY_MATH_387
15891    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15892        || TARGET_MIX_SSE_I387)
15893    && flag_unsafe_math_optimizations"
15894   "fyl2xp1"
15895   [(set_attr "type" "fpspc")
15896    (set_attr "mode" "XF")])
15897
15898 (define_expand "log1pxf2"
15899   [(use (match_operand:XF 0 "register_operand" ""))
15900    (use (match_operand:XF 1 "register_operand" ""))]
15901   "TARGET_USE_FANCY_MATH_387
15902    && flag_unsafe_math_optimizations"
15903 {
15904   if (optimize_insn_for_size_p ())
15905     FAIL;
15906
15907   ix86_emit_i387_log1p (operands[0], operands[1]);
15908   DONE;
15909 })
15910
15911 (define_expand "log1p<mode>2"
15912   [(use (match_operand:MODEF 0 "register_operand" ""))
15913    (use (match_operand:MODEF 1 "register_operand" ""))]
15914   "TARGET_USE_FANCY_MATH_387
15915    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15916        || TARGET_MIX_SSE_I387)
15917    && flag_unsafe_math_optimizations"
15918 {
15919   rtx op0;
15920
15921   if (optimize_insn_for_size_p ())
15922     FAIL;
15923
15924   op0 = gen_reg_rtx (XFmode);
15925
15926   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
15927
15928   ix86_emit_i387_log1p (op0, operands[1]);
15929   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15930   DONE;
15931 })
15932
15933 (define_insn "fxtractxf3_i387"
15934   [(set (match_operand:XF 0 "register_operand" "=f")
15935         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15936                    UNSPEC_XTRACT_FRACT))
15937    (set (match_operand:XF 1 "register_operand" "=u")
15938         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
15939   "TARGET_USE_FANCY_MATH_387
15940    && flag_unsafe_math_optimizations"
15941   "fxtract"
15942   [(set_attr "type" "fpspc")
15943    (set_attr "mode" "XF")])
15944
15945 (define_insn "fxtract_extend<mode>xf3_i387"
15946   [(set (match_operand:XF 0 "register_operand" "=f")
15947         (unspec:XF [(float_extend:XF
15948                       (match_operand:MODEF 2 "register_operand" "0"))]
15949                    UNSPEC_XTRACT_FRACT))
15950    (set (match_operand:XF 1 "register_operand" "=u")
15951         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
15952   "TARGET_USE_FANCY_MATH_387
15953    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15954        || TARGET_MIX_SSE_I387)
15955    && flag_unsafe_math_optimizations"
15956   "fxtract"
15957   [(set_attr "type" "fpspc")
15958    (set_attr "mode" "XF")])
15959
15960 (define_expand "logbxf2"
15961   [(parallel [(set (match_dup 2)
15962                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15963                               UNSPEC_XTRACT_FRACT))
15964               (set (match_operand:XF 0 "register_operand" "")
15965                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15966   "TARGET_USE_FANCY_MATH_387
15967    && flag_unsafe_math_optimizations"
15968 {
15969   operands[2] = gen_reg_rtx (XFmode);
15970 })
15971
15972 (define_expand "logb<mode>2"
15973   [(use (match_operand:MODEF 0 "register_operand" ""))
15974    (use (match_operand:MODEF 1 "register_operand" ""))]
15975   "TARGET_USE_FANCY_MATH_387
15976    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15977        || TARGET_MIX_SSE_I387)
15978    && flag_unsafe_math_optimizations"
15979 {
15980   rtx op0 = gen_reg_rtx (XFmode);
15981   rtx op1 = gen_reg_rtx (XFmode);
15982
15983   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
15984   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
15985   DONE;
15986 })
15987
15988 (define_expand "ilogbxf2"
15989   [(use (match_operand:SI 0 "register_operand" ""))
15990    (use (match_operand:XF 1 "register_operand" ""))]
15991   "TARGET_USE_FANCY_MATH_387
15992    && flag_unsafe_math_optimizations"
15993 {
15994   rtx op0, op1;
15995
15996   if (optimize_insn_for_size_p ())
15997     FAIL;
15998
15999   op0 = gen_reg_rtx (XFmode);
16000   op1 = gen_reg_rtx (XFmode);
16001
16002   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
16003   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16004   DONE;
16005 })
16006
16007 (define_expand "ilogb<mode>2"
16008   [(use (match_operand:SI 0 "register_operand" ""))
16009    (use (match_operand:MODEF 1 "register_operand" ""))]
16010   "TARGET_USE_FANCY_MATH_387
16011    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16012        || TARGET_MIX_SSE_I387)
16013    && flag_unsafe_math_optimizations"
16014 {
16015   rtx op0, op1;
16016
16017   if (optimize_insn_for_size_p ())
16018     FAIL;
16019
16020   op0 = gen_reg_rtx (XFmode);
16021   op1 = gen_reg_rtx (XFmode);
16022
16023   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16024   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16025   DONE;
16026 })
16027
16028 (define_insn "*f2xm1xf2_i387"
16029   [(set (match_operand:XF 0 "register_operand" "=f")
16030         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16031                    UNSPEC_F2XM1))]
16032   "TARGET_USE_FANCY_MATH_387
16033    && flag_unsafe_math_optimizations"
16034   "f2xm1"
16035   [(set_attr "type" "fpspc")
16036    (set_attr "mode" "XF")])
16037
16038 (define_insn "*fscalexf4_i387"
16039   [(set (match_operand:XF 0 "register_operand" "=f")
16040         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16041                     (match_operand:XF 3 "register_operand" "1")]
16042                    UNSPEC_FSCALE_FRACT))
16043    (set (match_operand:XF 1 "register_operand" "=u")
16044         (unspec:XF [(match_dup 2) (match_dup 3)]
16045                    UNSPEC_FSCALE_EXP))]
16046   "TARGET_USE_FANCY_MATH_387
16047    && flag_unsafe_math_optimizations"
16048   "fscale"
16049   [(set_attr "type" "fpspc")
16050    (set_attr "mode" "XF")])
16051
16052 (define_expand "expNcorexf3"
16053   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16054                                (match_operand:XF 2 "register_operand" "")))
16055    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16056    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16057    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16058    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16059    (parallel [(set (match_operand:XF 0 "register_operand" "")
16060                    (unspec:XF [(match_dup 8) (match_dup 4)]
16061                               UNSPEC_FSCALE_FRACT))
16062               (set (match_dup 9)
16063                    (unspec:XF [(match_dup 8) (match_dup 4)]
16064                               UNSPEC_FSCALE_EXP))])]
16065   "TARGET_USE_FANCY_MATH_387
16066    && flag_unsafe_math_optimizations"
16067 {
16068   int i;
16069
16070   if (optimize_insn_for_size_p ())
16071     FAIL;
16072
16073   for (i = 3; i < 10; i++)
16074     operands[i] = gen_reg_rtx (XFmode);
16075
16076   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16077 })
16078
16079 (define_expand "expxf2"
16080   [(use (match_operand:XF 0 "register_operand" ""))
16081    (use (match_operand:XF 1 "register_operand" ""))]
16082   "TARGET_USE_FANCY_MATH_387
16083    && flag_unsafe_math_optimizations"
16084 {
16085   rtx op2;
16086
16087   if (optimize_insn_for_size_p ())
16088     FAIL;
16089
16090   op2 = gen_reg_rtx (XFmode);
16091   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
16092
16093   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16094   DONE;
16095 })
16096
16097 (define_expand "exp<mode>2"
16098   [(use (match_operand:MODEF 0 "register_operand" ""))
16099    (use (match_operand:MODEF 1 "general_operand" ""))]
16100  "TARGET_USE_FANCY_MATH_387
16101    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16102        || TARGET_MIX_SSE_I387)
16103    && flag_unsafe_math_optimizations"
16104 {
16105   rtx op0, op1;
16106
16107   if (optimize_insn_for_size_p ())
16108     FAIL;
16109
16110   op0 = gen_reg_rtx (XFmode);
16111   op1 = gen_reg_rtx (XFmode);
16112
16113   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16114   emit_insn (gen_expxf2 (op0, op1));
16115   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16116   DONE;
16117 })
16118
16119 (define_expand "exp10xf2"
16120   [(use (match_operand:XF 0 "register_operand" ""))
16121    (use (match_operand:XF 1 "register_operand" ""))]
16122   "TARGET_USE_FANCY_MATH_387
16123    && flag_unsafe_math_optimizations"
16124 {
16125   rtx op2;
16126
16127   if (optimize_insn_for_size_p ())
16128     FAIL;
16129
16130   op2 = gen_reg_rtx (XFmode);
16131   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
16132
16133   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16134   DONE;
16135 })
16136
16137 (define_expand "exp10<mode>2"
16138   [(use (match_operand:MODEF 0 "register_operand" ""))
16139    (use (match_operand:MODEF 1 "general_operand" ""))]
16140  "TARGET_USE_FANCY_MATH_387
16141    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16142        || TARGET_MIX_SSE_I387)
16143    && flag_unsafe_math_optimizations"
16144 {
16145   rtx op0, op1;
16146
16147   if (optimize_insn_for_size_p ())
16148     FAIL;
16149
16150   op0 = gen_reg_rtx (XFmode);
16151   op1 = gen_reg_rtx (XFmode);
16152
16153   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16154   emit_insn (gen_exp10xf2 (op0, op1));
16155   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16156   DONE;
16157 })
16158
16159 (define_expand "exp2xf2"
16160   [(use (match_operand:XF 0 "register_operand" ""))
16161    (use (match_operand:XF 1 "register_operand" ""))]
16162   "TARGET_USE_FANCY_MATH_387
16163    && flag_unsafe_math_optimizations"
16164 {
16165   rtx op2;
16166
16167   if (optimize_insn_for_size_p ())
16168     FAIL;
16169
16170   op2 = gen_reg_rtx (XFmode);
16171   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
16172
16173   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16174   DONE;
16175 })
16176
16177 (define_expand "exp2<mode>2"
16178   [(use (match_operand:MODEF 0 "register_operand" ""))
16179    (use (match_operand:MODEF 1 "general_operand" ""))]
16180  "TARGET_USE_FANCY_MATH_387
16181    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16182        || TARGET_MIX_SSE_I387)
16183    && flag_unsafe_math_optimizations"
16184 {
16185   rtx op0, op1;
16186
16187   if (optimize_insn_for_size_p ())
16188     FAIL;
16189
16190   op0 = gen_reg_rtx (XFmode);
16191   op1 = gen_reg_rtx (XFmode);
16192
16193   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16194   emit_insn (gen_exp2xf2 (op0, op1));
16195   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16196   DONE;
16197 })
16198
16199 (define_expand "expm1xf2"
16200   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16201                                (match_dup 2)))
16202    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16203    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16204    (set (match_dup 9) (float_extend:XF (match_dup 13)))
16205    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16206    (parallel [(set (match_dup 7)
16207                    (unspec:XF [(match_dup 6) (match_dup 4)]
16208                               UNSPEC_FSCALE_FRACT))
16209               (set (match_dup 8)
16210                    (unspec:XF [(match_dup 6) (match_dup 4)]
16211                               UNSPEC_FSCALE_EXP))])
16212    (parallel [(set (match_dup 10)
16213                    (unspec:XF [(match_dup 9) (match_dup 8)]
16214                               UNSPEC_FSCALE_FRACT))
16215               (set (match_dup 11)
16216                    (unspec:XF [(match_dup 9) (match_dup 8)]
16217                               UNSPEC_FSCALE_EXP))])
16218    (set (match_dup 12) (minus:XF (match_dup 10)
16219                                  (float_extend:XF (match_dup 13))))
16220    (set (match_operand:XF 0 "register_operand" "")
16221         (plus:XF (match_dup 12) (match_dup 7)))]
16222   "TARGET_USE_FANCY_MATH_387
16223    && flag_unsafe_math_optimizations"
16224 {
16225   int i;
16226
16227   if (optimize_insn_for_size_p ())
16228     FAIL;
16229
16230   for (i = 2; i < 13; i++)
16231     operands[i] = gen_reg_rtx (XFmode);
16232
16233   operands[13]
16234     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
16235
16236   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
16237 })
16238
16239 (define_expand "expm1<mode>2"
16240   [(use (match_operand:MODEF 0 "register_operand" ""))
16241    (use (match_operand:MODEF 1 "general_operand" ""))]
16242  "TARGET_USE_FANCY_MATH_387
16243    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16244        || TARGET_MIX_SSE_I387)
16245    && flag_unsafe_math_optimizations"
16246 {
16247   rtx op0, op1;
16248
16249   if (optimize_insn_for_size_p ())
16250     FAIL;
16251
16252   op0 = gen_reg_rtx (XFmode);
16253   op1 = gen_reg_rtx (XFmode);
16254
16255   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16256   emit_insn (gen_expm1xf2 (op0, op1));
16257   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16258   DONE;
16259 })
16260
16261 (define_expand "ldexpxf3"
16262   [(set (match_dup 3)
16263         (float:XF (match_operand:SI 2 "register_operand" "")))
16264    (parallel [(set (match_operand:XF 0 " register_operand" "")
16265                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16266                                (match_dup 3)]
16267                               UNSPEC_FSCALE_FRACT))
16268               (set (match_dup 4)
16269                    (unspec:XF [(match_dup 1) (match_dup 3)]
16270                               UNSPEC_FSCALE_EXP))])]
16271   "TARGET_USE_FANCY_MATH_387
16272    && flag_unsafe_math_optimizations"
16273 {
16274   if (optimize_insn_for_size_p ())
16275     FAIL;
16276
16277   operands[3] = gen_reg_rtx (XFmode);
16278   operands[4] = gen_reg_rtx (XFmode);
16279 })
16280
16281 (define_expand "ldexp<mode>3"
16282   [(use (match_operand:MODEF 0 "register_operand" ""))
16283    (use (match_operand:MODEF 1 "general_operand" ""))
16284    (use (match_operand:SI 2 "register_operand" ""))]
16285  "TARGET_USE_FANCY_MATH_387
16286    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16287        || TARGET_MIX_SSE_I387)
16288    && flag_unsafe_math_optimizations"
16289 {
16290   rtx op0, op1;
16291
16292   if (optimize_insn_for_size_p ())
16293     FAIL;
16294
16295   op0 = gen_reg_rtx (XFmode);
16296   op1 = gen_reg_rtx (XFmode);
16297
16298   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16299   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
16300   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16301   DONE;
16302 })
16303
16304 (define_expand "scalbxf3"
16305   [(parallel [(set (match_operand:XF 0 " register_operand" "")
16306                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16307                                (match_operand:XF 2 "register_operand" "")]
16308                               UNSPEC_FSCALE_FRACT))
16309               (set (match_dup 3)
16310                    (unspec:XF [(match_dup 1) (match_dup 2)]
16311                               UNSPEC_FSCALE_EXP))])]
16312   "TARGET_USE_FANCY_MATH_387
16313    && flag_unsafe_math_optimizations"
16314 {
16315   if (optimize_insn_for_size_p ())
16316     FAIL;
16317
16318   operands[3] = gen_reg_rtx (XFmode);
16319 })
16320
16321 (define_expand "scalb<mode>3"
16322   [(use (match_operand:MODEF 0 "register_operand" ""))
16323    (use (match_operand:MODEF 1 "general_operand" ""))
16324    (use (match_operand:MODEF 2 "general_operand" ""))]
16325  "TARGET_USE_FANCY_MATH_387
16326    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16327        || TARGET_MIX_SSE_I387)
16328    && flag_unsafe_math_optimizations"
16329 {
16330   rtx op0, op1, op2;
16331
16332   if (optimize_insn_for_size_p ())
16333     FAIL;
16334
16335   op0 = gen_reg_rtx (XFmode);
16336   op1 = gen_reg_rtx (XFmode);
16337   op2 = gen_reg_rtx (XFmode);
16338
16339   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16340   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16341   emit_insn (gen_scalbxf3 (op0, op1, op2));
16342   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16343   DONE;
16344 })
16345
16346 (define_expand "significandxf2"
16347   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16348                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16349                               UNSPEC_XTRACT_FRACT))
16350               (set (match_dup 2)
16351                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16352   "TARGET_USE_FANCY_MATH_387
16353    && flag_unsafe_math_optimizations"
16354 {
16355   operands[2] = gen_reg_rtx (XFmode);
16356 })
16357
16358 (define_expand "significand<mode>2"
16359   [(use (match_operand:MODEF 0 "register_operand" ""))
16360    (use (match_operand:MODEF 1 "register_operand" ""))]
16361   "TARGET_USE_FANCY_MATH_387
16362    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16363        || TARGET_MIX_SSE_I387)
16364    && flag_unsafe_math_optimizations"
16365 {
16366   rtx op0 = gen_reg_rtx (XFmode);
16367   rtx op1 = gen_reg_rtx (XFmode);
16368
16369   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16370   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16371   DONE;
16372 })
16373 \f
16374
16375 (define_insn "sse4_1_round<mode>2"
16376   [(set (match_operand:MODEF 0 "register_operand" "=x")
16377         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
16378                        (match_operand:SI 2 "const_0_to_15_operand" "n")]
16379                       UNSPEC_ROUND))]
16380   "TARGET_ROUND"
16381   "%vrounds<ssemodefsuffix>\t{%2, %1, %d0|%d0, %1, %2}"
16382   [(set_attr "type" "ssecvt")
16383    (set_attr "prefix_extra" "1")
16384    (set_attr "prefix" "maybe_vex")
16385    (set_attr "mode" "<MODE>")])
16386
16387 (define_insn "rintxf2"
16388   [(set (match_operand:XF 0 "register_operand" "=f")
16389         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16390                    UNSPEC_FRNDINT))]
16391   "TARGET_USE_FANCY_MATH_387
16392    && flag_unsafe_math_optimizations"
16393   "frndint"
16394   [(set_attr "type" "fpspc")
16395    (set_attr "mode" "XF")])
16396
16397 (define_expand "rint<mode>2"
16398   [(use (match_operand:MODEF 0 "register_operand" ""))
16399    (use (match_operand:MODEF 1 "register_operand" ""))]
16400   "(TARGET_USE_FANCY_MATH_387
16401     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16402         || TARGET_MIX_SSE_I387)
16403     && flag_unsafe_math_optimizations)
16404    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16405        && !flag_trapping_math)"
16406 {
16407   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16408       && !flag_trapping_math)
16409     {
16410       if (!TARGET_ROUND && optimize_insn_for_size_p ())
16411         FAIL;
16412       if (TARGET_ROUND)
16413         emit_insn (gen_sse4_1_round<mode>2
16414                    (operands[0], operands[1], GEN_INT (0x04)));
16415       else
16416         ix86_expand_rint (operand0, operand1);
16417     }
16418   else
16419     {
16420       rtx op0 = gen_reg_rtx (XFmode);
16421       rtx op1 = gen_reg_rtx (XFmode);
16422
16423       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16424       emit_insn (gen_rintxf2 (op0, op1));
16425
16426       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16427     }
16428   DONE;
16429 })
16430
16431 (define_expand "round<mode>2"
16432   [(match_operand:MODEF 0 "register_operand" "")
16433    (match_operand:MODEF 1 "nonimmediate_operand" "")]
16434   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16435    && !flag_trapping_math && !flag_rounding_math"
16436 {
16437   if (optimize_insn_for_size_p ())
16438     FAIL;
16439   if (TARGET_64BIT || (<MODE>mode != DFmode))
16440     ix86_expand_round (operand0, operand1);
16441   else
16442     ix86_expand_rounddf_32 (operand0, operand1);
16443   DONE;
16444 })
16445
16446 (define_insn_and_split "*fistdi2_1"
16447   [(set (match_operand:DI 0 "nonimmediate_operand" "")
16448         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16449                    UNSPEC_FIST))]
16450   "TARGET_USE_FANCY_MATH_387
16451    && can_create_pseudo_p ()"
16452   "#"
16453   "&& 1"
16454   [(const_int 0)]
16455 {
16456   if (memory_operand (operands[0], VOIDmode))
16457     emit_insn (gen_fistdi2 (operands[0], operands[1]));
16458   else
16459     {
16460       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
16461       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
16462                                          operands[2]));
16463     }
16464   DONE;
16465 }
16466   [(set_attr "type" "fpspc")
16467    (set_attr "mode" "DI")])
16468
16469 (define_insn "fistdi2"
16470   [(set (match_operand:DI 0 "memory_operand" "=m")
16471         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16472                    UNSPEC_FIST))
16473    (clobber (match_scratch:XF 2 "=&1f"))]
16474   "TARGET_USE_FANCY_MATH_387"
16475   "* return output_fix_trunc (insn, operands, 0);"
16476   [(set_attr "type" "fpspc")
16477    (set_attr "mode" "DI")])
16478
16479 (define_insn "fistdi2_with_temp"
16480   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16481         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16482                    UNSPEC_FIST))
16483    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
16484    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
16485   "TARGET_USE_FANCY_MATH_387"
16486   "#"
16487   [(set_attr "type" "fpspc")
16488    (set_attr "mode" "DI")])
16489
16490 (define_split
16491   [(set (match_operand:DI 0 "register_operand" "")
16492         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16493                    UNSPEC_FIST))
16494    (clobber (match_operand:DI 2 "memory_operand" ""))
16495    (clobber (match_scratch 3 ""))]
16496   "reload_completed"
16497   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16498               (clobber (match_dup 3))])
16499    (set (match_dup 0) (match_dup 2))]
16500   "")
16501
16502 (define_split
16503   [(set (match_operand:DI 0 "memory_operand" "")
16504         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16505                    UNSPEC_FIST))
16506    (clobber (match_operand:DI 2 "memory_operand" ""))
16507    (clobber (match_scratch 3 ""))]
16508   "reload_completed"
16509   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16510               (clobber (match_dup 3))])]
16511   "")
16512
16513 (define_insn_and_split "*fist<mode>2_1"
16514   [(set (match_operand:X87MODEI12 0 "register_operand" "")
16515         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16516                            UNSPEC_FIST))]
16517   "TARGET_USE_FANCY_MATH_387
16518    && can_create_pseudo_p ()"
16519   "#"
16520   "&& 1"
16521   [(const_int 0)]
16522 {
16523   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16524   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
16525                                         operands[2]));
16526   DONE;
16527 }
16528   [(set_attr "type" "fpspc")
16529    (set_attr "mode" "<MODE>")])
16530
16531 (define_insn "fist<mode>2"
16532   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
16533         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16534                            UNSPEC_FIST))]
16535   "TARGET_USE_FANCY_MATH_387"
16536   "* return output_fix_trunc (insn, operands, 0);"
16537   [(set_attr "type" "fpspc")
16538    (set_attr "mode" "<MODE>")])
16539
16540 (define_insn "fist<mode>2_with_temp"
16541   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
16542         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16543                            UNSPEC_FIST))
16544    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
16545   "TARGET_USE_FANCY_MATH_387"
16546   "#"
16547   [(set_attr "type" "fpspc")
16548    (set_attr "mode" "<MODE>")])
16549
16550 (define_split
16551   [(set (match_operand:X87MODEI12 0 "register_operand" "")
16552         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16553                            UNSPEC_FIST))
16554    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16555   "reload_completed"
16556   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
16557    (set (match_dup 0) (match_dup 2))]
16558   "")
16559
16560 (define_split
16561   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
16562         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16563                            UNSPEC_FIST))
16564    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16565   "reload_completed"
16566   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
16567   "")
16568
16569 (define_expand "lrintxf<mode>2"
16570   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
16571      (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
16572                       UNSPEC_FIST))]
16573   "TARGET_USE_FANCY_MATH_387"
16574   "")
16575
16576 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
16577   [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
16578      (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
16579                         UNSPEC_FIX_NOTRUNC))]
16580   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
16581    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
16582   "")
16583
16584 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
16585   [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
16586    (match_operand:MODEF 1 "register_operand" "")]
16587   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
16588    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
16589    && !flag_trapping_math && !flag_rounding_math"
16590 {
16591   if (optimize_insn_for_size_p ())
16592     FAIL;
16593   ix86_expand_lround (operand0, operand1);
16594   DONE;
16595 })
16596
16597 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16598 (define_insn_and_split "frndintxf2_floor"
16599   [(set (match_operand:XF 0 "register_operand" "")
16600         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16601          UNSPEC_FRNDINT_FLOOR))
16602    (clobber (reg:CC FLAGS_REG))]
16603   "TARGET_USE_FANCY_MATH_387
16604    && flag_unsafe_math_optimizations
16605    && can_create_pseudo_p ()"
16606   "#"
16607   "&& 1"
16608   [(const_int 0)]
16609 {
16610   ix86_optimize_mode_switching[I387_FLOOR] = 1;
16611
16612   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16613   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
16614
16615   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
16616                                         operands[2], operands[3]));
16617   DONE;
16618 }
16619   [(set_attr "type" "frndint")
16620    (set_attr "i387_cw" "floor")
16621    (set_attr "mode" "XF")])
16622
16623 (define_insn "frndintxf2_floor_i387"
16624   [(set (match_operand:XF 0 "register_operand" "=f")
16625         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16626          UNSPEC_FRNDINT_FLOOR))
16627    (use (match_operand:HI 2 "memory_operand" "m"))
16628    (use (match_operand:HI 3 "memory_operand" "m"))]
16629   "TARGET_USE_FANCY_MATH_387
16630    && flag_unsafe_math_optimizations"
16631   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16632   [(set_attr "type" "frndint")
16633    (set_attr "i387_cw" "floor")
16634    (set_attr "mode" "XF")])
16635
16636 (define_expand "floorxf2"
16637   [(use (match_operand:XF 0 "register_operand" ""))
16638    (use (match_operand:XF 1 "register_operand" ""))]
16639   "TARGET_USE_FANCY_MATH_387
16640    && flag_unsafe_math_optimizations"
16641 {
16642   if (optimize_insn_for_size_p ())
16643     FAIL;
16644   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
16645   DONE;
16646 })
16647
16648 (define_expand "floor<mode>2"
16649   [(use (match_operand:MODEF 0 "register_operand" ""))
16650    (use (match_operand:MODEF 1 "register_operand" ""))]
16651   "(TARGET_USE_FANCY_MATH_387
16652     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16653         || TARGET_MIX_SSE_I387)
16654     && flag_unsafe_math_optimizations)
16655    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16656        && !flag_trapping_math)"
16657 {
16658   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16659       && !flag_trapping_math
16660       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
16661     {
16662       if (!TARGET_ROUND && optimize_insn_for_size_p ())
16663         FAIL;
16664       if (TARGET_ROUND)
16665         emit_insn (gen_sse4_1_round<mode>2
16666                    (operands[0], operands[1], GEN_INT (0x01)));
16667       else if (TARGET_64BIT || (<MODE>mode != DFmode))
16668         ix86_expand_floorceil (operand0, operand1, true);
16669       else
16670         ix86_expand_floorceildf_32 (operand0, operand1, true);
16671     }
16672   else
16673     {
16674       rtx op0, op1;
16675
16676       if (optimize_insn_for_size_p ())
16677         FAIL;
16678
16679       op0 = gen_reg_rtx (XFmode);
16680       op1 = gen_reg_rtx (XFmode);
16681       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16682       emit_insn (gen_frndintxf2_floor (op0, op1));
16683
16684       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16685     }
16686   DONE;
16687 })
16688
16689 (define_insn_and_split "*fist<mode>2_floor_1"
16690   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
16691         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
16692          UNSPEC_FIST_FLOOR))
16693    (clobber (reg:CC FLAGS_REG))]
16694   "TARGET_USE_FANCY_MATH_387
16695    && flag_unsafe_math_optimizations
16696    && can_create_pseudo_p ()"
16697   "#"
16698   "&& 1"
16699   [(const_int 0)]
16700 {
16701   ix86_optimize_mode_switching[I387_FLOOR] = 1;
16702
16703   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16704   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
16705   if (memory_operand (operands[0], VOIDmode))
16706     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
16707                                       operands[2], operands[3]));
16708   else
16709     {
16710       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16711       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
16712                                                   operands[2], operands[3],
16713                                                   operands[4]));
16714     }
16715   DONE;
16716 }
16717   [(set_attr "type" "fistp")
16718    (set_attr "i387_cw" "floor")
16719    (set_attr "mode" "<MODE>")])
16720
16721 (define_insn "fistdi2_floor"
16722   [(set (match_operand:DI 0 "memory_operand" "=m")
16723         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16724          UNSPEC_FIST_FLOOR))
16725    (use (match_operand:HI 2 "memory_operand" "m"))
16726    (use (match_operand:HI 3 "memory_operand" "m"))
16727    (clobber (match_scratch:XF 4 "=&1f"))]
16728   "TARGET_USE_FANCY_MATH_387
16729    && flag_unsafe_math_optimizations"
16730   "* return output_fix_trunc (insn, operands, 0);"
16731   [(set_attr "type" "fistp")
16732    (set_attr "i387_cw" "floor")
16733    (set_attr "mode" "DI")])
16734
16735 (define_insn "fistdi2_floor_with_temp"
16736   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16737         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16738          UNSPEC_FIST_FLOOR))
16739    (use (match_operand:HI 2 "memory_operand" "m,m"))
16740    (use (match_operand:HI 3 "memory_operand" "m,m"))
16741    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
16742    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
16743   "TARGET_USE_FANCY_MATH_387
16744    && flag_unsafe_math_optimizations"
16745   "#"
16746   [(set_attr "type" "fistp")
16747    (set_attr "i387_cw" "floor")
16748    (set_attr "mode" "DI")])
16749
16750 (define_split
16751   [(set (match_operand:DI 0 "register_operand" "")
16752         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16753          UNSPEC_FIST_FLOOR))
16754    (use (match_operand:HI 2 "memory_operand" ""))
16755    (use (match_operand:HI 3 "memory_operand" ""))
16756    (clobber (match_operand:DI 4 "memory_operand" ""))
16757    (clobber (match_scratch 5 ""))]
16758   "reload_completed"
16759   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
16760               (use (match_dup 2))
16761               (use (match_dup 3))
16762               (clobber (match_dup 5))])
16763    (set (match_dup 0) (match_dup 4))]
16764   "")
16765
16766 (define_split
16767   [(set (match_operand:DI 0 "memory_operand" "")
16768         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16769          UNSPEC_FIST_FLOOR))
16770    (use (match_operand:HI 2 "memory_operand" ""))
16771    (use (match_operand:HI 3 "memory_operand" ""))
16772    (clobber (match_operand:DI 4 "memory_operand" ""))
16773    (clobber (match_scratch 5 ""))]
16774   "reload_completed"
16775   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
16776               (use (match_dup 2))
16777               (use (match_dup 3))
16778               (clobber (match_dup 5))])]
16779   "")
16780
16781 (define_insn "fist<mode>2_floor"
16782   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
16783         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16784          UNSPEC_FIST_FLOOR))
16785    (use (match_operand:HI 2 "memory_operand" "m"))
16786    (use (match_operand:HI 3 "memory_operand" "m"))]
16787   "TARGET_USE_FANCY_MATH_387
16788    && flag_unsafe_math_optimizations"
16789   "* return output_fix_trunc (insn, operands, 0);"
16790   [(set_attr "type" "fistp")
16791    (set_attr "i387_cw" "floor")
16792    (set_attr "mode" "<MODE>")])
16793
16794 (define_insn "fist<mode>2_floor_with_temp"
16795   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
16796         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
16797          UNSPEC_FIST_FLOOR))
16798    (use (match_operand:HI 2 "memory_operand" "m,m"))
16799    (use (match_operand:HI 3 "memory_operand" "m,m"))
16800    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
16801   "TARGET_USE_FANCY_MATH_387
16802    && flag_unsafe_math_optimizations"
16803   "#"
16804   [(set_attr "type" "fistp")
16805    (set_attr "i387_cw" "floor")
16806    (set_attr "mode" "<MODE>")])
16807
16808 (define_split
16809   [(set (match_operand:X87MODEI12 0 "register_operand" "")
16810         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16811          UNSPEC_FIST_FLOOR))
16812    (use (match_operand:HI 2 "memory_operand" ""))
16813    (use (match_operand:HI 3 "memory_operand" ""))
16814    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
16815   "reload_completed"
16816   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
16817                                   UNSPEC_FIST_FLOOR))
16818               (use (match_dup 2))
16819               (use (match_dup 3))])
16820    (set (match_dup 0) (match_dup 4))]
16821   "")
16822
16823 (define_split
16824   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
16825         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16826          UNSPEC_FIST_FLOOR))
16827    (use (match_operand:HI 2 "memory_operand" ""))
16828    (use (match_operand:HI 3 "memory_operand" ""))
16829    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
16830   "reload_completed"
16831   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
16832                                   UNSPEC_FIST_FLOOR))
16833               (use (match_dup 2))
16834               (use (match_dup 3))])]
16835   "")
16836
16837 (define_expand "lfloorxf<mode>2"
16838   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
16839                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
16840                     UNSPEC_FIST_FLOOR))
16841               (clobber (reg:CC FLAGS_REG))])]
16842   "TARGET_USE_FANCY_MATH_387
16843    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16844    && flag_unsafe_math_optimizations"
16845   "")
16846
16847 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
16848   [(match_operand:SWI48 0 "nonimmediate_operand" "")
16849    (match_operand:MODEF 1 "register_operand" "")]
16850   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
16851    && !flag_trapping_math"
16852 {
16853   if (TARGET_64BIT && optimize_insn_for_size_p ())
16854     FAIL;
16855   ix86_expand_lfloorceil (operand0, operand1, true);
16856   DONE;
16857 })
16858
16859 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16860 (define_insn_and_split "frndintxf2_ceil"
16861   [(set (match_operand:XF 0 "register_operand" "")
16862         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16863          UNSPEC_FRNDINT_CEIL))
16864    (clobber (reg:CC FLAGS_REG))]
16865   "TARGET_USE_FANCY_MATH_387
16866    && flag_unsafe_math_optimizations
16867    && can_create_pseudo_p ()"
16868   "#"
16869   "&& 1"
16870   [(const_int 0)]
16871 {
16872   ix86_optimize_mode_switching[I387_CEIL] = 1;
16873
16874   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16875   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
16876
16877   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
16878                                        operands[2], operands[3]));
16879   DONE;
16880 }
16881   [(set_attr "type" "frndint")
16882    (set_attr "i387_cw" "ceil")
16883    (set_attr "mode" "XF")])
16884
16885 (define_insn "frndintxf2_ceil_i387"
16886   [(set (match_operand:XF 0 "register_operand" "=f")
16887         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16888          UNSPEC_FRNDINT_CEIL))
16889    (use (match_operand:HI 2 "memory_operand" "m"))
16890    (use (match_operand:HI 3 "memory_operand" "m"))]
16891   "TARGET_USE_FANCY_MATH_387
16892    && flag_unsafe_math_optimizations"
16893   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16894   [(set_attr "type" "frndint")
16895    (set_attr "i387_cw" "ceil")
16896    (set_attr "mode" "XF")])
16897
16898 (define_expand "ceilxf2"
16899   [(use (match_operand:XF 0 "register_operand" ""))
16900    (use (match_operand:XF 1 "register_operand" ""))]
16901   "TARGET_USE_FANCY_MATH_387
16902    && flag_unsafe_math_optimizations"
16903 {
16904   if (optimize_insn_for_size_p ())
16905     FAIL;
16906   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
16907   DONE;
16908 })
16909
16910 (define_expand "ceil<mode>2"
16911   [(use (match_operand:MODEF 0 "register_operand" ""))
16912    (use (match_operand:MODEF 1 "register_operand" ""))]
16913   "(TARGET_USE_FANCY_MATH_387
16914     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16915         || TARGET_MIX_SSE_I387)
16916     && flag_unsafe_math_optimizations)
16917    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16918        && !flag_trapping_math)"
16919 {
16920   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16921       && !flag_trapping_math
16922       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
16923     {
16924       if (TARGET_ROUND)
16925         emit_insn (gen_sse4_1_round<mode>2
16926                    (operands[0], operands[1], GEN_INT (0x02)));
16927       else if (optimize_insn_for_size_p ())
16928         FAIL;
16929       else if (TARGET_64BIT || (<MODE>mode != DFmode))
16930         ix86_expand_floorceil (operand0, operand1, false);
16931       else
16932         ix86_expand_floorceildf_32 (operand0, operand1, false);
16933     }
16934   else
16935     {
16936       rtx op0, op1;
16937
16938       if (optimize_insn_for_size_p ())
16939         FAIL;
16940
16941       op0 = gen_reg_rtx (XFmode);
16942       op1 = gen_reg_rtx (XFmode);
16943       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16944       emit_insn (gen_frndintxf2_ceil (op0, op1));
16945
16946       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16947     }
16948   DONE;
16949 })
16950
16951 (define_insn_and_split "*fist<mode>2_ceil_1"
16952   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
16953         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
16954          UNSPEC_FIST_CEIL))
16955    (clobber (reg:CC FLAGS_REG))]
16956   "TARGET_USE_FANCY_MATH_387
16957    && flag_unsafe_math_optimizations
16958    && can_create_pseudo_p ()"
16959   "#"
16960   "&& 1"
16961   [(const_int 0)]
16962 {
16963   ix86_optimize_mode_switching[I387_CEIL] = 1;
16964
16965   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16966   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
16967   if (memory_operand (operands[0], VOIDmode))
16968     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
16969                                      operands[2], operands[3]));
16970   else
16971     {
16972       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16973       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
16974                                                  operands[2], operands[3],
16975                                                  operands[4]));
16976     }
16977   DONE;
16978 }
16979   [(set_attr "type" "fistp")
16980    (set_attr "i387_cw" "ceil")
16981    (set_attr "mode" "<MODE>")])
16982
16983 (define_insn "fistdi2_ceil"
16984   [(set (match_operand:DI 0 "memory_operand" "=m")
16985         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16986          UNSPEC_FIST_CEIL))
16987    (use (match_operand:HI 2 "memory_operand" "m"))
16988    (use (match_operand:HI 3 "memory_operand" "m"))
16989    (clobber (match_scratch:XF 4 "=&1f"))]
16990   "TARGET_USE_FANCY_MATH_387
16991    && flag_unsafe_math_optimizations"
16992   "* return output_fix_trunc (insn, operands, 0);"
16993   [(set_attr "type" "fistp")
16994    (set_attr "i387_cw" "ceil")
16995    (set_attr "mode" "DI")])
16996
16997 (define_insn "fistdi2_ceil_with_temp"
16998   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16999         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17000          UNSPEC_FIST_CEIL))
17001    (use (match_operand:HI 2 "memory_operand" "m,m"))
17002    (use (match_operand:HI 3 "memory_operand" "m,m"))
17003    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
17004    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17005   "TARGET_USE_FANCY_MATH_387
17006    && flag_unsafe_math_optimizations"
17007   "#"
17008   [(set_attr "type" "fistp")
17009    (set_attr "i387_cw" "ceil")
17010    (set_attr "mode" "DI")])
17011
17012 (define_split
17013   [(set (match_operand:DI 0 "register_operand" "")
17014         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17015          UNSPEC_FIST_CEIL))
17016    (use (match_operand:HI 2 "memory_operand" ""))
17017    (use (match_operand:HI 3 "memory_operand" ""))
17018    (clobber (match_operand:DI 4 "memory_operand" ""))
17019    (clobber (match_scratch 5 ""))]
17020   "reload_completed"
17021   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17022               (use (match_dup 2))
17023               (use (match_dup 3))
17024               (clobber (match_dup 5))])
17025    (set (match_dup 0) (match_dup 4))]
17026   "")
17027
17028 (define_split
17029   [(set (match_operand:DI 0 "memory_operand" "")
17030         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17031          UNSPEC_FIST_CEIL))
17032    (use (match_operand:HI 2 "memory_operand" ""))
17033    (use (match_operand:HI 3 "memory_operand" ""))
17034    (clobber (match_operand:DI 4 "memory_operand" ""))
17035    (clobber (match_scratch 5 ""))]
17036   "reload_completed"
17037   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17038               (use (match_dup 2))
17039               (use (match_dup 3))
17040               (clobber (match_dup 5))])]
17041   "")
17042
17043 (define_insn "fist<mode>2_ceil"
17044   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17045         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17046          UNSPEC_FIST_CEIL))
17047    (use (match_operand:HI 2 "memory_operand" "m"))
17048    (use (match_operand:HI 3 "memory_operand" "m"))]
17049   "TARGET_USE_FANCY_MATH_387
17050    && flag_unsafe_math_optimizations"
17051   "* return output_fix_trunc (insn, operands, 0);"
17052   [(set_attr "type" "fistp")
17053    (set_attr "i387_cw" "ceil")
17054    (set_attr "mode" "<MODE>")])
17055
17056 (define_insn "fist<mode>2_ceil_with_temp"
17057   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17058         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17059          UNSPEC_FIST_CEIL))
17060    (use (match_operand:HI 2 "memory_operand" "m,m"))
17061    (use (match_operand:HI 3 "memory_operand" "m,m"))
17062    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
17063   "TARGET_USE_FANCY_MATH_387
17064    && flag_unsafe_math_optimizations"
17065   "#"
17066   [(set_attr "type" "fistp")
17067    (set_attr "i387_cw" "ceil")
17068    (set_attr "mode" "<MODE>")])
17069
17070 (define_split
17071   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17072         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17073          UNSPEC_FIST_CEIL))
17074    (use (match_operand:HI 2 "memory_operand" ""))
17075    (use (match_operand:HI 3 "memory_operand" ""))
17076    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17077   "reload_completed"
17078   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17079                                   UNSPEC_FIST_CEIL))
17080               (use (match_dup 2))
17081               (use (match_dup 3))])
17082    (set (match_dup 0) (match_dup 4))]
17083   "")
17084
17085 (define_split
17086   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17087         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17088          UNSPEC_FIST_CEIL))
17089    (use (match_operand:HI 2 "memory_operand" ""))
17090    (use (match_operand:HI 3 "memory_operand" ""))
17091    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17092   "reload_completed"
17093   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17094                                   UNSPEC_FIST_CEIL))
17095               (use (match_dup 2))
17096               (use (match_dup 3))])]
17097   "")
17098
17099 (define_expand "lceilxf<mode>2"
17100   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17101                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17102                     UNSPEC_FIST_CEIL))
17103               (clobber (reg:CC FLAGS_REG))])]
17104   "TARGET_USE_FANCY_MATH_387
17105    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17106    && flag_unsafe_math_optimizations"
17107   "")
17108
17109 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
17110   [(match_operand:SWI48 0 "nonimmediate_operand" "")
17111    (match_operand:MODEF 1 "register_operand" "")]
17112   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17113    && !flag_trapping_math"
17114 {
17115   ix86_expand_lfloorceil (operand0, operand1, false);
17116   DONE;
17117 })
17118
17119 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17120 (define_insn_and_split "frndintxf2_trunc"
17121   [(set (match_operand:XF 0 "register_operand" "")
17122         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17123          UNSPEC_FRNDINT_TRUNC))
17124    (clobber (reg:CC FLAGS_REG))]
17125   "TARGET_USE_FANCY_MATH_387
17126    && flag_unsafe_math_optimizations
17127    && can_create_pseudo_p ()"
17128   "#"
17129   "&& 1"
17130   [(const_int 0)]
17131 {
17132   ix86_optimize_mode_switching[I387_TRUNC] = 1;
17133
17134   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17135   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
17136
17137   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
17138                                         operands[2], operands[3]));
17139   DONE;
17140 }
17141   [(set_attr "type" "frndint")
17142    (set_attr "i387_cw" "trunc")
17143    (set_attr "mode" "XF")])
17144
17145 (define_insn "frndintxf2_trunc_i387"
17146   [(set (match_operand:XF 0 "register_operand" "=f")
17147         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17148          UNSPEC_FRNDINT_TRUNC))
17149    (use (match_operand:HI 2 "memory_operand" "m"))
17150    (use (match_operand:HI 3 "memory_operand" "m"))]
17151   "TARGET_USE_FANCY_MATH_387
17152    && flag_unsafe_math_optimizations"
17153   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17154   [(set_attr "type" "frndint")
17155    (set_attr "i387_cw" "trunc")
17156    (set_attr "mode" "XF")])
17157
17158 (define_expand "btruncxf2"
17159   [(use (match_operand:XF 0 "register_operand" ""))
17160    (use (match_operand:XF 1 "register_operand" ""))]
17161   "TARGET_USE_FANCY_MATH_387
17162    && flag_unsafe_math_optimizations"
17163 {
17164   if (optimize_insn_for_size_p ())
17165     FAIL;
17166   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
17167   DONE;
17168 })
17169
17170 (define_expand "btrunc<mode>2"
17171   [(use (match_operand:MODEF 0 "register_operand" ""))
17172    (use (match_operand:MODEF 1 "register_operand" ""))]
17173   "(TARGET_USE_FANCY_MATH_387
17174     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17175         || TARGET_MIX_SSE_I387)
17176     && flag_unsafe_math_optimizations)
17177    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17178        && !flag_trapping_math)"
17179 {
17180   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17181       && !flag_trapping_math
17182       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
17183     {
17184       if (TARGET_ROUND)
17185         emit_insn (gen_sse4_1_round<mode>2
17186                    (operands[0], operands[1], GEN_INT (0x03)));
17187       else if (optimize_insn_for_size_p ())
17188         FAIL;
17189       else if (TARGET_64BIT || (<MODE>mode != DFmode))
17190         ix86_expand_trunc (operand0, operand1);
17191       else
17192         ix86_expand_truncdf_32 (operand0, operand1);
17193     }
17194   else
17195     {
17196       rtx op0, op1;
17197
17198       if (optimize_insn_for_size_p ())
17199         FAIL;
17200
17201       op0 = gen_reg_rtx (XFmode);
17202       op1 = gen_reg_rtx (XFmode);
17203       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17204       emit_insn (gen_frndintxf2_trunc (op0, op1));
17205
17206       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17207     }
17208   DONE;
17209 })
17210
17211 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17212 (define_insn_and_split "frndintxf2_mask_pm"
17213   [(set (match_operand:XF 0 "register_operand" "")
17214         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17215          UNSPEC_FRNDINT_MASK_PM))
17216    (clobber (reg:CC FLAGS_REG))]
17217   "TARGET_USE_FANCY_MATH_387
17218    && flag_unsafe_math_optimizations
17219    && can_create_pseudo_p ()"
17220   "#"
17221   "&& 1"
17222   [(const_int 0)]
17223 {
17224   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
17225
17226   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17227   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
17228
17229   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
17230                                           operands[2], operands[3]));
17231   DONE;
17232 }
17233   [(set_attr "type" "frndint")
17234    (set_attr "i387_cw" "mask_pm")
17235    (set_attr "mode" "XF")])
17236
17237 (define_insn "frndintxf2_mask_pm_i387"
17238   [(set (match_operand:XF 0 "register_operand" "=f")
17239         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17240          UNSPEC_FRNDINT_MASK_PM))
17241    (use (match_operand:HI 2 "memory_operand" "m"))
17242    (use (match_operand:HI 3 "memory_operand" "m"))]
17243   "TARGET_USE_FANCY_MATH_387
17244    && flag_unsafe_math_optimizations"
17245   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
17246   [(set_attr "type" "frndint")
17247    (set_attr "i387_cw" "mask_pm")
17248    (set_attr "mode" "XF")])
17249
17250 (define_expand "nearbyintxf2"
17251   [(use (match_operand:XF 0 "register_operand" ""))
17252    (use (match_operand:XF 1 "register_operand" ""))]
17253   "TARGET_USE_FANCY_MATH_387
17254    && flag_unsafe_math_optimizations"
17255 {
17256   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
17257
17258   DONE;
17259 })
17260
17261 (define_expand "nearbyint<mode>2"
17262   [(use (match_operand:MODEF 0 "register_operand" ""))
17263    (use (match_operand:MODEF 1 "register_operand" ""))]
17264   "TARGET_USE_FANCY_MATH_387
17265    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17266        || TARGET_MIX_SSE_I387)
17267    && flag_unsafe_math_optimizations"
17268 {
17269   rtx op0 = gen_reg_rtx (XFmode);
17270   rtx op1 = gen_reg_rtx (XFmode);
17271
17272   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17273   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17274
17275   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17276   DONE;
17277 })
17278
17279 (define_insn "fxam<mode>2_i387"
17280   [(set (match_operand:HI 0 "register_operand" "=a")
17281         (unspec:HI
17282           [(match_operand:X87MODEF 1 "register_operand" "f")]
17283           UNSPEC_FXAM))]
17284   "TARGET_USE_FANCY_MATH_387"
17285   "fxam\n\tfnstsw\t%0"
17286   [(set_attr "type" "multi")
17287    (set_attr "length" "4")
17288    (set_attr "unit" "i387")
17289    (set_attr "mode" "<MODE>")])
17290
17291 (define_insn_and_split "fxam<mode>2_i387_with_temp"
17292   [(set (match_operand:HI 0 "register_operand" "")
17293         (unspec:HI
17294           [(match_operand:MODEF 1 "memory_operand" "")]
17295           UNSPEC_FXAM_MEM))]
17296   "TARGET_USE_FANCY_MATH_387
17297    && can_create_pseudo_p ()"
17298   "#"
17299   "&& 1"
17300   [(set (match_dup 2)(match_dup 1))
17301    (set (match_dup 0)
17302         (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
17303 {
17304   operands[2] = gen_reg_rtx (<MODE>mode);
17305
17306   MEM_VOLATILE_P (operands[1]) = 1;
17307 }
17308   [(set_attr "type" "multi")
17309    (set_attr "unit" "i387")
17310    (set_attr "mode" "<MODE>")])
17311
17312 (define_expand "isinfxf2"
17313   [(use (match_operand:SI 0 "register_operand" ""))
17314    (use (match_operand:XF 1 "register_operand" ""))]
17315   "TARGET_USE_FANCY_MATH_387
17316    && TARGET_C99_FUNCTIONS"
17317 {
17318   rtx mask = GEN_INT (0x45);
17319   rtx val = GEN_INT (0x05);
17320
17321   rtx cond;
17322
17323   rtx scratch = gen_reg_rtx (HImode);
17324   rtx res = gen_reg_rtx (QImode);
17325
17326   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
17327
17328   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
17329   emit_insn (gen_cmpqi_ext_3 (scratch, val));
17330   cond = gen_rtx_fmt_ee (EQ, QImode,
17331                          gen_rtx_REG (CCmode, FLAGS_REG),
17332                          const0_rtx);
17333   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
17334   emit_insn (gen_zero_extendqisi2 (operands[0], res));
17335   DONE;
17336 })
17337
17338 (define_expand "isinf<mode>2"
17339   [(use (match_operand:SI 0 "register_operand" ""))
17340    (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
17341   "TARGET_USE_FANCY_MATH_387
17342    && TARGET_C99_FUNCTIONS
17343    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
17344 {
17345   rtx mask = GEN_INT (0x45);
17346   rtx val = GEN_INT (0x05);
17347
17348   rtx cond;
17349
17350   rtx scratch = gen_reg_rtx (HImode);
17351   rtx res = gen_reg_rtx (QImode);
17352
17353   /* Remove excess precision by forcing value through memory. */
17354   if (memory_operand (operands[1], VOIDmode))
17355     emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
17356   else
17357     {
17358       enum ix86_stack_slot slot = (virtuals_instantiated
17359                                    ? SLOT_TEMP
17360                                    : SLOT_VIRTUAL);
17361       rtx temp = assign_386_stack_local (<MODE>mode, slot);
17362
17363       emit_move_insn (temp, operands[1]);
17364       emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
17365     }
17366
17367   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
17368   emit_insn (gen_cmpqi_ext_3 (scratch, val));
17369   cond = gen_rtx_fmt_ee (EQ, QImode,
17370                          gen_rtx_REG (CCmode, FLAGS_REG),
17371                          const0_rtx);
17372   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
17373   emit_insn (gen_zero_extendqisi2 (operands[0], res));
17374   DONE;
17375 })
17376
17377 (define_expand "signbit<mode>2"
17378   [(use (match_operand:SI 0 "register_operand" ""))
17379    (use (match_operand:X87MODEF 1 "register_operand" ""))]
17380   "TARGET_USE_FANCY_MATH_387
17381    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
17382 {
17383   rtx mask = GEN_INT (0x0200);
17384
17385   rtx scratch = gen_reg_rtx (HImode);
17386
17387   emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
17388   emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
17389   DONE;
17390 })
17391 \f
17392 ;; Block operation instructions
17393
17394 (define_insn "cld"
17395   [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
17396   ""
17397   "cld"
17398   [(set_attr "length" "1")
17399    (set_attr "length_immediate" "0")
17400    (set_attr "modrm" "0")])
17401
17402 (define_expand "movmemsi"
17403   [(use (match_operand:BLK 0 "memory_operand" ""))
17404    (use (match_operand:BLK 1 "memory_operand" ""))
17405    (use (match_operand:SI 2 "nonmemory_operand" ""))
17406    (use (match_operand:SI 3 "const_int_operand" ""))
17407    (use (match_operand:SI 4 "const_int_operand" ""))
17408    (use (match_operand:SI 5 "const_int_operand" ""))]
17409   ""
17410 {
17411  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
17412                          operands[4], operands[5]))
17413    DONE;
17414  else
17415    FAIL;
17416 })
17417
17418 (define_expand "movmemdi"
17419   [(use (match_operand:BLK 0 "memory_operand" ""))
17420    (use (match_operand:BLK 1 "memory_operand" ""))
17421    (use (match_operand:DI 2 "nonmemory_operand" ""))
17422    (use (match_operand:DI 3 "const_int_operand" ""))
17423    (use (match_operand:SI 4 "const_int_operand" ""))
17424    (use (match_operand:SI 5 "const_int_operand" ""))]
17425   "TARGET_64BIT"
17426 {
17427  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
17428                          operands[4], operands[5]))
17429    DONE;
17430  else
17431    FAIL;
17432 })
17433
17434 ;; Most CPUs don't like single string operations
17435 ;; Handle this case here to simplify previous expander.
17436
17437 (define_expand "strmov"
17438   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
17439    (set (match_operand 1 "memory_operand" "") (match_dup 4))
17440    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
17441               (clobber (reg:CC FLAGS_REG))])
17442    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
17443               (clobber (reg:CC FLAGS_REG))])]
17444   ""
17445 {
17446   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
17447
17448   /* If .md ever supports :P for Pmode, these can be directly
17449      in the pattern above.  */
17450   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
17451   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
17452
17453   /* Can't use this if the user has appropriated esi or edi.  */
17454   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
17455       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
17456     {
17457       emit_insn (gen_strmov_singleop (operands[0], operands[1],
17458                                       operands[2], operands[3],
17459                                       operands[5], operands[6]));
17460       DONE;
17461     }
17462
17463   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
17464 })
17465
17466 (define_expand "strmov_singleop"
17467   [(parallel [(set (match_operand 1 "memory_operand" "")
17468                    (match_operand 3 "memory_operand" ""))
17469               (set (match_operand 0 "register_operand" "")
17470                    (match_operand 4 "" ""))
17471               (set (match_operand 2 "register_operand" "")
17472                    (match_operand 5 "" ""))])]
17473   ""
17474   "ix86_current_function_needs_cld = 1;")
17475
17476 (define_insn "*strmovdi_rex_1"
17477   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
17478         (mem:DI (match_operand:DI 3 "register_operand" "1")))
17479    (set (match_operand:DI 0 "register_operand" "=D")
17480         (plus:DI (match_dup 2)
17481                  (const_int 8)))
17482    (set (match_operand:DI 1 "register_operand" "=S")
17483         (plus:DI (match_dup 3)
17484                  (const_int 8)))]
17485   "TARGET_64BIT"
17486   "movsq"
17487   [(set_attr "type" "str")
17488    (set_attr "mode" "DI")
17489    (set_attr "memory" "both")])
17490
17491 (define_insn "*strmovsi_1"
17492   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
17493         (mem:SI (match_operand:SI 3 "register_operand" "1")))
17494    (set (match_operand:SI 0 "register_operand" "=D")
17495         (plus:SI (match_dup 2)
17496                  (const_int 4)))
17497    (set (match_operand:SI 1 "register_operand" "=S")
17498         (plus:SI (match_dup 3)
17499                  (const_int 4)))]
17500   "!TARGET_64BIT"
17501   "movs{l|d}"
17502   [(set_attr "type" "str")
17503    (set_attr "mode" "SI")
17504    (set_attr "memory" "both")])
17505
17506 (define_insn "*strmovsi_rex_1"
17507   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
17508         (mem:SI (match_operand:DI 3 "register_operand" "1")))
17509    (set (match_operand:DI 0 "register_operand" "=D")
17510         (plus:DI (match_dup 2)
17511                  (const_int 4)))
17512    (set (match_operand:DI 1 "register_operand" "=S")
17513         (plus:DI (match_dup 3)
17514                  (const_int 4)))]
17515   "TARGET_64BIT"
17516   "movs{l|d}"
17517   [(set_attr "type" "str")
17518    (set_attr "mode" "SI")
17519    (set_attr "memory" "both")])
17520
17521 (define_insn "*strmovhi_1"
17522   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
17523         (mem:HI (match_operand:SI 3 "register_operand" "1")))
17524    (set (match_operand:SI 0 "register_operand" "=D")
17525         (plus:SI (match_dup 2)
17526                  (const_int 2)))
17527    (set (match_operand:SI 1 "register_operand" "=S")
17528         (plus:SI (match_dup 3)
17529                  (const_int 2)))]
17530   "!TARGET_64BIT"
17531   "movsw"
17532   [(set_attr "type" "str")
17533    (set_attr "memory" "both")
17534    (set_attr "mode" "HI")])
17535
17536 (define_insn "*strmovhi_rex_1"
17537   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
17538         (mem:HI (match_operand:DI 3 "register_operand" "1")))
17539    (set (match_operand:DI 0 "register_operand" "=D")
17540         (plus:DI (match_dup 2)
17541                  (const_int 2)))
17542    (set (match_operand:DI 1 "register_operand" "=S")
17543         (plus:DI (match_dup 3)
17544                  (const_int 2)))]
17545   "TARGET_64BIT"
17546   "movsw"
17547   [(set_attr "type" "str")
17548    (set_attr "memory" "both")
17549    (set_attr "mode" "HI")])
17550
17551 (define_insn "*strmovqi_1"
17552   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
17553         (mem:QI (match_operand:SI 3 "register_operand" "1")))
17554    (set (match_operand:SI 0 "register_operand" "=D")
17555         (plus:SI (match_dup 2)
17556                  (const_int 1)))
17557    (set (match_operand:SI 1 "register_operand" "=S")
17558         (plus:SI (match_dup 3)
17559                  (const_int 1)))]
17560   "!TARGET_64BIT"
17561   "movsb"
17562   [(set_attr "type" "str")
17563    (set_attr "memory" "both")
17564    (set_attr "mode" "QI")])
17565
17566 (define_insn "*strmovqi_rex_1"
17567   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
17568         (mem:QI (match_operand:DI 3 "register_operand" "1")))
17569    (set (match_operand:DI 0 "register_operand" "=D")
17570         (plus:DI (match_dup 2)
17571                  (const_int 1)))
17572    (set (match_operand:DI 1 "register_operand" "=S")
17573         (plus:DI (match_dup 3)
17574                  (const_int 1)))]
17575   "TARGET_64BIT"
17576   "movsb"
17577   [(set_attr "type" "str")
17578    (set_attr "memory" "both")
17579    (set_attr "prefix_rex" "0")
17580    (set_attr "mode" "QI")])
17581
17582 (define_expand "rep_mov"
17583   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
17584               (set (match_operand 0 "register_operand" "")
17585                    (match_operand 5 "" ""))
17586               (set (match_operand 2 "register_operand" "")
17587                    (match_operand 6 "" ""))
17588               (set (match_operand 1 "memory_operand" "")
17589                    (match_operand 3 "memory_operand" ""))
17590               (use (match_dup 4))])]
17591   ""
17592   "ix86_current_function_needs_cld = 1;")
17593
17594 (define_insn "*rep_movdi_rex64"
17595   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17596    (set (match_operand:DI 0 "register_operand" "=D")
17597         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17598                             (const_int 3))
17599                  (match_operand:DI 3 "register_operand" "0")))
17600    (set (match_operand:DI 1 "register_operand" "=S")
17601         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
17602                  (match_operand:DI 4 "register_operand" "1")))
17603    (set (mem:BLK (match_dup 3))
17604         (mem:BLK (match_dup 4)))
17605    (use (match_dup 5))]
17606   "TARGET_64BIT"
17607   "rep movsq"
17608   [(set_attr "type" "str")
17609    (set_attr "prefix_rep" "1")
17610    (set_attr "memory" "both")
17611    (set_attr "mode" "DI")])
17612
17613 (define_insn "*rep_movsi"
17614   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17615    (set (match_operand:SI 0 "register_operand" "=D")
17616         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
17617                             (const_int 2))
17618                  (match_operand:SI 3 "register_operand" "0")))
17619    (set (match_operand:SI 1 "register_operand" "=S")
17620         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
17621                  (match_operand:SI 4 "register_operand" "1")))
17622    (set (mem:BLK (match_dup 3))
17623         (mem:BLK (match_dup 4)))
17624    (use (match_dup 5))]
17625   "!TARGET_64BIT"
17626   "rep movs{l|d}"
17627   [(set_attr "type" "str")
17628    (set_attr "prefix_rep" "1")
17629    (set_attr "memory" "both")
17630    (set_attr "mode" "SI")])
17631
17632 (define_insn "*rep_movsi_rex64"
17633   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17634    (set (match_operand:DI 0 "register_operand" "=D")
17635         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17636                             (const_int 2))
17637                  (match_operand:DI 3 "register_operand" "0")))
17638    (set (match_operand:DI 1 "register_operand" "=S")
17639         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
17640                  (match_operand:DI 4 "register_operand" "1")))
17641    (set (mem:BLK (match_dup 3))
17642         (mem:BLK (match_dup 4)))
17643    (use (match_dup 5))]
17644   "TARGET_64BIT"
17645   "rep movs{l|d}"
17646   [(set_attr "type" "str")
17647    (set_attr "prefix_rep" "1")
17648    (set_attr "memory" "both")
17649    (set_attr "mode" "SI")])
17650
17651 (define_insn "*rep_movqi"
17652   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17653    (set (match_operand:SI 0 "register_operand" "=D")
17654         (plus:SI (match_operand:SI 3 "register_operand" "0")
17655                  (match_operand:SI 5 "register_operand" "2")))
17656    (set (match_operand:SI 1 "register_operand" "=S")
17657         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
17658    (set (mem:BLK (match_dup 3))
17659         (mem:BLK (match_dup 4)))
17660    (use (match_dup 5))]
17661   "!TARGET_64BIT"
17662   "rep movsb"
17663   [(set_attr "type" "str")
17664    (set_attr "prefix_rep" "1")
17665    (set_attr "memory" "both")
17666    (set_attr "mode" "SI")])
17667
17668 (define_insn "*rep_movqi_rex64"
17669   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17670    (set (match_operand:DI 0 "register_operand" "=D")
17671         (plus:DI (match_operand:DI 3 "register_operand" "0")
17672                  (match_operand:DI 5 "register_operand" "2")))
17673    (set (match_operand:DI 1 "register_operand" "=S")
17674         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
17675    (set (mem:BLK (match_dup 3))
17676         (mem:BLK (match_dup 4)))
17677    (use (match_dup 5))]
17678   "TARGET_64BIT"
17679   "rep movsb"
17680   [(set_attr "type" "str")
17681    (set_attr "prefix_rep" "1")
17682    (set_attr "memory" "both")
17683    (set_attr "mode" "SI")])
17684
17685 (define_expand "setmemsi"
17686    [(use (match_operand:BLK 0 "memory_operand" ""))
17687     (use (match_operand:SI 1 "nonmemory_operand" ""))
17688     (use (match_operand 2 "const_int_operand" ""))
17689     (use (match_operand 3 "const_int_operand" ""))
17690     (use (match_operand:SI 4 "const_int_operand" ""))
17691     (use (match_operand:SI 5 "const_int_operand" ""))]
17692   ""
17693 {
17694  if (ix86_expand_setmem (operands[0], operands[1],
17695                          operands[2], operands[3],
17696                          operands[4], operands[5]))
17697    DONE;
17698  else
17699    FAIL;
17700 })
17701
17702 (define_expand "setmemdi"
17703    [(use (match_operand:BLK 0 "memory_operand" ""))
17704     (use (match_operand:DI 1 "nonmemory_operand" ""))
17705     (use (match_operand 2 "const_int_operand" ""))
17706     (use (match_operand 3 "const_int_operand" ""))
17707     (use (match_operand 4 "const_int_operand" ""))
17708     (use (match_operand 5 "const_int_operand" ""))]
17709   "TARGET_64BIT"
17710 {
17711  if (ix86_expand_setmem (operands[0], operands[1],
17712                          operands[2], operands[3],
17713                          operands[4], operands[5]))
17714    DONE;
17715  else
17716    FAIL;
17717 })
17718
17719 ;; Most CPUs don't like single string operations
17720 ;; Handle this case here to simplify previous expander.
17721
17722 (define_expand "strset"
17723   [(set (match_operand 1 "memory_operand" "")
17724         (match_operand 2 "register_operand" ""))
17725    (parallel [(set (match_operand 0 "register_operand" "")
17726                    (match_dup 3))
17727               (clobber (reg:CC FLAGS_REG))])]
17728   ""
17729 {
17730   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
17731     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
17732
17733   /* If .md ever supports :P for Pmode, this can be directly
17734      in the pattern above.  */
17735   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
17736                               GEN_INT (GET_MODE_SIZE (GET_MODE
17737                                                       (operands[2]))));
17738   if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
17739     {
17740       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
17741                                       operands[3]));
17742       DONE;
17743     }
17744 })
17745
17746 (define_expand "strset_singleop"
17747   [(parallel [(set (match_operand 1 "memory_operand" "")
17748                    (match_operand 2 "register_operand" ""))
17749               (set (match_operand 0 "register_operand" "")
17750                    (match_operand 3 "" ""))])]
17751   ""
17752   "ix86_current_function_needs_cld = 1;")
17753
17754 (define_insn "*strsetdi_rex_1"
17755   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
17756         (match_operand:DI 2 "register_operand" "a"))
17757    (set (match_operand:DI 0 "register_operand" "=D")
17758         (plus:DI (match_dup 1)
17759                  (const_int 8)))]
17760   "TARGET_64BIT"
17761   "stosq"
17762   [(set_attr "type" "str")
17763    (set_attr "memory" "store")
17764    (set_attr "mode" "DI")])
17765
17766 (define_insn "*strsetsi_1"
17767   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
17768         (match_operand:SI 2 "register_operand" "a"))
17769    (set (match_operand:SI 0 "register_operand" "=D")
17770         (plus:SI (match_dup 1)
17771                  (const_int 4)))]
17772   "!TARGET_64BIT"
17773   "stos{l|d}"
17774   [(set_attr "type" "str")
17775    (set_attr "memory" "store")
17776    (set_attr "mode" "SI")])
17777
17778 (define_insn "*strsetsi_rex_1"
17779   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
17780         (match_operand:SI 2 "register_operand" "a"))
17781    (set (match_operand:DI 0 "register_operand" "=D")
17782         (plus:DI (match_dup 1)
17783                  (const_int 4)))]
17784   "TARGET_64BIT"
17785   "stos{l|d}"
17786   [(set_attr "type" "str")
17787    (set_attr "memory" "store")
17788    (set_attr "mode" "SI")])
17789
17790 (define_insn "*strsethi_1"
17791   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
17792         (match_operand:HI 2 "register_operand" "a"))
17793    (set (match_operand:SI 0 "register_operand" "=D")
17794         (plus:SI (match_dup 1)
17795                  (const_int 2)))]
17796   "!TARGET_64BIT"
17797   "stosw"
17798   [(set_attr "type" "str")
17799    (set_attr "memory" "store")
17800    (set_attr "mode" "HI")])
17801
17802 (define_insn "*strsethi_rex_1"
17803   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
17804         (match_operand:HI 2 "register_operand" "a"))
17805    (set (match_operand:DI 0 "register_operand" "=D")
17806         (plus:DI (match_dup 1)
17807                  (const_int 2)))]
17808   "TARGET_64BIT"
17809   "stosw"
17810   [(set_attr "type" "str")
17811    (set_attr "memory" "store")
17812    (set_attr "mode" "HI")])
17813
17814 (define_insn "*strsetqi_1"
17815   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
17816         (match_operand:QI 2 "register_operand" "a"))
17817    (set (match_operand:SI 0 "register_operand" "=D")
17818         (plus:SI (match_dup 1)
17819                  (const_int 1)))]
17820   "!TARGET_64BIT"
17821   "stosb"
17822   [(set_attr "type" "str")
17823    (set_attr "memory" "store")
17824    (set_attr "mode" "QI")])
17825
17826 (define_insn "*strsetqi_rex_1"
17827   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
17828         (match_operand:QI 2 "register_operand" "a"))
17829    (set (match_operand:DI 0 "register_operand" "=D")
17830         (plus:DI (match_dup 1)
17831                  (const_int 1)))]
17832   "TARGET_64BIT"
17833   "stosb"
17834   [(set_attr "type" "str")
17835    (set_attr "memory" "store")
17836    (set_attr "prefix_rex" "0")
17837    (set_attr "mode" "QI")])
17838
17839 (define_expand "rep_stos"
17840   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
17841               (set (match_operand 0 "register_operand" "")
17842                    (match_operand 4 "" ""))
17843               (set (match_operand 2 "memory_operand" "") (const_int 0))
17844               (use (match_operand 3 "register_operand" ""))
17845               (use (match_dup 1))])]
17846   ""
17847   "ix86_current_function_needs_cld = 1;")
17848
17849 (define_insn "*rep_stosdi_rex64"
17850   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17851    (set (match_operand:DI 0 "register_operand" "=D")
17852         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17853                             (const_int 3))
17854                  (match_operand:DI 3 "register_operand" "0")))
17855    (set (mem:BLK (match_dup 3))
17856         (const_int 0))
17857    (use (match_operand:DI 2 "register_operand" "a"))
17858    (use (match_dup 4))]
17859   "TARGET_64BIT"
17860   "rep stosq"
17861   [(set_attr "type" "str")
17862    (set_attr "prefix_rep" "1")
17863    (set_attr "memory" "store")
17864    (set_attr "mode" "DI")])
17865
17866 (define_insn "*rep_stossi"
17867   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17868    (set (match_operand:SI 0 "register_operand" "=D")
17869         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
17870                             (const_int 2))
17871                  (match_operand:SI 3 "register_operand" "0")))
17872    (set (mem:BLK (match_dup 3))
17873         (const_int 0))
17874    (use (match_operand:SI 2 "register_operand" "a"))
17875    (use (match_dup 4))]
17876   "!TARGET_64BIT"
17877   "rep stos{l|d}"
17878   [(set_attr "type" "str")
17879    (set_attr "prefix_rep" "1")
17880    (set_attr "memory" "store")
17881    (set_attr "mode" "SI")])
17882
17883 (define_insn "*rep_stossi_rex64"
17884   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17885    (set (match_operand:DI 0 "register_operand" "=D")
17886         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17887                             (const_int 2))
17888                  (match_operand:DI 3 "register_operand" "0")))
17889    (set (mem:BLK (match_dup 3))
17890         (const_int 0))
17891    (use (match_operand:SI 2 "register_operand" "a"))
17892    (use (match_dup 4))]
17893   "TARGET_64BIT"
17894   "rep stos{l|d}"
17895   [(set_attr "type" "str")
17896    (set_attr "prefix_rep" "1")
17897    (set_attr "memory" "store")
17898    (set_attr "mode" "SI")])
17899
17900 (define_insn "*rep_stosqi"
17901   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17902    (set (match_operand:SI 0 "register_operand" "=D")
17903         (plus:SI (match_operand:SI 3 "register_operand" "0")
17904                  (match_operand:SI 4 "register_operand" "1")))
17905    (set (mem:BLK (match_dup 3))
17906         (const_int 0))
17907    (use (match_operand:QI 2 "register_operand" "a"))
17908    (use (match_dup 4))]
17909   "!TARGET_64BIT"
17910   "rep stosb"
17911   [(set_attr "type" "str")
17912    (set_attr "prefix_rep" "1")
17913    (set_attr "memory" "store")
17914    (set_attr "mode" "QI")])
17915
17916 (define_insn "*rep_stosqi_rex64"
17917   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17918    (set (match_operand:DI 0 "register_operand" "=D")
17919         (plus:DI (match_operand:DI 3 "register_operand" "0")
17920                  (match_operand:DI 4 "register_operand" "1")))
17921    (set (mem:BLK (match_dup 3))
17922         (const_int 0))
17923    (use (match_operand:QI 2 "register_operand" "a"))
17924    (use (match_dup 4))]
17925   "TARGET_64BIT"
17926   "rep stosb"
17927   [(set_attr "type" "str")
17928    (set_attr "prefix_rep" "1")
17929    (set_attr "memory" "store")
17930    (set_attr "prefix_rex" "0")
17931    (set_attr "mode" "QI")])
17932
17933 (define_expand "cmpstrnsi"
17934   [(set (match_operand:SI 0 "register_operand" "")
17935         (compare:SI (match_operand:BLK 1 "general_operand" "")
17936                     (match_operand:BLK 2 "general_operand" "")))
17937    (use (match_operand 3 "general_operand" ""))
17938    (use (match_operand 4 "immediate_operand" ""))]
17939   ""
17940 {
17941   rtx addr1, addr2, out, outlow, count, countreg, align;
17942
17943   if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
17944     FAIL;
17945
17946   /* Can't use this if the user has appropriated esi or edi.  */
17947   if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
17948     FAIL;
17949
17950   out = operands[0];
17951   if (!REG_P (out))
17952     out = gen_reg_rtx (SImode);
17953
17954   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
17955   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
17956   if (addr1 != XEXP (operands[1], 0))
17957     operands[1] = replace_equiv_address_nv (operands[1], addr1);
17958   if (addr2 != XEXP (operands[2], 0))
17959     operands[2] = replace_equiv_address_nv (operands[2], addr2);
17960
17961   count = operands[3];
17962   countreg = ix86_zero_extend_to_Pmode (count);
17963
17964   /* %%% Iff we are testing strict equality, we can use known alignment
17965      to good advantage.  This may be possible with combine, particularly
17966      once cc0 is dead.  */
17967   align = operands[4];
17968
17969   if (CONST_INT_P (count))
17970     {
17971       if (INTVAL (count) == 0)
17972         {
17973           emit_move_insn (operands[0], const0_rtx);
17974           DONE;
17975         }
17976       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
17977                                      operands[1], operands[2]));
17978     }
17979   else
17980     {
17981       rtx (*cmp_insn)(rtx, rtx);
17982
17983       if (TARGET_64BIT)
17984         cmp_insn = gen_cmpdi_1;
17985       else
17986         cmp_insn = gen_cmpsi_1;
17987       emit_insn (cmp_insn (countreg, countreg));
17988       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
17989                                   operands[1], operands[2]));
17990     }
17991
17992   outlow = gen_lowpart (QImode, out);
17993   emit_insn (gen_cmpintqi (outlow));
17994   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
17995
17996   if (operands[0] != out)
17997     emit_move_insn (operands[0], out);
17998
17999   DONE;
18000 })
18001
18002 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18003
18004 (define_expand "cmpintqi"
18005   [(set (match_dup 1)
18006         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18007    (set (match_dup 2)
18008         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18009    (parallel [(set (match_operand:QI 0 "register_operand" "")
18010                    (minus:QI (match_dup 1)
18011                              (match_dup 2)))
18012               (clobber (reg:CC FLAGS_REG))])]
18013   ""
18014   "operands[1] = gen_reg_rtx (QImode);
18015    operands[2] = gen_reg_rtx (QImode);")
18016
18017 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
18018 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
18019
18020 (define_expand "cmpstrnqi_nz_1"
18021   [(parallel [(set (reg:CC FLAGS_REG)
18022                    (compare:CC (match_operand 4 "memory_operand" "")
18023                                (match_operand 5 "memory_operand" "")))
18024               (use (match_operand 2 "register_operand" ""))
18025               (use (match_operand:SI 3 "immediate_operand" ""))
18026               (clobber (match_operand 0 "register_operand" ""))
18027               (clobber (match_operand 1 "register_operand" ""))
18028               (clobber (match_dup 2))])]
18029   ""
18030   "ix86_current_function_needs_cld = 1;")
18031
18032 (define_insn "*cmpstrnqi_nz_1"
18033   [(set (reg:CC FLAGS_REG)
18034         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18035                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18036    (use (match_operand:SI 6 "register_operand" "2"))
18037    (use (match_operand:SI 3 "immediate_operand" "i"))
18038    (clobber (match_operand:SI 0 "register_operand" "=S"))
18039    (clobber (match_operand:SI 1 "register_operand" "=D"))
18040    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18041   "!TARGET_64BIT"
18042   "repz cmpsb"
18043   [(set_attr "type" "str")
18044    (set_attr "mode" "QI")
18045    (set_attr "prefix_rep" "1")])
18046
18047 (define_insn "*cmpstrnqi_nz_rex_1"
18048   [(set (reg:CC FLAGS_REG)
18049         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18050                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18051    (use (match_operand:DI 6 "register_operand" "2"))
18052    (use (match_operand:SI 3 "immediate_operand" "i"))
18053    (clobber (match_operand:DI 0 "register_operand" "=S"))
18054    (clobber (match_operand:DI 1 "register_operand" "=D"))
18055    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18056   "TARGET_64BIT"
18057   "repz cmpsb"
18058   [(set_attr "type" "str")
18059    (set_attr "mode" "QI")
18060    (set_attr "prefix_rex" "0")
18061    (set_attr "prefix_rep" "1")])
18062
18063 ;; The same, but the count is not known to not be zero.
18064
18065 (define_expand "cmpstrnqi_1"
18066   [(parallel [(set (reg:CC FLAGS_REG)
18067                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18068                                      (const_int 0))
18069                   (compare:CC (match_operand 4 "memory_operand" "")
18070                               (match_operand 5 "memory_operand" ""))
18071                   (const_int 0)))
18072               (use (match_operand:SI 3 "immediate_operand" ""))
18073               (use (reg:CC FLAGS_REG))
18074               (clobber (match_operand 0 "register_operand" ""))
18075               (clobber (match_operand 1 "register_operand" ""))
18076               (clobber (match_dup 2))])]
18077   ""
18078   "ix86_current_function_needs_cld = 1;")
18079
18080 (define_insn "*cmpstrnqi_1"
18081   [(set (reg:CC FLAGS_REG)
18082         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18083                              (const_int 0))
18084           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18085                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18086           (const_int 0)))
18087    (use (match_operand:SI 3 "immediate_operand" "i"))
18088    (use (reg:CC FLAGS_REG))
18089    (clobber (match_operand:SI 0 "register_operand" "=S"))
18090    (clobber (match_operand:SI 1 "register_operand" "=D"))
18091    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18092   "!TARGET_64BIT"
18093   "repz cmpsb"
18094   [(set_attr "type" "str")
18095    (set_attr "mode" "QI")
18096    (set_attr "prefix_rep" "1")])
18097
18098 (define_insn "*cmpstrnqi_rex_1"
18099   [(set (reg:CC FLAGS_REG)
18100         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18101                              (const_int 0))
18102           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18103                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18104           (const_int 0)))
18105    (use (match_operand:SI 3 "immediate_operand" "i"))
18106    (use (reg:CC FLAGS_REG))
18107    (clobber (match_operand:DI 0 "register_operand" "=S"))
18108    (clobber (match_operand:DI 1 "register_operand" "=D"))
18109    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18110   "TARGET_64BIT"
18111   "repz cmpsb"
18112   [(set_attr "type" "str")
18113    (set_attr "mode" "QI")
18114    (set_attr "prefix_rex" "0")
18115    (set_attr "prefix_rep" "1")])
18116
18117 (define_expand "strlensi"
18118   [(set (match_operand:SI 0 "register_operand" "")
18119         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
18120                     (match_operand:QI 2 "immediate_operand" "")
18121                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18122   ""
18123 {
18124  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18125    DONE;
18126  else
18127    FAIL;
18128 })
18129
18130 (define_expand "strlendi"
18131   [(set (match_operand:DI 0 "register_operand" "")
18132         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
18133                     (match_operand:QI 2 "immediate_operand" "")
18134                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18135   ""
18136 {
18137  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18138    DONE;
18139  else
18140    FAIL;
18141 })
18142
18143 (define_expand "strlenqi_1"
18144   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
18145               (clobber (match_operand 1 "register_operand" ""))
18146               (clobber (reg:CC FLAGS_REG))])]
18147   ""
18148   "ix86_current_function_needs_cld = 1;")
18149
18150 (define_insn "*strlenqi_1"
18151   [(set (match_operand:SI 0 "register_operand" "=&c")
18152         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
18153                     (match_operand:QI 2 "register_operand" "a")
18154                     (match_operand:SI 3 "immediate_operand" "i")
18155                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
18156    (clobber (match_operand:SI 1 "register_operand" "=D"))
18157    (clobber (reg:CC FLAGS_REG))]
18158   "!TARGET_64BIT"
18159   "repnz scasb"
18160   [(set_attr "type" "str")
18161    (set_attr "mode" "QI")
18162    (set_attr "prefix_rep" "1")])
18163
18164 (define_insn "*strlenqi_rex_1"
18165   [(set (match_operand:DI 0 "register_operand" "=&c")
18166         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
18167                     (match_operand:QI 2 "register_operand" "a")
18168                     (match_operand:DI 3 "immediate_operand" "i")
18169                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
18170    (clobber (match_operand:DI 1 "register_operand" "=D"))
18171    (clobber (reg:CC FLAGS_REG))]
18172   "TARGET_64BIT"
18173   "repnz scasb"
18174   [(set_attr "type" "str")
18175    (set_attr "mode" "QI")
18176    (set_attr "prefix_rex" "0")
18177    (set_attr "prefix_rep" "1")])
18178
18179 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
18180 ;; handled in combine, but it is not currently up to the task.
18181 ;; When used for their truth value, the cmpstrn* expanders generate
18182 ;; code like this:
18183 ;;
18184 ;;   repz cmpsb
18185 ;;   seta       %al
18186 ;;   setb       %dl
18187 ;;   cmpb       %al, %dl
18188 ;;   jcc        label
18189 ;;
18190 ;; The intermediate three instructions are unnecessary.
18191
18192 ;; This one handles cmpstrn*_nz_1...
18193 (define_peephole2
18194   [(parallel[
18195      (set (reg:CC FLAGS_REG)
18196           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18197                       (mem:BLK (match_operand 5 "register_operand" ""))))
18198      (use (match_operand 6 "register_operand" ""))
18199      (use (match_operand:SI 3 "immediate_operand" ""))
18200      (clobber (match_operand 0 "register_operand" ""))
18201      (clobber (match_operand 1 "register_operand" ""))
18202      (clobber (match_operand 2 "register_operand" ""))])
18203    (set (match_operand:QI 7 "register_operand" "")
18204         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18205    (set (match_operand:QI 8 "register_operand" "")
18206         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18207    (set (reg FLAGS_REG)
18208         (compare (match_dup 7) (match_dup 8)))
18209   ]
18210   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18211   [(parallel[
18212      (set (reg:CC FLAGS_REG)
18213           (compare:CC (mem:BLK (match_dup 4))
18214                       (mem:BLK (match_dup 5))))
18215      (use (match_dup 6))
18216      (use (match_dup 3))
18217      (clobber (match_dup 0))
18218      (clobber (match_dup 1))
18219      (clobber (match_dup 2))])]
18220   "")
18221
18222 ;; ...and this one handles cmpstrn*_1.
18223 (define_peephole2
18224   [(parallel[
18225      (set (reg:CC FLAGS_REG)
18226           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
18227                                (const_int 0))
18228             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18229                         (mem:BLK (match_operand 5 "register_operand" "")))
18230             (const_int 0)))
18231      (use (match_operand:SI 3 "immediate_operand" ""))
18232      (use (reg:CC FLAGS_REG))
18233      (clobber (match_operand 0 "register_operand" ""))
18234      (clobber (match_operand 1 "register_operand" ""))
18235      (clobber (match_operand 2 "register_operand" ""))])
18236    (set (match_operand:QI 7 "register_operand" "")
18237         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18238    (set (match_operand:QI 8 "register_operand" "")
18239         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18240    (set (reg FLAGS_REG)
18241         (compare (match_dup 7) (match_dup 8)))
18242   ]
18243   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18244   [(parallel[
18245      (set (reg:CC FLAGS_REG)
18246           (if_then_else:CC (ne (match_dup 6)
18247                                (const_int 0))
18248             (compare:CC (mem:BLK (match_dup 4))
18249                         (mem:BLK (match_dup 5)))
18250             (const_int 0)))
18251      (use (match_dup 3))
18252      (use (reg:CC FLAGS_REG))
18253      (clobber (match_dup 0))
18254      (clobber (match_dup 1))
18255      (clobber (match_dup 2))])]
18256   "")
18257
18258
18259 \f
18260 ;; Conditional move instructions.
18261
18262 (define_expand "mov<mode>cc"
18263   [(set (match_operand:SWIM 0 "register_operand" "")
18264         (if_then_else:SWIM (match_operand 1 "comparison_operator" "")
18265                            (match_operand:SWIM 2 "general_operand" "")
18266                            (match_operand:SWIM 3 "general_operand" "")))]
18267   ""
18268   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
18269
18270 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
18271 ;; the register first winds up with `sbbl $0,reg', which is also weird.
18272 ;; So just document what we're doing explicitly.
18273
18274 (define_expand "x86_mov<mode>cc_0_m1"
18275   [(parallel
18276     [(set (match_operand:SWI48 0 "register_operand" "")
18277           (if_then_else:SWI48
18278             (match_operator:SWI48 2 "ix86_carry_flag_operator"
18279              [(match_operand 1 "flags_reg_operand" "")
18280               (const_int 0)])
18281             (const_int -1)
18282             (const_int 0)))
18283      (clobber (reg:CC FLAGS_REG))])]
18284   ""
18285   "")
18286
18287 (define_insn "*x86_mov<mode>cc_0_m1"
18288   [(set (match_operand:SWI48 0 "register_operand" "=r")
18289         (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
18290                              [(reg FLAGS_REG) (const_int 0)])
18291           (const_int -1)
18292           (const_int 0)))
18293    (clobber (reg:CC FLAGS_REG))]
18294   ""
18295   "sbb{<imodesuffix>}\t%0, %0"
18296   ; Since we don't have the proper number of operands for an alu insn,
18297   ; fill in all the blanks.
18298   [(set_attr "type" "alu")
18299    (set_attr "use_carry" "1")
18300    (set_attr "pent_pair" "pu")
18301    (set_attr "memory" "none")
18302    (set_attr "imm_disp" "false")
18303    (set_attr "mode" "<MODE>")
18304    (set_attr "length_immediate" "0")])
18305
18306 (define_insn "*x86_mov<mode>cc_0_m1_se"
18307   [(set (match_operand:SWI48 0 "register_operand" "=r")
18308         (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
18309                              [(reg FLAGS_REG) (const_int 0)])
18310                             (const_int 1)
18311                             (const_int 0)))
18312    (clobber (reg:CC FLAGS_REG))]
18313   ""
18314   "sbb{<imodesuffix>}\t%0, %0"
18315   [(set_attr "type" "alu")
18316    (set_attr "use_carry" "1")
18317    (set_attr "pent_pair" "pu")
18318    (set_attr "memory" "none")
18319    (set_attr "imm_disp" "false")
18320    (set_attr "mode" "<MODE>")
18321    (set_attr "length_immediate" "0")])
18322
18323 (define_insn "*x86_mov<mode>cc_0_m1_neg"
18324   [(set (match_operand:SWI48 0 "register_operand" "=r")
18325         (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
18326                     [(reg FLAGS_REG) (const_int 0)])))]
18327   ""
18328   "sbb{<imodesuffix>}\t%0, %0"
18329   [(set_attr "type" "alu")
18330    (set_attr "use_carry" "1")
18331    (set_attr "pent_pair" "pu")
18332    (set_attr "memory" "none")
18333    (set_attr "imm_disp" "false")
18334    (set_attr "mode" "<MODE>")
18335    (set_attr "length_immediate" "0")])
18336
18337 (define_insn "*mov<mode>cc_noc"
18338   [(set (match_operand:SWI248 0 "register_operand" "=r,r")
18339         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
18340                                [(reg FLAGS_REG) (const_int 0)])
18341           (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
18342           (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
18343   "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18344   "@
18345    cmov%O2%C1\t{%2, %0|%0, %2}
18346    cmov%O2%c1\t{%3, %0|%0, %3}"
18347   [(set_attr "type" "icmov")
18348    (set_attr "mode" "<MODE>")])
18349
18350 (define_insn_and_split "*movqicc_noc"
18351   [(set (match_operand:QI 0 "register_operand" "=r,r")
18352         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
18353                            [(match_operand 4 "flags_reg_operand" "")
18354                             (const_int 0)])
18355                       (match_operand:QI 2 "register_operand" "r,0")
18356                       (match_operand:QI 3 "register_operand" "0,r")))]
18357   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
18358   "#"
18359   "&& reload_completed"
18360   [(set (match_dup 0)
18361         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18362                       (match_dup 2)
18363                       (match_dup 3)))]
18364   "operands[0] = gen_lowpart (SImode, operands[0]);
18365    operands[2] = gen_lowpart (SImode, operands[2]);
18366    operands[3] = gen_lowpart (SImode, operands[3]);"
18367   [(set_attr "type" "icmov")
18368    (set_attr "mode" "SI")])
18369
18370 (define_expand "mov<mode>cc"
18371   [(set (match_operand:X87MODEF 0 "register_operand" "")
18372         (if_then_else:X87MODEF
18373           (match_operand 1 "ix86_fp_comparison_operator" "")
18374           (match_operand:X87MODEF 2 "register_operand" "")
18375           (match_operand:X87MODEF 3 "register_operand" "")))]
18376   "(TARGET_80387 && TARGET_CMOVE)
18377    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18378   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
18379
18380 (define_insn "*movsfcc_1_387"
18381   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
18382         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18383                                 [(reg FLAGS_REG) (const_int 0)])
18384                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
18385                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
18386   "TARGET_80387 && TARGET_CMOVE
18387    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18388   "@
18389    fcmov%F1\t{%2, %0|%0, %2}
18390    fcmov%f1\t{%3, %0|%0, %3}
18391    cmov%O2%C1\t{%2, %0|%0, %2}
18392    cmov%O2%c1\t{%3, %0|%0, %3}"
18393   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18394    (set_attr "mode" "SF,SF,SI,SI")])
18395
18396 (define_insn "*movdfcc_1"
18397   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
18398         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18399                                 [(reg FLAGS_REG) (const_int 0)])
18400                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
18401                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
18402   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18403    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18404   "@
18405    fcmov%F1\t{%2, %0|%0, %2}
18406    fcmov%f1\t{%3, %0|%0, %3}
18407    #
18408    #"
18409   [(set_attr "type" "fcmov,fcmov,multi,multi")
18410    (set_attr "mode" "DF")])
18411
18412 (define_insn "*movdfcc_1_rex64"
18413   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
18414         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18415                                 [(reg FLAGS_REG) (const_int 0)])
18416                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
18417                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
18418   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18419    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18420   "@
18421    fcmov%F1\t{%2, %0|%0, %2}
18422    fcmov%f1\t{%3, %0|%0, %3}
18423    cmov%O2%C1\t{%2, %0|%0, %2}
18424    cmov%O2%c1\t{%3, %0|%0, %3}"
18425   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18426    (set_attr "mode" "DF")])
18427
18428 (define_split
18429   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
18430         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18431                                 [(match_operand 4 "flags_reg_operand" "")
18432                                  (const_int 0)])
18433                       (match_operand:DF 2 "nonimmediate_operand" "")
18434                       (match_operand:DF 3 "nonimmediate_operand" "")))]
18435   "!TARGET_64BIT && reload_completed"
18436   [(set (match_dup 2)
18437         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18438                       (match_dup 5)
18439                       (match_dup 6)))
18440    (set (match_dup 3)
18441         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18442                       (match_dup 7)
18443                       (match_dup 8)))]
18444   "split_di (&operands[2], 2, &operands[5], &operands[7]);
18445    split_di (&operands[0], 1, &operands[2], &operands[3]);")
18446
18447 (define_insn "*movxfcc_1"
18448   [(set (match_operand:XF 0 "register_operand" "=f,f")
18449         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
18450                                 [(reg FLAGS_REG) (const_int 0)])
18451                       (match_operand:XF 2 "register_operand" "f,0")
18452                       (match_operand:XF 3 "register_operand" "0,f")))]
18453   "TARGET_80387 && TARGET_CMOVE"
18454   "@
18455    fcmov%F1\t{%2, %0|%0, %2}
18456    fcmov%f1\t{%3, %0|%0, %3}"
18457   [(set_attr "type" "fcmov")
18458    (set_attr "mode" "XF")])
18459
18460 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
18461 ;; the scalar versions to have only XMM registers as operands.
18462
18463 ;; XOP conditional move
18464 (define_insn "*xop_pcmov_<mode>"
18465   [(set (match_operand:MODEF 0 "register_operand" "=x")
18466         (if_then_else:MODEF
18467           (match_operand:MODEF 1 "register_operand" "x")
18468           (match_operand:MODEF 2 "register_operand" "x")
18469           (match_operand:MODEF 3 "register_operand" "x")))]
18470   "TARGET_XOP"
18471   "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
18472   [(set_attr "type" "sse4arg")])
18473
18474 ;; These versions of the min/max patterns are intentionally ignorant of
18475 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
18476 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
18477 ;; are undefined in this condition, we're certain this is correct.
18478
18479 (define_insn "*avx_<code><mode>3"
18480   [(set (match_operand:MODEF 0 "register_operand" "=x")
18481         (smaxmin:MODEF
18482           (match_operand:MODEF 1 "nonimmediate_operand" "%x")
18483           (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
18484   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
18485   "v<maxminfprefix>s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
18486   [(set_attr "type" "sseadd")
18487    (set_attr "prefix" "vex")
18488    (set_attr "mode" "<MODE>")])
18489
18490 (define_insn "<code><mode>3"
18491   [(set (match_operand:MODEF 0 "register_operand" "=x")
18492         (smaxmin:MODEF
18493           (match_operand:MODEF 1 "nonimmediate_operand" "%0")
18494           (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
18495   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
18496   "<maxminfprefix>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
18497   [(set_attr "type" "sseadd")
18498    (set_attr "mode" "<MODE>")])
18499
18500 ;; These versions of the min/max patterns implement exactly the operations
18501 ;;   min = (op1 < op2 ? op1 : op2)
18502 ;;   max = (!(op1 < op2) ? op1 : op2)
18503 ;; Their operands are not commutative, and thus they may be used in the
18504 ;; presence of -0.0 and NaN.
18505
18506 (define_insn "*avx_ieee_smin<mode>3"
18507   [(set (match_operand:MODEF 0 "register_operand" "=x")
18508         (unspec:MODEF
18509           [(match_operand:MODEF 1 "register_operand" "x")
18510            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
18511          UNSPEC_IEEE_MIN))]
18512   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
18513   "vmins<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
18514   [(set_attr "type" "sseadd")
18515    (set_attr "prefix" "vex")
18516    (set_attr "mode" "<MODE>")])
18517
18518 (define_insn "*ieee_smin<mode>3"
18519   [(set (match_operand:MODEF 0 "register_operand" "=x")
18520         (unspec:MODEF
18521           [(match_operand:MODEF 1 "register_operand" "0")
18522            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
18523          UNSPEC_IEEE_MIN))]
18524   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
18525   "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
18526   [(set_attr "type" "sseadd")
18527    (set_attr "mode" "<MODE>")])
18528
18529 (define_insn "*avx_ieee_smax<mode>3"
18530   [(set (match_operand:MODEF 0 "register_operand" "=x")
18531         (unspec:MODEF
18532           [(match_operand:MODEF 1 "register_operand" "0")
18533            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
18534          UNSPEC_IEEE_MAX))]
18535   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
18536   "vmaxs<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
18537   [(set_attr "type" "sseadd")
18538    (set_attr "prefix" "vex")
18539    (set_attr "mode" "<MODE>")])
18540
18541 (define_insn "*ieee_smax<mode>3"
18542   [(set (match_operand:MODEF 0 "register_operand" "=x")
18543         (unspec:MODEF
18544           [(match_operand:MODEF 1 "register_operand" "0")
18545            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
18546          UNSPEC_IEEE_MAX))]
18547   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
18548   "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
18549   [(set_attr "type" "sseadd")
18550    (set_attr "mode" "<MODE>")])
18551
18552 ;; Make two stack loads independent:
18553 ;;   fld aa              fld aa
18554 ;;   fld %st(0)     ->   fld bb
18555 ;;   fmul bb             fmul %st(1), %st
18556 ;;
18557 ;; Actually we only match the last two instructions for simplicity.
18558 (define_peephole2
18559   [(set (match_operand 0 "fp_register_operand" "")
18560         (match_operand 1 "fp_register_operand" ""))
18561    (set (match_dup 0)
18562         (match_operator 2 "binary_fp_operator"
18563            [(match_dup 0)
18564             (match_operand 3 "memory_operand" "")]))]
18565   "REGNO (operands[0]) != REGNO (operands[1])"
18566   [(set (match_dup 0) (match_dup 3))
18567    (set (match_dup 0) (match_dup 4))]
18568
18569   ;; The % modifier is not operational anymore in peephole2's, so we have to
18570   ;; swap the operands manually in the case of addition and multiplication.
18571   "if (COMMUTATIVE_ARITH_P (operands[2]))
18572      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
18573                                  operands[0], operands[1]);
18574    else
18575      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
18576                                  operands[1], operands[0]);")
18577
18578 ;; Conditional addition patterns
18579 (define_expand "add<mode>cc"
18580   [(match_operand:SWI 0 "register_operand" "")
18581    (match_operand 1 "comparison_operator" "")
18582    (match_operand:SWI 2 "register_operand" "")
18583    (match_operand:SWI 3 "const_int_operand" "")]
18584   ""
18585   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
18586
18587 \f
18588 ;; Misc patterns (?)
18589
18590 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
18591 ;; Otherwise there will be nothing to keep
18592 ;;
18593 ;; [(set (reg ebp) (reg esp))]
18594 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
18595 ;;  (clobber (eflags)]
18596 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
18597 ;;
18598 ;; in proper program order.
18599 (define_insn "pro_epilogue_adjust_stack_1"
18600   [(set (match_operand:SI 0 "register_operand" "=r,r")
18601         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
18602                  (match_operand:SI 2 "immediate_operand" "i,i")))
18603    (clobber (reg:CC FLAGS_REG))
18604    (clobber (mem:BLK (scratch)))]
18605   "!TARGET_64BIT"
18606 {
18607   switch (get_attr_type (insn))
18608     {
18609     case TYPE_IMOV:
18610       return "mov{l}\t{%1, %0|%0, %1}";
18611
18612     case TYPE_ALU:
18613       if (CONST_INT_P (operands[2])
18614           && (INTVAL (operands[2]) == 128
18615               || (INTVAL (operands[2]) < 0
18616                   && INTVAL (operands[2]) != -128)))
18617         {
18618           operands[2] = GEN_INT (-INTVAL (operands[2]));
18619           return "sub{l}\t{%2, %0|%0, %2}";
18620         }
18621       return "add{l}\t{%2, %0|%0, %2}";
18622
18623     case TYPE_LEA:
18624       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18625       return "lea{l}\t{%a2, %0|%0, %a2}";
18626
18627     default:
18628       gcc_unreachable ();
18629     }
18630 }
18631   [(set (attr "type")
18632         (cond [(and (eq_attr "alternative" "0") 
18633                     (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
18634                  (const_string "alu")
18635                (match_operand:SI 2 "const0_operand" "")
18636                  (const_string "imov")
18637               ]
18638               (const_string "lea")))
18639    (set (attr "length_immediate")
18640         (cond [(eq_attr "type" "imov")
18641                  (const_string "0")
18642                (and (eq_attr "type" "alu")
18643                     (match_operand 2 "const128_operand" ""))
18644                  (const_string "1")
18645               ]
18646               (const_string "*")))
18647    (set_attr "mode" "SI")])
18648
18649 (define_insn "pro_epilogue_adjust_stack_rex64"
18650   [(set (match_operand:DI 0 "register_operand" "=r,r")
18651         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18652                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
18653    (clobber (reg:CC FLAGS_REG))
18654    (clobber (mem:BLK (scratch)))]
18655   "TARGET_64BIT"
18656 {
18657   switch (get_attr_type (insn))
18658     {
18659     case TYPE_IMOV:
18660       return "mov{q}\t{%1, %0|%0, %1}";
18661
18662     case TYPE_ALU:
18663       if (CONST_INT_P (operands[2])
18664           /* Avoid overflows.  */
18665           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
18666           && (INTVAL (operands[2]) == 128
18667               || (INTVAL (operands[2]) < 0
18668                   && INTVAL (operands[2]) != -128)))
18669         {
18670           operands[2] = GEN_INT (-INTVAL (operands[2]));
18671           return "sub{q}\t{%2, %0|%0, %2}";
18672         }
18673       return "add{q}\t{%2, %0|%0, %2}";
18674
18675     case TYPE_LEA:
18676       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18677       return "lea{q}\t{%a2, %0|%0, %a2}";
18678
18679     default:
18680       gcc_unreachable ();
18681     }
18682 }
18683   [(set (attr "type")
18684         (cond [(and (eq_attr "alternative" "0")
18685                     (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
18686                  (const_string "alu")
18687                (match_operand:DI 2 "const0_operand" "")
18688                  (const_string "imov")
18689               ]
18690               (const_string "lea")))
18691    (set (attr "length_immediate")
18692         (cond [(eq_attr "type" "imov")
18693                  (const_string "0")
18694                (and (eq_attr "type" "alu")
18695                     (match_operand 2 "const128_operand" ""))
18696                  (const_string "1")
18697               ]
18698               (const_string "*")))
18699    (set_attr "mode" "DI")])
18700
18701 (define_insn "pro_epilogue_adjust_stack_rex64_2"
18702   [(set (match_operand:DI 0 "register_operand" "=r,r")
18703         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18704                  (match_operand:DI 3 "immediate_operand" "i,i")))
18705    (use (match_operand:DI 2 "register_operand" "r,r"))
18706    (clobber (reg:CC FLAGS_REG))
18707    (clobber (mem:BLK (scratch)))]
18708   "TARGET_64BIT"
18709 {
18710   switch (get_attr_type (insn))
18711     {
18712     case TYPE_ALU:
18713       return "add{q}\t{%2, %0|%0, %2}";
18714
18715     case TYPE_LEA:
18716       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
18717       return "lea{q}\t{%a2, %0|%0, %a2}";
18718
18719     default:
18720       gcc_unreachable ();
18721     }
18722 }
18723   [(set_attr "type" "alu,lea")
18724    (set_attr "mode" "DI")])
18725
18726 (define_insn "allocate_stack_worker_32"
18727   [(set (match_operand:SI 0 "register_operand" "=a")
18728         (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")]
18729                             UNSPECV_STACK_PROBE))
18730    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 1)))
18731    (clobber (reg:CC FLAGS_REG))]
18732   "!TARGET_64BIT && TARGET_STACK_PROBE"
18733   "call\t___chkstk"
18734   [(set_attr "type" "multi")
18735    (set_attr "length" "5")])
18736
18737 (define_insn "allocate_stack_worker_64"
18738   [(set (match_operand:DI 0 "register_operand" "=a")
18739         (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "0")]
18740                             UNSPECV_STACK_PROBE))
18741    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 1)))
18742    (clobber (reg:DI R10_REG))
18743    (clobber (reg:DI R11_REG))
18744    (clobber (reg:CC FLAGS_REG))]
18745   "TARGET_64BIT && TARGET_STACK_PROBE"
18746   "call\t___chkstk"
18747   [(set_attr "type" "multi")
18748    (set_attr "length" "5")])
18749
18750 (define_expand "allocate_stack"
18751   [(match_operand 0 "register_operand" "")
18752    (match_operand 1 "general_operand" "")]
18753   "TARGET_STACK_PROBE"
18754 {
18755   rtx x;
18756
18757 #ifndef CHECK_STACK_LIMIT
18758 #define CHECK_STACK_LIMIT 0
18759 #endif
18760
18761   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
18762       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
18763     {
18764       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
18765                                stack_pointer_rtx, 0, OPTAB_DIRECT);
18766       if (x != stack_pointer_rtx)
18767         emit_move_insn (stack_pointer_rtx, x);
18768     }
18769   else
18770     {
18771       x = copy_to_mode_reg (Pmode, operands[1]);
18772       if (TARGET_64BIT)
18773         x = gen_allocate_stack_worker_64 (x, x);
18774       else
18775         x = gen_allocate_stack_worker_32 (x, x);
18776       emit_insn (x);
18777     }
18778
18779   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
18780   DONE;
18781 })
18782
18783 ;; Use IOR for stack probes, this is shorter.
18784 (define_expand "probe_stack"
18785   [(match_operand 0 "memory_operand" "")]
18786   ""
18787 {
18788   if (GET_MODE (operands[0]) == DImode)
18789     emit_insn (gen_iordi3 (operands[0], operands[0], const0_rtx));
18790   else
18791     emit_insn (gen_iorsi3 (operands[0], operands[0], const0_rtx));
18792   DONE;
18793 })
18794
18795 (define_expand "builtin_setjmp_receiver"
18796   [(label_ref (match_operand 0 "" ""))]
18797   "!TARGET_64BIT && flag_pic"
18798 {
18799 #if TARGET_MACHO
18800   if (TARGET_MACHO)
18801     {
18802       rtx xops[3];
18803       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
18804       rtx label_rtx = gen_label_rtx ();
18805       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
18806       xops[0] = xops[1] = picreg;
18807       xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
18808       ix86_expand_binary_operator (MINUS, SImode, xops);
18809     }
18810   else
18811 #endif
18812     emit_insn (gen_set_got (pic_offset_table_rtx));
18813   DONE;
18814 })
18815 \f
18816 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
18817
18818 (define_split
18819   [(set (match_operand 0 "register_operand" "")
18820         (match_operator 3 "promotable_binary_operator"
18821            [(match_operand 1 "register_operand" "")
18822             (match_operand 2 "aligned_operand" "")]))
18823    (clobber (reg:CC FLAGS_REG))]
18824   "! TARGET_PARTIAL_REG_STALL && reload_completed
18825    && ((GET_MODE (operands[0]) == HImode
18826         && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
18827             /* ??? next two lines just !satisfies_constraint_K (...) */
18828             || !CONST_INT_P (operands[2])
18829             || satisfies_constraint_K (operands[2])))
18830        || (GET_MODE (operands[0]) == QImode
18831            && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
18832   [(parallel [(set (match_dup 0)
18833                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18834               (clobber (reg:CC FLAGS_REG))])]
18835   "operands[0] = gen_lowpart (SImode, operands[0]);
18836    operands[1] = gen_lowpart (SImode, operands[1]);
18837    if (GET_CODE (operands[3]) != ASHIFT)
18838      operands[2] = gen_lowpart (SImode, operands[2]);
18839    PUT_MODE (operands[3], SImode);")
18840
18841 ; Promote the QImode tests, as i386 has encoding of the AND
18842 ; instruction with 32-bit sign-extended immediate and thus the
18843 ; instruction size is unchanged, except in the %eax case for
18844 ; which it is increased by one byte, hence the ! optimize_size.
18845 (define_split
18846   [(set (match_operand 0 "flags_reg_operand" "")
18847         (match_operator 2 "compare_operator"
18848           [(and (match_operand 3 "aligned_operand" "")
18849                 (match_operand 4 "const_int_operand" ""))
18850            (const_int 0)]))
18851    (set (match_operand 1 "register_operand" "")
18852         (and (match_dup 3) (match_dup 4)))]
18853   "! TARGET_PARTIAL_REG_STALL && reload_completed
18854    && optimize_insn_for_speed_p ()
18855    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
18856        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
18857    /* Ensure that the operand will remain sign-extended immediate.  */
18858    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
18859   [(parallel [(set (match_dup 0)
18860                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
18861                                     (const_int 0)]))
18862               (set (match_dup 1)
18863                    (and:SI (match_dup 3) (match_dup 4)))])]
18864 {
18865   operands[4]
18866     = gen_int_mode (INTVAL (operands[4])
18867                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
18868   operands[1] = gen_lowpart (SImode, operands[1]);
18869   operands[3] = gen_lowpart (SImode, operands[3]);
18870 })
18871
18872 ; Don't promote the QImode tests, as i386 doesn't have encoding of
18873 ; the TEST instruction with 32-bit sign-extended immediate and thus
18874 ; the instruction size would at least double, which is not what we
18875 ; want even with ! optimize_size.
18876 (define_split
18877   [(set (match_operand 0 "flags_reg_operand" "")
18878         (match_operator 1 "compare_operator"
18879           [(and (match_operand:HI 2 "aligned_operand" "")
18880                 (match_operand:HI 3 "const_int_operand" ""))
18881            (const_int 0)]))]
18882   "! TARGET_PARTIAL_REG_STALL && reload_completed
18883    && ! TARGET_FAST_PREFIX
18884    && optimize_insn_for_speed_p ()
18885    /* Ensure that the operand will remain sign-extended immediate.  */
18886    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
18887   [(set (match_dup 0)
18888         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18889                          (const_int 0)]))]
18890 {
18891   operands[3]
18892     = gen_int_mode (INTVAL (operands[3])
18893                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
18894   operands[2] = gen_lowpart (SImode, operands[2]);
18895 })
18896
18897 (define_split
18898   [(set (match_operand 0 "register_operand" "")
18899         (neg (match_operand 1 "register_operand" "")))
18900    (clobber (reg:CC FLAGS_REG))]
18901   "! TARGET_PARTIAL_REG_STALL && reload_completed
18902    && (GET_MODE (operands[0]) == HImode
18903        || (GET_MODE (operands[0]) == QImode
18904            && (TARGET_PROMOTE_QImode
18905                || optimize_insn_for_size_p ())))"
18906   [(parallel [(set (match_dup 0)
18907                    (neg:SI (match_dup 1)))
18908               (clobber (reg:CC FLAGS_REG))])]
18909   "operands[0] = gen_lowpart (SImode, operands[0]);
18910    operands[1] = gen_lowpart (SImode, operands[1]);")
18911
18912 (define_split
18913   [(set (match_operand 0 "register_operand" "")
18914         (not (match_operand 1 "register_operand" "")))]
18915   "! TARGET_PARTIAL_REG_STALL && reload_completed
18916    && (GET_MODE (operands[0]) == HImode
18917        || (GET_MODE (operands[0]) == QImode
18918            && (TARGET_PROMOTE_QImode
18919                || optimize_insn_for_size_p ())))"
18920   [(set (match_dup 0)
18921         (not:SI (match_dup 1)))]
18922   "operands[0] = gen_lowpart (SImode, operands[0]);
18923    operands[1] = gen_lowpart (SImode, operands[1]);")
18924
18925 (define_split
18926   [(set (match_operand 0 "register_operand" "")
18927         (if_then_else (match_operator 1 "comparison_operator"
18928                                 [(reg FLAGS_REG) (const_int 0)])
18929                       (match_operand 2 "register_operand" "")
18930                       (match_operand 3 "register_operand" "")))]
18931   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
18932    && (GET_MODE (operands[0]) == HImode
18933        || (GET_MODE (operands[0]) == QImode
18934            && (TARGET_PROMOTE_QImode
18935                || optimize_insn_for_size_p ())))"
18936   [(set (match_dup 0)
18937         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
18938   "operands[0] = gen_lowpart (SImode, operands[0]);
18939    operands[2] = gen_lowpart (SImode, operands[2]);
18940    operands[3] = gen_lowpart (SImode, operands[3]);")
18941
18942 \f
18943 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
18944 ;; transform a complex memory operation into two memory to register operations.
18945
18946 ;; Don't push memory operands
18947 (define_peephole2
18948   [(set (match_operand:SI 0 "push_operand" "")
18949         (match_operand:SI 1 "memory_operand" ""))
18950    (match_scratch:SI 2 "r")]
18951   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
18952    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18953   [(set (match_dup 2) (match_dup 1))
18954    (set (match_dup 0) (match_dup 2))]
18955   "")
18956
18957 (define_peephole2
18958   [(set (match_operand:DI 0 "push_operand" "")
18959         (match_operand:DI 1 "memory_operand" ""))
18960    (match_scratch:DI 2 "r")]
18961   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
18962    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18963   [(set (match_dup 2) (match_dup 1))
18964    (set (match_dup 0) (match_dup 2))]
18965   "")
18966
18967 ;; We need to handle SFmode only, because DFmode and XFmode is split to
18968 ;; SImode pushes.
18969 (define_peephole2
18970   [(set (match_operand:SF 0 "push_operand" "")
18971         (match_operand:SF 1 "memory_operand" ""))
18972    (match_scratch:SF 2 "r")]
18973   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
18974    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18975   [(set (match_dup 2) (match_dup 1))
18976    (set (match_dup 0) (match_dup 2))]
18977   "")
18978
18979 (define_peephole2
18980   [(set (match_operand:HI 0 "push_operand" "")
18981         (match_operand:HI 1 "memory_operand" ""))
18982    (match_scratch:HI 2 "r")]
18983   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
18984    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18985   [(set (match_dup 2) (match_dup 1))
18986    (set (match_dup 0) (match_dup 2))]
18987   "")
18988
18989 (define_peephole2
18990   [(set (match_operand:QI 0 "push_operand" "")
18991         (match_operand:QI 1 "memory_operand" ""))
18992    (match_scratch:QI 2 "q")]
18993   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
18994    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18995   [(set (match_dup 2) (match_dup 1))
18996    (set (match_dup 0) (match_dup 2))]
18997   "")
18998
18999 ;; Don't move an immediate directly to memory when the instruction
19000 ;; gets too big.
19001 (define_peephole2
19002   [(match_scratch:SI 1 "r")
19003    (set (match_operand:SI 0 "memory_operand" "")
19004         (const_int 0))]
19005   "optimize_insn_for_speed_p ()
19006    && ! TARGET_USE_MOV0
19007    && TARGET_SPLIT_LONG_MOVES
19008    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
19009    && peep2_regno_dead_p (0, FLAGS_REG)"
19010   [(parallel [(set (match_dup 1) (const_int 0))
19011               (clobber (reg:CC FLAGS_REG))])
19012    (set (match_dup 0) (match_dup 1))]
19013   "")
19014
19015 (define_peephole2
19016   [(match_scratch:HI 1 "r")
19017    (set (match_operand:HI 0 "memory_operand" "")
19018         (const_int 0))]
19019   "optimize_insn_for_speed_p ()
19020    && ! TARGET_USE_MOV0
19021    && TARGET_SPLIT_LONG_MOVES
19022    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
19023    && peep2_regno_dead_p (0, FLAGS_REG)"
19024   [(parallel [(set (match_dup 2) (const_int 0))
19025               (clobber (reg:CC FLAGS_REG))])
19026    (set (match_dup 0) (match_dup 1))]
19027   "operands[2] = gen_lowpart (SImode, operands[1]);")
19028
19029 (define_peephole2
19030   [(match_scratch:QI 1 "q")
19031    (set (match_operand:QI 0 "memory_operand" "")
19032         (const_int 0))]
19033   "optimize_insn_for_speed_p ()
19034    && ! TARGET_USE_MOV0
19035    && TARGET_SPLIT_LONG_MOVES
19036    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
19037    && peep2_regno_dead_p (0, FLAGS_REG)"
19038   [(parallel [(set (match_dup 2) (const_int 0))
19039               (clobber (reg:CC FLAGS_REG))])
19040    (set (match_dup 0) (match_dup 1))]
19041   "operands[2] = gen_lowpart (SImode, operands[1]);")
19042
19043 (define_peephole2
19044   [(match_scratch:SI 2 "r")
19045    (set (match_operand:SI 0 "memory_operand" "")
19046         (match_operand:SI 1 "immediate_operand" ""))]
19047   "optimize_insn_for_speed_p ()
19048    && TARGET_SPLIT_LONG_MOVES
19049    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
19050   [(set (match_dup 2) (match_dup 1))
19051    (set (match_dup 0) (match_dup 2))]
19052   "")
19053
19054 (define_peephole2
19055   [(match_scratch:HI 2 "r")
19056    (set (match_operand:HI 0 "memory_operand" "")
19057         (match_operand:HI 1 "immediate_operand" ""))]
19058   "optimize_insn_for_speed_p ()
19059    && TARGET_SPLIT_LONG_MOVES
19060    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
19061   [(set (match_dup 2) (match_dup 1))
19062    (set (match_dup 0) (match_dup 2))]
19063   "")
19064
19065 (define_peephole2
19066   [(match_scratch:QI 2 "q")
19067    (set (match_operand:QI 0 "memory_operand" "")
19068         (match_operand:QI 1 "immediate_operand" ""))]
19069   "optimize_insn_for_speed_p ()
19070    && TARGET_SPLIT_LONG_MOVES
19071    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
19072   [(set (match_dup 2) (match_dup 1))
19073    (set (match_dup 0) (match_dup 2))]
19074   "")
19075
19076 ;; Don't compare memory with zero, load and use a test instead.
19077 (define_peephole2
19078   [(set (match_operand 0 "flags_reg_operand" "")
19079         (match_operator 1 "compare_operator"
19080           [(match_operand:SI 2 "memory_operand" "")
19081            (const_int 0)]))
19082    (match_scratch:SI 3 "r")]
19083   "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
19084   [(set (match_dup 3) (match_dup 2))
19085    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
19086   "")
19087
19088 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
19089 ;; Don't split NOTs with a displacement operand, because resulting XOR
19090 ;; will not be pairable anyway.
19091 ;;
19092 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19093 ;; represented using a modRM byte.  The XOR replacement is long decoded,
19094 ;; so this split helps here as well.
19095 ;;
19096 ;; Note: Can't do this as a regular split because we can't get proper
19097 ;; lifetime information then.
19098
19099 (define_peephole2
19100   [(set (match_operand:SI 0 "nonimmediate_operand" "")
19101         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
19102   "optimize_insn_for_speed_p ()
19103    && ((TARGET_NOT_UNPAIRABLE
19104         && (!MEM_P (operands[0])
19105             || !memory_displacement_operand (operands[0], SImode)))
19106        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
19107    && peep2_regno_dead_p (0, FLAGS_REG)"
19108   [(parallel [(set (match_dup 0)
19109                    (xor:SI (match_dup 1) (const_int -1)))
19110               (clobber (reg:CC FLAGS_REG))])]
19111   "")
19112
19113 (define_peephole2
19114   [(set (match_operand:HI 0 "nonimmediate_operand" "")
19115         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
19116   "optimize_insn_for_speed_p ()
19117    && ((TARGET_NOT_UNPAIRABLE
19118         && (!MEM_P (operands[0])
19119             || !memory_displacement_operand (operands[0], HImode)))
19120        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
19121    && peep2_regno_dead_p (0, FLAGS_REG)"
19122   [(parallel [(set (match_dup 0)
19123                    (xor:HI (match_dup 1) (const_int -1)))
19124               (clobber (reg:CC FLAGS_REG))])]
19125   "")
19126
19127 (define_peephole2
19128   [(set (match_operand:QI 0 "nonimmediate_operand" "")
19129         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
19130   "optimize_insn_for_speed_p ()
19131    && ((TARGET_NOT_UNPAIRABLE
19132         && (!MEM_P (operands[0])
19133             || !memory_displacement_operand (operands[0], QImode)))
19134        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
19135    && peep2_regno_dead_p (0, FLAGS_REG)"
19136   [(parallel [(set (match_dup 0)
19137                    (xor:QI (match_dup 1) (const_int -1)))
19138               (clobber (reg:CC FLAGS_REG))])]
19139   "")
19140
19141 ;; Non pairable "test imm, reg" instructions can be translated to
19142 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
19143 ;; byte opcode instead of two, have a short form for byte operands),
19144 ;; so do it for other CPUs as well.  Given that the value was dead,
19145 ;; this should not create any new dependencies.  Pass on the sub-word
19146 ;; versions if we're concerned about partial register stalls.
19147
19148 (define_peephole2
19149   [(set (match_operand 0 "flags_reg_operand" "")
19150         (match_operator 1 "compare_operator"
19151           [(and:SI (match_operand:SI 2 "register_operand" "")
19152                    (match_operand:SI 3 "immediate_operand" ""))
19153            (const_int 0)]))]
19154   "ix86_match_ccmode (insn, CCNOmode)
19155    && (true_regnum (operands[2]) != AX_REG
19156        || satisfies_constraint_K (operands[3]))
19157    && peep2_reg_dead_p (1, operands[2])"
19158   [(parallel
19159      [(set (match_dup 0)
19160            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19161                             (const_int 0)]))
19162       (set (match_dup 2)
19163            (and:SI (match_dup 2) (match_dup 3)))])]
19164   "")
19165
19166 ;; We don't need to handle HImode case, because it will be promoted to SImode
19167 ;; on ! TARGET_PARTIAL_REG_STALL
19168
19169 (define_peephole2
19170   [(set (match_operand 0 "flags_reg_operand" "")
19171         (match_operator 1 "compare_operator"
19172           [(and:QI (match_operand:QI 2 "register_operand" "")
19173                    (match_operand:QI 3 "immediate_operand" ""))
19174            (const_int 0)]))]
19175   "! TARGET_PARTIAL_REG_STALL
19176    && ix86_match_ccmode (insn, CCNOmode)
19177    && true_regnum (operands[2]) != AX_REG
19178    && peep2_reg_dead_p (1, operands[2])"
19179   [(parallel
19180      [(set (match_dup 0)
19181            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
19182                             (const_int 0)]))
19183       (set (match_dup 2)
19184            (and:QI (match_dup 2) (match_dup 3)))])]
19185   "")
19186
19187 (define_peephole2
19188   [(set (match_operand 0 "flags_reg_operand" "")
19189         (match_operator 1 "compare_operator"
19190           [(and:SI
19191              (zero_extract:SI
19192                (match_operand 2 "ext_register_operand" "")
19193                (const_int 8)
19194                (const_int 8))
19195              (match_operand 3 "const_int_operand" ""))
19196            (const_int 0)]))]
19197   "! TARGET_PARTIAL_REG_STALL
19198    && ix86_match_ccmode (insn, CCNOmode)
19199    && true_regnum (operands[2]) != AX_REG
19200    && peep2_reg_dead_p (1, operands[2])"
19201   [(parallel [(set (match_dup 0)
19202                    (match_op_dup 1
19203                      [(and:SI
19204                         (zero_extract:SI
19205                           (match_dup 2)
19206                           (const_int 8)
19207                           (const_int 8))
19208                         (match_dup 3))
19209                       (const_int 0)]))
19210               (set (zero_extract:SI (match_dup 2)
19211                                     (const_int 8)
19212                                     (const_int 8))
19213                    (and:SI
19214                      (zero_extract:SI
19215                        (match_dup 2)
19216                        (const_int 8)
19217                        (const_int 8))
19218                      (match_dup 3)))])]
19219   "")
19220
19221 ;; Don't do logical operations with memory inputs.
19222 (define_peephole2
19223   [(match_scratch:SI 2 "r")
19224    (parallel [(set (match_operand:SI 0 "register_operand" "")
19225                    (match_operator:SI 3 "arith_or_logical_operator"
19226                      [(match_dup 0)
19227                       (match_operand:SI 1 "memory_operand" "")]))
19228               (clobber (reg:CC FLAGS_REG))])]
19229   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
19230   [(set (match_dup 2) (match_dup 1))
19231    (parallel [(set (match_dup 0)
19232                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
19233               (clobber (reg:CC FLAGS_REG))])]
19234   "")
19235
19236 (define_peephole2
19237   [(match_scratch:SI 2 "r")
19238    (parallel [(set (match_operand:SI 0 "register_operand" "")
19239                    (match_operator:SI 3 "arith_or_logical_operator"
19240                      [(match_operand:SI 1 "memory_operand" "")
19241                       (match_dup 0)]))
19242               (clobber (reg:CC FLAGS_REG))])]
19243   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
19244   [(set (match_dup 2) (match_dup 1))
19245    (parallel [(set (match_dup 0)
19246                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
19247               (clobber (reg:CC FLAGS_REG))])]
19248   "")
19249
19250 ;; Prefer Load+RegOp to Mov+MemOp.  Watch out for cases when the memory address
19251 ;; refers to the destination of the load!
19252
19253 (define_peephole2
19254   [(set (match_operand:SI 0 "register_operand" "")
19255         (match_operand:SI 1 "register_operand" ""))
19256    (parallel [(set (match_dup 0)
19257                    (match_operator:SI 3 "commutative_operator"
19258                      [(match_dup 0)
19259                       (match_operand:SI 2 "memory_operand" "")]))
19260               (clobber (reg:CC FLAGS_REG))])]
19261   "REGNO (operands[0]) != REGNO (operands[1])
19262    && GENERAL_REGNO_P (REGNO (operands[0]))
19263    && GENERAL_REGNO_P (REGNO (operands[1]))"
19264   [(set (match_dup 0) (match_dup 4))
19265    (parallel [(set (match_dup 0)
19266                    (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
19267               (clobber (reg:CC FLAGS_REG))])]
19268   "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
19269
19270 (define_peephole2
19271   [(set (match_operand 0 "register_operand" "")
19272         (match_operand 1 "register_operand" ""))
19273    (set (match_dup 0)
19274                    (match_operator 3 "commutative_operator"
19275                      [(match_dup 0)
19276                       (match_operand 2 "memory_operand" "")]))]
19277   "REGNO (operands[0]) != REGNO (operands[1])
19278    && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1])) 
19279        || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
19280   [(set (match_dup 0) (match_dup 2))
19281    (set (match_dup 0)
19282         (match_op_dup 3 [(match_dup 0) (match_dup 1)]))]
19283   "")
19284
19285 ; Don't do logical operations with memory outputs
19286 ;
19287 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19288 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
19289 ; the same decoder scheduling characteristics as the original.
19290
19291 (define_peephole2
19292   [(match_scratch:SI 2 "r")
19293    (parallel [(set (match_operand:SI 0 "memory_operand" "")
19294                    (match_operator:SI 3 "arith_or_logical_operator"
19295                      [(match_dup 0)
19296                       (match_operand:SI 1 "nonmemory_operand" "")]))
19297               (clobber (reg:CC FLAGS_REG))])]
19298   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
19299    /* Do not split stack checking probes.  */
19300    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
19301   [(set (match_dup 2) (match_dup 0))
19302    (parallel [(set (match_dup 2)
19303                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19304               (clobber (reg:CC FLAGS_REG))])
19305    (set (match_dup 0) (match_dup 2))]
19306   "")
19307
19308 (define_peephole2
19309   [(match_scratch:SI 2 "r")
19310    (parallel [(set (match_operand:SI 0 "memory_operand" "")
19311                    (match_operator:SI 3 "arith_or_logical_operator"
19312                      [(match_operand:SI 1 "nonmemory_operand" "")
19313                       (match_dup 0)]))
19314               (clobber (reg:CC FLAGS_REG))])]
19315   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
19316    /* Do not split stack checking probes.  */
19317    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
19318   [(set (match_dup 2) (match_dup 0))
19319    (parallel [(set (match_dup 2)
19320                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19321               (clobber (reg:CC FLAGS_REG))])
19322    (set (match_dup 0) (match_dup 2))]
19323   "")
19324
19325 ;; Attempt to always use XOR for zeroing registers.
19326 (define_peephole2
19327   [(set (match_operand 0 "register_operand" "")
19328         (match_operand 1 "const0_operand" ""))]
19329   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
19330    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
19331    && GENERAL_REG_P (operands[0])
19332    && peep2_regno_dead_p (0, FLAGS_REG)"
19333   [(parallel [(set (match_dup 0) (const_int 0))
19334               (clobber (reg:CC FLAGS_REG))])]
19335 {
19336   operands[0] = gen_lowpart (word_mode, operands[0]);
19337 })
19338
19339 (define_peephole2
19340   [(set (strict_low_part (match_operand 0 "register_operand" ""))
19341         (const_int 0))]
19342   "(GET_MODE (operands[0]) == QImode
19343     || GET_MODE (operands[0]) == HImode)
19344    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
19345    && peep2_regno_dead_p (0, FLAGS_REG)"
19346   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19347               (clobber (reg:CC FLAGS_REG))])])
19348
19349 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
19350 (define_peephole2
19351   [(set (match_operand 0 "register_operand" "")
19352         (const_int -1))]
19353   "(GET_MODE (operands[0]) == HImode
19354     || GET_MODE (operands[0]) == SImode
19355     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19356    && (optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
19357    && peep2_regno_dead_p (0, FLAGS_REG)"
19358   [(parallel [(set (match_dup 0) (const_int -1))
19359               (clobber (reg:CC FLAGS_REG))])]
19360   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19361                               operands[0]);")
19362
19363 ;; Attempt to convert simple leas to adds. These can be created by
19364 ;; move expanders.
19365 (define_peephole2
19366   [(set (match_operand:SI 0 "register_operand" "")
19367         (plus:SI (match_dup 0)
19368                  (match_operand:SI 1 "nonmemory_operand" "")))]
19369   "peep2_regno_dead_p (0, FLAGS_REG)"
19370   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
19371               (clobber (reg:CC FLAGS_REG))])]
19372   "")
19373
19374 (define_peephole2
19375   [(set (match_operand:SI 0 "register_operand" "")
19376         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
19377                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
19378   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
19379   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
19380               (clobber (reg:CC FLAGS_REG))])]
19381   "operands[2] = gen_lowpart (SImode, operands[2]);")
19382
19383 (define_peephole2
19384   [(set (match_operand:DI 0 "register_operand" "")
19385         (plus:DI (match_dup 0)
19386                  (match_operand:DI 1 "x86_64_general_operand" "")))]
19387   "peep2_regno_dead_p (0, FLAGS_REG)"
19388   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
19389               (clobber (reg:CC FLAGS_REG))])]
19390   "")
19391
19392 (define_peephole2
19393   [(set (match_operand:SI 0 "register_operand" "")
19394         (mult:SI (match_dup 0)
19395                  (match_operand:SI 1 "const_int_operand" "")))]
19396   "exact_log2 (INTVAL (operands[1])) >= 0
19397    && peep2_regno_dead_p (0, FLAGS_REG)"
19398   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19399               (clobber (reg:CC FLAGS_REG))])]
19400   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19401
19402 (define_peephole2
19403   [(set (match_operand:DI 0 "register_operand" "")
19404         (mult:DI (match_dup 0)
19405                  (match_operand:DI 1 "const_int_operand" "")))]
19406   "exact_log2 (INTVAL (operands[1])) >= 0
19407    && peep2_regno_dead_p (0, FLAGS_REG)"
19408   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
19409               (clobber (reg:CC FLAGS_REG))])]
19410   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19411
19412 (define_peephole2
19413   [(set (match_operand:SI 0 "register_operand" "")
19414         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
19415                    (match_operand:DI 2 "const_int_operand" "")) 0))]
19416   "exact_log2 (INTVAL (operands[2])) >= 0
19417    && REGNO (operands[0]) == REGNO (operands[1])
19418    && peep2_regno_dead_p (0, FLAGS_REG)"
19419   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19420               (clobber (reg:CC FLAGS_REG))])]
19421   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19422
19423 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
19424 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
19425 ;; many CPUs it is also faster, since special hardware to avoid esp
19426 ;; dependencies is present.
19427
19428 ;; While some of these conversions may be done using splitters, we use peepholes
19429 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
19430
19431 ;; Convert prologue esp subtractions to push.
19432 ;; We need register to push.  In order to keep verify_flow_info happy we have
19433 ;; two choices
19434 ;; - use scratch and clobber it in order to avoid dependencies
19435 ;; - use already live register
19436 ;; We can't use the second way right now, since there is no reliable way how to
19437 ;; verify that given register is live.  First choice will also most likely in
19438 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
19439 ;; call clobbered registers are dead.  We may want to use base pointer as an
19440 ;; alternative when no register is available later.
19441
19442 (define_peephole2
19443   [(match_scratch:SI 0 "r")
19444    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19445               (clobber (reg:CC FLAGS_REG))
19446               (clobber (mem:BLK (scratch)))])]
19447   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
19448   [(clobber (match_dup 0))
19449    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19450               (clobber (mem:BLK (scratch)))])])
19451
19452 (define_peephole2
19453   [(match_scratch:SI 0 "r")
19454    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19455               (clobber (reg:CC FLAGS_REG))
19456               (clobber (mem:BLK (scratch)))])]
19457   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
19458   [(clobber (match_dup 0))
19459    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19460    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19461               (clobber (mem:BLK (scratch)))])])
19462
19463 ;; Convert esp subtractions to push.
19464 (define_peephole2
19465   [(match_scratch:SI 0 "r")
19466    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19467               (clobber (reg:CC FLAGS_REG))])]
19468   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
19469   [(clobber (match_dup 0))
19470    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19471
19472 (define_peephole2
19473   [(match_scratch:SI 0 "r")
19474    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19475               (clobber (reg:CC FLAGS_REG))])]
19476   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
19477   [(clobber (match_dup 0))
19478    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19479    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19480
19481 ;; Convert epilogue deallocator to pop.
19482 (define_peephole2
19483   [(match_scratch:SI 0 "r")
19484    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19485               (clobber (reg:CC FLAGS_REG))
19486               (clobber (mem:BLK (scratch)))])]
19487   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
19488   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19489               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19490               (clobber (mem:BLK (scratch)))])]
19491   "")
19492
19493 ;; Two pops case is tricky, since pop causes dependency on destination register.
19494 ;; We use two registers if available.
19495 (define_peephole2
19496   [(match_scratch:SI 0 "r")
19497    (match_scratch:SI 1 "r")
19498    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19499               (clobber (reg:CC FLAGS_REG))
19500               (clobber (mem:BLK (scratch)))])]
19501   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
19502   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19503               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19504               (clobber (mem:BLK (scratch)))])
19505    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19506               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19507   "")
19508
19509 (define_peephole2
19510   [(match_scratch:SI 0 "r")
19511    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19512               (clobber (reg:CC FLAGS_REG))
19513               (clobber (mem:BLK (scratch)))])]
19514   "optimize_insn_for_size_p ()"
19515   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19516               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19517               (clobber (mem:BLK (scratch)))])
19518    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19519               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19520   "")
19521
19522 ;; Convert esp additions to pop.
19523 (define_peephole2
19524   [(match_scratch:SI 0 "r")
19525    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19526               (clobber (reg:CC FLAGS_REG))])]
19527   ""
19528   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19529               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19530   "")
19531
19532 ;; Two pops case is tricky, since pop causes dependency on destination register.
19533 ;; We use two registers if available.
19534 (define_peephole2
19535   [(match_scratch:SI 0 "r")
19536    (match_scratch:SI 1 "r")
19537    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19538               (clobber (reg:CC FLAGS_REG))])]
19539   ""
19540   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19541               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19542    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19543               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19544   "")
19545
19546 (define_peephole2
19547   [(match_scratch:SI 0 "r")
19548    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19549               (clobber (reg:CC FLAGS_REG))])]
19550   "optimize_insn_for_size_p ()"
19551   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19552               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19553    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19554               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19555   "")
19556 \f
19557 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
19558 ;; required and register dies.  Similarly for 128 to -128.
19559 (define_peephole2
19560   [(set (match_operand 0 "flags_reg_operand" "")
19561         (match_operator 1 "compare_operator"
19562           [(match_operand 2 "register_operand" "")
19563            (match_operand 3 "const_int_operand" "")]))]
19564   "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
19565      && incdec_operand (operands[3], GET_MODE (operands[3])))
19566     || (!TARGET_FUSE_CMP_AND_BRANCH
19567         && INTVAL (operands[3]) == 128))
19568    && ix86_match_ccmode (insn, CCGCmode)
19569    && peep2_reg_dead_p (1, operands[2])"
19570   [(parallel [(set (match_dup 0)
19571                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
19572               (clobber (match_dup 2))])]
19573   "")
19574 \f
19575 (define_peephole2
19576   [(match_scratch:DI 0 "r")
19577    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19578               (clobber (reg:CC FLAGS_REG))
19579               (clobber (mem:BLK (scratch)))])]
19580   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
19581   [(clobber (match_dup 0))
19582    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19583               (clobber (mem:BLK (scratch)))])])
19584
19585 (define_peephole2
19586   [(match_scratch:DI 0 "r")
19587    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19588               (clobber (reg:CC FLAGS_REG))
19589               (clobber (mem:BLK (scratch)))])]
19590   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
19591   [(clobber (match_dup 0))
19592    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19593    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19594               (clobber (mem:BLK (scratch)))])])
19595
19596 ;; Convert esp subtractions to push.
19597 (define_peephole2
19598   [(match_scratch:DI 0 "r")
19599    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19600               (clobber (reg:CC FLAGS_REG))])]
19601   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
19602   [(clobber (match_dup 0))
19603    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19604
19605 (define_peephole2
19606   [(match_scratch:DI 0 "r")
19607    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19608               (clobber (reg:CC FLAGS_REG))])]
19609   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
19610   [(clobber (match_dup 0))
19611    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19612    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19613
19614 ;; Convert epilogue deallocator to pop.
19615 (define_peephole2
19616   [(match_scratch:DI 0 "r")
19617    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19618               (clobber (reg:CC FLAGS_REG))
19619               (clobber (mem:BLK (scratch)))])]
19620   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
19621   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19622               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19623               (clobber (mem:BLK (scratch)))])]
19624   "")
19625
19626 ;; Two pops case is tricky, since pop causes dependency on destination register.
19627 ;; We use two registers if available.
19628 (define_peephole2
19629   [(match_scratch:DI 0 "r")
19630    (match_scratch:DI 1 "r")
19631    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19632               (clobber (reg:CC FLAGS_REG))
19633               (clobber (mem:BLK (scratch)))])]
19634   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
19635   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19636               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19637               (clobber (mem:BLK (scratch)))])
19638    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19639               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19640   "")
19641
19642 (define_peephole2
19643   [(match_scratch:DI 0 "r")
19644    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19645               (clobber (reg:CC FLAGS_REG))
19646               (clobber (mem:BLK (scratch)))])]
19647   "optimize_insn_for_size_p ()"
19648   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19649               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19650               (clobber (mem:BLK (scratch)))])
19651    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19652               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19653   "")
19654
19655 ;; Convert esp additions to pop.
19656 (define_peephole2
19657   [(match_scratch:DI 0 "r")
19658    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19659               (clobber (reg:CC FLAGS_REG))])]
19660   ""
19661   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19662               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19663   "")
19664
19665 ;; Two pops case is tricky, since pop causes dependency on destination register.
19666 ;; We use two registers if available.
19667 (define_peephole2
19668   [(match_scratch:DI 0 "r")
19669    (match_scratch:DI 1 "r")
19670    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19671               (clobber (reg:CC FLAGS_REG))])]
19672   ""
19673   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19674               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19675    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19676               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19677   "")
19678
19679 (define_peephole2
19680   [(match_scratch:DI 0 "r")
19681    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19682               (clobber (reg:CC FLAGS_REG))])]
19683   "optimize_insn_for_size_p ()"
19684   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19685               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19686    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19687               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19688   "")
19689 \f
19690 ;; Convert imul by three, five and nine into lea
19691 (define_peephole2
19692   [(parallel
19693     [(set (match_operand:SI 0 "register_operand" "")
19694           (mult:SI (match_operand:SI 1 "register_operand" "")
19695                    (match_operand:SI 2 "const_int_operand" "")))
19696      (clobber (reg:CC FLAGS_REG))])]
19697   "INTVAL (operands[2]) == 3
19698    || INTVAL (operands[2]) == 5
19699    || INTVAL (operands[2]) == 9"
19700   [(set (match_dup 0)
19701         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
19702                  (match_dup 1)))]
19703   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19704
19705 (define_peephole2
19706   [(parallel
19707     [(set (match_operand:SI 0 "register_operand" "")
19708           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19709                    (match_operand:SI 2 "const_int_operand" "")))
19710      (clobber (reg:CC FLAGS_REG))])]
19711   "optimize_insn_for_speed_p ()
19712    && (INTVAL (operands[2]) == 3
19713        || INTVAL (operands[2]) == 5
19714        || INTVAL (operands[2]) == 9)"
19715   [(set (match_dup 0) (match_dup 1))
19716    (set (match_dup 0)
19717         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
19718                  (match_dup 0)))]
19719   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19720
19721 (define_peephole2
19722   [(parallel
19723     [(set (match_operand:DI 0 "register_operand" "")
19724           (mult:DI (match_operand:DI 1 "register_operand" "")
19725                    (match_operand:DI 2 "const_int_operand" "")))
19726      (clobber (reg:CC FLAGS_REG))])]
19727   "TARGET_64BIT
19728    && (INTVAL (operands[2]) == 3
19729        || INTVAL (operands[2]) == 5
19730        || INTVAL (operands[2]) == 9)"
19731   [(set (match_dup 0)
19732         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
19733                  (match_dup 1)))]
19734   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19735
19736 (define_peephole2
19737   [(parallel
19738     [(set (match_operand:DI 0 "register_operand" "")
19739           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19740                    (match_operand:DI 2 "const_int_operand" "")))
19741      (clobber (reg:CC FLAGS_REG))])]
19742   "TARGET_64BIT
19743    && optimize_insn_for_speed_p ()
19744    && (INTVAL (operands[2]) == 3
19745        || INTVAL (operands[2]) == 5
19746        || INTVAL (operands[2]) == 9)"
19747   [(set (match_dup 0) (match_dup 1))
19748    (set (match_dup 0)
19749         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
19750                  (match_dup 0)))]
19751   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19752
19753 ;; Imul $32bit_imm, mem, reg is vector decoded, while
19754 ;; imul $32bit_imm, reg, reg is direct decoded.
19755 (define_peephole2
19756   [(match_scratch:DI 3 "r")
19757    (parallel [(set (match_operand:DI 0 "register_operand" "")
19758                    (mult:DI (match_operand:DI 1 "memory_operand" "")
19759                             (match_operand:DI 2 "immediate_operand" "")))
19760               (clobber (reg:CC FLAGS_REG))])]
19761   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
19762    && !satisfies_constraint_K (operands[2])"
19763   [(set (match_dup 3) (match_dup 1))
19764    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
19765               (clobber (reg:CC FLAGS_REG))])]
19766 "")
19767
19768 (define_peephole2
19769   [(match_scratch:SI 3 "r")
19770    (parallel [(set (match_operand:SI 0 "register_operand" "")
19771                    (mult:SI (match_operand:SI 1 "memory_operand" "")
19772                             (match_operand:SI 2 "immediate_operand" "")))
19773               (clobber (reg:CC FLAGS_REG))])]
19774   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
19775    && !satisfies_constraint_K (operands[2])"
19776   [(set (match_dup 3) (match_dup 1))
19777    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
19778               (clobber (reg:CC FLAGS_REG))])]
19779 "")
19780
19781 (define_peephole2
19782   [(match_scratch:SI 3 "r")
19783    (parallel [(set (match_operand:DI 0 "register_operand" "")
19784                    (zero_extend:DI
19785                      (mult:SI (match_operand:SI 1 "memory_operand" "")
19786                               (match_operand:SI 2 "immediate_operand" ""))))
19787               (clobber (reg:CC FLAGS_REG))])]
19788   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
19789    && !satisfies_constraint_K (operands[2])"
19790   [(set (match_dup 3) (match_dup 1))
19791    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19792               (clobber (reg:CC FLAGS_REG))])]
19793 "")
19794
19795 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19796 ;; Convert it into imul reg, reg
19797 ;; It would be better to force assembler to encode instruction using long
19798 ;; immediate, but there is apparently no way to do so.
19799 (define_peephole2
19800   [(parallel [(set (match_operand:DI 0 "register_operand" "")
19801                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19802                             (match_operand:DI 2 "const_int_operand" "")))
19803               (clobber (reg:CC FLAGS_REG))])
19804    (match_scratch:DI 3 "r")]
19805   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
19806    && satisfies_constraint_K (operands[2])"
19807   [(set (match_dup 3) (match_dup 2))
19808    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
19809               (clobber (reg:CC FLAGS_REG))])]
19810 {
19811   if (!rtx_equal_p (operands[0], operands[1]))
19812     emit_move_insn (operands[0], operands[1]);
19813 })
19814
19815 (define_peephole2
19816   [(parallel [(set (match_operand:SI 0 "register_operand" "")
19817                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19818                             (match_operand:SI 2 "const_int_operand" "")))
19819               (clobber (reg:CC FLAGS_REG))])
19820    (match_scratch:SI 3 "r")]
19821   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
19822    && satisfies_constraint_K (operands[2])"
19823   [(set (match_dup 3) (match_dup 2))
19824    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
19825               (clobber (reg:CC FLAGS_REG))])]
19826 {
19827   if (!rtx_equal_p (operands[0], operands[1]))
19828     emit_move_insn (operands[0], operands[1]);
19829 })
19830
19831 (define_peephole2
19832   [(parallel [(set (match_operand:HI 0 "register_operand" "")
19833                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
19834                             (match_operand:HI 2 "immediate_operand" "")))
19835               (clobber (reg:CC FLAGS_REG))])
19836    (match_scratch:HI 3 "r")]
19837   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()"
19838   [(set (match_dup 3) (match_dup 2))
19839    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
19840               (clobber (reg:CC FLAGS_REG))])]
19841 {
19842   if (!rtx_equal_p (operands[0], operands[1]))
19843     emit_move_insn (operands[0], operands[1]);
19844 })
19845
19846 ;; After splitting up read-modify operations, array accesses with memory
19847 ;; operands might end up in form:
19848 ;;  sall    $2, %eax
19849 ;;  movl    4(%esp), %edx
19850 ;;  addl    %edx, %eax
19851 ;; instead of pre-splitting:
19852 ;;  sall    $2, %eax
19853 ;;  addl    4(%esp), %eax
19854 ;; Turn it into:
19855 ;;  movl    4(%esp), %edx
19856 ;;  leal    (%edx,%eax,4), %eax
19857
19858 (define_peephole2
19859   [(parallel [(set (match_operand 0 "register_operand" "")
19860                    (ashift (match_operand 1 "register_operand" "")
19861                            (match_operand 2 "const_int_operand" "")))
19862                (clobber (reg:CC FLAGS_REG))])
19863    (set (match_operand 3 "register_operand")
19864         (match_operand 4 "x86_64_general_operand" ""))
19865    (parallel [(set (match_operand 5 "register_operand" "")
19866                    (plus (match_operand 6 "register_operand" "")
19867                          (match_operand 7 "register_operand" "")))
19868                    (clobber (reg:CC FLAGS_REG))])]
19869   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
19870    /* Validate MODE for lea.  */
19871    && ((!TARGET_PARTIAL_REG_STALL
19872         && (GET_MODE (operands[0]) == QImode
19873             || GET_MODE (operands[0]) == HImode))
19874        || GET_MODE (operands[0]) == SImode
19875        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
19876    /* We reorder load and the shift.  */
19877    && !rtx_equal_p (operands[1], operands[3])
19878    && !reg_overlap_mentioned_p (operands[0], operands[4])
19879    /* Last PLUS must consist of operand 0 and 3.  */
19880    && !rtx_equal_p (operands[0], operands[3])
19881    && (rtx_equal_p (operands[3], operands[6])
19882        || rtx_equal_p (operands[3], operands[7]))
19883    && (rtx_equal_p (operands[0], operands[6])
19884        || rtx_equal_p (operands[0], operands[7]))
19885    /* The intermediate operand 0 must die or be same as output.  */
19886    && (rtx_equal_p (operands[0], operands[5])
19887        || peep2_reg_dead_p (3, operands[0]))"
19888   [(set (match_dup 3) (match_dup 4))
19889    (set (match_dup 0) (match_dup 1))]
19890 {
19891   enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
19892   int scale = 1 << INTVAL (operands[2]);
19893   rtx index = gen_lowpart (Pmode, operands[1]);
19894   rtx base = gen_lowpart (Pmode, operands[3]);
19895   rtx dest = gen_lowpart (mode, operands[5]);
19896
19897   operands[1] = gen_rtx_PLUS (Pmode, base,
19898                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
19899   if (mode != Pmode)
19900     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
19901   operands[0] = dest;
19902 })
19903 \f
19904 ;; Call-value patterns last so that the wildcard operand does not
19905 ;; disrupt insn-recog's switch tables.
19906
19907 (define_insn "*call_value_pop_0"
19908   [(set (match_operand 0 "" "")
19909         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19910               (match_operand:SI 2 "" "")))
19911    (set (reg:SI SP_REG)
19912         (plus:SI (reg:SI SP_REG)
19913                  (match_operand:SI 3 "immediate_operand" "")))]
19914   "!TARGET_64BIT"
19915 {
19916   if (SIBLING_CALL_P (insn))
19917     return "jmp\t%P1";
19918   else
19919     return "call\t%P1";
19920 }
19921   [(set_attr "type" "callv")])
19922
19923 (define_insn "*call_value_pop_1"
19924   [(set (match_operand 0 "" "")
19925         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
19926               (match_operand:SI 2 "" "")))
19927    (set (reg:SI SP_REG)
19928         (plus:SI (reg:SI SP_REG)
19929                  (match_operand:SI 3 "immediate_operand" "i")))]
19930   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
19931 {
19932   if (constant_call_address_operand (operands[1], Pmode))
19933     return "call\t%P1";
19934   return "call\t%A1";
19935 }
19936   [(set_attr "type" "callv")])
19937
19938 (define_insn "*sibcall_value_pop_1"
19939   [(set (match_operand 0 "" "")
19940         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
19941               (match_operand:SI 2 "" "")))
19942    (set (reg:SI SP_REG)
19943         (plus:SI (reg:SI SP_REG)
19944                  (match_operand:SI 3 "immediate_operand" "i,i")))]
19945   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
19946   "@
19947    jmp\t%P1
19948    jmp\t%A1"
19949   [(set_attr "type" "callv")])
19950
19951 (define_insn "*call_value_0"
19952   [(set (match_operand 0 "" "")
19953         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19954               (match_operand:SI 2 "" "")))]
19955   "!TARGET_64BIT"
19956 {
19957   if (SIBLING_CALL_P (insn))
19958     return "jmp\t%P1";
19959   else
19960     return "call\t%P1";
19961 }
19962   [(set_attr "type" "callv")])
19963
19964 (define_insn "*call_value_0_rex64"
19965   [(set (match_operand 0 "" "")
19966         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19967               (match_operand:DI 2 "const_int_operand" "")))]
19968   "TARGET_64BIT"
19969 {
19970   if (SIBLING_CALL_P (insn))
19971     return "jmp\t%P1";
19972   else
19973     return "call\t%P1";
19974 }
19975   [(set_attr "type" "callv")])
19976
19977 (define_insn "*call_value_0_rex64_ms_sysv"
19978   [(set (match_operand 0 "" "")
19979         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19980               (match_operand:DI 2 "const_int_operand" "")))
19981    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
19982    (clobber (reg:TI XMM6_REG))
19983    (clobber (reg:TI XMM7_REG))
19984    (clobber (reg:TI XMM8_REG))
19985    (clobber (reg:TI XMM9_REG))
19986    (clobber (reg:TI XMM10_REG))
19987    (clobber (reg:TI XMM11_REG))
19988    (clobber (reg:TI XMM12_REG))
19989    (clobber (reg:TI XMM13_REG))
19990    (clobber (reg:TI XMM14_REG))
19991    (clobber (reg:TI XMM15_REG))
19992    (clobber (reg:DI SI_REG))
19993    (clobber (reg:DI DI_REG))]
19994   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
19995 {
19996   if (SIBLING_CALL_P (insn))
19997     return "jmp\t%P1";
19998   else
19999     return "call\t%P1";
20000 }
20001   [(set_attr "type" "callv")])
20002
20003 (define_insn "*call_value_1"
20004   [(set (match_operand 0 "" "")
20005         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
20006               (match_operand:SI 2 "" "")))]
20007   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
20008 {
20009   if (constant_call_address_operand (operands[1], Pmode))
20010     return "call\t%P1";
20011   return "call\t%A1";
20012 }
20013   [(set_attr "type" "callv")])
20014
20015 (define_insn "*sibcall_value_1"
20016   [(set (match_operand 0 "" "")
20017         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
20018               (match_operand:SI 2 "" "")))]
20019   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
20020   "@
20021    jmp\t%P1
20022    jmp\t%A1"
20023   [(set_attr "type" "callv")])
20024
20025 (define_insn "*call_value_1_rex64"
20026   [(set (match_operand 0 "" "")
20027         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20028               (match_operand:DI 2 "" "")))]
20029   "TARGET_64BIT && !SIBLING_CALL_P (insn)
20030    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
20031 {
20032   if (constant_call_address_operand (operands[1], Pmode))
20033     return "call\t%P1";
20034   return "call\t%A1";
20035 }
20036   [(set_attr "type" "callv")])
20037
20038 (define_insn "*call_value_1_rex64_ms_sysv"
20039   [(set (match_operand 0 "" "")
20040         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20041               (match_operand:DI 2 "" "")))
20042    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
20043    (clobber (reg:TI XMM6_REG))
20044    (clobber (reg:TI XMM7_REG))
20045    (clobber (reg:TI XMM8_REG))
20046    (clobber (reg:TI XMM9_REG))
20047    (clobber (reg:TI XMM10_REG))
20048    (clobber (reg:TI XMM11_REG))
20049    (clobber (reg:TI XMM12_REG))
20050    (clobber (reg:TI XMM13_REG))
20051    (clobber (reg:TI XMM14_REG))
20052    (clobber (reg:TI XMM15_REG))
20053    (clobber (reg:DI SI_REG))
20054    (clobber (reg:DI DI_REG))]
20055   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
20056 {
20057   if (constant_call_address_operand (operands[1], Pmode))
20058     return "call\t%P1";
20059   return "call\t%A1";
20060 }
20061   [(set_attr "type" "callv")])
20062
20063 (define_insn "*call_value_1_rex64_large"
20064   [(set (match_operand 0 "" "")
20065         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
20066               (match_operand:DI 2 "" "")))]
20067   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
20068   "call\t%A1"
20069   [(set_attr "type" "callv")])
20070
20071 (define_insn "*sibcall_value_1_rex64"
20072   [(set (match_operand 0 "" "")
20073         (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
20074               (match_operand:DI 2 "" "")))]
20075   "TARGET_64BIT && SIBLING_CALL_P (insn)"
20076   "@
20077    jmp\t%P1
20078    jmp\t%A1"
20079   [(set_attr "type" "callv")])
20080 \f
20081 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20082 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
20083 ;; caught for use by garbage collectors and the like.  Using an insn that
20084 ;; maps to SIGILL makes it more likely the program will rightfully die.
20085 ;; Keeping with tradition, "6" is in honor of #UD.
20086 (define_insn "trap"
20087   [(trap_if (const_int 1) (const_int 6))]
20088   ""
20089   { return ASM_SHORT "0x0b0f"; }
20090   [(set_attr "length" "2")])
20091
20092 (define_expand "sse_prologue_save"
20093   [(parallel [(set (match_operand:BLK 0 "" "")
20094                    (unspec:BLK [(reg:DI XMM0_REG)
20095                                 (reg:DI XMM1_REG)
20096                                 (reg:DI XMM2_REG)
20097                                 (reg:DI XMM3_REG)
20098                                 (reg:DI XMM4_REG)
20099                                 (reg:DI XMM5_REG)
20100                                 (reg:DI XMM6_REG)
20101                                 (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE))
20102               (use (match_operand:DI 1 "register_operand" ""))
20103               (use (match_operand:DI 2 "immediate_operand" ""))
20104               (use (label_ref:DI (match_operand 3 "" "")))])]
20105   "TARGET_64BIT"
20106   "")
20107
20108 (define_insn "*sse_prologue_save_insn"
20109   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20110                           (match_operand:DI 4 "const_int_operand" "n")))
20111         (unspec:BLK [(reg:DI XMM0_REG)
20112                      (reg:DI XMM1_REG)
20113                      (reg:DI XMM2_REG)
20114                      (reg:DI XMM3_REG)
20115                      (reg:DI XMM4_REG)
20116                      (reg:DI XMM5_REG)
20117                      (reg:DI XMM6_REG)
20118                      (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE))
20119    (use (match_operand:DI 1 "register_operand" "r"))
20120    (use (match_operand:DI 2 "const_int_operand" "i"))
20121    (use (label_ref:DI (match_operand 3 "" "X")))]
20122   "TARGET_64BIT
20123    && INTVAL (operands[4]) + X86_64_SSE_REGPARM_MAX * 16 - 16 < 128
20124    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20125 {
20126   int i;
20127   operands[0] = gen_rtx_MEM (Pmode,
20128                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20129   /* VEX instruction with a REX prefix will #UD.  */
20130   if (TARGET_AVX && GET_CODE (XEXP (operands[0], 0)) != PLUS)
20131     gcc_unreachable ();
20132
20133   output_asm_insn ("jmp\t%A1", operands);
20134   for (i = X86_64_SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20135     {
20136       operands[4] = adjust_address (operands[0], DImode, i*16);
20137       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20138       PUT_MODE (operands[4], TImode);
20139       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20140         output_asm_insn ("rex", operands);
20141       output_asm_insn ("%vmovaps\t{%5, %4|%4, %5}", operands);
20142     }
20143   (*targetm.asm_out.internal_label) (asm_out_file, "L",
20144                                      CODE_LABEL_NUMBER (operands[3]));
20145   return "";
20146 }
20147   [(set_attr "type" "other")
20148    (set_attr "length_immediate" "0")
20149    (set_attr "length_address" "0")
20150    (set (attr "length")
20151      (if_then_else
20152        (eq (symbol_ref "TARGET_AVX") (const_int 0))
20153        (const_string "34")
20154        (const_string "42")))
20155    (set_attr "memory" "store")
20156    (set_attr "modrm" "0")
20157    (set_attr "prefix" "maybe_vex")
20158    (set_attr "mode" "DI")])
20159
20160 (define_expand "prefetch"
20161   [(prefetch (match_operand 0 "address_operand" "")
20162              (match_operand:SI 1 "const_int_operand" "")
20163              (match_operand:SI 2 "const_int_operand" ""))]
20164   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20165 {
20166   int rw = INTVAL (operands[1]);
20167   int locality = INTVAL (operands[2]);
20168
20169   gcc_assert (rw == 0 || rw == 1);
20170   gcc_assert (locality >= 0 && locality <= 3);
20171   gcc_assert (GET_MODE (operands[0]) == Pmode
20172               || GET_MODE (operands[0]) == VOIDmode);
20173
20174   /* Use 3dNOW prefetch in case we are asking for write prefetch not
20175      supported by SSE counterpart or the SSE prefetch is not available
20176      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
20177      of locality.  */
20178   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
20179     operands[2] = GEN_INT (3);
20180   else
20181     operands[1] = const0_rtx;
20182 })
20183
20184 (define_insn "*prefetch_sse"
20185   [(prefetch (match_operand:SI 0 "address_operand" "p")
20186              (const_int 0)
20187              (match_operand:SI 1 "const_int_operand" ""))]
20188   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
20189 {
20190   static const char * const patterns[4] = {
20191    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20192   };
20193
20194   int locality = INTVAL (operands[1]);
20195   gcc_assert (locality >= 0 && locality <= 3);
20196
20197   return patterns[locality];
20198 }
20199   [(set_attr "type" "sse")
20200    (set_attr "atom_sse_attr" "prefetch")
20201    (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
20202    (set_attr "memory" "none")])
20203
20204 (define_insn "*prefetch_sse_rex"
20205   [(prefetch (match_operand:DI 0 "address_operand" "p")
20206              (const_int 0)
20207              (match_operand:SI 1 "const_int_operand" ""))]
20208   "TARGET_PREFETCH_SSE && TARGET_64BIT"
20209 {
20210   static const char * const patterns[4] = {
20211    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20212   };
20213
20214   int locality = INTVAL (operands[1]);
20215   gcc_assert (locality >= 0 && locality <= 3);
20216
20217   return patterns[locality];
20218 }
20219   [(set_attr "type" "sse")
20220    (set_attr "atom_sse_attr" "prefetch")
20221    (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
20222    (set_attr "memory" "none")])
20223
20224 (define_insn "*prefetch_3dnow"
20225   [(prefetch (match_operand:SI 0 "address_operand" "p")
20226              (match_operand:SI 1 "const_int_operand" "n")
20227              (const_int 3))]
20228   "TARGET_3DNOW && !TARGET_64BIT"
20229 {
20230   if (INTVAL (operands[1]) == 0)
20231     return "prefetch\t%a0";
20232   else
20233     return "prefetchw\t%a0";
20234 }
20235   [(set_attr "type" "mmx")
20236    (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
20237    (set_attr "memory" "none")])
20238
20239 (define_insn "*prefetch_3dnow_rex"
20240   [(prefetch (match_operand:DI 0 "address_operand" "p")
20241              (match_operand:SI 1 "const_int_operand" "n")
20242              (const_int 3))]
20243   "TARGET_3DNOW && TARGET_64BIT"
20244 {
20245   if (INTVAL (operands[1]) == 0)
20246     return "prefetch\t%a0";
20247   else
20248     return "prefetchw\t%a0";
20249 }
20250   [(set_attr "type" "mmx")
20251    (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
20252    (set_attr "memory" "none")])
20253
20254 (define_expand "stack_protect_set"
20255   [(match_operand 0 "memory_operand" "")
20256    (match_operand 1 "memory_operand" "")]
20257   ""
20258 {
20259 #ifdef TARGET_THREAD_SSP_OFFSET
20260   if (TARGET_64BIT)
20261     emit_insn (gen_stack_tls_protect_set_di (operands[0],
20262                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20263   else
20264     emit_insn (gen_stack_tls_protect_set_si (operands[0],
20265                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20266 #else
20267   if (TARGET_64BIT)
20268     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
20269   else
20270     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
20271 #endif
20272   DONE;
20273 })
20274
20275 (define_insn "stack_protect_set_si"
20276   [(set (match_operand:SI 0 "memory_operand" "=m")
20277         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20278    (set (match_scratch:SI 2 "=&r") (const_int 0))
20279    (clobber (reg:CC FLAGS_REG))]
20280   ""
20281   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20282   [(set_attr "type" "multi")])
20283
20284 (define_insn "stack_protect_set_di"
20285   [(set (match_operand:DI 0 "memory_operand" "=m")
20286         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20287    (set (match_scratch:DI 2 "=&r") (const_int 0))
20288    (clobber (reg:CC FLAGS_REG))]
20289   "TARGET_64BIT"
20290   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20291   [(set_attr "type" "multi")])
20292
20293 (define_insn "stack_tls_protect_set_si"
20294   [(set (match_operand:SI 0 "memory_operand" "=m")
20295         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20296    (set (match_scratch:SI 2 "=&r") (const_int 0))
20297    (clobber (reg:CC FLAGS_REG))]
20298   ""
20299   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20300   [(set_attr "type" "multi")])
20301
20302 (define_insn "stack_tls_protect_set_di"
20303   [(set (match_operand:DI 0 "memory_operand" "=m")
20304         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20305    (set (match_scratch:DI 2 "=&r") (const_int 0))
20306    (clobber (reg:CC FLAGS_REG))]
20307   "TARGET_64BIT"
20308   {
20309      /* The kernel uses a different segment register for performance reasons; a
20310         system call would not have to trash the userspace segment register,
20311         which would be expensive */
20312      if (ix86_cmodel != CM_KERNEL)
20313         return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20314      else
20315         return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20316   }
20317   [(set_attr "type" "multi")])
20318
20319 (define_expand "stack_protect_test"
20320   [(match_operand 0 "memory_operand" "")
20321    (match_operand 1 "memory_operand" "")
20322    (match_operand 2 "" "")]
20323   ""
20324 {
20325   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
20326
20327 #ifdef TARGET_THREAD_SSP_OFFSET
20328   if (TARGET_64BIT)
20329     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
20330                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20331   else
20332     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
20333                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20334 #else
20335   if (TARGET_64BIT)
20336     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
20337   else
20338     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
20339 #endif
20340
20341   emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
20342                                   flags, const0_rtx, operands[2]));
20343   DONE;
20344 })
20345
20346 (define_insn "stack_protect_test_si"
20347   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20348         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20349                      (match_operand:SI 2 "memory_operand" "m")]
20350                     UNSPEC_SP_TEST))
20351    (clobber (match_scratch:SI 3 "=&r"))]
20352   ""
20353   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
20354   [(set_attr "type" "multi")])
20355
20356 (define_insn "stack_protect_test_di"
20357   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20358         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20359                      (match_operand:DI 2 "memory_operand" "m")]
20360                     UNSPEC_SP_TEST))
20361    (clobber (match_scratch:DI 3 "=&r"))]
20362   "TARGET_64BIT"
20363   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
20364   [(set_attr "type" "multi")])
20365
20366 (define_insn "stack_tls_protect_test_si"
20367   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20368         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20369                      (match_operand:SI 2 "const_int_operand" "i")]
20370                     UNSPEC_SP_TLS_TEST))
20371    (clobber (match_scratch:SI 3 "=r"))]
20372   ""
20373   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
20374   [(set_attr "type" "multi")])
20375
20376 (define_insn "stack_tls_protect_test_di"
20377   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20378         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20379                      (match_operand:DI 2 "const_int_operand" "i")]
20380                     UNSPEC_SP_TLS_TEST))
20381    (clobber (match_scratch:DI 3 "=r"))]
20382   "TARGET_64BIT"
20383   {
20384      /* The kernel uses a different segment register for performance reasons; a
20385         system call would not have to trash the userspace segment register,
20386         which would be expensive */
20387      if (ix86_cmodel != CM_KERNEL)
20388         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
20389      else
20390         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
20391   }
20392   [(set_attr "type" "multi")])
20393
20394 (define_insn "sse4_2_crc32<mode>"
20395   [(set (match_operand:SI 0 "register_operand" "=r")
20396         (unspec:SI
20397           [(match_operand:SI 1 "register_operand" "0")
20398            (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
20399           UNSPEC_CRC32))]
20400   "TARGET_SSE4_2 || TARGET_CRC32"
20401   "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
20402   [(set_attr "type" "sselog1")
20403    (set_attr "prefix_rep" "1")
20404    (set_attr "prefix_extra" "1")
20405    (set (attr "prefix_data16")
20406      (if_then_else (match_operand:HI 2 "" "")
20407        (const_string "1")
20408        (const_string "*")))
20409    (set (attr "prefix_rex")
20410      (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
20411        (const_string "1")
20412        (const_string "*")))
20413    (set_attr "mode" "SI")])
20414
20415 (define_insn "sse4_2_crc32di"
20416   [(set (match_operand:DI 0 "register_operand" "=r")
20417         (unspec:DI
20418           [(match_operand:DI 1 "register_operand" "0")
20419            (match_operand:DI 2 "nonimmediate_operand" "rm")]
20420           UNSPEC_CRC32))]
20421   "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
20422   "crc32{q}\t{%2, %0|%0, %2}"
20423   [(set_attr "type" "sselog1")
20424    (set_attr "prefix_rep" "1")
20425    (set_attr "prefix_extra" "1")
20426    (set_attr "mode" "DI")])
20427
20428 (define_expand "rdpmc"
20429   [(match_operand:DI 0 "register_operand" "")
20430    (match_operand:SI 1 "register_operand" "")]
20431   ""
20432 {
20433   rtx reg = gen_reg_rtx (DImode);
20434   rtx si;
20435
20436   /* Force operand 1 into ECX.  */
20437   rtx ecx = gen_rtx_REG (SImode, CX_REG);
20438   emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
20439   si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
20440                                 UNSPECV_RDPMC);
20441
20442   if (TARGET_64BIT)
20443     {
20444       rtvec vec = rtvec_alloc (2);
20445       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
20446       rtx upper = gen_reg_rtx (DImode);
20447       rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
20448                                         gen_rtvec (1, const0_rtx),
20449                                         UNSPECV_RDPMC);
20450       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
20451       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
20452       emit_insn (load);
20453       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
20454                                    NULL, 1, OPTAB_DIRECT);
20455       reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
20456                                  OPTAB_DIRECT);
20457     }
20458   else
20459     emit_insn (gen_rtx_SET (VOIDmode, reg, si));
20460   emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
20461   DONE;
20462 })
20463
20464 (define_insn "*rdpmc"
20465   [(set (match_operand:DI 0 "register_operand" "=A")
20466         (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
20467                             UNSPECV_RDPMC))]
20468   "!TARGET_64BIT"
20469   "rdpmc"
20470   [(set_attr "type" "other")
20471    (set_attr "length" "2")])
20472
20473 (define_insn "*rdpmc_rex64"
20474   [(set (match_operand:DI 0 "register_operand" "=a")
20475         (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
20476                             UNSPECV_RDPMC))
20477   (set (match_operand:DI 1 "register_operand" "=d")
20478        (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
20479   "TARGET_64BIT"
20480   "rdpmc"
20481   [(set_attr "type" "other")
20482    (set_attr "length" "2")])
20483
20484 (define_expand "rdtsc"
20485   [(set (match_operand:DI 0 "register_operand" "")
20486         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
20487   ""
20488 {
20489   if (TARGET_64BIT)
20490     {
20491       rtvec vec = rtvec_alloc (2);
20492       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
20493       rtx upper = gen_reg_rtx (DImode);
20494       rtx lower = gen_reg_rtx (DImode);
20495       rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
20496                                          gen_rtvec (1, const0_rtx),
20497                                          UNSPECV_RDTSC);
20498       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
20499       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
20500       emit_insn (load);
20501       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
20502                                    NULL, 1, OPTAB_DIRECT);
20503       lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
20504                                    OPTAB_DIRECT);
20505       emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
20506       DONE;
20507     }
20508 })
20509
20510 (define_insn "*rdtsc"
20511   [(set (match_operand:DI 0 "register_operand" "=A")
20512         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
20513   "!TARGET_64BIT"
20514   "rdtsc"
20515   [(set_attr "type" "other")
20516    (set_attr "length" "2")])
20517
20518 (define_insn "*rdtsc_rex64"
20519   [(set (match_operand:DI 0 "register_operand" "=a")
20520         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
20521    (set (match_operand:DI 1 "register_operand" "=d")
20522         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
20523   "TARGET_64BIT"
20524   "rdtsc"
20525   [(set_attr "type" "other")
20526    (set_attr "length" "2")])
20527
20528 (define_expand "rdtscp"
20529   [(match_operand:DI 0 "register_operand" "")
20530    (match_operand:SI 1 "memory_operand" "")]
20531   ""
20532 {
20533   rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
20534                                     gen_rtvec (1, const0_rtx),
20535                                     UNSPECV_RDTSCP);
20536   rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
20537                                     gen_rtvec (1, const0_rtx),
20538                                     UNSPECV_RDTSCP);
20539   rtx reg = gen_reg_rtx (DImode);
20540   rtx tmp = gen_reg_rtx (SImode);
20541
20542   if (TARGET_64BIT)
20543     {
20544       rtvec vec = rtvec_alloc (3);
20545       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
20546       rtx upper = gen_reg_rtx (DImode);
20547       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
20548       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
20549       RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
20550       emit_insn (load);
20551       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
20552                                    NULL, 1, OPTAB_DIRECT);
20553       reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
20554                                  OPTAB_DIRECT);
20555     }
20556   else
20557     {
20558       rtvec vec = rtvec_alloc (2);
20559       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
20560       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
20561       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
20562       emit_insn (load);
20563     }
20564   emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
20565   emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
20566   DONE;
20567 })
20568
20569 (define_insn "*rdtscp"
20570   [(set (match_operand:DI 0 "register_operand" "=A")
20571         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
20572    (set (match_operand:SI 1 "register_operand" "=c")
20573         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
20574   "!TARGET_64BIT"
20575   "rdtscp"
20576   [(set_attr "type" "other")
20577    (set_attr "length" "3")])
20578
20579 (define_insn "*rdtscp_rex64"
20580   [(set (match_operand:DI 0 "register_operand" "=a")
20581         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
20582    (set (match_operand:DI 1 "register_operand" "=d")
20583         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
20584    (set (match_operand:SI 2 "register_operand" "=c")
20585         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
20586   "TARGET_64BIT"
20587   "rdtscp"
20588   [(set_attr "type" "other")
20589    (set_attr "length" "3")])
20590
20591 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
20592 ;;
20593 ;; LWP instructions
20594 ;;
20595 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
20596
20597 (define_expand "lwp_llwpcb"
20598   [(unspec_volatile [(match_operand 0 "register_operand" "r")]
20599                     UNSPECV_LLWP_INTRINSIC)]
20600   "TARGET_LWP"
20601   "")
20602
20603 (define_insn "*lwp_llwpcb<mode>1"
20604   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
20605                     UNSPECV_LLWP_INTRINSIC)]
20606   "TARGET_LWP"
20607   "llwpcb\t%0"
20608   [(set_attr "type" "lwp")
20609    (set_attr "mode" "<MODE>")
20610    (set_attr "length" "5")])
20611
20612 (define_expand "lwp_slwpcb"
20613   [(set (match_operand 0 "register_operand" "=r")
20614         (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
20615   "TARGET_LWP"
20616   {
20617     if (TARGET_64BIT)
20618       emit_insn (gen_lwp_slwpcbdi (operands[0]));
20619     else
20620       emit_insn (gen_lwp_slwpcbsi (operands[0]));
20621     DONE;
20622   })
20623
20624 (define_insn "lwp_slwpcb<mode>"
20625   [(set (match_operand:P 0 "register_operand" "=r")
20626         (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
20627   "TARGET_LWP"
20628   "slwpcb\t%0"
20629   [(set_attr "type" "lwp")
20630    (set_attr "mode" "<MODE>")
20631    (set_attr "length" "5")])
20632
20633 (define_expand "lwp_lwpval<mode>3"
20634   [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
20635                      (match_operand:SI 2 "nonimmediate_operand" "rm")
20636                      (match_operand:SI 3 "const_int_operand" "i")]
20637                     UNSPECV_LWPVAL_INTRINSIC)]
20638   "TARGET_LWP"
20639   "/* Avoid unused variable warning.  */
20640    (void) operand0;")
20641
20642 (define_insn "*lwp_lwpval<mode>3_1"
20643   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
20644                      (match_operand:SI 1 "nonimmediate_operand" "rm")
20645                      (match_operand:SI 2 "const_int_operand" "i")]
20646                     UNSPECV_LWPVAL_INTRINSIC)]
20647   "TARGET_LWP"
20648   "lwpval\t{%2, %1, %0|%0, %1, %2}"
20649   [(set_attr "type" "lwp")
20650    (set_attr "mode" "<MODE>")
20651    (set (attr "length")
20652         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
20653
20654 (define_expand "lwp_lwpins<mode>3"
20655   [(set (reg:CCC FLAGS_REG)
20656         (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
20657                               (match_operand:SI 2 "nonimmediate_operand" "rm")
20658                               (match_operand:SI 3 "const_int_operand" "i")]
20659                              UNSPECV_LWPINS_INTRINSIC))
20660    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
20661         (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
20662   "TARGET_LWP"
20663   "")
20664
20665 (define_insn "*lwp_lwpins<mode>3_1"
20666   [(set (reg:CCC FLAGS_REG)
20667         (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
20668                               (match_operand:SI 1 "nonimmediate_operand" "rm")
20669                               (match_operand:SI 2 "const_int_operand" "i")]
20670                              UNSPECV_LWPINS_INTRINSIC))]
20671   "TARGET_LWP"
20672   "lwpins\t{%2, %1, %0|%0, %1, %2}"
20673   [(set_attr "type" "lwp")
20674    (set_attr "mode" "<MODE>")
20675    (set (attr "length")
20676         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
20677
20678 (include "mmx.md")
20679 (include "sse.md")
20680 (include "sync.md")